1use serde::{Deserialize, Serialize};
2
3use crate::{
4 access_token::AccessTokenProvider,
5 error::{CommonError, CommonResponse},
6 wechat::WxApiRequestBuilder,
7 SdkResult, WxSdk,
8};
9
10use super::media::MediaId;
11
12pub struct DraftModule<'a, T: AccessTokenProvider>(pub(crate) &'a WxSdk<T>);
13
14#[derive(Serialize, Deserialize)]
15pub struct Articles {
16 pub title: String,
17 pub author: String,
18 pub digest: String,
19 pub content: String,
20 pub content_source_url: String,
21 pub thumb_media_id: String,
22 pub show_cover_pic: i8,
24 pub need_open_comment: Option<i8>,
25 pub only_fans_can_comment: Option<i8>,
26 #[serde(skip_serializing)]
27 pub url: Option<String>,
28 #[serde(skip_serializing)]
29 pub is_deleted: Option<bool>,
30}
31
32#[derive(Serialize, Deserialize)]
33pub struct NewsItemList {
34 pub news_item: Vec<Articles>,
35}
36
37#[derive(Serialize, Deserialize)]
38pub struct UpdateNews {
39 pub media_id: String,
40 pub index: i32,
42 pub articles: Articles,
44}
45
46#[derive(Serialize, Deserialize)]
47pub struct TotalCount {
48 pub total_count: i32,
49}
50
51#[derive(Serialize, Deserialize)]
52pub struct NewsItem {
53 pub media_id: String,
54 pub content: NewsItemList,
55 pub update_time: i64,
56}
57#[derive(Serialize, Deserialize)]
58pub struct BatchList {
59 pub total_count: i32,
60 pub item_count: i32,
61 pub item: Vec<NewsItem>,
62}
63
64impl<'a, T: AccessTokenProvider> DraftModule<'a, T> {
65 pub async fn add(&self, articles: &[Articles]) -> SdkResult<MediaId> {
67 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/add";
68 let sdk = self.0;
69 let builder = sdk.wx_post(base_url).await?;
70 let res: CommonResponse<MediaId> = builder
71 .json(&serde_json::json!({ "articles": articles }))
72 .send()
73 .await?
74 .json()
75 .await?;
76 res.into()
77 }
78
79 pub async fn get(&self, media_id: &str) -> SdkResult<NewsItemList> {
81 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/get";
82 let sdk = self.0;
83 let builder = sdk.wx_post(base_url).await?;
84 let res: CommonResponse<NewsItemList> = builder
85 .json(&serde_json::json!({ "media_id": media_id }))
86 .send()
87 .await?
88 .json()
89 .await?;
90
91 res.into()
92 }
93
94 pub async fn delete(&self, media_id: &str) -> SdkResult<()> {
96 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/delete";
97 let sdk = self.0;
98 let builder = sdk.wx_post(base_url).await?;
99 let res: CommonError = builder
100 .json(&serde_json::json!({ "media_id": media_id }))
101 .send()
102 .await?
103 .json()
104 .await?;
105
106 res.into()
107 }
108
109 pub async fn update(&self, news: &UpdateNews) -> SdkResult<()> {
111 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/update";
112 let sdk = self.0;
113 let builder = sdk.wx_post(base_url).await?;
114
115 let res: CommonError = builder.json(news).send().await?.json().await?;
116
117 res.into()
118 }
119
120 pub async fn count(&self) -> SdkResult<TotalCount> {
122 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/count";
123 let sdk = self.0;
124 let res: CommonResponse<TotalCount> =
125 sdk.wx_get(base_url).await?.send().await?.json().await?;
126 res.into()
127 }
128
129 pub async fn batchget(&self, offset: u32, count: u32, no_content: u32) -> SdkResult<BatchList> {
131 let base_url = "https://api.weixin.qq.com/cgi-bin/draft/batchget";
132 let sdk = self.0;
133 let builder = sdk.wx_post(base_url).await?;
134 let res: CommonResponse<BatchList> = builder
135 .json(
136 &serde_json::json!({ "offset": offset, "count": count, "no_content": no_content }),
137 )
138 .send()
139 .await?
140 .json()
141 .await?;
142
143 res.into()
144 }
145}