Skip to main content

wechat_mp_sdk/api/
hardware.rs

1//! Hardware Device API
2
3use std::collections::HashMap;
4use std::sync::Arc;
5
6use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9use super::{WechatApi, WechatContext};
10use crate::error::WechatError;
11
12#[non_exhaustive]
13#[derive(Debug, Clone, Serialize)]
14pub struct HardwareRequest {
15    #[serde(flatten)]
16    pub payload: HashMap<String, Value>,
17}
18
19#[non_exhaustive]
20#[derive(Debug, Clone, Deserialize, Serialize)]
21pub struct HardwareResponse {
22    #[serde(default)]
23    pub(crate) errcode: i32,
24    #[serde(default)]
25    pub(crate) errmsg: String,
26    #[serde(flatten)]
27    pub extra: HashMap<String, Value>,
28}
29
30pub struct HardwareApi {
31    context: Arc<WechatContext>,
32}
33
34impl HardwareApi {
35    pub fn new(context: Arc<WechatContext>) -> Self {
36        Self { context }
37    }
38
39    pub async fn send_hardware_device_message(
40        &self,
41        request: &HardwareRequest,
42    ) -> Result<HardwareResponse, WechatError> {
43        self.post_json("/cgi-bin/message/device/subscribe/send", request)
44            .await
45    }
46
47    pub async fn get_sn_ticket(
48        &self,
49        request: &HardwareRequest,
50    ) -> Result<HardwareResponse, WechatError> {
51        self.post_json("/wxa/business/hardware/sn_ticket/get", request)
52            .await
53    }
54
55    pub async fn create_iot_group_id(
56        &self,
57        request: &HardwareRequest,
58    ) -> Result<HardwareResponse, WechatError> {
59        self.post_json("/wxa/business/hardware/group/create", request)
60            .await
61    }
62
63    pub async fn get_iot_group_info(
64        &self,
65        request: &HardwareRequest,
66    ) -> Result<HardwareResponse, WechatError> {
67        self.post_json("/wxa/business/hardware/group/get", request)
68            .await
69    }
70
71    pub async fn add_iot_group_device(
72        &self,
73        request: &HardwareRequest,
74    ) -> Result<HardwareResponse, WechatError> {
75        self.post_json("/wxa/business/hardware/group/device/add", request)
76            .await
77    }
78
79    pub async fn remove_iot_group_device(
80        &self,
81        request: &HardwareRequest,
82    ) -> Result<HardwareResponse, WechatError> {
83        self.post_json("/wxa/business/hardware/group/device/remove", request)
84            .await
85    }
86
87    async fn post_json<B: Serialize>(
88        &self,
89        endpoint: &str,
90        body: &B,
91    ) -> Result<HardwareResponse, WechatError> {
92        let response: HardwareResponse = self.context.authed_post(endpoint, body).await?;
93        WechatError::check_api(response.errcode, &response.errmsg)?;
94        Ok(response)
95    }
96}
97
98impl WechatApi for HardwareApi {
99    fn context(&self) -> &WechatContext {
100        &self.context
101    }
102
103    fn api_name(&self) -> &'static str {
104        "hardware"
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn hardware_response_deserializes() {
114        let json = r#"{"errcode":0,"errmsg":"ok","ticket":"abc"}"#;
115        let response: HardwareResponse = serde_json::from_str(json).unwrap();
116        assert_eq!(response.errcode, 0);
117        assert!(response.extra.contains_key("ticket"));
118    }
119}