serenity/builder/
create_thread.rs

1#[cfg(feature = "http")]
2use super::Builder;
3#[cfg(feature = "http")]
4use crate::http::CacheHttp;
5#[cfg(feature = "http")]
6use crate::internal::prelude::*;
7use crate::model::prelude::*;
8
9/// Discord docs:
10/// - [starting thread from message](https://discord.com/developers/docs/resources/channel#start-thread-from-message)
11/// - [starting thread without message](https://discord.com/developers/docs/resources/channel#start-thread-without-message)
12#[derive(Clone, Debug, Serialize)]
13#[must_use]
14pub struct CreateThread<'a> {
15    name: String,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    auto_archive_duration: Option<AutoArchiveDuration>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    #[serde(rename = "type")]
20    kind: Option<ChannelType>,
21    #[serde(skip_serializing_if = "Option::is_none")]
22    invitable: Option<bool>,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    rate_limit_per_user: Option<u16>,
25
26    #[serde(skip)]
27    audit_log_reason: Option<&'a str>,
28}
29
30impl<'a> CreateThread<'a> {
31    /// Creates a builder with the given thread name, leaving all other fields empty.
32    pub fn new(name: impl Into<String>) -> Self {
33        Self {
34            name: name.into(),
35            auto_archive_duration: None,
36            rate_limit_per_user: None,
37            invitable: None,
38            kind: None,
39            audit_log_reason: None,
40        }
41    }
42
43    /// The name of the thread. Replaces the current value as set in [`Self::new`].
44    ///
45    /// **Note**: Must be between 2 and 100 characters long.
46    pub fn name(mut self, name: impl Into<String>) -> Self {
47        self.name = name.into();
48        self
49    }
50
51    /// Duration in minutes to automatically archive the thread after recent activity.
52    pub fn auto_archive_duration(mut self, duration: AutoArchiveDuration) -> Self {
53        self.auto_archive_duration = Some(duration);
54        self
55    }
56
57    /// How many seconds must a user wait before sending another message.
58    ///
59    /// Bots, or users with the [`MANAGE_MESSAGES`] and/or [`MANAGE_CHANNELS`] permissions are
60    /// exempt from this restriction.
61    ///
62    /// **Note**: Must be between 0 and 21600 seconds (360 minutes or 6 hours).
63    ///
64    /// [`MANAGE_MESSAGES`]: crate::model::permissions::Permissions::MANAGE_MESSAGES
65    /// [`MANAGE_CHANNELS`]: crate::model::permissions::Permissions::MANAGE_CHANNELS
66    #[doc(alias = "slowmode")]
67    pub fn rate_limit_per_user(mut self, seconds: u16) -> Self {
68        self.rate_limit_per_user = Some(seconds);
69        self
70    }
71
72    /// Whether or not non-moderators can add other non-moderators to a thread.
73    pub fn invitable(mut self, invitable: bool) -> Self {
74        self.invitable = Some(invitable);
75        self
76    }
77
78    /// The thread type, either [`ChannelType::PublicThread`] or [`ChannelType::PrivateThread`].
79    ///
80    /// **Note**: This field is ignored for message threads, and defaults to
81    /// [`ChannelType::PrivateThread`] for standalone threads in order to match the behavior when
82    /// thread documentation was first published. This is a bit of a weird default though, and
83    /// thus is highly likely to change in the future, so it is recommended to always explicitly
84    /// setting it to avoid any breaking change.
85    pub fn kind(mut self, kind: ChannelType) -> Self {
86        self.kind = Some(kind);
87        self
88    }
89
90    /// Sets the request's audit log reason.
91    pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
92        self.audit_log_reason = Some(reason);
93        self
94    }
95}
96
97#[cfg(feature = "http")]
98#[async_trait::async_trait]
99impl Builder for CreateThread<'_> {
100    type Context<'ctx> = (ChannelId, Option<MessageId>);
101    type Built = GuildChannel;
102
103    /// Creates a thread, either private or public. Public threads require a message to connect the
104    /// thread to.
105    ///
106    /// # Errors
107    ///
108    /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
109    async fn execute(
110        self,
111        cache_http: impl CacheHttp,
112        ctx: Self::Context<'_>,
113    ) -> Result<GuildChannel> {
114        let http = cache_http.http();
115        match ctx.1 {
116            Some(id) => {
117                http.create_thread_from_message(ctx.0, id, &self, self.audit_log_reason).await
118            },
119            None => http.create_thread(ctx.0, &self, self.audit_log_reason).await,
120        }
121    }
122}