async_dingtalk/
contact.rs1use crate::DingTalk;
2use log::info;
3use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug)]
7pub struct UserInfo {
8 pub email: Option<String>,
9 pub mobile: Option<String>,
10 #[serde(rename = "nick")]
11 pub username: String,
12 #[serde(default, rename = "openId")]
13 pub open_id: Option<String>,
14 #[serde(rename = "unionId")]
15 pub union_id: String,
16 #[serde(rename = "stateCode")]
17 pub state_code: String,
18 pub visitor: Option<bool>,
19}
20
21impl DingTalk {
22 pub async fn get_contact_userinfo(
34 &self,
35 union_id: String,
36 ) -> Result<UserInfo, Box<dyn std::error::Error>> {
37 let mut headers = HeaderMap::new();
38 match self.get_app_access_token().await {
39 Ok(at) => headers.insert(
40 HeaderName::from_static("x-acs-dingtalk-access-token"),
41 HeaderValue::from_str(&at).unwrap(),
42 ),
43 Err(e) => return Err(e),
44 };
45
46 let url: String = format!("https://api.dingtalk.com/v1.0/contact/users/{}", union_id);
47 let response = self.client.get(&url).headers(headers).send().await?;
48
49 if !response.status().is_success() {
50 return Err(format!("Failed to get user info: {}", response.status()).into());
51 }
52
53 let result = response.json::<UserInfo>().await?;
54
55 info!("union_id: {union_id}, fetch user info: {:#?}", &result);
56
57 Ok(result)
58 }
59}