serenity/model/guild/guild_id.rs
1use std::fmt;
2
3#[cfg(feature = "model")]
4use futures::stream::Stream;
5
6#[cfg(feature = "model")]
7use crate::builder::{
8 AddMember,
9 Builder,
10 CreateChannel,
11 CreateCommand,
12 CreateScheduledEvent,
13 CreateSticker,
14 EditAutoModRule,
15 EditCommandPermissions,
16 EditGuild,
17 EditGuildWelcomeScreen,
18 EditGuildWidget,
19 EditMember,
20 EditRole,
21 EditScheduledEvent,
22 EditSticker,
23};
24#[cfg(all(feature = "cache", feature = "model"))]
25use crate::cache::{Cache, GuildRef};
26#[cfg(feature = "collector")]
27use crate::collector::{MessageCollector, ReactionCollector};
28#[cfg(feature = "collector")]
29use crate::gateway::ShardMessenger;
30#[cfg(feature = "model")]
31use crate::http::{CacheHttp, Http, UserPagination};
32#[cfg(feature = "model")]
33use crate::internal::prelude::*;
34#[cfg(feature = "model")]
35use crate::json::json;
36use crate::model::prelude::*;
37
38#[cfg(feature = "model")]
39impl GuildId {
40 /// Gets all auto moderation [`Rule`]s of this guild via HTTP.
41 ///
42 /// **Note**: Requires the [Manage Guild] permission.
43 ///
44 /// # Errors
45 ///
46 /// Returns an [`Error::Http`] if the guild is unavailable.
47 ///
48 /// [Manage Guild]: Permissions::MANAGE_GUILD
49 #[inline]
50 pub async fn automod_rules(self, http: impl AsRef<Http>) -> Result<Vec<Rule>> {
51 http.as_ref().get_automod_rules(self).await
52 }
53
54 /// Gets an auto moderation [`Rule`] of this guild by its ID via HTTP.
55 ///
56 /// **Note**: Requires the [Manage Guild] permission.
57 ///
58 /// # Errors
59 ///
60 /// Returns an [`Error::Http`] if a rule with the given ID does not exist.
61 ///
62 /// [Manage Guild]: Permissions::MANAGE_GUILD
63 #[inline]
64 pub async fn automod_rule(
65 self,
66 http: impl AsRef<Http>,
67 rule_id: impl Into<RuleId>,
68 ) -> Result<Rule> {
69 http.as_ref().get_automod_rule(self, rule_id.into()).await
70 }
71
72 /// Creates an auto moderation [`Rule`] in the guild.
73 ///
74 /// **Note**: Requires the [Manage Guild] permission.
75 ///
76 /// # Examples
77 ///
78 /// Create a custom keyword filter to block the message and timeout the author.
79 ///
80 /// ```
81 /// use std::time::Duration;
82 ///
83 /// use serenity::builder::EditAutoModRule;
84 /// use serenity::model::guild::automod::{Action, Trigger};
85 /// use serenity::model::id::GuildId;
86 ///
87 /// # async fn run() {
88 /// # use serenity::http::Http;
89 /// # let http: Http = unimplemented!();
90 /// let builder = EditAutoModRule::new()
91 /// .name("foobar filter")
92 /// .trigger(Trigger::Keyword {
93 /// strings: vec!["foo*".to_string(), "*bar".to_string()],
94 /// regex_patterns: vec![],
95 /// allow_list: vec![],
96 /// })
97 /// .actions(vec![
98 /// Action::BlockMessage {
99 /// custom_message: None,
100 /// },
101 /// Action::Timeout(Duration::from_secs(60)),
102 /// ]);
103 /// let _rule = GuildId::new(7).create_automod_rule(&http, builder).await;
104 /// # }
105 /// ```
106 ///
107 /// # Errors
108 ///
109 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
110 ///
111 /// [Manage Guild]: Permissions::MANAGE_GUILD
112 #[inline]
113 pub async fn create_automod_rule(
114 self,
115 cache_http: impl CacheHttp,
116 builder: EditAutoModRule<'_>,
117 ) -> Result<Rule> {
118 builder.execute(cache_http, (self, None)).await
119 }
120
121 /// Edit an auto moderation [`Rule`], given its Id.
122 ///
123 /// **Note**: Requires the [Manage Guild] permission.
124 ///
125 /// # Errors
126 ///
127 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
128 ///
129 /// [Manage Guild]: Permissions::MANAGE_GUILD
130 #[inline]
131 pub async fn edit_automod_rule(
132 self,
133 cache_http: impl CacheHttp,
134 rule_id: impl Into<RuleId>,
135 builder: EditAutoModRule<'_>,
136 ) -> Result<Rule> {
137 builder.execute(cache_http, (self, Some(rule_id.into()))).await
138 }
139
140 /// Deletes an auto moderation [`Rule`] from the guild.
141 ///
142 /// **Note**: Requires the [Manage Guild] permission.
143 ///
144 /// # Errors
145 ///
146 /// Returns [`Error::Http`] if the current user lacks permission, or if a rule with that Id
147 /// does not exist.
148 ///
149 /// [Manage Guild]: Permissions::MANAGE_GUILD
150 #[inline]
151 pub async fn delete_automod_rule(
152 self,
153 http: impl AsRef<Http>,
154 rule_id: impl Into<RuleId>,
155 ) -> Result<()> {
156 http.as_ref().delete_automod_rule(self, rule_id.into(), None).await
157 }
158
159 /// Adds a [`User`] to this guild with a valid OAuth2 access token.
160 ///
161 /// Returns the created [`Member`] object, or nothing if the user is already a member of the
162 /// guild.
163 ///
164 /// # Errors
165 ///
166 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
167 #[inline]
168 pub async fn add_member(
169 self,
170 cache_http: impl CacheHttp,
171 user_id: impl Into<UserId>,
172 builder: AddMember,
173 ) -> Result<Option<Member>> {
174 builder.execute(cache_http, (self, user_id.into())).await
175 }
176
177 /// Ban a [`User`] from the guild, deleting a number of days' worth of messages (`dmd`) between
178 /// the range 0 and 7.
179 ///
180 /// Refer to the documentation for [`Guild::ban`] for more information.
181 ///
182 /// **Note**: Requires the [Ban Members] permission.
183 ///
184 /// # Examples
185 ///
186 /// Ban a member and remove all messages they've sent in the last 4 days:
187 ///
188 /// ```rust,no_run
189 /// use serenity::model::id::{GuildId, UserId};
190 ///
191 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
192 /// # use serenity::http::Http;
193 /// # let http: Http = unimplemented!();
194 /// # let user = UserId::new(1);
195 /// // assuming a `user` has already been bound
196 /// let _ = GuildId::new(81384788765712384).ban(&http, user, 4).await;
197 /// # Ok(())
198 /// # }
199 /// ```
200 ///
201 /// # Errors
202 ///
203 /// Returns a [`ModelError::DeleteMessageDaysAmount`] if the number of days' worth of messages
204 /// to delete is over the maximum.
205 ///
206 /// Also can return [`Error::Http`] if the current user lacks permission.
207 ///
208 /// [Ban Members]: Permissions::BAN_MEMBERS
209 #[inline]
210 pub async fn ban(self, http: impl AsRef<Http>, user: impl Into<UserId>, dmd: u8) -> Result<()> {
211 self.ban_(http, user.into(), dmd, None).await
212 }
213
214 /// Ban a [`User`] from the guild with a reason. Refer to [`Self::ban`] to further
215 /// documentation.
216 ///
217 /// # Errors
218 ///
219 /// In addition to the reasons [`Self::ban`] may return an error, may also return
220 /// [`Error::ExceededLimit`] if `reason` is too long.
221 #[inline]
222 pub async fn ban_with_reason(
223 self,
224 http: impl AsRef<Http>,
225 user: impl Into<UserId>,
226 dmd: u8,
227 reason: impl AsRef<str>,
228 ) -> Result<()> {
229 self.ban_(http, user.into(), dmd, Some(reason.as_ref())).await
230 }
231
232 async fn ban_(
233 self,
234 http: impl AsRef<Http>,
235 user: UserId,
236 dmd: u8,
237 reason: Option<&str>,
238 ) -> Result<()> {
239 if dmd > 7 {
240 return Err(Error::Model(ModelError::DeleteMessageDaysAmount(dmd)));
241 }
242
243 if let Some(reason) = reason {
244 if reason.chars().count() > 512 {
245 return Err(Error::ExceededLimit(reason.to_string(), 512));
246 }
247 }
248
249 http.as_ref().ban_user(self, user, dmd, reason).await
250 }
251
252 /// Bans multiple users from the guild, returning the users that were and weren't banned, and
253 /// optionally deleting messages that are younger than the provided `delete_message_seconds`.
254 ///
255 /// # Errors
256 ///
257 /// Errors if none of the users are banned or you do not have the
258 /// required [`BAN_MEMBERS`] and [`MANAGE_GUILD`] permissions.
259 ///
260 /// [`BAN_MEMBERS`]: Permissions::BAN_MEMBERS
261 /// [`MANAGE_GUILD`]: Permissions::MANAGE_GUILD
262 pub async fn bulk_ban(
263 self,
264 http: &Http,
265 user_ids: &[UserId],
266 delete_message_seconds: u32,
267 reason: Option<&str>,
268 ) -> Result<BulkBanResponse> {
269 #[derive(serde::Serialize)]
270 struct BulkBan<'a> {
271 user_ids: &'a [UserId],
272 delete_message_seconds: u32,
273 }
274
275 let map = BulkBan {
276 user_ids,
277 delete_message_seconds,
278 };
279
280 http.bulk_ban_users(self, &map, reason).await
281 }
282
283 /// Gets a list of the guild's bans, with additional options and filtering. See
284 /// [`Http::get_bans`] for details.
285 ///
286 /// **Note**: Requires the [Ban Members] permission.
287 ///
288 /// # Errors
289 ///
290 /// Returns [`Error::Http`] if the current user lacks permission.
291 ///
292 /// [Ban Members]: Permissions::BAN_MEMBERS
293 #[inline]
294 pub async fn bans(
295 self,
296 http: impl AsRef<Http>,
297 target: Option<UserPagination>,
298 limit: Option<u8>,
299 ) -> Result<Vec<Ban>> {
300 http.as_ref().get_bans(self, target, limit).await
301 }
302
303 /// Gets a list of the guild's audit log entries
304 ///
305 /// **Note**: Requires the [View Audit Log] permission.
306 ///
307 /// # Errors
308 ///
309 /// Returns [`Error::Http`] if the current user lacks permission, or if an invalid value is
310 /// given.
311 ///
312 /// [View Audit Log]: Permissions::VIEW_AUDIT_LOG
313 #[inline]
314 pub async fn audit_logs(
315 self,
316 http: impl AsRef<Http>,
317 action_type: Option<audit_log::Action>,
318 user_id: Option<UserId>,
319 before: Option<AuditLogEntryId>,
320 limit: Option<u8>,
321 ) -> Result<AuditLogs> {
322 http.as_ref().get_audit_logs(self, action_type, user_id, before, limit).await
323 }
324
325 /// Gets all of the guild's channels over the REST API.
326 ///
327 /// # Errors
328 ///
329 /// Returns [`Error::Http`] if the current user is not in the guild.
330 pub async fn channels(
331 self,
332 http: impl AsRef<Http>,
333 ) -> Result<HashMap<ChannelId, GuildChannel>> {
334 let channels = http.as_ref().get_channels(self).await?;
335
336 Ok(channels.into_iter().map(|c| (c.id, c)).collect())
337 }
338
339 /// Creates a [`GuildChannel`] in the the guild.
340 ///
341 /// Refer to [`Http::create_channel`] for more information.
342 ///
343 /// **Note**: Requires the [Manage Channels] permission.
344 ///
345 /// # Examples
346 ///
347 /// Create a voice channel in a guild with the name `test`:
348 ///
349 /// ```rust,no_run
350 /// # use serenity::http::Http;
351 /// use serenity::builder::CreateChannel;
352 /// use serenity::model::channel::ChannelType;
353 /// use serenity::model::id::GuildId;
354 ///
355 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
356 /// # let http: Http = unimplemented!();
357 /// let builder = CreateChannel::new("test").kind(ChannelType::Voice);
358 /// let _channel = GuildId::new(7).create_channel(&http, builder).await?;
359 /// # Ok(())
360 /// # }
361 /// ```
362 ///
363 /// # Errors
364 ///
365 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
366 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
367 ///
368 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
369 #[inline]
370 pub async fn create_channel(
371 self,
372 cache_http: impl CacheHttp,
373 builder: CreateChannel<'_>,
374 ) -> Result<GuildChannel> {
375 builder.execute(cache_http, self).await
376 }
377
378 /// Creates an emoji in the guild with a name and base64-encoded image.
379 ///
380 /// Refer to the documentation for [`Guild::create_emoji`] for more information.
381 ///
382 /// Requires the [Create Guild Expressions] permission.
383 ///
384 /// # Examples
385 ///
386 /// See the [`EditProfile::avatar`] example for an in-depth example as to how to read an image
387 /// from the filesystem and encode it as base64. Most of the example can be applied similarly
388 /// for this method.
389 ///
390 /// # Errors
391 ///
392 /// Returns [`Error::Http`] if the current user lacks permission, if the name is too long, or
393 /// if the image is too big.
394 ///
395 /// [`EditProfile::avatar`]: crate::builder::EditProfile::avatar
396 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
397 #[inline]
398 pub async fn create_emoji(
399 self,
400 http: impl AsRef<Http>,
401 name: &str,
402 image: &str,
403 ) -> Result<Emoji> {
404 let map = json!({
405 "name": name,
406 "image": image,
407 });
408
409 http.as_ref().create_emoji(self, &map, None).await
410 }
411
412 /// Creates an integration for the guild.
413 ///
414 /// Requires the [Manage Guild] permission.
415 ///
416 /// # Errors
417 ///
418 /// Returns [`Error::Http`] if the current user lacks permission.
419 ///
420 /// [Manage Guild]: Permissions::MANAGE_GUILD
421 #[inline]
422 pub async fn create_integration(
423 self,
424 http: impl AsRef<Http>,
425 integration_id: impl Into<IntegrationId>,
426 kind: &str,
427 ) -> Result<()> {
428 let integration_id = integration_id.into();
429 let map = json!({
430 "id": integration_id,
431 "type": kind,
432 });
433
434 http.as_ref().create_guild_integration(self, integration_id, &map, None).await
435 }
436
437 /// Creates a new role in the guild with the data set, if any.
438 ///
439 /// See the documentation for [`Guild::create_role`] on how to use this.
440 ///
441 /// **Note**: Requires the [Manage Roles] permission.
442 ///
443 /// # Errors
444 ///
445 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
446 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
447 ///
448 /// [Manage Roles]: Permissions::MANAGE_ROLES
449 #[inline]
450 pub async fn create_role(
451 self,
452 cache_http: impl CacheHttp,
453 builder: EditRole<'_>,
454 ) -> Result<Role> {
455 builder.execute(cache_http, (self, None)).await
456 }
457
458 /// Creates a new scheduled event in the guild with the data set, if any.
459 ///
460 /// **Note**: Requires the [Create Events] permission.
461 ///
462 /// # Errors
463 ///
464 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
465 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
466 ///
467 /// [Manage Events]: Permissions::CREATE_EVENTS
468 pub async fn create_scheduled_event(
469 self,
470 cache_http: impl CacheHttp,
471 builder: CreateScheduledEvent<'_>,
472 ) -> Result<ScheduledEvent> {
473 builder.execute(cache_http, self).await
474 }
475
476 /// Creates a new sticker in the guild with the data set, if any.
477 ///
478 /// **Note**: Requires the [Create Guild Expressions] permission.
479 ///
480 /// # Errors
481 ///
482 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
483 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
484 ///
485 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
486 #[inline]
487 pub async fn create_sticker(
488 self,
489 cache_http: impl CacheHttp,
490 builder: CreateSticker<'_>,
491 ) -> Result<Sticker> {
492 builder.execute(cache_http, self).await
493 }
494
495 /// Deletes the current guild if the current account is the owner of the
496 /// guild.
497 ///
498 /// Refer to [`Guild::delete`] for more information.
499 ///
500 /// **Note**: Requires the current user to be the owner of the guild.
501 ///
502 /// # Errors
503 ///
504 /// Returns [`Error::Http`] if the current user is not the owner of the guild.
505 #[inline]
506 pub async fn delete(self, http: impl AsRef<Http>) -> Result<()> {
507 http.as_ref().delete_guild(self).await
508 }
509
510 /// Deletes an [`Emoji`] from the guild.
511 ///
512 /// **Note**: If the emoji was created by the current user, requires either the [Create Guild
513 /// Expressions] or the [Manage Guild Expressions] permission. Otherwise, the [Manage Guild
514 /// Expressions] permission is required.
515 ///
516 /// # Errors
517 ///
518 /// Returns [`Error::Http`] if the current user lacks permission, or if an emoji with the given
519 /// id does not exist in the guild.
520 ///
521 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
522 /// [Manage Guild Expressions]: Permissions::MANAGE_GUILD_EXPRESSIONS
523 #[inline]
524 pub async fn delete_emoji(
525 self,
526 http: impl AsRef<Http>,
527 emoji_id: impl Into<EmojiId>,
528 ) -> Result<()> {
529 http.as_ref().delete_emoji(self, emoji_id.into(), None).await
530 }
531
532 /// Deletes an integration by Id from the guild.
533 ///
534 /// **Note**: Requires the [Manage Guild] permission.
535 ///
536 /// # Errors
537 ///
538 /// Returns [`Error::Http`] if the current user lacks permission, or if an integration with
539 /// that Id does not exist.
540 ///
541 /// [Manage Guild]: Permissions::MANAGE_GUILD
542 #[inline]
543 pub async fn delete_integration(
544 self,
545 http: impl AsRef<Http>,
546 integration_id: impl Into<IntegrationId>,
547 ) -> Result<()> {
548 http.as_ref().delete_guild_integration(self, integration_id.into(), None).await
549 }
550
551 /// Deletes a [`Role`] by Id from the guild.
552 ///
553 /// Also see [`Role::delete`] if you have the `cache` and `model` features enabled.
554 ///
555 /// **Note**: Requires the [Manage Roles] permission.
556 ///
557 /// # Errors
558 ///
559 /// Returns [`Error::Http`] if the current user lacks permission, or if a role with that Id
560 /// does not exist.
561 ///
562 /// [Manage Roles]: Permissions::MANAGE_ROLES
563 #[inline]
564 pub async fn delete_role(
565 self,
566 http: impl AsRef<Http>,
567 role_id: impl Into<RoleId>,
568 ) -> Result<()> {
569 http.as_ref().delete_role(self, role_id.into(), None).await
570 }
571
572 /// Deletes a specified scheduled event in the guild.
573 ///
574 /// **Note**: If the event was created by the current user, requires either [Create Events] or
575 /// the [Manage Events] permission. Otherwise, the [Manage Events] permission is required.
576 ///
577 /// # Errors
578 ///
579 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
580 ///
581 /// [Create Events]: Permissions::CREATE_EVENTS
582 /// [Manage Events]: Permissions::MANAGE_EVENTS
583 #[inline]
584 pub async fn delete_scheduled_event(
585 self,
586 http: impl AsRef<Http>,
587 event_id: impl Into<ScheduledEventId>,
588 ) -> Result<()> {
589 http.as_ref().delete_scheduled_event(self, event_id.into()).await
590 }
591
592 /// Deletes a [`Sticker`] by id from the guild.
593 ///
594 /// **Note**: If the sticker was created by the current user, requires either the [Create Guild
595 /// Expressions] or the [Manage Guild Expressions] permission. Otherwise, the [Manage Guild
596 /// Expressions] permission is required.
597 ///
598 /// # Errors
599 ///
600 /// Returns [`Error::Http`] if the current user lacks permission, or if a sticker with that id
601 /// does not exist.
602 ///
603 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
604 /// [Manage Guild Expressions]: Permissions::MANAGE_GUILD_EXPRESSIONS
605 #[inline]
606 pub async fn delete_sticker(
607 self,
608 http: impl AsRef<Http>,
609 sticker_id: impl Into<StickerId>,
610 ) -> Result<()> {
611 http.as_ref().delete_sticker(self, sticker_id.into(), None).await
612 }
613
614 /// Edits the current guild with new data where specified.
615 ///
616 /// **Note**: Requires the [Manage Guild] permission.
617 ///
618 /// # Errors
619 ///
620 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
621 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
622 ///
623 /// [Manage Guild]: Permissions::MANAGE_GUILD
624 #[inline]
625 pub async fn edit(
626 self,
627 cache_http: impl CacheHttp,
628 builder: EditGuild<'_>,
629 ) -> Result<PartialGuild> {
630 builder.execute(cache_http, self).await
631 }
632
633 /// Edits an [`Emoji`]'s name in the guild.
634 ///
635 /// Also see [`Emoji::edit`] if you have the `cache` and `methods` features enabled.
636 ///
637 /// **Note**: If the emoji was created by the current user, requires either the [Create Guild
638 /// Expressions] or the [Manage Guild Expressions] permission. Otherwise, the [Manage Guild
639 /// Expressions] permission is required.
640 ///
641 /// # Errors
642 ///
643 /// Returns [`Error::Http`] if the current user lacks permission, or if an emoji with the given
644 /// id does not exist.
645 ///
646 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
647 /// [Manage Guild Expressions]: Permissions::MANAGE_GUILD_EXPRESSIONS
648 #[inline]
649 pub async fn edit_emoji(
650 self,
651 http: impl AsRef<Http>,
652 emoji_id: impl Into<EmojiId>,
653 name: &str,
654 ) -> Result<Emoji> {
655 let map = json!({
656 "name": name,
657 });
658
659 http.as_ref().edit_emoji(self, emoji_id.into(), &map, None).await
660 }
661
662 /// Edits the properties a guild member, such as muting or nicknaming them. Returns the new
663 /// member.
664 ///
665 /// Refer to the documentation of [`EditMember`] for a full list of methods and permission
666 /// restrictions.
667 ///
668 /// # Examples
669 ///
670 /// Mute a member and set their roles to just one role with a predefined Id:
671 ///
672 /// ```rust,no_run
673 /// # use serenity::builder::EditMember;
674 /// # use serenity::http::Http;
675 /// # use serenity::model::id::{GuildId, RoleId, UserId};
676 /// #
677 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
678 /// # let http: Http = unimplemented!();
679 /// # let role_id = RoleId::new(7);
680 /// # let user_id = UserId::new(7);
681 /// let builder = EditMember::new().mute(true).roles(vec![role_id]);
682 /// let _ = GuildId::new(7).edit_member(&http, user_id, builder).await?;
683 /// # Ok(())
684 /// # }
685 /// ```
686 ///
687 /// # Errors
688 ///
689 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
690 #[inline]
691 pub async fn edit_member(
692 self,
693 cache_http: impl CacheHttp,
694 user_id: impl Into<UserId>,
695 builder: EditMember<'_>,
696 ) -> Result<Member> {
697 builder.execute(cache_http, (self, user_id.into())).await
698 }
699
700 /// Edits the guild's MFA level. Returns the new level on success.
701 ///
702 /// Requires guild ownership.
703 ///
704 /// # Errors
705 ///
706 /// Returns [`Error::Http`] if the current user lacks permission.
707 pub async fn edit_mfa_level(
708 self,
709 http: impl AsRef<Http>,
710 mfa_level: MfaLevel,
711 audit_log_reason: Option<&str>,
712 ) -> Result<MfaLevel> {
713 let value = json!({
714 "level": mfa_level,
715 });
716 http.as_ref().edit_guild_mfa_level(self, &value, audit_log_reason).await
717 }
718
719 /// Edits the current user's nickname for the guild.
720 ///
721 /// Pass [`None`] to reset the nickname.
722 ///
723 /// Requires the [Change Nickname] permission.
724 ///
725 /// # Errors
726 ///
727 /// Returns [`Error::Http`] if the current user lacks permission.
728 ///
729 /// [Change Nickname]: Permissions::CHANGE_NICKNAME
730 #[inline]
731 pub async fn edit_nickname(
732 self,
733 http: impl AsRef<Http>,
734 new_nickname: Option<&str>,
735 ) -> Result<()> {
736 http.as_ref().edit_nickname(self, new_nickname, None).await
737 }
738
739 /// Edits a [`Role`], optionally setting its new fields.
740 ///
741 /// **Note**: Requires the [Manage Roles] permission.
742 ///
743 /// # Examples
744 ///
745 /// Make a role hoisted, and change its name:
746 ///
747 /// ```rust,no_run
748 /// # use serenity::builder::EditRole;
749 /// # use serenity::http::Http;
750 /// # use serenity::model::id::{GuildId, RoleId};
751 /// # use std::sync::Arc;
752 /// #
753 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
754 /// # let http: Arc<Http> = unimplemented!();
755 /// # let guild_id = GuildId::new(2);
756 /// # let role_id = RoleId::new(8);
757 /// #
758 /// // assuming a `role_id` and `guild_id` has been bound
759 /// let builder = EditRole::new().name("a test role").hoist(true);
760 /// let role = guild_id.edit_role(&http, role_id, builder).await?;
761 /// # Ok(())
762 /// # }
763 /// ```
764 ///
765 /// # Errors
766 ///
767 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
768 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
769 ///
770 /// [Manage Roles]: Permissions::MANAGE_ROLES
771 #[inline]
772 pub async fn edit_role(
773 self,
774 cache_http: impl CacheHttp,
775 role_id: impl Into<RoleId>,
776 builder: EditRole<'_>,
777 ) -> Result<Role> {
778 builder.execute(cache_http, (self, Some(role_id.into()))).await
779 }
780
781 /// Modifies a scheduled event in the guild with the data set, if any.
782 ///
783 /// **Note**: If the event was created by the current user, requires either [Create Events] or
784 /// the [Manage Events] permission. Otherwise, the [Manage Events] permission is required.
785 ///
786 /// # Errors
787 ///
788 /// If the `cache` is enabled, returns a [`ModelError::InvalidPermissions`] if the current user
789 /// lacks permission. Otherwise returns [`Error::Http`], as well as if invalid data is given.
790 ///
791 /// [Create Events]: Permissions::CREATE_EVENTS
792 /// [Manage Events]: Permissions::MANAGE_EVENTS
793 pub async fn edit_scheduled_event(
794 self,
795 cache_http: impl CacheHttp,
796 event_id: impl Into<ScheduledEventId>,
797 builder: EditScheduledEvent<'_>,
798 ) -> Result<ScheduledEvent> {
799 builder.execute(cache_http, (self, event_id.into())).await
800 }
801
802 /// Edits a sticker.
803 ///
804 /// **Note**: If the sticker was created by the current user, requires either the [Create Guild
805 /// Expressions] or the [Manage Guild Expressions] permission. Otherwise, the [Manage Guild
806 /// Expressions] permission is required.
807 ///
808 /// # Examples
809 ///
810 /// Rename a sticker:
811 ///
812 /// ```rust,no_run
813 /// # use serenity::http::Http;
814 /// use serenity::builder::EditSticker;
815 /// use serenity::model::id::{GuildId, StickerId};
816 ///
817 /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
818 /// # let http: Http = unimplemented!();
819 /// let builder = EditSticker::new().name("Bun bun meow");
820 /// let _ = GuildId::new(7).edit_sticker(&http, StickerId::new(7), builder).await?;
821 /// # Ok(())
822 /// # }
823 /// ```
824 ///
825 /// # Errors
826 ///
827 /// Returns [`Error::Http`] if the current user lacks permission, or if invalid data is given.
828 ///
829 /// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
830 /// [Manage Guild Expressions]: Permissions::MANAGE_GUILD_EXPRESSIONS
831 #[inline]
832 pub async fn edit_sticker(
833 self,
834 cache_http: impl CacheHttp,
835 sticker_id: impl Into<StickerId>,
836 builder: EditSticker<'_>,
837 ) -> Result<Sticker> {
838 builder.execute(cache_http, (self, sticker_id.into())).await
839 }
840
841 /// Edit the position of a [`Role`] relative to all others in the [`Guild`].
842 ///
843 /// **Note**: Requires the [Manage Roles] permission.
844 ///
845 /// # Examples
846 ///
847 /// ```rust,ignore
848 /// use serenity::model::{GuildId, RoleId};
849 /// GuildId::new(7).edit_role_position(&context, RoleId::new(8), 2);
850 /// ```
851 ///
852 /// # Errors
853 ///
854 /// Returns an [`Error::Http`] if the current user lacks permission.
855 ///
856 /// [Manage Roles]: Permissions::MANAGE_ROLES
857 #[inline]
858 pub async fn edit_role_position(
859 self,
860 http: impl AsRef<Http>,
861 role_id: impl Into<RoleId>,
862 position: u16,
863 ) -> Result<Vec<Role>> {
864 http.as_ref().edit_role_position(self, role_id.into(), position, None).await
865 }
866
867 /// Edits the guild's welcome screen.
868 ///
869 /// **Note**: Requires the [Manage Guild] permission.
870 ///
871 /// # Errors
872 ///
873 /// Returns [`Error::Http`] if the current user lacks permission.
874 ///
875 /// [Manage Guild]: Permissions::MANAGE_GUILD
876 pub async fn edit_welcome_screen(
877 self,
878 cache_http: impl CacheHttp,
879 builder: EditGuildWelcomeScreen<'_>,
880 ) -> Result<GuildWelcomeScreen> {
881 builder.execute(cache_http, self).await
882 }
883
884 /// Edits the guild's widget.
885 ///
886 /// **Note**: Requires the [Manage Guild] permission.
887 ///
888 /// # Errors
889 ///
890 /// Returns [`Error::Http`] if the current user lacks permission.
891 ///
892 /// [Manage Guild]: Permissions::MANAGE_GUILD
893 pub async fn edit_widget(
894 self,
895 cache_http: impl CacheHttp,
896 builder: EditGuildWidget<'_>,
897 ) -> Result<GuildWidget> {
898 builder.execute(cache_http, self).await
899 }
900
901 /// Gets a specific role in the guild, by Id.
902 ///
903 /// # Errors
904 ///
905 /// Returns [`Error::Http`] if the current user is not in the guild, or if the role does not
906 /// exist.
907 pub async fn role(self, http: impl AsRef<Http>, role_id: RoleId) -> Result<Role> {
908 http.as_ref().get_guild_role(self, role_id).await
909 }
910
911 /// Gets all of the guild's roles over the REST API.
912 ///
913 /// # Errors
914 ///
915 /// Returns [`Error::Http`] if the current user is not in
916 /// the guild.
917 pub async fn roles(self, http: impl AsRef<Http>) -> Result<HashMap<RoleId, Role>> {
918 let roles = http.as_ref().get_guild_roles(self).await?;
919
920 Ok(roles.into_iter().map(|r| (r.id, r)).collect())
921 }
922
923 /// Gets the default permission role (@everyone) from the guild.
924 #[inline]
925 #[must_use]
926 pub fn everyone_role(&self) -> RoleId {
927 RoleId::from(self.get())
928 }
929
930 /// Tries to find the [`Guild`] by its Id in the cache.
931 #[cfg(feature = "cache")]
932 #[inline]
933 pub fn to_guild_cached(self, cache: &impl AsRef<Cache>) -> Option<GuildRef<'_>> {
934 cache.as_ref().guild(self)
935 }
936
937 /// Requests [`PartialGuild`] over REST API.
938 ///
939 /// **Note**: This will not be a [`Guild`], as the REST API does not send
940 /// all data with a guild retrieval.
941 ///
942 /// # Errors
943 ///
944 /// Returns an [`Error::Http`] if the current user is not in the guild.
945 #[inline]
946 pub async fn to_partial_guild(self, cache_http: impl CacheHttp) -> Result<PartialGuild> {
947 #[cfg(feature = "cache")]
948 {
949 if let Some(cache) = cache_http.cache() {
950 if let Some(guild) = cache.guild(self) {
951 return Ok(guild.clone().into());
952 }
953 }
954 }
955
956 cache_http.http().get_guild(self).await
957 }
958
959 /// Requests [`PartialGuild`] over REST API with counts.
960 ///
961 /// **Note**: This will not be a [`Guild`], as the REST API does not send all data with a guild
962 /// retrieval.
963 ///
964 /// # Errors
965 ///
966 /// Returns an [`Error::Http`] if the current user is not in the guild.
967 #[inline]
968 pub async fn to_partial_guild_with_counts(
969 self,
970 http: impl AsRef<Http>,
971 ) -> Result<PartialGuild> {
972 http.as_ref().get_guild_with_counts(self).await
973 }
974
975 /// Gets all [`Emoji`]s of this guild via HTTP.
976 ///
977 /// # Errors
978 ///
979 /// Returns an [`Error::Http`] if the guild is unavailable.
980 #[inline]
981 pub async fn emojis(self, http: impl AsRef<Http>) -> Result<Vec<Emoji>> {
982 http.as_ref().get_emojis(self).await
983 }
984
985 /// Gets an [`Emoji`] of this guild by its ID via HTTP.
986 ///
987 /// # Errors
988 ///
989 /// Returns an [`Error::Http`] if an emoji with that id does not exist.
990 #[inline]
991 pub async fn emoji(self, http: impl AsRef<Http>, emoji_id: EmojiId) -> Result<Emoji> {
992 http.as_ref().get_emoji(self, emoji_id).await
993 }
994
995 /// Gets all [`Sticker`]s of this guild via HTTP.
996 ///
997 /// # Errors
998 ///
999 /// Returns an [`Error::Http`] if the guild is unavailable.
1000 #[inline]
1001 pub async fn stickers(self, http: impl AsRef<Http>) -> Result<Vec<Sticker>> {
1002 http.as_ref().get_guild_stickers(self).await
1003 }
1004
1005 /// Gets an [`Sticker`] of this guild by its ID via HTTP.
1006 ///
1007 /// # Errors
1008 ///
1009 /// Returns an [`Error::Http`] if an sticker with that Id does not exist.
1010 #[inline]
1011 pub async fn sticker(self, http: impl AsRef<Http>, sticker_id: StickerId) -> Result<Sticker> {
1012 http.as_ref().get_guild_sticker(self, sticker_id).await
1013 }
1014
1015 /// Gets all integration of the guild.
1016 ///
1017 /// Requires the [Manage Guild] permission.
1018 ///
1019 /// # Errors
1020 ///
1021 /// Returns an [`Error::Http`] if the current user lacks permission, also may return
1022 /// [`Error::Json`] if there is an error in deserializing the API response.
1023 ///
1024 /// [Manage Guild]: Permissions::MANAGE_GUILD
1025 #[inline]
1026 pub async fn integrations(self, http: impl AsRef<Http>) -> Result<Vec<Integration>> {
1027 http.as_ref().get_guild_integrations(self).await
1028 }
1029
1030 /// Gets all of the guild's invites.
1031 ///
1032 /// Requires the [Manage Guild] permission.
1033 ///
1034 /// # Errors
1035 ///
1036 /// Returns [`Error::Http`] if the current user lacks permission, also may return
1037 /// [`Error::Json`] if there is an error in deserializing the API response.
1038 ///
1039 /// [Manage Guild]: Permissions::MANAGE_GUILD
1040 #[inline]
1041 pub async fn invites(self, http: impl AsRef<Http>) -> Result<Vec<RichInvite>> {
1042 http.as_ref().get_guild_invites(self).await
1043 }
1044
1045 /// Kicks a [`Member`] from the guild.
1046 ///
1047 /// Requires the [Kick Members] permission.
1048 ///
1049 /// # Errors
1050 ///
1051 /// Returns [`Error::Http`] if the member cannot be kicked by the current user.
1052 ///
1053 /// [Kick Members]: Permissions::KICK_MEMBERS
1054 #[inline]
1055 pub async fn kick(self, http: impl AsRef<Http>, user_id: impl Into<UserId>) -> Result<()> {
1056 http.as_ref().kick_member(self, user_id.into(), None).await
1057 }
1058
1059 /// # Errors
1060 ///
1061 /// In addition to the reasons [`Self::kick`] may return an error, may also return an error if
1062 /// the reason is too long.
1063 #[inline]
1064 pub async fn kick_with_reason(
1065 self,
1066 http: impl AsRef<Http>,
1067 user_id: impl Into<UserId>,
1068 reason: &str,
1069 ) -> Result<()> {
1070 http.as_ref().kick_member(self, user_id.into(), Some(reason)).await
1071 }
1072
1073 /// Returns a guild [`Member`] object for the current user.
1074 ///
1075 /// See [`Http::get_current_user_guild_member`] for more.
1076 ///
1077 /// # Errors
1078 ///
1079 /// Returns an [`Error::Http`] if the current user is not in the guild or the access token
1080 /// lacks the necessary scope.
1081 #[inline]
1082 pub async fn current_user_member(self, http: impl AsRef<Http>) -> Result<Member> {
1083 http.as_ref().get_current_user_guild_member(self).await
1084 }
1085
1086 /// Leaves the guild.
1087 ///
1088 /// # Errors
1089 ///
1090 /// May return an [`Error::Http`] if the current user cannot leave the guild, or currently is
1091 /// not in the guild.
1092 #[inline]
1093 pub async fn leave(self, http: impl AsRef<Http>) -> Result<()> {
1094 http.as_ref().leave_guild(self).await
1095 }
1096
1097 /// Gets a user's [`Member`] for the guild by Id.
1098 ///
1099 /// If the cache feature is enabled the cache will be checked first. If not found it will
1100 /// resort to an http request.
1101 ///
1102 /// # Errors
1103 ///
1104 /// Returns an [`Error::Http`] if the user is not in the guild, or if the guild is otherwise
1105 /// unavailable
1106 #[inline]
1107 pub async fn member(
1108 self,
1109 cache_http: impl CacheHttp,
1110 user_id: impl Into<UserId>,
1111 ) -> Result<Member> {
1112 let user_id = user_id.into();
1113
1114 #[cfg(feature = "cache")]
1115 {
1116 if let Some(cache) = cache_http.cache() {
1117 if let Some(guild) = cache.guild(self) {
1118 if let Some(member) = guild.members.get(&user_id) {
1119 return Ok(member.clone());
1120 }
1121 }
1122 }
1123 }
1124
1125 cache_http.http().get_member(self, user_id).await
1126 }
1127
1128 /// Gets a list of the guild's members.
1129 ///
1130 /// Optionally pass in the `limit` to limit the number of results. Minimum value is 1, maximum
1131 /// and default value is 1000.
1132 ///
1133 /// Optionally pass in `after` to offset the results by a [`User`]'s Id.
1134 ///
1135 /// # Errors
1136 ///
1137 /// Returns an [`Error::Http`] if the API returns an error, may also return
1138 /// [`Error::NotInRange`] if the input is not within range.
1139 ///
1140 /// [`User`]: crate::model::user::User
1141 #[inline]
1142 pub async fn members(
1143 self,
1144 http: impl AsRef<Http>,
1145 limit: Option<u64>,
1146 after: impl Into<Option<UserId>>,
1147 ) -> Result<Vec<Member>> {
1148 http.as_ref().get_guild_members(self, limit, after.into().map(UserId::get)).await
1149 }
1150
1151 /// Streams over all the members in a guild.
1152 ///
1153 /// This is accomplished and equivalent to repeated calls to [`Self::members`]. A buffer of at
1154 /// most 1,000 members is used to reduce the number of calls necessary.
1155 ///
1156 /// # Examples
1157 /// ```rust,no_run
1158 /// # use serenity::model::id::GuildId;
1159 /// # use serenity::http::Http;
1160 /// #
1161 /// # async fn run() {
1162 /// # let guild_id = GuildId::new(1);
1163 /// # let ctx: Http = unimplemented!();
1164 /// use serenity::futures::StreamExt;
1165 /// use serenity::model::guild::MembersIter;
1166 ///
1167 /// let mut members = guild_id.members_iter(&ctx).boxed();
1168 /// while let Some(member_result) = members.next().await {
1169 /// match member_result {
1170 /// Ok(member) => println!("{} is {}", member, member.display_name(),),
1171 /// Err(error) => eprintln!("Uh oh! Error: {}", error),
1172 /// }
1173 /// }
1174 /// # }
1175 /// ```
1176 pub fn members_iter<H: AsRef<Http>>(self, http: H) -> impl Stream<Item = Result<Member>> {
1177 MembersIter::<H>::stream(http, self)
1178 }
1179
1180 /// Moves a member to a specific voice channel.
1181 ///
1182 /// **Note**: Requires the [Move Members] permission.
1183 ///
1184 /// # Errors
1185 ///
1186 /// Returns [`Error::Http`] if the current user lacks permission, or if the member is not
1187 /// currently in a voice channel for this [`Guild`].
1188 ///
1189 /// [Move Members]: Permissions::MOVE_MEMBERS
1190 #[inline]
1191 pub async fn move_member(
1192 self,
1193 cache_http: impl CacheHttp,
1194 user_id: impl Into<UserId>,
1195 channel_id: impl Into<ChannelId>,
1196 ) -> Result<Member> {
1197 let builder = EditMember::new().voice_channel(channel_id.into());
1198 self.edit_member(cache_http, user_id, builder).await
1199 }
1200
1201 /// Returns the name of whatever guild this id holds.
1202 #[cfg(feature = "cache")]
1203 #[must_use]
1204 pub fn name(self, cache: impl AsRef<Cache>) -> Option<String> {
1205 self.to_guild_cached(cache.as_ref()).map(|g| g.name.clone())
1206 }
1207
1208 /// Disconnects a member from a voice channel in the guild.
1209 ///
1210 /// **Note**: Requires the [Move Members] permission.
1211 ///
1212 /// # Errors
1213 ///
1214 /// Returns [`Error::Http`] if the current user lacks permission, or if the member is not
1215 /// currently in a voice channel for this [`Guild`].
1216 ///
1217 /// [Move Members]: Permissions::MOVE_MEMBERS
1218 #[inline]
1219 pub async fn disconnect_member(
1220 self,
1221 cache_http: impl CacheHttp,
1222 user_id: impl Into<UserId>,
1223 ) -> Result<Member> {
1224 self.edit_member(cache_http, user_id, EditMember::new().disconnect_member()).await
1225 }
1226
1227 /// Gets the number of [`Member`]s that would be pruned with the given number of days.
1228 ///
1229 /// Requires the [Kick Members] permission.
1230 ///
1231 /// # Errors
1232 ///
1233 /// Returns [`Error::Http`] if the current user does not have permission.
1234 ///
1235 /// [Kick Members]: Permissions::KICK_MEMBERS
1236 #[inline]
1237 pub async fn prune_count(self, http: impl AsRef<Http>, days: u8) -> Result<GuildPrune> {
1238 http.as_ref().get_guild_prune_count(self, days).await
1239 }
1240
1241 /// Re-orders the channels of the guild.
1242 ///
1243 /// Accepts an iterator of a tuple of the channel ID to modify and its new position.
1244 ///
1245 /// Although not required, you should specify all channels' positions, regardless of whether
1246 /// they were updated. Otherwise, positioning can sometimes get weird.
1247 ///
1248 /// **Note**: Requires the [Manage Channels] permission.
1249 ///
1250 /// # Errors
1251 ///
1252 /// Returns [`Error::Http`] if the current user lacks permission.
1253 ///
1254 /// [Manage Channels]: Permissions::MANAGE_CHANNELS
1255 #[inline]
1256 pub async fn reorder_channels(
1257 self,
1258 http: impl AsRef<Http>,
1259 channels: impl IntoIterator<Item = (ChannelId, u64)>,
1260 ) -> Result<()> {
1261 let items = channels
1262 .into_iter()
1263 .map(|(id, pos)| {
1264 json!({
1265 "id": id,
1266 "position": pos,
1267 })
1268 })
1269 .collect::<Vec<_>>()
1270 .into();
1271
1272 http.as_ref().edit_guild_channel_positions(self, &items).await
1273 }
1274
1275 /// Returns a list of [`Member`]s in a [`Guild`] whose username or nickname starts with a
1276 /// provided string.
1277 ///
1278 /// Optionally pass in the `limit` to limit the number of results. Minimum value is 1, maximum
1279 /// and default value is 1000.
1280 ///
1281 /// # Errors
1282 ///
1283 /// Returns an [`Error::Http`] if the API returns an error.
1284 #[inline]
1285 pub async fn search_members(
1286 self,
1287 http: impl AsRef<Http>,
1288 query: &str,
1289 limit: Option<u64>,
1290 ) -> Result<Vec<Member>> {
1291 http.as_ref().search_guild_members(self, query, limit).await
1292 }
1293
1294 /// Fetches a specified scheduled event in the guild, by Id. If `with_user_count` is set to
1295 /// `true`, then the `user_count` field will be populated, indicating the number of users
1296 /// interested in the event.
1297 ///
1298 /// **Note**: Requires the [View Channel] permission for the channel associated with the event.
1299 ///
1300 /// # Errors
1301 ///
1302 /// Returns [`Error::Http`] if the current user lacks permission, or if the provided id is
1303 /// invalid.
1304 ///
1305 /// [View Channel]: Permissions::VIEW_CHANNEL
1306 pub async fn scheduled_event(
1307 self,
1308 http: impl AsRef<Http>,
1309 event_id: impl Into<ScheduledEventId>,
1310 with_user_count: bool,
1311 ) -> Result<ScheduledEvent> {
1312 http.as_ref().get_scheduled_event(self, event_id.into(), with_user_count).await
1313 }
1314
1315 /// Fetches a list of all scheduled events in the guild. If `with_user_count` is set to `true`,
1316 /// then each event returned will have its `user_count` field populated.
1317 ///
1318 /// **Note**: Requires the [View Channel] permission at the guild level.
1319 ///
1320 /// # Errors
1321 ///
1322 /// Returns [`Error::Http`] if the current user lacks permission.
1323 ///
1324 /// [View Channel]: Permissions::VIEW_CHANNEL
1325 pub async fn scheduled_events(
1326 self,
1327 http: impl AsRef<Http>,
1328 with_user_count: bool,
1329 ) -> Result<Vec<ScheduledEvent>> {
1330 http.as_ref().get_scheduled_events(self, with_user_count).await
1331 }
1332
1333 /// Fetches a list of interested users for the specified event.
1334 ///
1335 /// If `limit` is left unset, by default at most 100 users are returned.
1336 ///
1337 /// **Note**: Requires the [View Channel] permission for the channel associated with the event.
1338 ///
1339 /// # Errors
1340 ///
1341 /// Returns [`Error::Http`] if the current user lacks permission, or if the provided Id is
1342 /// invalid.
1343 ///
1344 /// [View Channel]: Permissions::VIEW_CHANNEL
1345 pub async fn scheduled_event_users(
1346 self,
1347 http: impl AsRef<Http>,
1348 event_id: impl Into<ScheduledEventId>,
1349 limit: Option<u64>,
1350 ) -> Result<Vec<ScheduledEventUser>> {
1351 http.as_ref().get_scheduled_event_users(self, event_id.into(), limit, None, None).await
1352 }
1353
1354 /// Fetches a list of interested users for the specified event, with additional options and
1355 /// filtering. See [`Http::get_scheduled_event_users`] for details.
1356 ///
1357 /// **Note**: Requires the [View Channel] permission for the channel associated with the event.
1358 ///
1359 /// # Errors
1360 ///
1361 /// Returns [`Error::Http`] if the current user lacks permission, or if the provided Id is
1362 /// invalid.
1363 ///
1364 /// [View Channel]: Permissions::VIEW_CHANNEL
1365 pub async fn scheduled_event_users_optioned(
1366 self,
1367 http: impl AsRef<Http>,
1368 event_id: impl Into<ScheduledEventId>,
1369 limit: Option<u64>,
1370 target: Option<UserPagination>,
1371 with_member: Option<bool>,
1372 ) -> Result<Vec<ScheduledEventUser>> {
1373 http.as_ref()
1374 .get_scheduled_event_users(self, event_id.into(), limit, target, with_member)
1375 .await
1376 }
1377
1378 /// Returns the Id of the shard associated with the guild.
1379 ///
1380 /// When the cache is enabled this will automatically retrieve the total number of shards.
1381 ///
1382 /// **Note**: When the cache is enabled, this function unlocks the cache to retrieve the total
1383 /// number of shards in use. If you already have the total, consider using [`utils::shard_id`].
1384 ///
1385 /// [`utils::shard_id`]: crate::utils::shard_id
1386 #[cfg(all(feature = "cache", feature = "utils"))]
1387 #[inline]
1388 #[must_use]
1389 pub fn shard_id(self, cache: impl AsRef<Cache>) -> u32 {
1390 crate::utils::shard_id(self, cache.as_ref().shard_count())
1391 }
1392
1393 /// Returns the Id of the shard associated with the guild.
1394 ///
1395 /// When the cache is enabled this will automatically retrieve the total number of shards.
1396 ///
1397 /// When the cache is not enabled, the total number of shards being used will need to be
1398 /// passed.
1399 ///
1400 /// # Examples
1401 ///
1402 /// Retrieve the Id of the shard for a guild with Id `81384788765712384`, using 17 shards:
1403 ///
1404 /// ```rust
1405 /// use serenity::model::id::GuildId;
1406 /// use serenity::utils;
1407 ///
1408 /// let guild_id = GuildId::new(81384788765712384);
1409 ///
1410 /// assert_eq!(guild_id.shard_id(17), 7);
1411 /// ```
1412 #[cfg(all(feature = "utils", not(feature = "cache")))]
1413 #[inline]
1414 #[must_use]
1415 pub fn shard_id(self, shard_count: u32) -> u32 {
1416 crate::utils::shard_id(self, shard_count)
1417 }
1418
1419 /// Starts an integration sync for the given integration Id.
1420 ///
1421 /// Requires the [Manage Guild] permission.
1422 ///
1423 /// # Errors
1424 ///
1425 /// Returns [`Error::Http`] if the current user lacks permission, or if an [`Integration`] with
1426 /// that Id does not exist.
1427 ///
1428 /// [Manage Guild]: Permissions::MANAGE_GUILD
1429 #[inline]
1430 pub async fn start_integration_sync(
1431 self,
1432 http: impl AsRef<Http>,
1433 integration_id: impl Into<IntegrationId>,
1434 ) -> Result<()> {
1435 http.as_ref().start_integration_sync(self, integration_id.into()).await
1436 }
1437
1438 /// Starts a prune of [`Member`]s.
1439 ///
1440 /// See the documentation on [`GuildPrune`] for more information.
1441 ///
1442 /// **Note**: Requires [Kick Members] and [Manage Guild] permissions.
1443 ///
1444 /// # Errors
1445 ///
1446 /// Returns [`Error::Http`] if the current user lacks permission.
1447 ///
1448 /// [Kick Members]: Permissions::KICK_MEMBERS
1449 /// [Manage Guild]: Permissions::MANAGE_GUILD
1450 #[inline]
1451 pub async fn start_prune(self, http: impl AsRef<Http>, days: u8) -> Result<GuildPrune> {
1452 http.as_ref().start_guild_prune(self, days, None).await
1453 }
1454
1455 /// Unbans a [`User`] from the guild.
1456 ///
1457 /// **Note**: Requires the [Ban Members] permission.
1458 ///
1459 /// # Errors
1460 ///
1461 /// Returns [`Error::Http`] if the current user does not have permission.
1462 ///
1463 /// [Ban Members]: Permissions::BAN_MEMBERS
1464 #[inline]
1465 pub async fn unban(self, http: impl AsRef<Http>, user_id: impl Into<UserId>) -> Result<()> {
1466 http.as_ref().remove_ban(self, user_id.into(), None).await
1467 }
1468
1469 /// Retrieve's the guild's vanity URL.
1470 ///
1471 /// **Note**: Requires the [Manage Guild] permission.
1472 ///
1473 /// # Errors
1474 ///
1475 /// Will return [`Error::Http`] if the current user lacks permission. Can also return
1476 /// [`Error::Json`] if there is an error deserializing the API response.
1477 ///
1478 /// [Manage Guild]: Permissions::MANAGE_GUILD
1479 #[inline]
1480 pub async fn vanity_url(self, http: impl AsRef<Http>) -> Result<String> {
1481 http.as_ref().get_guild_vanity_url(self).await
1482 }
1483
1484 /// Retrieves the guild's webhooks.
1485 ///
1486 /// **Note**: Requires the [Manage Webhooks] permission.
1487 ///
1488 /// [Manage Webhooks]: Permissions::MANAGE_WEBHOOKS
1489 ///
1490 /// # Errors
1491 ///
1492 /// Will return an [`Error::Http`] if the bot is lacking permissions. Can also return an
1493 /// [`Error::Json`] if there is an error deserializing the API response.
1494 #[inline]
1495 pub async fn webhooks(self, http: impl AsRef<Http>) -> Result<Vec<Webhook>> {
1496 http.as_ref().get_guild_webhooks(self).await
1497 }
1498 /// Returns a builder which can be awaited to obtain a message or stream of messages in this
1499 /// guild.
1500 #[cfg(feature = "collector")]
1501 pub fn await_reply(self, shard_messenger: impl AsRef<ShardMessenger>) -> MessageCollector {
1502 MessageCollector::new(shard_messenger).guild_id(self)
1503 }
1504
1505 /// Same as [`Self::await_reply`].
1506 #[cfg(feature = "collector")]
1507 pub fn await_replies(&self, shard_messenger: impl AsRef<ShardMessenger>) -> MessageCollector {
1508 self.await_reply(shard_messenger)
1509 }
1510
1511 /// Returns a builder which can be awaited to obtain a message or stream of reactions sent in
1512 /// this guild.
1513 #[cfg(feature = "collector")]
1514 pub fn await_reaction(self, shard_messenger: impl AsRef<ShardMessenger>) -> ReactionCollector {
1515 ReactionCollector::new(shard_messenger).guild_id(self)
1516 }
1517
1518 /// Same as [`Self::await_reaction`].
1519 #[cfg(feature = "collector")]
1520 pub fn await_reactions(
1521 &self,
1522 shard_messenger: impl AsRef<ShardMessenger>,
1523 ) -> ReactionCollector {
1524 self.await_reaction(shard_messenger)
1525 }
1526
1527 /// Create a guild specific application [`Command`].
1528 ///
1529 /// **Note**: Unlike global commands, guild commands will update instantly.
1530 ///
1531 /// # Errors
1532 ///
1533 /// See [`CreateCommand::execute`] for a list of possible errors.
1534 pub async fn create_command(
1535 self,
1536 cache_http: impl CacheHttp,
1537 builder: CreateCommand,
1538 ) -> Result<Command> {
1539 builder.execute(cache_http, (Some(self), None)).await
1540 }
1541
1542 /// Override all guild application commands.
1543 ///
1544 /// # Errors
1545 ///
1546 /// Returns the same errors as [`Self::create_command`].
1547 pub async fn set_commands(
1548 self,
1549 http: impl AsRef<Http>,
1550 commands: Vec<CreateCommand>,
1551 ) -> Result<Vec<Command>> {
1552 http.as_ref().create_guild_commands(self, &commands).await
1553 }
1554
1555 /// Overwrites permissions for a specific command.
1556 ///
1557 /// **Note**: It will update instantly.
1558 ///
1559 /// # Errors
1560 ///
1561 /// See [`EditCommandPermissions::execute`] for a list of possible errors.
1562 pub async fn edit_command_permissions(
1563 self,
1564 cache_http: impl CacheHttp,
1565 command_id: CommandId,
1566 builder: EditCommandPermissions,
1567 ) -> Result<CommandPermissions> {
1568 builder.execute(cache_http, (self, command_id)).await
1569 }
1570
1571 /// Get all guild application commands.
1572 ///
1573 /// # Errors
1574 ///
1575 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1576 pub async fn get_commands(self, http: impl AsRef<Http>) -> Result<Vec<Command>> {
1577 http.as_ref().get_guild_commands(self).await
1578 }
1579
1580 /// Get all guild application commands with localizations.
1581 ///
1582 /// # Errors
1583 ///
1584 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1585 pub async fn get_commands_with_localizations(
1586 self,
1587 http: impl AsRef<Http>,
1588 ) -> Result<Vec<Command>> {
1589 http.as_ref().get_guild_commands_with_localizations(self).await
1590 }
1591
1592 /// Get a specific guild application command by its Id.
1593 ///
1594 /// # Errors
1595 ///
1596 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1597 pub async fn get_command(
1598 self,
1599 http: impl AsRef<Http>,
1600 command_id: CommandId,
1601 ) -> Result<Command> {
1602 http.as_ref().get_guild_command(self, command_id).await
1603 }
1604
1605 /// Edit a guild application command, given its Id.
1606 ///
1607 /// # Errors
1608 ///
1609 /// See [`CreateCommand::execute`] for a list of possible errors.
1610 pub async fn edit_command(
1611 self,
1612 cache_http: impl CacheHttp,
1613 command_id: CommandId,
1614 builder: CreateCommand,
1615 ) -> Result<Command> {
1616 builder.execute(cache_http, (Some(self), Some(command_id))).await
1617 }
1618
1619 /// Delete guild application command by its Id.
1620 ///
1621 /// # Errors
1622 ///
1623 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1624 pub async fn delete_command(self, http: impl AsRef<Http>, command_id: CommandId) -> Result<()> {
1625 http.as_ref().delete_guild_command(self, command_id).await
1626 }
1627
1628 /// Get all guild application commands permissions only.
1629 ///
1630 /// # Errors
1631 ///
1632 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1633 pub async fn get_commands_permissions(
1634 self,
1635 http: impl AsRef<Http>,
1636 ) -> Result<Vec<CommandPermissions>> {
1637 http.as_ref().get_guild_commands_permissions(self).await
1638 }
1639
1640 /// Get permissions for specific guild application command by its Id.
1641 ///
1642 /// # Errors
1643 ///
1644 /// If there is an error, it will be either [`Error::Http`] or [`Error::Json`].
1645 pub async fn get_command_permissions(
1646 self,
1647 http: impl AsRef<Http>,
1648 command_id: CommandId,
1649 ) -> Result<CommandPermissions> {
1650 http.as_ref().get_guild_command_permissions(self, command_id).await
1651 }
1652
1653 /// Get the guild welcome screen.
1654 ///
1655 /// # Errors
1656 ///
1657 /// Returns [`Error::Http`] if the guild does not have a welcome screen.
1658 pub async fn get_welcome_screen(self, http: impl AsRef<Http>) -> Result<GuildWelcomeScreen> {
1659 http.as_ref().get_guild_welcome_screen(self).await
1660 }
1661
1662 /// Get the guild preview.
1663 ///
1664 /// **Note**: The bot need either to be part of the guild or the guild needs to have the
1665 /// `DISCOVERABLE` feature.
1666 ///
1667 /// # Errors
1668 ///
1669 /// Returns [`Error::Http`] if the bot cannot see the guild preview, see the note.
1670 pub async fn get_preview(self, http: impl AsRef<Http>) -> Result<GuildPreview> {
1671 http.as_ref().get_guild_preview(self).await
1672 }
1673
1674 /// Get the guild widget.
1675 ///
1676 /// # Errors
1677 ///
1678 /// Returns [`Error::Http`] if the bot does not have `MANAGE_MESSAGES` permission.
1679 pub async fn get_widget(self, http: impl AsRef<Http>) -> Result<GuildWidget> {
1680 http.as_ref().get_guild_widget(self).await
1681 }
1682
1683 /// Get the widget image URL.
1684 #[must_use]
1685 pub fn widget_image_url(self, style: GuildWidgetStyle) -> String {
1686 api!("/guilds/{}/widget.png?style={}", self, style)
1687 }
1688
1689 /// Gets the guild active threads.
1690 ///
1691 /// # Errors
1692 ///
1693 /// Returns [`Error::Http`] if there is an error in the deserialization, or if the bot issuing
1694 /// the request is not in the guild.
1695 pub async fn get_active_threads(self, http: impl AsRef<Http>) -> Result<ThreadsData> {
1696 http.as_ref().get_guild_active_threads(self).await
1697 }
1698}
1699
1700impl From<PartialGuild> for GuildId {
1701 /// Gets the Id of a partial guild.
1702 fn from(guild: PartialGuild) -> GuildId {
1703 guild.id
1704 }
1705}
1706
1707impl From<&PartialGuild> for GuildId {
1708 /// Gets the Id of a partial guild.
1709 fn from(guild: &PartialGuild) -> GuildId {
1710 guild.id
1711 }
1712}
1713
1714impl From<GuildInfo> for GuildId {
1715 /// Gets the Id of Guild information struct.
1716 fn from(guild_info: GuildInfo) -> GuildId {
1717 guild_info.id
1718 }
1719}
1720
1721impl From<&GuildInfo> for GuildId {
1722 /// Gets the Id of Guild information struct.
1723 fn from(guild_info: &GuildInfo) -> GuildId {
1724 guild_info.id
1725 }
1726}
1727
1728impl From<InviteGuild> for GuildId {
1729 /// Gets the Id of Invite Guild struct.
1730 fn from(invite_guild: InviteGuild) -> GuildId {
1731 invite_guild.id
1732 }
1733}
1734
1735impl From<&InviteGuild> for GuildId {
1736 /// Gets the Id of Invite Guild struct.
1737 fn from(invite_guild: &InviteGuild) -> GuildId {
1738 invite_guild.id
1739 }
1740}
1741
1742impl From<Guild> for GuildId {
1743 /// Gets the Id of Guild.
1744 fn from(live_guild: Guild) -> GuildId {
1745 live_guild.id
1746 }
1747}
1748
1749impl From<&Guild> for GuildId {
1750 /// Gets the Id of Guild.
1751 fn from(live_guild: &Guild) -> GuildId {
1752 live_guild.id
1753 }
1754}
1755
1756impl From<WebhookGuild> for GuildId {
1757 /// Gets the Id of Webhook Guild struct.
1758 fn from(webhook_guild: WebhookGuild) -> GuildId {
1759 webhook_guild.id
1760 }
1761}
1762
1763impl From<&WebhookGuild> for GuildId {
1764 /// Gets the Id of Webhook Guild struct.
1765 fn from(webhook_guild: &WebhookGuild) -> GuildId {
1766 webhook_guild.id
1767 }
1768}
1769
1770/// A helper class returned by [`GuildId::members_iter`]
1771#[derive(Clone, Debug)]
1772#[cfg(feature = "model")]
1773pub struct MembersIter<H: AsRef<Http>> {
1774 guild_id: GuildId,
1775 http: H,
1776 buffer: Vec<Member>,
1777 after: Option<UserId>,
1778 tried_fetch: bool,
1779}
1780
1781#[cfg(feature = "model")]
1782impl<H: AsRef<Http>> MembersIter<H> {
1783 fn new(guild_id: GuildId, http: H) -> MembersIter<H> {
1784 MembersIter {
1785 guild_id,
1786 http,
1787 buffer: Vec::new(),
1788 after: None,
1789 tried_fetch: false,
1790 }
1791 }
1792
1793 /// Fills the `self.buffer` cache of Members.
1794 ///
1795 /// This drops any members that were currently in the buffer, so it should only be called when
1796 /// `self.buffer` is empty. Additionally, this updates `self.after` so that the next call does
1797 /// not return duplicate items. If there are no more members to be fetched, then this marks
1798 /// `self.after` as None, indicating that no more calls ought to be made.
1799 async fn refresh(&mut self) -> Result<()> {
1800 // Number of profiles to fetch
1801 let grab_size: u64 = 1000;
1802
1803 self.buffer = self.guild_id.members(&self.http, Some(grab_size), self.after).await?;
1804
1805 // Get the last member. If shorter than 1000, there are no more results anyway
1806 self.after = self.buffer.get(grab_size as usize - 1).map(|member| member.user.id);
1807
1808 // Reverse to optimize pop()
1809 self.buffer.reverse();
1810
1811 self.tried_fetch = true;
1812
1813 Ok(())
1814 }
1815
1816 /// Streams over all the members in a guild.
1817 ///
1818 /// This is accomplished and equivalent to repeated calls to [`GuildId::members`]. A buffer of
1819 /// at most 1,000 members is used to reduce the number of calls necessary.
1820 ///
1821 /// # Examples
1822 ///
1823 /// ```rust,no_run
1824 /// # use serenity::model::id::GuildId;
1825 /// # use serenity::http::Http;
1826 /// #
1827 /// # async fn run() {
1828 /// # let guild_id = GuildId::new(1);
1829 /// # let ctx: Http = unimplemented!();
1830 /// use serenity::futures::StreamExt;
1831 /// use serenity::model::guild::MembersIter;
1832 ///
1833 /// let mut members = MembersIter::<Http>::stream(&ctx, guild_id).boxed();
1834 /// while let Some(member_result) = members.next().await {
1835 /// match member_result {
1836 /// Ok(member) => println!("{} is {}", member, member.display_name(),),
1837 /// Err(error) => eprintln!("Uh oh! Error: {}", error),
1838 /// }
1839 /// }
1840 /// # }
1841 /// ```
1842 pub fn stream(http: impl AsRef<Http>, guild_id: GuildId) -> impl Stream<Item = Result<Member>> {
1843 let init_state = MembersIter::new(guild_id, http);
1844
1845 futures::stream::unfold(init_state, |mut state| async {
1846 if state.buffer.is_empty() && state.after.is_some() || !state.tried_fetch {
1847 if let Err(error) = state.refresh().await {
1848 return Some((Err(error), state));
1849 }
1850 }
1851
1852 state.buffer.pop().map(|entry| (Ok(entry), state))
1853 })
1854 }
1855}
1856
1857#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Deserialize, Serialize)]
1858#[non_exhaustive]
1859pub enum GuildWidgetStyle {
1860 Shield,
1861 Banner1,
1862 Banner2,
1863 Banner3,
1864 Banner4,
1865}
1866
1867impl fmt::Display for GuildWidgetStyle {
1868 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1869 match self {
1870 Self::Shield => f.write_str("shield"),
1871 Self::Banner1 => f.write_str("banner1"),
1872 Self::Banner2 => f.write_str("banner2"),
1873 Self::Banner3 => f.write_str("banner3"),
1874 Self::Banner4 => f.write_str("banner4"),
1875 }
1876 }
1877}