Skip to main content

slack_morphism/api/
conversations.rs

1//!
2//! Support for Slack Conversations API methods
3//!
4
5use rsb_derive::Builder;
6use rvstruct::ValueStruct;
7use serde::{Deserialize, Serialize};
8use serde_with::skip_serializing_none;
9
10use crate::models::*;
11use crate::ratectl::*;
12use crate::*;
13use futures::future::{BoxFuture, FutureExt};
14use std::collections::HashSet;
15
16impl<'a, SCHC> SlackClientSession<'a, SCHC>
17where
18    SCHC: SlackClientHttpConnector + Send,
19{
20    ///
21    /// https://api.slack.com/methods/conversations.archive
22    ///
23    pub async fn conversations_archive(
24        &self,
25        req: &SlackApiConversationsArchiveRequest,
26    ) -> ClientResult<SlackApiConversationsArchiveResponse> {
27        self.http_session_api
28            .http_post(
29                "conversations.archive",
30                req,
31                Some(&SLACK_TIER2_METHOD_CONFIG),
32            )
33            .await
34    }
35
36    ///
37    /// https://api.slack.com/methods/conversations.close
38    ///
39    pub async fn conversations_close(
40        &self,
41        req: &SlackApiConversationsCloseRequest,
42    ) -> ClientResult<SlackApiConversationsCloseResponse> {
43        self.http_session_api
44            .http_post("conversations.close", req, Some(&SLACK_TIER2_METHOD_CONFIG))
45            .await
46    }
47
48    ///
49    /// https://api.slack.com/methods/conversations.create
50    ///
51    pub async fn conversations_create(
52        &self,
53        req: &SlackApiConversationsCreateRequest,
54    ) -> ClientResult<SlackApiConversationsCreateResponse> {
55        self.http_session_api
56            .http_post(
57                "conversations.create",
58                req,
59                Some(&SLACK_TIER2_METHOD_CONFIG),
60            )
61            .await
62    }
63
64    ///
65    /// https://api.slack.com/methods/conversations.history
66    ///
67    pub async fn conversations_history(
68        &self,
69        req: &SlackApiConversationsHistoryRequest,
70    ) -> ClientResult<SlackApiConversationsHistoryResponse> {
71        self.http_session_api
72            .http_get(
73                "conversations.history",
74                &vec![
75                    ("channel", req.channel.as_ref().map(|x| x.value())),
76                    ("cursor", req.cursor.as_ref().map(|x| x.value())),
77                    ("limit", req.limit.map(|v| v.to_string()).as_ref()),
78                    ("inclusive", req.inclusive.map(|v| v.to_string()).as_ref()),
79                    (
80                        "include_all_metadata",
81                        req.include_all_metadata.map(|v| v.to_string()).as_ref(),
82                    ),
83                    ("latest", req.latest.as_ref().map(|x| x.value())),
84                    ("oldest", req.oldest.as_ref().map(|x| x.value())),
85                ],
86                Some(&SLACK_TIER3_METHOD_CONFIG),
87            )
88            .await
89    }
90
91    ///
92    /// https://api.slack.com/methods/conversations.info
93    ///
94    pub async fn conversations_info(
95        &self,
96        req: &SlackApiConversationsInfoRequest,
97    ) -> ClientResult<SlackApiConversationsInfoResponse> {
98        self.http_session_api
99            .http_get(
100                "conversations.info",
101                &vec![
102                    ("channel", Some(req.channel.value())),
103                    (
104                        "include_num_members",
105                        req.include_num_members.map(|v| v.to_string()).as_ref(),
106                    ),
107                    (
108                        "include_locale",
109                        req.include_locale.map(|v| v.to_string()).as_ref(),
110                    ),
111                ],
112                Some(&SLACK_TIER3_METHOD_CONFIG),
113            )
114            .await
115    }
116
117    ///
118    /// https://api.slack.com/methods/conversations.invite
119    ///
120    pub async fn conversations_invite(
121        &self,
122        req: &SlackApiConversationsInviteRequest,
123    ) -> ClientResult<SlackApiConversationsInviteResponse> {
124        self.http_session_api
125            .http_post(
126                "conversations.invite",
127                req,
128                Some(&SLACK_TIER3_METHOD_CONFIG),
129            )
130            .await
131    }
132
133    ///
134    /// https://api.slack.com/methods/conversations.join
135    ///
136    pub async fn conversations_join(
137        &self,
138        req: &SlackApiConversationsJoinRequest,
139    ) -> ClientResult<SlackApiConversationsJoinResponse> {
140        self.http_session_api
141            .http_post("conversations.join", req, Some(&SLACK_TIER3_METHOD_CONFIG))
142            .await
143    }
144
145    ///
146    /// https://api.slack.com/methods/conversations.kick
147    ///
148    pub async fn conversations_kick(
149        &self,
150        req: &SlackApiConversationsKickRequest,
151    ) -> ClientResult<SlackApiConversationsKickResponse> {
152        self.http_session_api
153            .http_post("conversations.kick", req, Some(&SLACK_TIER3_METHOD_CONFIG))
154            .await
155    }
156
157    ///
158    /// https://api.slack.com/methods/conversations.leave
159    ///
160    pub async fn conversations_leave(
161        &self,
162        req: &SlackApiConversationsLeaveRequest,
163    ) -> ClientResult<SlackApiConversationsLeaveResponse> {
164        self.http_session_api
165            .http_post("conversations.leave", req, Some(&SLACK_TIER3_METHOD_CONFIG))
166            .await
167    }
168
169    ///
170    /// https://api.slack.com/methods/conversations.list
171    ///
172    pub async fn conversations_list(
173        &self,
174        req: &SlackApiConversationsListRequest,
175    ) -> ClientResult<SlackApiConversationsListResponse> {
176        self.http_session_api
177            .http_get(
178                "conversations.list",
179                &vec![
180                    ("cursor", req.cursor.as_ref().map(|x| x.value())),
181                    ("limit", req.limit.map(|v| v.to_string()).as_ref()),
182                    (
183                        "exclude_archived",
184                        req.exclude_archived.map(|v| v.to_string()).as_ref(),
185                    ),
186                    (
187                        "types",
188                        req.types
189                            .as_ref()
190                            .map(|xs| {
191                                xs.iter()
192                                    .map(|x| x.to_string())
193                                    .collect::<Vec<String>>()
194                                    .join(",")
195                            })
196                            .as_ref(),
197                    ),
198                ],
199                Some(&SLACK_TIER2_METHOD_CONFIG),
200            )
201            .await
202    }
203
204    ///
205    /// https://api.slack.com/methods/conversations.members
206    ///
207    pub async fn conversations_members(
208        &self,
209        req: &SlackApiConversationsMembersRequest,
210    ) -> ClientResult<SlackApiConversationsMembersResponse> {
211        self.http_session_api
212            .http_get(
213                "conversations.members",
214                &vec![
215                    ("channel", req.channel.as_ref().map(|x| x.value())),
216                    ("cursor", req.cursor.as_ref().map(|x| x.value())),
217                    ("limit", req.limit.map(|v| v.to_string()).as_ref()),
218                ],
219                Some(&SLACK_TIER4_METHOD_CONFIG),
220            )
221            .await
222    }
223
224    ///
225    /// https://api.slack.com/methods/conversations.open
226    /// return_im is set to None
227    ///
228    pub async fn conversations_open(
229        &self,
230        req: &SlackApiConversationsOpenRequest,
231    ) -> ClientResult<SlackApiConversationsOpenResponse<SlackBasicChannelInfo>> {
232        self.http_session_api
233            .http_post(
234                "conversations.open",
235                &req.clone().without_return_im(),
236                Some(&SLACK_TIER3_METHOD_CONFIG),
237            )
238            .await
239    }
240
241    ///
242    /// https://api.slack.com/methods/conversations.open
243    /// return_im is set to Some(true)
244    ///
245    pub async fn conversations_open_full(
246        &self,
247        req: &SlackApiConversationsOpenRequest,
248    ) -> ClientResult<SlackApiConversationsOpenResponse<SlackChannelInfo>> {
249        self.http_session_api
250            .http_post(
251                "conversations.open",
252                &req.clone().with_return_im(true),
253                Some(&SLACK_TIER3_METHOD_CONFIG),
254            )
255            .await
256    }
257
258    ///
259    /// https://api.slack.com/methods/conversations.rename
260    ///
261    pub async fn conversations_rename(
262        &self,
263        req: &SlackApiConversationsRenameRequest,
264    ) -> ClientResult<SlackApiConversationsRenameResponse> {
265        self.http_session_api
266            .http_post(
267                "conversations.rename",
268                req,
269                Some(&SLACK_TIER2_METHOD_CONFIG),
270            )
271            .await
272    }
273
274    ///
275    /// https://api.slack.com/methods/conversations.replies
276    ///
277    pub async fn conversations_replies(
278        &self,
279        req: &SlackApiConversationsRepliesRequest,
280    ) -> ClientResult<SlackApiConversationsRepliesResponse> {
281        self.http_session_api
282            .http_get(
283                "conversations.replies",
284                &vec![
285                    ("channel", Some(req.channel.value())),
286                    ("ts", Some(req.ts.value())),
287                    ("cursor", req.cursor.as_ref().map(|x| x.value())),
288                    ("limit", req.limit.map(|v| v.to_string()).as_ref()),
289                    ("inclusive", req.inclusive.map(|v| v.to_string()).as_ref()),
290                    ("latest", req.latest.as_ref().map(|x| x.value())),
291                    ("oldest", req.oldest.as_ref().map(|x| x.value())),
292                ],
293                Some(&SLACK_TIER3_METHOD_CONFIG),
294            )
295            .await
296    }
297
298    ///
299    /// https://api.slack.com/methods/conversations.setPurpose
300    ///
301    pub async fn conversations_set_purpose(
302        &self,
303        req: &SlackApiConversationsSetPurposeRequest,
304    ) -> ClientResult<SlackApiConversationsSetPurposeResponse> {
305        self.http_session_api
306            .http_post(
307                "conversations.setPurpose",
308                req,
309                Some(&SLACK_TIER2_METHOD_CONFIG),
310            )
311            .await
312    }
313
314    ///
315    /// https://api.slack.com/methods/conversations.setTopic
316    ///
317    pub async fn conversations_set_topic(
318        &self,
319        req: &SlackApiConversationsSetTopicRequest,
320    ) -> ClientResult<SlackApiConversationsSetTopicResponse> {
321        self.http_session_api
322            .http_post(
323                "conversations.setTopic",
324                req,
325                Some(&SLACK_TIER2_METHOD_CONFIG),
326            )
327            .await
328    }
329
330    ///
331    /// https://api.slack.com/methods/conversations.unarchive
332    ///
333    pub async fn conversations_unarchive(
334        &self,
335        req: &SlackApiConversationsUnarchiveRequest,
336    ) -> ClientResult<SlackApiConversationsUnarchiveResponse> {
337        self.http_session_api
338            .http_post(
339                "conversations.setTopic",
340                req,
341                Some(&SLACK_TIER2_METHOD_CONFIG),
342            )
343            .await
344    }
345}
346
347#[skip_serializing_none]
348#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
349pub struct SlackApiConversationsArchiveRequest {
350    pub channel: SlackChannelId,
351}
352
353#[skip_serializing_none]
354#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
355pub struct SlackApiConversationsArchiveResponse {}
356
357#[skip_serializing_none]
358#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
359pub struct SlackApiConversationsCloseRequest {
360    pub channel: SlackChannelId,
361}
362
363#[skip_serializing_none]
364#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
365pub struct SlackApiConversationsCloseResponse {
366    pub no_op: Option<bool>,
367    pub already_closed: Option<bool>,
368}
369
370#[skip_serializing_none]
371#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
372pub struct SlackApiConversationsCreateRequest {
373    pub name: String,
374    pub is_private: Option<bool>,
375    pub user_ds: Option<HashSet<SlackUserId>>,
376}
377
378#[skip_serializing_none]
379#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
380pub struct SlackApiConversationsCreateResponse {
381    pub channel: SlackChannelInfo,
382}
383
384#[skip_serializing_none]
385#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
386pub struct SlackApiConversationsHistoryRequest {
387    pub channel: Option<SlackChannelId>,
388    pub cursor: Option<SlackCursorId>,
389    pub latest: Option<SlackTs>,
390    pub limit: Option<u16>,
391    pub oldest: Option<SlackTs>,
392    pub inclusive: Option<bool>,
393    pub include_all_metadata: Option<bool>,
394}
395
396#[skip_serializing_none]
397#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
398pub struct SlackApiConversationsHistoryResponse {
399    pub messages: Vec<SlackHistoryMessage>,
400    pub response_metadata: Option<SlackResponseMetadata>,
401    pub has_more: Option<bool>,
402    pub pin_count: Option<u64>,
403}
404
405impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiConversationsHistoryRequest
406where
407    SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
408{
409    type ResponseType = SlackApiConversationsHistoryResponse;
410    type CursorType = SlackCursorId;
411    type ResponseItemType = SlackHistoryMessage;
412
413    fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
414        self.clone().opt_cursor(new_cursor.cloned())
415    }
416
417    fn scroll<'a, 's>(
418        &'a self,
419        session: &'a SlackClientSession<'s, SCHC>,
420    ) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
421        async move { session.conversations_history(self).await }.boxed()
422    }
423}
424
425impl SlackApiScrollableResponse for SlackApiConversationsHistoryResponse {
426    type CursorType = SlackCursorId;
427    type ResponseItemType = SlackHistoryMessage;
428
429    fn next_cursor(&self) -> Option<Self::CursorType> {
430        self.response_metadata
431            .as_ref()
432            .and_then(|rm| rm.next_cursor.as_ref())
433            .cloned()
434    }
435
436    fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
437        Box::new(self.messages.iter())
438    }
439}
440
441#[skip_serializing_none]
442#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
443pub struct SlackApiConversationsInfoRequest {
444    pub channel: SlackChannelId,
445    pub include_locale: Option<bool>,
446    pub include_num_members: Option<bool>,
447}
448
449#[skip_serializing_none]
450#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
451pub struct SlackApiConversationsInfoResponse {
452    pub channel: SlackChannelInfo,
453}
454
455#[skip_serializing_none]
456#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
457pub struct SlackApiConversationsInviteRequest {
458    pub channel: SlackChannelId,
459    pub users: Vec<SlackUserId>,
460}
461
462#[skip_serializing_none]
463#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
464pub struct SlackApiConversationsInviteResponse {
465    pub channel: SlackChannelInfo,
466}
467
468#[skip_serializing_none]
469#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
470pub struct SlackApiConversationsJoinRequest {
471    pub channel: SlackChannelId,
472}
473
474#[skip_serializing_none]
475#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
476pub struct SlackApiConversationsJoinResponse {
477    pub channel: SlackChannelInfo,
478    pub response_metadata: Option<SlackResponseMetadata>,
479}
480
481#[skip_serializing_none]
482#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
483pub struct SlackApiConversationsKickRequest {
484    pub channel: SlackChannelId,
485    pub user: SlackUserId,
486}
487
488#[skip_serializing_none]
489#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
490pub struct SlackApiConversationsKickResponse {}
491
492#[skip_serializing_none]
493#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
494pub struct SlackApiConversationsLeaveRequest {
495    pub channel: SlackChannelId,
496}
497
498#[skip_serializing_none]
499#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
500pub struct SlackApiConversationsLeaveResponse {
501    pub not_in_channel: Option<bool>,
502}
503
504#[skip_serializing_none]
505#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
506pub struct SlackApiConversationsListRequest {
507    pub cursor: Option<SlackCursorId>,
508    pub limit: Option<u16>,
509    pub exclude_archived: Option<bool>,
510    pub types: Option<Vec<SlackConversationType>>,
511}
512
513#[skip_serializing_none]
514#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
515pub struct SlackApiConversationsListResponse {
516    pub channels: Vec<SlackChannelInfo>,
517    pub response_metadata: Option<SlackResponseMetadata>,
518}
519
520impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiConversationsListRequest
521where
522    SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
523{
524    type ResponseType = SlackApiConversationsListResponse;
525    type CursorType = SlackCursorId;
526    type ResponseItemType = SlackChannelInfo;
527
528    fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
529        self.clone().opt_cursor(new_cursor.cloned())
530    }
531
532    fn scroll<'a, 's>(
533        &'a self,
534        session: &'a SlackClientSession<'s, SCHC>,
535    ) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
536        async move { session.conversations_list(self).await }.boxed()
537    }
538}
539
540impl SlackApiScrollableResponse for SlackApiConversationsListResponse {
541    type CursorType = SlackCursorId;
542    type ResponseItemType = SlackChannelInfo;
543
544    fn next_cursor(&self) -> Option<Self::CursorType> {
545        self.response_metadata
546            .as_ref()
547            .and_then(|rm| rm.next_cursor.as_ref())
548            .cloned()
549    }
550
551    fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
552        Box::new(self.channels.iter())
553    }
554}
555
556#[skip_serializing_none]
557#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
558pub struct SlackApiConversationsMembersRequest {
559    pub channel: Option<SlackChannelId>,
560    pub cursor: Option<SlackCursorId>,
561    pub limit: Option<u16>,
562}
563
564#[skip_serializing_none]
565#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
566pub struct SlackApiConversationsMembersResponse {
567    pub members: Vec<SlackUserId>,
568    pub response_metadata: Option<SlackResponseMetadata>,
569}
570
571impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiConversationsMembersRequest
572where
573    SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
574{
575    type ResponseType = SlackApiConversationsMembersResponse;
576    type CursorType = SlackCursorId;
577    type ResponseItemType = SlackUserId;
578
579    fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
580        self.clone().opt_cursor(new_cursor.cloned())
581    }
582
583    fn scroll<'a, 's>(
584        &'a self,
585        session: &'a SlackClientSession<'s, SCHC>,
586    ) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
587        async move { session.conversations_members(self).await }.boxed()
588    }
589}
590
591impl SlackApiScrollableResponse for SlackApiConversationsMembersResponse {
592    type CursorType = SlackCursorId;
593    type ResponseItemType = SlackUserId;
594
595    fn next_cursor(&self) -> Option<Self::CursorType> {
596        self.response_metadata
597            .as_ref()
598            .and_then(|rm| rm.next_cursor.as_ref())
599            .cloned()
600    }
601
602    fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
603        Box::new(self.members.iter())
604    }
605}
606
607#[skip_serializing_none]
608#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
609pub struct SlackApiConversationsOpenRequest {
610    pub channel: Option<SlackChannelId>,
611    pub return_im: Option<bool>,
612    pub users: Option<Vec<SlackUserId>>,
613}
614
615#[skip_serializing_none]
616#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
617pub struct SlackApiConversationsOpenResponse<T>
618where
619    T: HasChannelInfo,
620{
621    pub channel: T,
622    pub already_open: Option<bool>,
623    pub no_op: Option<bool>,
624}
625
626#[skip_serializing_none]
627#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
628pub struct SlackApiConversationsRenameRequest {
629    pub channel: SlackChannelId,
630    pub name: String,
631}
632
633#[skip_serializing_none]
634#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
635pub struct SlackApiConversationsRenameResponse {
636    pub channel: SlackChannelInfo,
637}
638
639#[skip_serializing_none]
640#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
641pub struct SlackApiConversationsRepliesRequest {
642    pub channel: SlackChannelId,
643    pub ts: SlackTs,
644    pub cursor: Option<SlackCursorId>,
645    pub latest: Option<SlackTs>,
646    pub limit: Option<u16>,
647    pub oldest: Option<SlackTs>,
648    pub inclusive: Option<bool>,
649}
650
651#[skip_serializing_none]
652#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
653pub struct SlackApiConversationsRepliesResponse {
654    pub messages: Vec<SlackHistoryMessage>,
655    pub response_metadata: Option<SlackResponseMetadata>,
656    pub has_more: Option<bool>,
657}
658
659impl<SCHC> SlackApiScrollableRequest<SCHC> for SlackApiConversationsRepliesRequest
660where
661    SCHC: SlackClientHttpConnector + Send + Sync + Clone + 'static,
662{
663    type ResponseType = SlackApiConversationsRepliesResponse;
664    type CursorType = SlackCursorId;
665    type ResponseItemType = SlackHistoryMessage;
666
667    fn with_new_cursor(&self, new_cursor: Option<&Self::CursorType>) -> Self {
668        self.clone().opt_cursor(new_cursor.cloned())
669    }
670
671    fn scroll<'a, 's>(
672        &'a self,
673        session: &'a SlackClientSession<'s, SCHC>,
674    ) -> BoxFuture<'a, ClientResult<Self::ResponseType>> {
675        async move { session.conversations_replies(self).await }.boxed()
676    }
677}
678
679impl SlackApiScrollableResponse for SlackApiConversationsRepliesResponse {
680    type CursorType = SlackCursorId;
681    type ResponseItemType = SlackHistoryMessage;
682
683    fn next_cursor(&self) -> Option<Self::CursorType> {
684        self.response_metadata
685            .as_ref()
686            .and_then(|rm| rm.next_cursor.as_ref())
687            .cloned()
688    }
689
690    fn scrollable_items<'a>(&'a self) -> Box<dyn Iterator<Item = &'a Self::ResponseItemType> + 'a> {
691        Box::new(self.messages.iter())
692    }
693}
694
695#[skip_serializing_none]
696#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
697pub struct SlackApiConversationsSetPurposeRequest {
698    pub channel: SlackChannelId,
699    pub purpose: String,
700}
701
702#[skip_serializing_none]
703#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
704pub struct SlackApiConversationsSetPurposeResponse {
705    pub purpose: Option<String>,
706}
707
708#[skip_serializing_none]
709#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
710pub struct SlackApiConversationsSetTopicRequest {
711    pub channel: SlackChannelId,
712    pub topic: String,
713}
714
715#[skip_serializing_none]
716#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
717pub struct SlackApiConversationsSetTopicResponse {
718    pub topic: Option<String>,
719}
720
721#[skip_serializing_none]
722#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
723pub struct SlackApiConversationsUnarchiveRequest {
724    pub channel: SlackChannelId,
725}
726
727#[skip_serializing_none]
728#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Builder)]
729pub struct SlackApiConversationsUnarchiveResponse {}