1use rsb_derive::Builder;
6use rvstruct::*;
7use serde::{Deserialize, Serialize};
8use serde_with::skip_serializing_none;
9
10use crate::models::blocks::{SlackBlock, SlackBlockText};
11use crate::models::*;
12use crate::ratectl::*;
13use crate::scroller::*;
14use crate::SlackClientSession;
15use crate::{ClientResult, SlackClientHttpConnector};
16use futures::future::{BoxFuture, FutureExt};
17use lazy_static::lazy_static;
18use std::collections::HashMap;
19use url::Url;
20
21impl<'a, SCHC> SlackClientSession<'a, SCHC>
22where
23 SCHC: SlackClientHttpConnector + Send,
24{
25 pub async fn chat_delete(
29 &self,
30 req: &SlackApiChatDeleteRequest,
31 ) -> ClientResult<SlackApiChatDeleteResponse> {
32 self.http_session_api
33 .http_post("chat.delete", req, Some(&SLACK_TIER3_METHOD_CONFIG))
34 .await
35 }
36
37 pub async fn chat_delete_scheduled_message(
41 &self,
42 req: &SlackApiChatDeleteScheduledMessageRequest,
43 ) -> ClientResult<SlackApiChatDeleteScheduledMessageResponse> {
44 self.http_session_api
45 .http_post(
46 "chat.deleteScheduledMessage",
47 req,
48 Some(&SLACK_TIER3_METHOD_CONFIG),
49 )
50 .await
51 }
52
53 pub async fn chat_get_permalink(
57 &self,
58 req: &SlackApiChatGetPermalinkRequest,
59 ) -> ClientResult<SlackApiChatGetPermalinkResponse> {
60 self.http_session_api
61 .http_get(
62 "chat.getPermalink",
63 &vec![
64 ("channel", Some(&req.channel.value())),
65 ("message_ts", Some(&req.message_ts.value())),
66 ],
67 Some(&CHAT_GET_PERMLINK_SPECIAL_LIMIT_RATE_CTL),
68 )
69 .await
70 }
71
72 pub async fn chat_post_ephemeral(
76 &self,
77 req: &SlackApiChatPostEphemeralRequest,
78 ) -> ClientResult<SlackApiChatPostEphemeralResponse> {
79 self.http_session_api
80 .http_post("chat.postEphemeral", req, Some(&SLACK_TIER4_METHOD_CONFIG))
81 .await
82 }
83
84 pub async fn chat_post_message(
88 &self,
89 req: &SlackApiChatPostMessageRequest,
90 ) -> ClientResult<SlackApiChatPostMessageResponse> {
91 self.http_session_api
92 .http_post(
93 "chat.postMessage",
94 req,
95 Some(&CHAT_POST_MESSAGE_SPECIAL_LIMIT_RATE_CTL),
96 )
97 .await
98 }
99
100 pub async fn chat_schedule_message(
104 &self,
105 req: &SlackApiChatScheduleMessageRequest,
106 ) -> ClientResult<SlackApiChatScheduleMessageResponse> {
107 self.http_session_api
108 .http_post(
109 "chat.scheduleMessage",
110 req,
111 Some(&SLACK_TIER3_METHOD_CONFIG),
112 )
113 .await
114 }
115
116 pub async fn chat_unfurl(
121 &self,
122 req: &SlackApiChatUnfurlRequest,
123 ) -> ClientResult<SlackApiChatUnfurlResponse> {
124 self.http_session_api
125 .http_post("chat.unfurl", req, Some(&SLACK_TIER3_METHOD_CONFIG))
126 .await
127 }
128
129 pub async fn chat_unfurl_v2(
134 &self,
135 req: &SlackApiChatUnfurlRequestV2,
136 ) -> ClientResult<SlackApiChatUnfurlResponse> {
137 self.http_session_api
138 .http_post("chat.unfurl", req, Some(&SLACK_TIER3_METHOD_CONFIG))
139 .await
140 }
141
142 pub async fn chat_update(
146 &self,
147 req: &SlackApiChatUpdateRequest,
148 ) -> ClientResult<SlackApiChatUpdateResponse> {
149 self.http_session_api
150 .http_post("chat.update", req, Some(&SLACK_TIER3_METHOD_CONFIG))
151 .await
152 }
153
154 pub async fn chat_scheduled_messages_list(
158 &self,
159 req: &SlackApiChatScheduledMessagesListRequest,
160 ) -> ClientResult<SlackApiChatScheduledMessagesListResponse> {
161 self.http_session_api
162 .http_post(
163 "chat.scheduledMessages.list",
164 req,
165 Some(&SLACK_TIER3_METHOD_CONFIG),
166 )
167 .await
168 }
169}
170
171#[skip_serializing_none]
172#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
173pub struct SlackApiChatDeleteRequest {
174 pub channel: SlackChannelId,
175 pub ts: SlackTs,
176 pub as_user: Option<bool>,
177}
178
179#[skip_serializing_none]
180#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
181pub struct SlackApiChatDeleteResponse {
182 pub channel: SlackChannelId,
183 pub ts: SlackTs,
184}
185
186#[skip_serializing_none]
187#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
188pub struct SlackApiChatDeleteScheduledMessageRequest {
189 pub channel: SlackChannelId,
190 pub scheduled_message: SlackScheduledMid,
191 pub as_user: Option<bool>,
192}
193
194#[skip_serializing_none]
195#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
196pub struct SlackApiChatDeleteScheduledMessageResponse {}
197
198#[skip_serializing_none]
199#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
200pub struct SlackApiChatGetPermalinkRequest {
201 pub channel: SlackChannelId,
202 pub message_ts: SlackTs,
203}
204
205#[skip_serializing_none]
206#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
207pub struct SlackApiChatGetPermalinkResponse {
208 pub channel: SlackChannelId,
209 pub permalink: Url,
210}
211
212#[skip_serializing_none]
213#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
214pub struct SlackApiChatPostEphemeralRequest {
215 pub channel: SlackChannelId,
216 pub user: SlackUserId,
217 #[serde(flatten)]
218 pub content: SlackMessageContent,
219 pub as_user: Option<bool>,
220 pub icon_emoji: Option<String>,
221 pub icon_url: Option<String>,
222 pub link_names: Option<bool>,
223 pub parse: Option<String>,
224 pub thread_ts: Option<SlackTs>,
225 pub username: Option<String>,
226}
227
228#[skip_serializing_none]
229#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
230pub struct SlackApiChatPostEphemeralResponse {}
231
232#[skip_serializing_none]
233#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
234pub struct SlackApiChatPostMessageRequest {
235 pub channel: SlackChannelId,
236 #[serde(flatten)]
237 pub content: SlackMessageContent,
238 pub as_user: Option<bool>,
239 pub icon_emoji: Option<String>,
240 pub icon_url: Option<String>,
241 pub link_names: Option<bool>,
242 pub parse: Option<String>,
243 pub thread_ts: Option<SlackTs>,
244 pub username: Option<String>,
245 pub reply_broadcast: Option<bool>,
246 pub unfurl_links: Option<bool>,
247 pub unfurl_media: Option<bool>,
248}
249
250#[skip_serializing_none]
251#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
252pub struct SlackApiChatPostMessageResponse {
253 pub channel: SlackChannelId,
254 pub ts: SlackTs,
255 pub message: SlackMessage,
256}
257
258#[skip_serializing_none]
259#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
260pub struct SlackApiChatScheduleMessageRequest {
261 pub channel: SlackChannelId,
262 #[serde(flatten)]
263 pub content: SlackMessageContent,
264 pub post_at: SlackDateTime,
265 pub as_user: Option<bool>,
266 pub icon_emoji: Option<String>,
267 pub icon_url: Option<String>,
268 pub link_names: Option<bool>,
269 pub parse: Option<String>,
270 pub thread_ts: Option<SlackTs>,
271 pub username: Option<String>,
272 pub reply_broadcast: Option<bool>,
273 pub unfurl_links: Option<bool>,
274 pub unfurl_media: Option<bool>,
275}
276
277#[skip_serializing_none]
278#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
279pub struct SlackApiChatScheduleMessageResponse {
280 pub channel: SlackChannelId,
281 pub scheduled_message_id: SlackScheduledMid,
282 pub post_at: SlackDateTime,
283}
284
285#[skip_serializing_none]
286#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
287pub struct SlackApiChatUnfurlRequest {
288 pub channel: SlackChannelId,
289 pub ts: SlackTs,
290 pub unfurls: HashMap<String, SlackApiChatUnfurlMapItem>,
291 pub user_auth_message: Option<String>,
292 pub user_auth_required: Option<bool>,
293 pub user_auth_url: Option<Url>,
294}
295
296#[skip_serializing_none]
297#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
298pub struct SlackApiChatUnfurlRequestV2 {
299 pub source: SlackApiChatUnfurlSource,
300 pub unfurl_id: SlackUnfurlId,
301 pub unfurls: HashMap<String, SlackApiChatUnfurlMapItemV2>,
302 pub user_auth_message: Option<String>,
303 pub user_auth_required: Option<bool>,
304 pub user_auth_url: Option<Url>,
305}
306
307#[skip_serializing_none]
308#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
309pub enum SlackApiChatUnfurlSource {
310 #[serde(rename = "composer")]
311 Composer,
312 #[serde(rename = "conversations_history")]
313 ConversationsHistory,
314}
315
316#[skip_serializing_none]
317#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
318pub struct SlackApiChatUnfurlMapItem {
319 pub text: String,
320}
321
322#[skip_serializing_none]
323#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
324pub struct SlackApiChatUnfurlMapItemV2 {
325 pub blocks: Vec<SlackBlock>,
326 pub preview: Option<SlackApiChatUnfurlPreview>,
327}
328
329#[skip_serializing_none]
330#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
331pub struct SlackApiChatUnfurlPreview {
332 pub title: SlackBlockText,
333 pub icon_url: Option<Url>,
334}
335
336#[skip_serializing_none]
337#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
338pub struct SlackApiChatUnfurlResponse {}
339
340#[skip_serializing_none]
341#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
342pub struct SlackApiChatUpdateRequest {
343 pub channel: SlackChannelId,
344 #[serde(flatten)]
345 pub content: SlackMessageContent,
346 pub ts: SlackTs,
347 pub as_user: Option<bool>,
348 pub link_names: Option<bool>,
349 pub parse: Option<String>,
350 pub reply_broadcast: Option<bool>,
351}
352
353#[skip_serializing_none]
354#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
355pub struct SlackApiChatUpdateResponse {
356 pub channel: SlackChannelId,
357 pub ts: SlackTs,
358 pub thread_ts: Option<SlackTs>,
359 pub message: SlackUpdatedMessage,
360}
361
362#[skip_serializing_none]
363#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
364pub struct SlackApiChatScheduledMessagesListRequest {
365 pub channel: Option<SlackChannelId>,
366 pub cursor: Option<SlackCursorId>,
367 pub latest: Option<SlackTs>,
368 pub limit: Option<u16>,
369 pub oldest: Option<SlackTs>,
370}
371
372#[skip_serializing_none]
373#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
374pub struct SlackApiChatScheduledMessagesListResponse {
375 pub scheduled_messages: Vec<SlackApiChatScheduledMessageInfo>,
376 pub response_metadata: Option<SlackResponseMetadata>,
377}
378
379#[skip_serializing_none]
380#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
381pub struct SlackApiChatScheduledMessageInfo {
382 pub id: SlackScheduledMid,
383 pub channel_id: SlackChannelId,
384 pub post_at: SlackDateTime,
385 pub date_created: SlackDateTime,
386}
387
388impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiChatScheduledMessagesListRequest
389where
390 SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
391{
392 type ResponseType = SlackApiChatScheduledMessagesListResponse;
393 type CursorType = SlackCursorId;
394 type ResponseItemType = SlackApiChatScheduledMessageInfo;
395
396 fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
397 self.clone().opt_cursor(new_cursor.cloned())
398 }
399
400 fn scroll<'a, 's>(
401 &'a self,
402 session: &'a SlackClientSession<'s, SCHC>,
403 ) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
404 async move { session.chat_scheduled_messages_list(self).await }.boxed()
405 }
406}
407
408impl SlackApiScrollableResponse for SlackApiChatScheduledMessagesListResponse {
409 type CursorType = SlackCursorId;
410 type ResponseItemType = SlackApiChatScheduledMessageInfo;
411
412 fn next_cursor(&self) -> Option<&Self::CursorType> {
413 self.response_metadata
414 .as_ref()
415 .and_then(|rm| rm.next_cursor.as_ref())
416 }
417
418 fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
419 Box::new(self.scheduled_messages.iter())
420 }
421}
422
423lazy_static! {
424 pub static ref CHAT_GET_PERMLINK_SPECIAL_LIMIT_RATE_CTL: SlackApiMethodRateControlConfig =
425 SlackApiMethodRateControlConfig::new().with_special_rate_limit(
426 SlackApiRateControlSpecialLimit::new(
427 "chat.getPermalink".into(),
428 SlackApiRateControlLimit::new(100, std::time::Duration::from_secs(1))
429 )
430 );
431 pub static ref CHAT_POST_MESSAGE_SPECIAL_LIMIT_RATE_CTL: SlackApiMethodRateControlConfig =
432 SlackApiMethodRateControlConfig::new().with_special_rate_limit(
433 SlackApiRateControlSpecialLimit::new(
434 "chat.postMessage".into(),
435 SlackApiRateControlLimit::new(1, std::time::Duration::from_secs(1))
436 )
437 );
438}