open_lark/service/im/v1/batch_message/
mod.rs

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5use crate::{
6    core::{
7        api_req::ApiRequest,
8        api_resp::{ApiResponseTrait, BaseResponse, EmptyResponse, ResponseFormat},
9        config::Config,
10        constants::AccessTokenType,
11        http::Transport,
12        req_option::RequestOption,
13        SDKResult,
14    },
15    service::im::v1::models::{BatchMessageStatus, ReceiveIdType, UserIdType},
16};
17
18/// 批量消息服务
19pub struct BatchMessageService {
20    pub config: Config,
21}
22
23/// 批量发送消息请求
24#[derive(Debug, Serialize, Deserialize)]
25pub struct BatchSendMessageRequest {
26    /// 消息接收者ID列表
27    pub receive_id_list: Vec<String>,
28    /// 消息内容
29    pub msg_type: String,
30    /// 消息内容
31    pub content: String,
32    /// 用户ID类型,可选值为open_id、user_id、union_id
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub uuid: Option<String>,
35}
36
37/// 批量发送消息响应
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct BatchSendMessageResponse {
40    /// 批量消息ID
41    pub batch_message_id: String,
42    /// 无效的接收者ID列表
43    pub invalid_receive_ids: Vec<String>,
44}
45
46impl ApiResponseTrait for BatchSendMessageResponse {
47    fn data_format() -> ResponseFormat {
48        ResponseFormat::Data
49    }
50}
51
52/// 查询批量消息进度响应
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct GetBatchProgressResponse {
55    /// 批量消息进度信息
56    pub batch_message_progress: BatchMessageProgress,
57}
58
59/// 批量消息进度信息
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct BatchMessageProgress {
62    /// 批量消息ID
63    pub batch_message_id: String,
64    /// 状态
65    pub status: BatchMessageStatus,
66    /// 总数
67    pub total_count: i32,
68    /// 成功数
69    pub success_count: i32,
70    /// 失败数
71    pub fail_count: i32,
72    /// 已读数
73    pub read_count: i32,
74}
75
76impl ApiResponseTrait for GetBatchProgressResponse {
77    fn data_format() -> ResponseFormat {
78        ResponseFormat::Data
79    }
80}
81
82/// 查询批量消息推送和阅读人数响应
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct GetBatchReadUserResponse {
85    /// 已读用户列表
86    pub read_users: Vec<BatchReadUser>,
87    /// 是否还有更多数据
88    pub has_more: bool,
89    /// 分页标记
90    pub page_token: Option<String>,
91}
92
93/// 批量消息已读用户信息
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct BatchReadUser {
96    /// 用户ID
97    pub user_id: String,
98    /// 用户姓名
99    pub name: Option<String>,
100    /// 阅读时间
101    pub read_time: String,
102}
103
104impl ApiResponseTrait for GetBatchReadUserResponse {
105    fn data_format() -> ResponseFormat {
106        ResponseFormat::Data
107    }
108}
109
110impl BatchMessageService {
111    pub fn new(config: Config) -> Self {
112        Self { config }
113    }
114
115    /// 批量发送消息
116    pub async fn send(
117        &self,
118        receive_id_type: ReceiveIdType,
119        request: BatchSendMessageRequest,
120        option: Option<RequestOption>,
121    ) -> SDKResult<BaseResponse<BatchSendMessageResponse>> {
122        let api_req = ApiRequest {
123            http_method: Method::POST,
124            api_path: "/open-apis/im/v1/batch_messages".to_string(),
125            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
126            query_params: HashMap::from([(
127                "receive_id_type".to_string(),
128                receive_id_type.as_str().to_string(),
129            )]),
130            body: serde_json::to_vec(&request)?,
131            ..Default::default()
132        };
133
134        Transport::request(api_req, &self.config, option).await
135    }
136
137    /// 批量撤回消息
138    pub async fn delete(
139        &self,
140        batch_message_id: &str,
141        option: Option<RequestOption>,
142    ) -> SDKResult<BaseResponse<EmptyResponse>> {
143        let api_req = ApiRequest {
144            http_method: Method::DELETE,
145            api_path: format!("/open-apis/im/v1/batch_messages/{batch_message_id}"),
146            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
147            ..Default::default()
148        };
149
150        Transport::request(api_req, &self.config, option).await
151    }
152
153    /// 查询批量消息整体进度
154    pub async fn get_progress(
155        &self,
156        batch_message_id: &str,
157        option: Option<RequestOption>,
158    ) -> SDKResult<BaseResponse<GetBatchProgressResponse>> {
159        let api_req = ApiRequest {
160            http_method: Method::GET,
161            api_path: format!("/open-apis/im/v1/batch_messages/{batch_message_id}/get_progress"),
162            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
163            ..Default::default()
164        };
165
166        Transport::request(api_req, &self.config, option).await
167    }
168
169    /// 查询批量消息推送和阅读人数
170    pub async fn read_user(
171        &self,
172        batch_message_id: &str,
173        user_id_type: Option<UserIdType>,
174        page_size: Option<i32>,
175        page_token: Option<String>,
176        option: Option<RequestOption>,
177    ) -> SDKResult<BaseResponse<GetBatchReadUserResponse>> {
178        let mut query_params = HashMap::new();
179        if let Some(user_id_type) = user_id_type {
180            query_params.insert(
181                "user_id_type".to_string(),
182                user_id_type.as_str().to_string(),
183            );
184        }
185        if let Some(page_size) = page_size {
186            query_params.insert("page_size".to_string(), page_size.to_string());
187        }
188        if let Some(page_token) = page_token {
189            query_params.insert("page_token".to_string(), page_token);
190        }
191
192        let api_req = ApiRequest {
193            http_method: Method::GET,
194            api_path: format!("/open-apis/im/v1/batch_messages/{batch_message_id}/read_user"),
195            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
196            query_params,
197            ..Default::default()
198        };
199
200        Transport::request(api_req, &self.config, option).await
201    }
202}