wechat_oa_sdk/api/
user.rs1use serde::Deserialize;
2
3use crate::client::WeChatClient;
4use crate::error::Result;
5use crate::models::user::{
6 BatchUserInfoResponse, CreateTagResponse, Tag, TagListResponse, UserInfo, UserListResponse,
7 UsersByTagResponse,
8};
9
10#[derive(Deserialize)]
11#[allow(dead_code)]
12struct ApiResponse {
13 errcode: Option<i64>,
14 errmsg: Option<String>,
15}
16
17impl WeChatClient {
18 pub async fn get_user_info(&self, openid: &str, lang: Option<&str>) -> Result<UserInfo> {
20 let lang = lang.unwrap_or("zh_CN");
21 self.get("/user/info", &[("openid", openid), ("lang", lang)])
22 .await
23 }
24
25 pub async fn batch_get_user_info(
27 &self,
28 openids: &[&str],
29 lang: Option<&str>,
30 ) -> Result<BatchUserInfoResponse> {
31 let lang = lang.unwrap_or("zh_CN");
32 let user_list: Vec<_> = openids
33 .iter()
34 .map(|openid| {
35 serde_json::json!({
36 "openid": openid,
37 "lang": lang
38 })
39 })
40 .collect();
41
42 let body = serde_json::json!({
43 "user_list": user_list
44 });
45
46 self.post_json("/user/info/batchget", &body).await
47 }
48
49 pub async fn get_user_list(&self, next_openid: Option<&str>) -> Result<UserListResponse> {
51 let params: Vec<(&str, &str)> = match next_openid {
52 Some(openid) => vec![("next_openid", openid)],
53 None => vec![],
54 };
55 self.get("/user/get", ¶ms).await
56 }
57
58 pub async fn set_user_remark(&self, openid: &str, remark: &str) -> Result<()> {
60 let body = serde_json::json!({
61 "openid": openid,
62 "remark": remark
63 });
64 let _: ApiResponse = self.post_json("/user/info/updateremark", &body).await?;
65 Ok(())
66 }
67
68 pub async fn create_tag(&self, name: &str) -> Result<Tag> {
72 let body = serde_json::json!({
73 "tag": { "name": name }
74 });
75 let resp: CreateTagResponse = self.post_json("/tags/create", &body).await?;
76 Ok(resp.tag)
77 }
78
79 pub async fn get_tags(&self) -> Result<TagListResponse> {
81 self.get("/tags/get", &[]).await
82 }
83
84 pub async fn update_tag(&self, tag_id: i32, name: &str) -> Result<()> {
86 let body = serde_json::json!({
87 "tag": {
88 "id": tag_id,
89 "name": name
90 }
91 });
92 let _: ApiResponse = self.post_json("/tags/update", &body).await?;
93 Ok(())
94 }
95
96 pub async fn delete_tag(&self, tag_id: i32) -> Result<()> {
98 let body = serde_json::json!({
99 "tag": { "id": tag_id }
100 });
101 let _: ApiResponse = self.post_json("/tags/delete", &body).await?;
102 Ok(())
103 }
104
105 pub async fn get_users_by_tag(
107 &self,
108 tag_id: i32,
109 next_openid: Option<&str>,
110 ) -> Result<UsersByTagResponse> {
111 let body = serde_json::json!({
112 "tagid": tag_id,
113 "next_openid": next_openid.unwrap_or("")
114 });
115 self.post_json("/user/tag/get", &body).await
116 }
117
118 pub async fn batch_tag_users(&self, openids: &[&str], tag_id: i32) -> Result<()> {
120 let body = serde_json::json!({
121 "openid_list": openids,
122 "tagid": tag_id
123 });
124 let _: ApiResponse = self.post_json("/tags/members/batchtagging", &body).await?;
125 Ok(())
126 }
127
128 pub async fn batch_untag_users(&self, openids: &[&str], tag_id: i32) -> Result<()> {
130 let body = serde_json::json!({
131 "openid_list": openids,
132 "tagid": tag_id
133 });
134 let _: ApiResponse = self
135 .post_json("/tags/members/batchuntagging", &body)
136 .await?;
137 Ok(())
138 }
139
140 pub async fn get_user_tags(&self, openid: &str) -> Result<Vec<i32>> {
142 let body = serde_json::json!({
143 "openid": openid
144 });
145
146 #[derive(Deserialize)]
147 struct Response {
148 tagid_list: Vec<i32>,
149 }
150
151 let resp: Response = self.post_json("/tags/getidlist", &body).await?;
152 Ok(resp.tagid_list)
153 }
154}