1use crate::{access_token::AccessTokenProvider, error::CommonResponse, SdkResult, WxSdk};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Serialize, Deserialize)]
5pub struct GrantAccessToken {
6 access_token: String,
7 expires_in: u32,
8 refresh_token: String,
9 openid: String,
10 scope: String,
11}
12
13#[derive(Debug, Serialize, Deserialize)]
14pub struct UserInfo {
15 openid: String,
16 nickname: String,
17 sex: u8,
18 province: String,
19 city: String,
20 country: String,
21 headimgurl: String,
22 privilege: Option<Vec<String>>,
23 unionid: Option<String>,
24}
25
26pub struct SnsModule<'a, T: AccessTokenProvider>(pub(crate) &'a WxSdk<T>);
27
28impl<'a, T: AccessTokenProvider> SnsModule<'a, T> {
29 pub async fn oauth_access_token(&self, code: String) -> SdkResult<GrantAccessToken> {
33 let base_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
34 let client = self.0.http_client.get(base_url);
35
36 let app_id = self.0.app_id.clone();
37 let app_secret = self.0.app_secret.clone();
38 let client = client.query(&[
39 ("appid", app_id),
40 ("secret", app_secret),
41 ("code", code),
42 ("grant_type", "authorization_code".to_owned()),
43 ]);
44 let res: CommonResponse<GrantAccessToken> = client.send().await?.json().await?;
45 res.into()
46 }
47 pub async fn oauth_refresh_token(&self, refresh_token: String) -> SdkResult<GrantAccessToken> {
50 let base_url = "https://api.weixin.qq.com/sns/oauth2/refresh_token";
51 let client = self.0.http_client.get(base_url);
52
53 let app_id = self.0.app_id.clone();
54 let client = client.query(&[
55 ("appid", app_id),
56 ("refresh_token", refresh_token),
57 ("grant_type", "refresh_token".to_owned()),
58 ]);
59 let res: CommonResponse<GrantAccessToken> = client.send().await?.json().await?;
60 res.into()
61 }
62
63 pub async fn userinfo(
66 &self,
67 openid: String,
68 access_token: String,
69 lang: String,
70 ) -> SdkResult<UserInfo> {
71 let base_url = "https://api.weixin.qq.com/sns/userinfo";
72 let client = self.0.http_client.get(base_url);
73
74 let client = client.query(&[
75 ("access_token", access_token),
76 ("openid", openid),
77 ("lang", lang),
78 ]);
79 let res: CommonResponse<UserInfo> = client.send().await?.json().await?;
80 res.into()
81 }
82}