serenity/builder/edit_guild.rs
1#[cfg(feature = "http")]
2use super::Builder;
3use super::CreateAttachment;
4#[cfg(feature = "http")]
5use crate::http::CacheHttp;
6#[cfg(feature = "http")]
7use crate::internal::prelude::*;
8use crate::model::prelude::*;
9
10/// A builder to optionally edit certain fields of a guild
11///
12/// [Discord docs](https://discord.com/developers/docs/resources/guild#modify-guild).
13#[derive(Clone, Debug, Default, Serialize)]
14#[must_use]
15pub struct EditGuild<'a> {
16 #[serde(skip_serializing_if = "Option::is_none")]
17 name: Option<String>,
18 // [Omitting region because Discord deprecated it]
19 #[serde(skip_serializing_if = "Option::is_none")]
20 verification_level: Option<VerificationLevel>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 default_message_notifications: Option<Option<DefaultMessageNotificationLevel>>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 explicit_content_filter: Option<Option<ExplicitContentFilter>>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 afk_channel_id: Option<Option<ChannelId>>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 afk_timeout: Option<AfkTimeout>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 icon: Option<Option<String>>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 owner_id: Option<UserId>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 splash: Option<Option<String>>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 discovery_splash: Option<Option<String>>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 banner: Option<Option<String>>,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 system_channel_id: Option<Option<ChannelId>>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 system_channel_flags: Option<SystemChannelFlags>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 rules_channel_id: Option<Option<ChannelId>>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 public_updates_channel_id: Option<Option<ChannelId>>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 preferred_locale: Option<Option<String>>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 features: Option<Vec<String>>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 description: Option<String>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 premium_progress_bar_enabled: Option<bool>,
55
56 #[serde(skip)]
57 audit_log_reason: Option<&'a str>,
58}
59
60impl<'a> EditGuild<'a> {
61 /// Equivalent to [`Self::default`].
62 pub fn new() -> Self {
63 Self::default()
64 }
65
66 /// Set the "AFK voice channel" that users are to move to if they have been AFK for an amount
67 /// of time, configurable by [`Self::afk_timeout`]. Pass [`None`] to unset the current value.
68 #[inline]
69 pub fn afk_channel(mut self, channel: Option<ChannelId>) -> Self {
70 self.afk_channel_id = Some(channel);
71 self
72 }
73
74 /// Set the amount of time a user is to be moved to the AFK channel - configured via
75 /// [`Self::afk_channel`] - after being AFK.
76 pub fn afk_timeout(mut self, timeout: AfkTimeout) -> Self {
77 self.afk_timeout = Some(timeout);
78 self
79 }
80
81 /// Set the icon of the guild. Pass [`None`] to remove the icon.
82 ///
83 /// # Examples
84 ///
85 /// Using the utility builder - [`CreateAttachment`] - to read an image and encode it in
86 /// base64, to then set as the guild icon.
87 ///
88 /// ```rust,no_run
89 /// # use serenity::builder::{EditGuild, CreateAttachment};
90 /// # use serenity::{http::Http, model::id::GuildId};
91 /// #
92 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
93 /// # let http: Http = unimplemented!();
94 /// # let mut guild = GuildId::new(1).to_partial_guild(&http).await?;
95 /// let icon = CreateAttachment::path("./guild_icon.png").await?;
96 ///
97 /// // assuming a `guild` has already been bound
98 /// let builder = EditGuild::new().icon(Some(&icon));
99 /// guild.edit(&http, builder).await?;
100 /// # Ok(())
101 /// # }
102 /// ```
103 pub fn icon(mut self, icon: Option<&CreateAttachment>) -> Self {
104 self.icon = Some(icon.map(CreateAttachment::to_base64));
105 self
106 }
107
108 /// Clear the current guild icon, resetting it to the default logo.
109 pub fn delete_icon(mut self) -> Self {
110 self.icon = Some(None);
111 self
112 }
113
114 /// Set the name of the guild.
115 ///
116 /// **Note**: Must be between (and including) 2-100 characters.
117 pub fn name(mut self, name: impl Into<String>) -> Self {
118 self.name = Some(name.into());
119 self
120 }
121
122 /// Set the description of the guild.
123 ///
124 /// **Note**: Requires that the guild have the `DISCOVERABLE` feature enabled. You can check
125 /// this through a guild's [`features`] list.
126 ///
127 /// [`features`]: Guild::features
128 pub fn description(mut self, name: impl Into<String>) -> Self {
129 self.description = Some(name.into());
130 self
131 }
132
133 /// Set the features of the guild.
134 ///
135 /// **Note**: Requires that the guild have the `DISCOVERABLE` feature enabled. You can check
136 /// this through a guild's [`features`] list.
137 ///
138 /// [`features`]: Guild::features
139 pub fn features(mut self, features: Vec<String>) -> Self {
140 self.features = Some(features);
141 self
142 }
143
144 /// Transfers the ownership of the guild to another user by Id.
145 ///
146 /// **Note**: The current user must be the owner of the guild.
147 #[inline]
148 pub fn owner(mut self, user_id: impl Into<UserId>) -> Self {
149 self.owner_id = Some(user_id.into());
150 self
151 }
152
153 /// Set the splash image of the guild on the invitation page.
154 ///
155 /// The `splash` must be base64-encoded 1024x1024 png/jpeg/gif image-data.
156 ///
157 /// Requires that the guild have the `INVITE_SPLASH` feature enabled. You can check this
158 /// through a guild's [`features`] list.
159 ///
160 /// [`features`]: Guild::features
161 pub fn splash(mut self, splash: Option<String>) -> Self {
162 self.splash = Some(splash);
163 self
164 }
165
166 /// Set the splash image of the guild on the discovery page.
167 ///
168 /// The `splash` must be base64-encoded 1024x1024 png/jpeg/gif image-data.
169 ///
170 /// Requires that the guild have the `DISCOVERABLE` feature enabled. You can check this through
171 /// a guild's [`features`] list.
172 ///
173 /// [`features`]: Guild::features
174 pub fn discovery_splash(mut self, splash: Option<String>) -> Self {
175 self.discovery_splash = Some(splash);
176 self
177 }
178
179 /// Set the banner image of the guild, it appears on the left side-bar.
180 ///
181 /// The `banner` must be base64-encoded 16:9 png/jpeg image data.
182 ///
183 /// Requires that the guild have the `BANNER` feature enabled. You can check this through a
184 /// guild's [`features`] list.
185 ///
186 /// [`features`]: Guild::features
187 pub fn banner(mut self, banner: Option<String>) -> Self {
188 self.banner = Some(banner);
189 self
190 }
191
192 /// Set the channel ID where welcome messages and boost events will be posted.
193 pub fn system_channel_id(mut self, channel_id: Option<ChannelId>) -> Self {
194 self.system_channel_id = Some(channel_id);
195 self
196 }
197
198 /// Set the channel ID of the rules and guidelines channel.
199 ///
200 /// **Note**: This feature is for Community guilds only.
201 pub fn rules_channel_id(mut self, channel_id: Option<ChannelId>) -> Self {
202 self.rules_channel_id = Some(channel_id);
203 self
204 }
205
206 /// Set the channel ID where admins and moderators receive update messages from Discord.
207 ///
208 /// **Note**: This feature is for Community guilds only.
209 pub fn public_updates_channel_id(mut self, channel_id: Option<ChannelId>) -> Self {
210 self.public_updates_channel_id = Some(channel_id);
211 self
212 }
213
214 /// Set the preferred locale used in Server Discovery and update messages from Discord.
215 ///
216 /// If this is not set, the locale will default to "en-US";
217 ///
218 /// **Note**: This feature is for Community guilds only.
219 pub fn preferred_locale(mut self, locale: Option<String>) -> Self {
220 self.preferred_locale = Some(locale);
221 self
222 }
223
224 /// Set the content filter level.
225 pub fn explicit_content_filter(mut self, level: Option<ExplicitContentFilter>) -> Self {
226 self.explicit_content_filter = Some(level);
227 self
228 }
229
230 /// Set the default message notification level.
231 pub fn default_message_notifications(
232 mut self,
233 level: Option<DefaultMessageNotificationLevel>,
234 ) -> Self {
235 self.default_message_notifications = Some(level);
236 self
237 }
238
239 /// Set the verification level of the guild. This can restrict what a user must have prior to
240 /// being able to send messages in a guild.
241 ///
242 /// Refer to the documentation for [`VerificationLevel`] for more information on each variant.
243 ///
244 /// # Examples
245 ///
246 /// Setting the verification level to [`High`][`VerificationLevel::High`]:
247 ///
248 /// ```rust,no_run
249 /// # use serenity::builder::EditGuild;
250 /// # use serenity::{http::Http, model::guild::Guild};
251 /// #
252 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
253 /// # let http: Http = unimplemented!();
254 /// # let mut guild: Guild = unimplemented!();
255 /// use serenity::model::guild::VerificationLevel;
256 ///
257 /// let builder = EditGuild::new().verification_level(VerificationLevel::High);
258 ///
259 /// // assuming a `guild` has already been bound
260 /// let edit = guild.edit(&http, builder).await;
261 /// if let Err(why) = edit {
262 /// println!("Error setting verification level: {:?}", why);
263 /// }
264 /// # Ok(())
265 /// # }
266 /// ```
267 #[inline]
268 pub fn verification_level(mut self, verification_level: impl Into<VerificationLevel>) -> Self {
269 self.verification_level = Some(verification_level.into());
270 self
271 }
272
273 /// Modifies the notifications that are sent by discord to the configured system channel.
274 ///
275 /// ```rust,no_run
276 /// # use serenity::builder::EditGuild;
277 /// # use serenity::{http::Http, model::guild::Guild};
278 /// #
279 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
280 /// # let http: Http = unimplemented!();
281 /// # let mut guild: Guild = unimplemented!();
282 /// use serenity::model::guild::SystemChannelFlags;
283 ///
284 /// let builder = EditGuild::new().system_channel_flags(
285 /// SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATIONS
286 /// | SystemChannelFlags::SUPPRESS_GUILD_REMINDER_NOTIFICATIONS,
287 /// );
288 ///
289 /// // assuming a `guild` has already been bound
290 /// let edit = guild.edit(&http, builder).await;
291 /// if let Err(why) = edit {
292 /// println!("Error setting system channel flags: {:?}", why);
293 /// }
294 /// # Ok(())
295 /// # }
296 /// ```
297 pub fn system_channel_flags(mut self, system_channel_flags: SystemChannelFlags) -> Self {
298 self.system_channel_flags = Some(system_channel_flags);
299 self
300 }
301
302 /// Sets the request's audit log reason.
303 pub fn audit_log_reason(mut self, reason: &'a str) -> Self {
304 self.audit_log_reason = Some(reason);
305 self
306 }
307
308 /// Whether the guild's boost progress bar should be enabled
309 pub fn premium_progress_bar_enabled(mut self, premium_progress_bar_enabled: bool) -> Self {
310 self.premium_progress_bar_enabled = Some(premium_progress_bar_enabled);
311 self
312 }
313}
314
315#[cfg(feature = "http")]
316#[async_trait::async_trait]
317impl Builder for EditGuild<'_> {
318 type Context<'ctx> = GuildId;
319 type Built = PartialGuild;
320
321 /// Edits the given guild.
322 ///
323 /// **Note**: Requires the [Manage Guild] permission.
324 ///
325 /// # Errors
326 ///
327 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
328 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
329 ///
330 /// [Manage Guild]: Permissions::MANAGE_GUILD
331 async fn execute(
332 self,
333 cache_http: impl CacheHttp,
334 ctx: Self::Context<'_>,
335 ) -> Result<Self::Built> {
336 #[cfg(feature = "cache")]
337 crate::utils::user_has_guild_perms(&cache_http, ctx, Permissions::MANAGE_GUILD)?;
338
339 cache_http.http().edit_guild(ctx, &self, self.audit_log_reason).await
340 }
341}