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

1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5use crate::impl_full_service;
6use crate::{
7    core::{
8        api_req::ApiRequest,
9        api_resp::{ApiResponseTrait, BaseResponse, EmptyResponse, ResponseFormat},
10        config::Config,
11        constants::AccessTokenType,
12        endpoints::EndpointBuilder,
13        http::Transport,
14        req_option::RequestOption,
15        standard_response::StandardResponse,
16        SDKResult,
17    },
18    service::im::v1::models::{Pin, UserIdType},
19};
20
21/// Pin消息服务
22pub struct PinService {
23    pub config: Config,
24}
25
26/// Pin信息响应
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct CreatePinResponse {
29    /// Pin信息
30    pub pin: PinInfo,
31}
32
33// 接入统一 Service 抽象(IM v1 - PinService)
34impl_full_service!(PinService, "im.pin", "v1");
35
36/// Pin信息
37#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
38pub struct PinInfo {
39    /// Pin ID
40    pub pin_id: String,
41    /// 消息ID
42    pub message_id: String,
43    /// 聊天ID
44    pub chat_id: String,
45    /// Pin创建者
46    pub operator_id: String,
47    /// 创建时间
48    pub create_time: String,
49}
50
51impl ApiResponseTrait for CreatePinResponse {
52    fn data_format() -> ResponseFormat {
53        ResponseFormat::Data
54    }
55}
56
57/// 获取Pin消息列表响应
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct ListPinResponse {
60    /// Pin消息列表
61    pub pins: Vec<Pin>,
62    /// 是否还有更多数据
63    pub has_more: bool,
64    /// 分页标记
65    pub page_token: Option<String>,
66}
67
68impl ApiResponseTrait for ListPinResponse {
69    fn data_format() -> ResponseFormat {
70        ResponseFormat::Data
71    }
72}
73
74impl PinService {
75    pub fn new(config: Config) -> Self {
76        Self { config }
77    }
78
79    /// Pin消息
80    pub async fn create(
81        &self,
82        message_id: &str,
83        user_id_type: Option<UserIdType>,
84        option: Option<RequestOption>,
85    ) -> SDKResult<CreatePinResponse> {
86        let mut query_params = HashMap::new();
87        query_params.insert("message_id", message_id.to_string());
88        if let Some(user_id_type) = user_id_type {
89            query_params.insert("user_id_type", user_id_type.as_str().to_string());
90        }
91
92        let api_req = ApiRequest {
93            http_method: Method::POST,
94            api_path: crate::core::endpoints::im::IM_V1_PINS.to_string(),
95            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
96            query_params,
97            ..Default::default()
98        };
99
100        let api_resp: BaseResponse<CreatePinResponse> =
101            Transport::request(api_req, &self.config, option).await?;
102        api_resp.into_result()
103    }
104
105    /// 移除Pin消息
106    pub async fn delete(
107        &self,
108        pin_id: &str,
109        user_id_type: Option<UserIdType>,
110        option: Option<RequestOption>,
111    ) -> SDKResult<EmptyResponse> {
112        let query_params = if let Some(user_id_type) = user_id_type {
113            HashMap::from([("user_id_type", user_id_type.as_str().to_string())])
114        } else {
115            HashMap::new()
116        };
117
118        let api_req = ApiRequest {
119            http_method: Method::DELETE,
120            api_path: EndpointBuilder::replace_param(
121                crate::core::endpoints::im::IM_V1_DELETE_PIN,
122                "pin_id",
123                pin_id,
124            ),
125            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
126            query_params,
127            ..Default::default()
128        };
129
130        let api_resp: BaseResponse<EmptyResponse> =
131            Transport::request(api_req, &self.config, option).await?;
132        api_resp.into_result()
133    }
134
135    /// 获取群内Pin消息
136    pub async fn list(
137        &self,
138        chat_id: &str,
139        user_id_type: Option<UserIdType>,
140        page_size: Option<i32>,
141        page_token: Option<String>,
142        option: Option<RequestOption>,
143    ) -> SDKResult<ListPinResponse> {
144        let mut query_params = HashMap::new();
145        query_params.insert("chat_id", chat_id.to_string());
146        if let Some(user_id_type) = user_id_type {
147            query_params.insert("user_id_type", user_id_type.as_str().to_string());
148        }
149        if let Some(page_size) = page_size {
150            query_params.insert("page_size", page_size.to_string());
151        }
152        if let Some(page_token) = page_token {
153            query_params.insert("page_token", page_token);
154        }
155
156        let api_req = ApiRequest {
157            http_method: Method::GET,
158            api_path: crate::core::endpoints::im::IM_V1_PINS.to_string(),
159            supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
160            query_params,
161            ..Default::default()
162        };
163
164        let api_resp: BaseResponse<ListPinResponse> =
165            Transport::request(api_req, &self.config, option).await?;
166        api_resp.into_result()
167    }
168}