serenity/builder/create_invite.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/// A builder to create a [`RichInvite`] for use via [`GuildChannel::create_invite`].
10///
11/// This is a structured and cleaner way of creating an invite, as all parameters are optional.
12///
13/// # Examples
14///
15/// Create an invite with a max age of 3600 seconds and 10 max uses:
16///
17/// ```rust,no_run
18/// # use serenity::{prelude::*, model::prelude::*};
19/// use serenity::builder::CreateInvite;
20/// # async fn run(context: impl CacheHttp, channel: GuildChannel) -> Result<(), Box<dyn std::error::Error>> {
21/// let builder = CreateInvite::new().max_age(3600).max_uses(10);
22/// let creation = channel.create_invite(&context, builder).await?;
23/// # Ok(())
24/// # }
25/// ```
26///
27/// [Discord docs](https://discord.com/developers/docs/resources/channel#create-channel-invite)
28#[derive(Clone, Debug, Default, Serialize)]
29#[must_use]
30pub struct CreateInvite<'a> {
31 #[serde(skip_serializing_if = "Option::is_none")]
32 max_age: Option<u32>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 max_uses: Option<u8>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 temporary: Option<bool>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 unique: Option<bool>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 target_type: Option<InviteTargetType>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 target_user_id: Option<UserId>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 target_application_id: Option<ApplicationId>,
45
46 #[serde(skip)]
47 audit_log_reason: Option<&'a str>,
48}
49
50impl<'a> CreateInvite<'a> {
51 /// Equivalent to [`Self::default`].
52 pub fn new() -> Self {
53 Self::default()
54 }
55
56 /// The duration that the invite will be valid for.
57 ///
58 /// Set to `0` for an invite which does not expire after an amount of time.
59 ///
60 /// Defaults to `86400`, or 24 hours.
61 ///
62 /// # Examples
63 ///
64 /// Create an invite with a max age of `3600` seconds, or 1 hour:
65 ///
66 /// ```rust,no_run
67 /// # use serenity::model::prelude::*;
68 /// # use serenity::builder::CreateInvite;
69 /// # use serenity::http::CacheHttp;
70 /// #
71 /// # async fn example(context: impl CacheHttp, channel: GuildChannel) -> Result<(), Box<dyn std::error::Error>> {
72 /// let builder = CreateInvite::new().max_age(3600);
73 /// let invite = channel.create_invite(context, builder).await?;
74 /// # Ok(())
75 /// # }
76 /// ```
77 pub fn max_age(mut self, max_age: u32) -> Self {
78 self.max_age = Some(max_age);
79 self
80 }
81
82 /// The number of uses that the invite will be valid for.
83 ///
84 /// Set to `0` for an invite which does not expire after a number of uses.
85 ///
86 /// Defaults to `0`.
87 ///
88 /// # Examples
89 ///
90 /// Create an invite with a max use limit of `5`:
91 ///
92 /// Create an invite with a max age of `3600` seconds, or 1 hour:
93 ///
94 /// ```rust,no_run
95 /// # use serenity::model::prelude::*;
96 /// # use serenity::builder::CreateInvite;
97 /// # use serenity::http::CacheHttp;
98 /// #
99 /// # async fn example(context: impl CacheHttp, channel: GuildChannel) -> Result<(), Box<dyn std::error::Error>> {
100 /// let builder = CreateInvite::new().max_uses(5);
101 /// let invite = channel.create_invite(context, builder).await?;
102 /// # Ok(())
103 /// # }
104 /// ```
105 pub fn max_uses(mut self, max_uses: u8) -> Self {
106 self.max_uses = Some(max_uses);
107 self
108 }
109
110 /// Whether an invite grants a temporary membership.
111 ///
112 /// Defaults to `false`.
113 ///
114 /// # Examples
115 ///
116 /// Create an invite which is temporary:
117 ///
118 /// ```rust,no_run
119 /// # use serenity::model::prelude::*;
120 /// # use serenity::builder::CreateInvite;
121 /// # use serenity::http::CacheHttp;
122 /// #
123 /// # async fn example(context: impl CacheHttp, channel: GuildChannel) -> Result<(), Box<dyn std::error::Error>> {
124 /// let builder = CreateInvite::new().temporary(true);
125 /// let invite = channel.create_invite(context, builder).await?;
126 /// # Ok(())
127 /// # }
128 /// ```
129 pub fn temporary(mut self, temporary: bool) -> Self {
130 self.temporary = Some(temporary);
131 self
132 }
133
134 /// Whether or not to try to reuse a similar invite.
135 ///
136 /// Defaults to `false`.
137 ///
138 /// # Examples
139 ///
140 /// Create an invite which is unique:
141 ///
142 /// ```rust,no_run
143 /// # use serenity::model::prelude::*;
144 /// # use serenity::builder::CreateInvite;
145 /// # use serenity::http::CacheHttp;
146 /// #
147 /// # async fn example(context: impl CacheHttp, channel: GuildChannel) -> Result<(), Box<dyn std::error::Error>> {
148 /// let builder = CreateInvite::new().unique(true);
149 /// let invite = channel.create_invite(context, builder).await?;
150 /// # Ok(())
151 /// # }
152 /// ```
153 pub fn unique(mut self, unique: bool) -> Self {
154 self.unique = Some(unique);
155 self
156 }
157
158 /// The type of target for this voice channel invite.
159 pub fn target_type(mut self, target_type: InviteTargetType) -> Self {
160 self.target_type = Some(target_type);
161 self
162 }
163
164 /// The ID of the user whose stream to display for this invite, required if `target_type` is
165 /// `Stream`
166 /// The user must be streaming in the channel.
167 pub fn target_user_id(mut self, target_user_id: UserId) -> Self {
168 self.target_user_id = Some(target_user_id);
169 self
170 }
171
172 /// The ID of the embedded application to open for this invite, required if `target_type` is
173 /// `EmmbeddedApplication`.
174 ///
175 /// The application must have the `EMBEDDED` flag.
176 ///
177 /// When sending an invite with this value, the first user to use the invite will have to click
178 /// on the URL, that will enable the buttons in the embed.
179 ///
180 /// These are some of the known applications which have the flag:
181 ///
182 /// betrayal: `773336526917861400`
183 /// youtube: `755600276941176913`
184 /// fishing: `814288819477020702`
185 /// poker: `755827207812677713`
186 /// chess: `832012774040141894`
187 pub fn target_application_id(mut self, target_application_id: ApplicationId) -> Self {
188 self.target_application_id = Some(target_application_id);
189 self
190 }
191
192 /// Sets the request's audit log reason.
193 pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
194 self.audit_log_reason = Some(reason);
195 self
196 }
197}
198
199#[cfg(feature = "http")]
200#[async_trait::async_trait]
201impl Builder for CreateInvite<'_> {
202 type Context<'ctx> = ChannelId;
203 type Built = RichInvite;
204
205 /// Creates an invite for the given channel.
206 ///
207 /// **Note**: Requires the [Create Instant Invite] permission.
208 ///
209 /// # Errors
210 ///
211 /// If the `cache` is enabled, returns [`ModelError::InvalidPermissions`] if the current user
212 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
213 ///
214 /// [Create Instant Invite]: Permissions::CREATE_INSTANT_INVITE
215 async fn execute(
216 self,
217 cache_http: impl CacheHttp,
218 ctx: Self::Context<'_>,
219 ) -> Result<RichInvite> {
220 #[cfg(feature = "cache")]
221 {
222 if let Some(cache) = cache_http.cache() {
223 crate::utils::user_has_perms_cache(cache, ctx, Permissions::CREATE_INSTANT_INVITE)?;
224 }
225 }
226
227 cache_http.http().create_invite(ctx, &self, self.audit_log_reason).await
228 }
229}