Skip to main content

wechat_mp_sdk/api/
operations.rs

1//! Operations 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 EmptyRequest {}
15
16#[non_exhaustive]
17#[derive(Debug, Clone, Serialize)]
18pub struct RealtimeLogSearchRequest {
19    #[serde(flatten)]
20    pub payload: HashMap<String, Value>,
21}
22
23#[non_exhaustive]
24#[derive(Debug, Clone, Serialize)]
25pub struct FeedbackRequest {
26    #[serde(flatten)]
27    pub payload: HashMap<String, Value>,
28}
29
30#[non_exhaustive]
31#[derive(Debug, Clone, Serialize)]
32pub struct FeedbackMediaRequest {
33    #[serde(flatten)]
34    pub payload: HashMap<String, Value>,
35}
36
37#[non_exhaustive]
38#[derive(Debug, Clone, Serialize)]
39pub struct JsErrDetailRequest {
40    #[serde(flatten)]
41    pub payload: HashMap<String, Value>,
42}
43
44#[non_exhaustive]
45#[derive(Debug, Clone, Serialize)]
46pub struct JsErrListRequest {
47    #[serde(flatten)]
48    pub payload: HashMap<String, Value>,
49}
50
51#[non_exhaustive]
52#[derive(Debug, Clone, Deserialize, Serialize)]
53pub struct OperationsResponse {
54    #[serde(default)]
55    pub(crate) errcode: i32,
56    #[serde(default)]
57    pub(crate) errmsg: String,
58    #[serde(flatten)]
59    pub extra: HashMap<String, Value>,
60}
61
62pub struct OperationsApi {
63    context: Arc<WechatContext>,
64}
65
66impl OperationsApi {
67    pub fn new(context: Arc<WechatContext>) -> Self {
68        Self { context }
69    }
70
71    pub async fn get_domain_info(&self) -> Result<OperationsResponse, WechatError> {
72        self.post_json("/wxa/get_wxa_domain", &EmptyRequest {})
73            .await
74    }
75
76    pub async fn get_performance(&self) -> Result<OperationsResponse, WechatError> {
77        self.post_json("/wxaapi/log/get_performance", &EmptyRequest {})
78            .await
79    }
80
81    pub async fn get_scene_list(&self) -> Result<OperationsResponse, WechatError> {
82        self.get_json("/wxaapi/log/get_scene").await
83    }
84
85    pub async fn get_version_list(&self) -> Result<OperationsResponse, WechatError> {
86        self.get_json("/wxaapi/log/get_client_version").await
87    }
88
89    pub async fn realtime_log_search(
90        &self,
91        request: &RealtimeLogSearchRequest,
92    ) -> Result<OperationsResponse, WechatError> {
93        self.post_json("/wxaapi/userlog/userlog_search", request)
94            .await
95    }
96
97    pub async fn get_feedback(
98        &self,
99        request: &FeedbackRequest,
100    ) -> Result<OperationsResponse, WechatError> {
101        self.post_json("/wxaapi/feedback/list", request).await
102    }
103
104    pub async fn get_feedback_media(
105        &self,
106        request: &FeedbackMediaRequest,
107    ) -> Result<OperationsResponse, WechatError> {
108        self.post_json("/wxaapi/feedback/media/get", request).await
109    }
110
111    pub async fn get_js_err_detail(
112        &self,
113        request: &JsErrDetailRequest,
114    ) -> Result<OperationsResponse, WechatError> {
115        self.post_json("/wxaapi/log/jserr_detail", request).await
116    }
117
118    pub async fn get_js_err_list(
119        &self,
120        request: &JsErrListRequest,
121    ) -> Result<OperationsResponse, WechatError> {
122        self.post_json("/wxaapi/log/jserr_list", request).await
123    }
124
125    pub async fn get_gray_release_plan(&self) -> Result<OperationsResponse, WechatError> {
126        self.get_json("/wxa/getgrayreleaseplan").await
127    }
128
129    async fn get_json(&self, endpoint: &str) -> Result<OperationsResponse, WechatError> {
130        let response: OperationsResponse = self.context.authed_get(endpoint, &[]).await?;
131        WechatError::check_api(response.errcode, &response.errmsg)?;
132        Ok(response)
133    }
134
135    async fn post_json<B: Serialize>(
136        &self,
137        endpoint: &str,
138        body: &B,
139    ) -> Result<OperationsResponse, WechatError> {
140        let response: OperationsResponse = self.context.authed_post(endpoint, body).await?;
141        WechatError::check_api(response.errcode, &response.errmsg)?;
142        Ok(response)
143    }
144}
145
146impl WechatApi for OperationsApi {
147    fn context(&self) -> &WechatContext {
148        &self.context
149    }
150
151    fn api_name(&self) -> &'static str {
152        "operations"
153    }
154}
155
156#[cfg(test)]
157mod tests {
158    use super::*;
159
160    #[test]
161    fn operations_response_deserializes() {
162        let json = r#"{"errcode":0,"errmsg":"ok","items":[1,2]}"#;
163        let response: OperationsResponse = serde_json::from_str(json).unwrap();
164        assert_eq!(response.errcode, 0);
165        assert!(response.extra.contains_key("items"));
166    }
167}