br_wechat/
applet.rs

1use chrono::Local;
2use json::{JsonValue, object};
3use log::info;
4use crate::{WechatMethod, ACCOUNT};
5
6#[derive(Clone)]
7pub struct Applet {
8    pub appid: String,
9    pub secret: String,
10    pub access_token: String,
11    pub expires_in: i64,
12}
13
14impl Applet {
15    fn access_token(&mut self) -> Result<String, String> {
16        let dt = Local::now();
17        let timestamp = dt.timestamp_millis();
18        if self.expires_in > timestamp {
19            return Ok(self.access_token.clone());
20        }
21        let url = format!("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", self.appid, self.secret);
22        let mut http = br_reqwest::Client::new();
23        http.get(url.as_str());
24        let res = http.send()?.json()?;
25        if res["errcode"].is_empty() {
26            self.access_token = res["access_token"].to_string();
27            self.expires_in = timestamp + res["expires_in"].as_i64().unwrap();
28            {
29                ACCOUNT.write().unwrap().get_mut(&self.appid.clone()).unwrap().access_token = self.access_token.clone();
30                ACCOUNT.write().unwrap().get_mut(&self.appid.clone()).unwrap().expires_in = self.expires_in;
31            }
32            Ok(self.access_token.clone())
33        } else {
34            Err(res["errmsg"].to_string())
35        }
36    }
37}
38
39impl WechatMethod for Applet {
40    fn check(&mut self) -> Result<bool, String> {
41        match self.access_token() {
42            Ok(_) => Ok(true),
43            Err(e) => Err(e),
44        }
45    }
46    /// 获取访问用户身份
47    fn code2_session(&mut self, code: &str) -> Result<JsonValue, String> {
48        let url = "https://api.weixin.qq.com/sns/jscode2session".to_string();
49        let mut http = br_reqwest::Client::new();
50        http.get(url.as_str()).raw_json(object! {
51            appid:self.appid.clone(),
52            secret:self.secret.clone(),
53            js_code:code,
54            grant_type:"authorization_code"
55        });
56        let res = http.send()?;
57        let res = res.json()?;
58        let mut user_info = object! {};
59        let res = json::parse(res.as_str().unwrap()).unwrap();
60        if res["errcode"].is_empty() {
61            user_info["session_key"] = res["session_key"].clone();
62            user_info["unionid"] = res["unionid"].as_str().unwrap_or("").into();
63            user_info["openid"] = res["openid"].clone();
64        } else {
65            info!("code2_session: {}", res["errmsg"].as_str().unwrap());
66        }
67        Ok(user_info)
68    }
69    /// 获取访问用户身份
70    fn getuserinfo(&mut self, code: &str) -> Result<JsonValue, String> {
71        let url = format!("https://api.weixin.qq.com/wxa/getpluginopenpid?access_token={}", self.access_token()?);
72        let mut http = br_reqwest::Client::new();
73        http.post(url.as_str());
74        http.raw_json(object! {
75            code:code
76        });
77        let res = http.send()?;
78        let res = res.json()?;
79        let mut user_info = object! {};
80        if res["errcode"].as_i32().unwrap() == 0 {
81            user_info["userid"] = res["userid"].clone();
82            user_info["user_ticket"] = res["user_ticket"].clone();
83        } else {
84            info!("getuserinfo: {}", res["errmsg"].as_str().unwrap());
85        }
86        Ok(user_info)
87    }
88    /// 获取手机号
89    fn get_phone_number(&mut self, iv: &str, encrypted_data: &str, session_key: &str) -> Result<JsonValue, String> {
90        let data = br_crypto::aes::aes_128_cbc(iv, encrypted_data, session_key)?;
91        let mut data = json::parse(&data).unwrap();
92        data["phone"] = data["purePhoneNumber"].clone();
93        Ok(data)
94    }
95
96    fn login(&mut self, code: &str) -> Result<JsonValue, String> {
97        let mut http = br_reqwest::Client::new();
98        http.get("https://api.weixin.qq.com/sns/jscode2session".to_string().as_str());
99        http.header("Accept", "application/json");
100        http.header("User-Agent", "api");
101        http.header("Content-Type", "application/json");
102        http.query(object! {
103                appid: self.appid.as_str(),
104                secret: self.secret.as_str(),
105                js_code:code,
106                grant_type:"authorization_code",
107        });
108        match http.send()?.json() {
109            Ok(e) => Ok(e),
110            Err(e) => Err(e),
111        }
112    }
113}