Skip to main content

wechat_oa_sdk/api/
stats.rs

1use serde::{Deserialize, Serialize};
2
3use crate::client::WeChatClient;
4use crate::error::Result;
5
6/// Time range for statistics queries.
7#[derive(Debug, Clone, Serialize)]
8pub struct DateRange {
9    pub begin_date: String,
10    pub end_date: String,
11}
12
13impl DateRange {
14    pub fn new(begin: impl Into<String>, end: impl Into<String>) -> Self {
15        Self {
16            begin_date: begin.into(),
17            end_date: end.into(),
18        }
19    }
20}
21
22/// User summary data item.
23#[derive(Debug, Clone, Deserialize)]
24pub struct UserSummaryItem {
25    pub ref_date: String,
26    pub user_source: i32,
27    pub new_user: i32,
28    pub cancel_user: i32,
29}
30
31/// User cumulate data item.
32#[derive(Debug, Clone, Deserialize)]
33pub struct UserCumulateItem {
34    pub ref_date: String,
35    pub cumulate_user: i32,
36}
37
38/// Article summary data item.
39#[derive(Debug, Clone, Deserialize)]
40pub struct ArticleSummaryItem {
41    pub ref_date: String,
42    pub msgid: Option<String>,
43    pub title: Option<String>,
44    pub int_page_read_user: Option<i32>,
45    pub int_page_read_count: Option<i32>,
46    pub ori_page_read_user: Option<i32>,
47    pub ori_page_read_count: Option<i32>,
48    pub share_user: Option<i32>,
49    pub share_count: Option<i32>,
50    pub add_to_fav_user: Option<i32>,
51    pub add_to_fav_count: Option<i32>,
52}
53
54/// Article total data item.
55#[derive(Debug, Clone, Deserialize)]
56pub struct ArticleTotalItem {
57    pub ref_date: String,
58    pub msgid: String,
59    pub title: String,
60    pub details: Vec<ArticleDetailItem>,
61}
62
63#[derive(Debug, Clone, Deserialize)]
64pub struct ArticleDetailItem {
65    pub stat_date: String,
66    pub target_user: i32,
67    pub int_page_read_user: i32,
68    pub int_page_read_count: i32,
69    pub ori_page_read_user: i32,
70    pub ori_page_read_count: i32,
71    pub share_user: i32,
72    pub share_count: i32,
73    pub add_to_fav_user: i32,
74    pub add_to_fav_count: i32,
75}
76
77/// Upstream message data item.
78#[derive(Debug, Clone, Deserialize)]
79pub struct UpstreamMsgItem {
80    pub ref_date: String,
81    pub msg_type: i32,
82    pub msg_user: i32,
83    pub msg_count: i32,
84}
85
86/// Interface summary data item.
87#[derive(Debug, Clone, Deserialize)]
88pub struct InterfaceSummaryItem {
89    pub ref_date: String,
90    pub callback_count: i32,
91    pub fail_count: i32,
92    pub total_time_cost: i32,
93    pub max_time_cost: i32,
94}
95
96#[derive(Debug, Deserialize)]
97struct ListResponse<T> {
98    list: Vec<T>,
99}
100
101impl WeChatClient {
102    // ========== User Analysis ==========
103
104    /// Get user summary statistics.
105    /// Date range must be within 7 days.
106    pub async fn get_user_summary(&self, range: &DateRange) -> Result<Vec<UserSummaryItem>> {
107        let resp: ListResponse<UserSummaryItem> =
108            self.post_json("/datacube/getusersummary", range).await?;
109        Ok(resp.list)
110    }
111
112    /// Get user cumulate statistics.
113    /// Date range must be within 7 days.
114    pub async fn get_user_cumulate(&self, range: &DateRange) -> Result<Vec<UserCumulateItem>> {
115        let resp: ListResponse<UserCumulateItem> =
116            self.post_json("/datacube/getusercumulate", range).await?;
117        Ok(resp.list)
118    }
119
120    // ========== Article Analysis ==========
121
122    /// Get article summary statistics (single day only).
123    pub async fn get_article_summary(&self, range: &DateRange) -> Result<Vec<ArticleSummaryItem>> {
124        let resp: ListResponse<ArticleSummaryItem> =
125            self.post_json("/datacube/getarticlesummary", range).await?;
126        Ok(resp.list)
127    }
128
129    /// Get article total statistics (single day only).
130    pub async fn get_article_total(&self, range: &DateRange) -> Result<Vec<ArticleTotalItem>> {
131        let resp: ListResponse<ArticleTotalItem> =
132            self.post_json("/datacube/getarticletotal", range).await?;
133        Ok(resp.list)
134    }
135
136    /// Get user read statistics (up to 3 days).
137    pub async fn get_user_read(&self, range: &DateRange) -> Result<Vec<ArticleSummaryItem>> {
138        let resp: ListResponse<ArticleSummaryItem> =
139            self.post_json("/datacube/getuserread", range).await?;
140        Ok(resp.list)
141    }
142
143    /// Get user read hour statistics (single day only).
144    pub async fn get_user_read_hour(&self, range: &DateRange) -> Result<Vec<ArticleSummaryItem>> {
145        let resp: ListResponse<ArticleSummaryItem> =
146            self.post_json("/datacube/getuserreadhour", range).await?;
147        Ok(resp.list)
148    }
149
150    /// Get user share statistics (up to 7 days).
151    pub async fn get_user_share(&self, range: &DateRange) -> Result<Vec<ArticleSummaryItem>> {
152        let resp: ListResponse<ArticleSummaryItem> =
153            self.post_json("/datacube/getusershare", range).await?;
154        Ok(resp.list)
155    }
156
157    /// Get user share hour statistics (single day only).
158    pub async fn get_user_share_hour(&self, range: &DateRange) -> Result<Vec<ArticleSummaryItem>> {
159        let resp: ListResponse<ArticleSummaryItem> =
160            self.post_json("/datacube/getusersharehour", range).await?;
161        Ok(resp.list)
162    }
163
164    // ========== Message Analysis ==========
165
166    /// Get upstream message statistics (up to 7 days).
167    pub async fn get_upstream_msg(&self, range: &DateRange) -> Result<Vec<UpstreamMsgItem>> {
168        let resp: ListResponse<UpstreamMsgItem> =
169            self.post_json("/datacube/getupstreammsg", range).await?;
170        Ok(resp.list)
171    }
172
173    /// Get upstream message hour statistics (single day only).
174    pub async fn get_upstream_msg_hour(&self, range: &DateRange) -> Result<Vec<UpstreamMsgItem>> {
175        let resp: ListResponse<UpstreamMsgItem> = self
176            .post_json("/datacube/getupstreammsghour", range)
177            .await?;
178        Ok(resp.list)
179    }
180
181    // ========== Interface Analysis ==========
182
183    /// Get interface summary statistics (up to 30 days).
184    pub async fn get_interface_summary(
185        &self,
186        range: &DateRange,
187    ) -> Result<Vec<InterfaceSummaryItem>> {
188        let resp: ListResponse<InterfaceSummaryItem> = self
189            .post_json("/datacube/getinterfacesummary", range)
190            .await?;
191        Ok(resp.list)
192    }
193
194    /// Get interface summary hour statistics (single day only).
195    pub async fn get_interface_summary_hour(
196        &self,
197        range: &DateRange,
198    ) -> Result<Vec<InterfaceSummaryItem>> {
199        let resp: ListResponse<InterfaceSummaryItem> = self
200            .post_json("/datacube/getinterfacesummaryhour", range)
201            .await?;
202        Ok(resp.list)
203    }
204}