Skip to main content

twilight_http/client/
mod.rs

1mod builder;
2pub(crate) mod connector;
3mod interaction;
4
5pub use self::{builder::ClientBuilder, interaction::InteractionClient};
6
7use crate::request::{
8    application::{
9        emoji::{
10            AddApplicationEmoji, DeleteApplicationEmoji, ListApplicationEmojis,
11            UpdateApplicationEmoji,
12        },
13        monetization::{
14            ConsumeEntitlement, CreateTestEntitlement, CreateTestEntitlementOwner,
15            DeleteTestEntitlement, GetEntitlement, GetEntitlements, GetSKUSubscription,
16            GetSKUSubscriptions, GetSKUs,
17        },
18    },
19    guild::user::{GetCurrentUserVoiceState, GetUserVoiceState},
20};
21#[allow(deprecated)]
22use crate::{
23    API_VERSION,
24    client::connector::Connector,
25    error::{Error, ErrorType},
26    request::{
27        GetCurrentAuthorizationInformation, GetGateway, GetUserApplicationInfo, GetVoiceRegions,
28        Method, Request, UpdateCurrentUserApplication,
29        channel::{
30            CreatePin, CreateTypingTrigger, DeleteChannel, DeleteChannelPermission, DeletePin,
31            FollowNewsChannel, GetChannel, GetPins, UpdateChannel, UpdateChannelPermission,
32            invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite},
33            message::{
34                CreateMessage, CrosspostMessage, DeleteMessage, DeleteMessages, GetChannelMessages,
35                GetMessage, UpdateMessage,
36            },
37            reaction::{
38                CreateReaction, DeleteAllReaction, DeleteAllReactions, DeleteReaction,
39                GetReactions, RequestReactionType, delete_reaction::TargetUser,
40            },
41            stage::{
42                CreateStageInstance, DeleteStageInstance, GetStageInstance, UpdateStageInstance,
43            },
44            thread::{
45                AddThreadMember, CreateForumThread, CreateThread, CreateThreadFromMessage,
46                GetJoinedPrivateArchivedThreads, GetPrivateArchivedThreads,
47                GetPublicArchivedThreads, GetThreadMember, GetThreadMembers, JoinThread,
48                LeaveThread, RemoveThreadMember, UpdateThread,
49            },
50            webhook::{
51                CreateWebhook, DeleteWebhook, DeleteWebhookMessage, ExecuteWebhook,
52                GetChannelWebhooks, GetWebhook, GetWebhookMessage, UpdateWebhook,
53                UpdateWebhookMessage, UpdateWebhookWithToken,
54            },
55        },
56        guild::{
57            CreateGuildChannel, CreateGuildPrune, DeleteGuild, GetActiveThreads, GetAuditLog,
58            GetGuild, GetGuildChannels, GetGuildInvites, GetGuildOnboarding, GetGuildPreview,
59            GetGuildPruneCount, GetGuildVanityUrl, GetGuildVoiceRegions, GetGuildWebhooks,
60            GetGuildWelcomeScreen, GetGuildWidget, GetGuildWidgetSettings, UpdateCurrentMember,
61            UpdateGuild, UpdateGuildChannelPositions, UpdateGuildMfa, UpdateGuildWelcomeScreen,
62            UpdateGuildWidgetSettings,
63            auto_moderation::{
64                CreateAutoModerationRule, DeleteAutoModerationRule, GetAutoModerationRule,
65                GetGuildAutoModerationRules, UpdateAutoModerationRule,
66            },
67            ban::{CreateBan, DeleteBan, GetBan, GetBans},
68            emoji::{CreateEmoji, DeleteEmoji, GetEmoji, GetEmojis, UpdateEmoji},
69            integration::{DeleteGuildIntegration, GetGuildIntegrations},
70            member::{
71                AddGuildMember, AddRoleToMember, GetGuildMembers, GetMember, RemoveMember,
72                RemoveRoleFromMember, SearchGuildMembers, UpdateGuildMember,
73            },
74            role::{
75                CreateRole, DeleteRole, GetGuildRoleMemberCounts, GetGuildRoles, GetRole,
76                UpdateRole, UpdateRolePositions,
77            },
78            sticker::{
79                CreateGuildSticker, DeleteGuildSticker, GetGuildSticker, GetGuildStickers,
80                UpdateGuildSticker,
81            },
82            update_guild_onboarding::{UpdateGuildOnboarding, UpdateGuildOnboardingFields},
83            user::{UpdateCurrentUserVoiceState, UpdateUserVoiceState},
84        },
85        poll::{EndPoll, GetAnswerVoters},
86        scheduled_event::{
87            CreateGuildScheduledEvent, DeleteGuildScheduledEvent, GetGuildScheduledEvent,
88            GetGuildScheduledEventUsers, GetGuildScheduledEvents, UpdateGuildScheduledEvent,
89        },
90        sticker::{GetNitroStickerPacks, GetSticker},
91        template::{
92            CreateGuildFromTemplate, CreateTemplate, DeleteTemplate, GetTemplate, GetTemplates,
93            SyncTemplate, UpdateTemplate,
94        },
95        user::{
96            CreatePrivateChannel, GetCurrentUser, GetCurrentUserConnections,
97            GetCurrentUserGuildMember, GetCurrentUserGuilds, GetUser, LeaveGuild,
98            UpdateCurrentUser,
99        },
100    },
101    response::ResponseFuture,
102};
103use http::header::{
104    AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, HeaderMap, HeaderValue, USER_AGENT,
105};
106use http_body_util::Full;
107use hyper::body::Bytes;
108use hyper_util::client::legacy::Client as HyperClient;
109use std::{
110    fmt::{Debug, Formatter, Result as FmtResult},
111    ops::Deref,
112    sync::{
113        Arc,
114        atomic::{AtomicBool, Ordering},
115    },
116    time::Duration,
117};
118use twilight_http_ratelimiting::{Endpoint, RateLimiter};
119use twilight_model::{
120    channel::{ChannelType, message::AllowedMentions},
121    guild::{
122        MfaLevel, RolePosition, auto_moderation::AutoModerationEventType,
123        scheduled_event::PrivacyLevel,
124    },
125    http::{channel_position::Position, permission_overwrite::PermissionOverwrite},
126    id::{
127        Id,
128        marker::{
129            ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker,
130            EntitlementMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker,
131            ScheduledEventMarker, SkuMarker, StickerMarker, SubscriptionMarker, UserMarker,
132            WebhookMarker,
133        },
134    },
135};
136
137const TWILIGHT_USER_AGENT: &str = concat!(
138    "DiscordBot (",
139    env!("CARGO_PKG_HOMEPAGE"),
140    ", ",
141    env!("CARGO_PKG_VERSION"),
142    ") Twilight-rs",
143);
144
145/// Wrapper for an authorization token with a debug implementation that redacts
146/// the string.
147#[derive(Default)]
148struct Token {
149    /// Authorization token that is redacted in the Debug implementation.
150    inner: Box<str>,
151}
152
153impl Token {
154    /// Create a new authorization wrapper.
155    const fn new(token: Box<str>) -> Self {
156        Self { inner: token }
157    }
158}
159
160impl Debug for Token {
161    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
162        f.write_str("<redacted>")
163    }
164}
165
166impl Deref for Token {
167    type Target = str;
168
169    fn deref(&self) -> &Self::Target {
170        &self.inner
171    }
172}
173
174/// Twilight's http client.
175///
176/// Almost all of the client methods require authentication, and as such, the client must be
177/// supplied with a Discord Token. Get yours [here].
178///
179/// # Interactions
180///
181/// HTTP interaction requests may be accessed via the [`Client::interaction`]
182/// method.
183///
184/// # OAuth2
185///
186/// To use Bearer tokens prefix the token with `"Bearer "`, including the space
187/// at the end like so:
188///
189/// ```no_run
190/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
191/// use std::env;
192/// use twilight_http::Client;
193///
194/// let bearer = env::var("BEARER_TOKEN")?;
195/// let token = format!("Bearer {bearer}");
196///
197/// let client = Client::new(token);
198/// # Ok(()) }
199/// ```
200///
201/// # Using the client in multiple tasks
202///
203/// To use a client instance in multiple tasks, consider wrapping it in an
204/// [`std::sync::Arc`] or [`std::rc::Rc`].
205///
206/// # Unauthorized behavior
207///
208/// When the client encounters an Unauthorized response it will take note that
209/// the configured token is invalid. This may occur when the token has been
210/// revoked or expired. When this happens, you must create a new client with the
211/// new token. The client will no longer execute requests in order to
212/// prevent API bans and will always return [`ErrorType::Unauthorized`].
213///
214/// # Examples
215///
216/// Create a client called `client`:
217/// ```no_run
218/// use twilight_http::Client;
219///
220/// # #[tokio::main]
221/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
222/// let client = Client::new("my token".to_owned());
223/// # Ok(()) }
224/// ```
225///
226/// Use [`ClientBuilder`] to create a client called `client`, with a shorter
227/// timeout:
228/// ```no_run
229/// use std::time::Duration;
230/// use twilight_http::Client;
231///
232/// # #[tokio::main]
233/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
234/// let client = Client::builder()
235///     .token("my token".to_owned())
236///     .timeout(Duration::from_secs(5))
237///     .build();
238/// # Ok(()) }
239/// ```
240///
241/// All the examples on this page assume you have already created a client, and have named it
242/// `client`.
243///
244/// [here]: https://discord.com/developers/applications
245#[derive(Debug)]
246pub struct Client {
247    pub(crate) default_allowed_mentions: Option<AllowedMentions>,
248    default_headers: Option<HeaderMap>,
249    http: HyperClient<Connector, Full<Bytes>>,
250    proxy: Option<Box<str>>,
251    ratelimiter: Option<RateLimiter>,
252    timeout: Duration,
253    /// Whether the token is invalidated.
254    ///
255    /// Whether an invalid token is tracked can be configured via
256    /// [`ClientBuilder::remember_invalid_token`].
257    token_invalidated: Option<Arc<AtomicBool>>,
258    token: Option<Token>,
259    use_http: bool,
260}
261
262impl Client {
263    /// Create a new client with a token.
264    pub fn new(token: String) -> Self {
265        ClientBuilder::default().token(token).build()
266    }
267
268    /// Create a new builder to create a client.
269    ///
270    /// Refer to its documentation for more information.
271    pub fn builder() -> ClientBuilder {
272        ClientBuilder::new()
273    }
274
275    /// Retrieve an immutable reference to the token used by the client.
276    ///
277    /// If the initial token provided is not prefixed with `Bot `, it will be, and this method
278    /// reflects that.
279    pub fn token(&self) -> Option<&str> {
280        self.token.as_deref()
281    }
282
283    /// Create an interface for using interactions.
284    ///
285    /// An application ID is required to be passed in to use interactions. The
286    /// ID may be retrieved via [`current_user_application`] and cached for use
287    /// with this method.
288    ///
289    /// # Examples
290    ///
291    /// Retrieve the application ID and then use an interaction request:
292    ///
293    /// ```no_run
294    /// # #[tokio::main]
295    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
296    /// use std::env;
297    /// use twilight_http::Client;
298    ///
299    /// let client = Client::new(env::var("DISCORD_TOKEN")?);
300    ///
301    /// // Cache the application ID for repeated use later in the process.
302    /// let application_id = {
303    ///     let response = client.current_user_application().await?;
304    ///
305    ///     response.model().await?.id
306    /// };
307    ///
308    /// // Later in the process...
309    /// let commands = client
310    ///     .interaction(application_id)
311    ///     .global_commands()
312    ///     .await?
313    ///     .models()
314    ///     .await?;
315    ///
316    /// println!("there are {} global commands", commands.len());
317    /// # Ok(()) }
318    /// ```
319    ///
320    /// [`current_user_application`]: Self::current_user_application
321    pub const fn interaction(
322        &self,
323        application_id: Id<ApplicationMarker>,
324    ) -> InteractionClient<'_> {
325        InteractionClient::new(self, application_id)
326    }
327
328    /// Get an immutable reference to the default [`AllowedMentions`] for sent
329    /// messages.
330    pub const fn default_allowed_mentions(&self) -> Option<&AllowedMentions> {
331        self.default_allowed_mentions.as_ref()
332    }
333
334    /// Get the Ratelimiter used by the client internally.
335    ///
336    /// This will return `None` only if ratelimit handling
337    /// has been explicitly disabled in the [`ClientBuilder`].
338    pub const fn ratelimiter(&self) -> Option<&RateLimiter> {
339        self.ratelimiter.as_ref()
340    }
341
342    /// Get an auto moderation rule in a guild.
343    ///
344    /// Requires the [`MANAGE_GUILD`] permission.
345    ///
346    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
347    pub const fn auto_moderation_rule(
348        &self,
349        guild_id: Id<GuildMarker>,
350        auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
351    ) -> GetAutoModerationRule<'_> {
352        GetAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
353    }
354
355    /// Get the auto moderation rules in a guild.
356    ///
357    /// Requires the [`MANAGE_GUILD`] permission.
358    ///
359    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
360    pub const fn auto_moderation_rules(
361        &self,
362        guild_id: Id<GuildMarker>,
363    ) -> GetGuildAutoModerationRules<'_> {
364        GetGuildAutoModerationRules::new(self, guild_id)
365    }
366
367    /// Create an auto moderation rule within a guild.
368    ///
369    /// Requires the [`MANAGE_GUILD`] permission.
370    ///
371    /// # Examples
372    ///
373    /// Create a rule that deletes messages that contain the word "darn":
374    ///
375    /// ```no_run
376    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
377    /// use twilight_http::Client;
378    /// use twilight_model::{guild::auto_moderation::AutoModerationEventType, id::Id};
379    ///
380    /// let client = Client::new("my token".to_owned());
381    ///
382    /// let guild_id = Id::new(1);
383    /// client
384    ///     .create_auto_moderation_rule(guild_id, "no darns", AutoModerationEventType::MessageSend)
385    ///     .action_block_message()
386    ///     .enabled(true)
387    ///     .with_keyword(&["darn"], &["d(?:4|a)rn"], &["darn it"])
388    ///     .await?;
389    /// # Ok(()) }
390    /// ```
391    ///
392    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
393    pub const fn create_auto_moderation_rule<'a>(
394        &'a self,
395        guild_id: Id<GuildMarker>,
396        name: &'a str,
397        event_type: AutoModerationEventType,
398    ) -> CreateAutoModerationRule<'a> {
399        CreateAutoModerationRule::new(self, guild_id, name, event_type)
400    }
401
402    /// Delete an auto moderation rule in a guild.
403    ///
404    /// Requires the [`MANAGE_GUILD`] permission.
405    ///
406    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
407    pub const fn delete_auto_moderation_rule(
408        &self,
409        guild_id: Id<GuildMarker>,
410        auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
411    ) -> DeleteAutoModerationRule<'_> {
412        DeleteAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
413    }
414
415    /// Update an auto moderation rule in a guild.
416    ///
417    /// Requires the [`MANAGE_GUILD`] permission.
418    ///
419    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
420    pub const fn update_auto_moderation_rule(
421        &self,
422        guild_id: Id<GuildMarker>,
423        auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
424    ) -> UpdateAutoModerationRule<'_> {
425        UpdateAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
426    }
427
428    /// Get the audit log for a guild.
429    ///
430    /// # Examples
431    ///
432    /// ```no_run
433    /// # use twilight_http::Client;
434    /// use twilight_model::id::Id;
435    ///
436    /// # #[tokio::main]
437    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
438    /// # let client = Client::new("token".to_owned());
439    /// let guild_id = Id::new(101);
440    /// let audit_log = client.audit_log(guild_id).await?;
441    /// # Ok(()) }
442    /// ```
443    pub const fn audit_log(&self, guild_id: Id<GuildMarker>) -> GetAuditLog<'_> {
444        GetAuditLog::new(self, guild_id)
445    }
446
447    /// Retrieve the bans for a guild.
448    ///
449    /// # Examples
450    ///
451    /// Retrieve the bans for guild `1`:
452    ///
453    /// ```no_run
454    /// # use twilight_http::Client;
455    /// use twilight_model::id::Id;
456    /// #
457    /// # #[tokio::main]
458    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
459    /// # let client = Client::new("my token".to_owned());
460    /// #
461    /// let guild_id = Id::new(1);
462    ///
463    /// let bans = client.bans(guild_id).await?;
464    /// # Ok(()) }
465    /// ```
466    pub const fn bans(&self, guild_id: Id<GuildMarker>) -> GetBans<'_> {
467        GetBans::new(self, guild_id)
468    }
469
470    /// Get information about a ban of a guild.
471    ///
472    /// Includes the user banned and the reason.
473    pub const fn ban(&self, guild_id: Id<GuildMarker>, user_id: Id<UserMarker>) -> GetBan<'_> {
474        GetBan::new(self, guild_id, user_id)
475    }
476
477    /// Bans a user from a guild, optionally with the number of seconds' worth of
478    /// messages to delete and the reason.
479    ///
480    /// # Examples
481    ///
482    /// Ban user `200` from guild `100`, deleting
483    /// `86_400` second's (this is equivalent to `1` day) worth of messages, for the reason `"memes"`:
484    ///
485    /// ```no_run
486    /// # use twilight_http::{request::AuditLogReason, Client};
487    /// use twilight_model::id::Id;
488    /// #
489    /// # #[tokio::main]
490    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
491    /// # let client = Client::new("my token".to_owned());
492    /// #
493    /// let guild_id = Id::new(100);
494    /// let user_id = Id::new(200);
495    /// client
496    ///     .create_ban(guild_id, user_id)
497    ///     .delete_message_seconds(86_400)
498    ///     .reason("memes")
499    ///     .await?;
500    /// # Ok(()) }
501    /// ```
502    pub const fn create_ban(
503        &self,
504        guild_id: Id<GuildMarker>,
505        user_id: Id<UserMarker>,
506    ) -> CreateBan<'_> {
507        CreateBan::new(self, guild_id, user_id)
508    }
509
510    /// Remove a ban from a user in a guild.
511    ///
512    /// # Examples
513    ///
514    /// Unban user `200` from guild `100`:
515    ///
516    /// ```no_run
517    /// # use twilight_http::Client;
518    /// use twilight_model::id::Id;
519    /// #
520    /// # #[tokio::main]
521    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
522    /// # let client = Client::new("my token".to_owned());
523    /// #
524    /// let guild_id = Id::new(100);
525    /// let user_id = Id::new(200);
526    ///
527    /// client.delete_ban(guild_id, user_id).await?;
528    /// # Ok(()) }
529    /// ```
530    pub const fn delete_ban(
531        &self,
532        guild_id: Id<GuildMarker>,
533        user_id: Id<UserMarker>,
534    ) -> DeleteBan<'_> {
535        DeleteBan::new(self, guild_id, user_id)
536    }
537
538    /// Get a channel by its ID.
539    ///
540    /// # Examples
541    ///
542    /// Get channel `100`:
543    ///
544    /// ```no_run
545    /// # use twilight_http::Client;
546    /// # use twilight_model::id::Id;
547    /// #
548    /// # #[tokio::main]
549    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
550    /// # let client = Client::new("my token".to_owned());
551    /// #
552    /// let channel_id = Id::new(100);
553    /// #
554    /// let channel = client.channel(channel_id).await?;
555    /// # Ok(()) }
556    /// ```
557    pub const fn channel(&self, channel_id: Id<ChannelMarker>) -> GetChannel<'_> {
558        GetChannel::new(self, channel_id)
559    }
560
561    /// Delete a channel by ID.
562    pub const fn delete_channel(&self, channel_id: Id<ChannelMarker>) -> DeleteChannel<'_> {
563        DeleteChannel::new(self, channel_id)
564    }
565
566    /// Update a channel.
567    pub const fn update_channel(&self, channel_id: Id<ChannelMarker>) -> UpdateChannel<'_> {
568        UpdateChannel::new(self, channel_id)
569    }
570
571    /// Follows a news channel by [`Id<ChannelMarker>`].
572    ///
573    /// The type returned is [`FollowedChannel`].
574    ///
575    /// [`FollowedChannel`]: ::twilight_model::channel::FollowedChannel
576    pub const fn follow_news_channel(
577        &self,
578        channel_id: Id<ChannelMarker>,
579        webhook_channel_id: Id<ChannelMarker>,
580    ) -> FollowNewsChannel<'_> {
581        FollowNewsChannel::new(self, channel_id, webhook_channel_id)
582    }
583
584    /// Get the invites for a guild channel.
585    ///
586    /// Requires the [`MANAGE_CHANNELS`] permission. This method only works if
587    /// the channel is a guild channel.
588    ///
589    /// [`MANAGE_CHANNELS`]: twilight_model::guild::Permissions::MANAGE_CHANNELS
590    pub const fn channel_invites(&self, channel_id: Id<ChannelMarker>) -> GetChannelInvites<'_> {
591        GetChannelInvites::new(self, channel_id)
592    }
593
594    /// Get channel messages, by [`Id<ChannelMarker>`].
595    ///
596    /// Only one of [`after`], [`around`], and [`before`] can be specified at a time.
597    /// Once these are specified, the type returned is [`GetChannelMessagesConfigured`].
598    ///
599    /// If [`limit`] is unspecified, the default set by Discord is 50.
600    ///
601    /// # Examples
602    ///
603    /// ```no_run
604    /// use twilight_http::Client;
605    /// use twilight_model::id::Id;
606    ///
607    /// # #[tokio::main]
608    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
609    /// let client = Client::new("my token".to_owned());
610    /// let channel_id = Id::new(123);
611    /// let message_id = Id::new(234);
612    /// let limit: u16 = 6;
613    ///
614    /// let messages = client
615    ///     .channel_messages(channel_id)
616    ///     .before(message_id)
617    ///     .limit(limit)
618    ///     .await?;
619    ///
620    /// # Ok(()) }
621    /// ```
622    ///
623    /// # Errors
624    ///
625    /// Returns an error of type [`ValidationErrorType::GetChannelMessages`] if
626    /// the amount is less than 1 or greater than 100.
627    ///
628    /// [`GetChannelMessagesConfigured`]: crate::request::channel::message::GetChannelMessagesConfigured
629    /// [`ValidationErrorType::GetChannelMessages`]: twilight_validate::request::ValidationErrorType::GetChannelMessages
630    /// [`after`]: GetChannelMessages::after
631    /// [`around`]: GetChannelMessages::around
632    /// [`before`]: GetChannelMessages::before
633    /// [`limit`]: GetChannelMessages::limit
634    pub const fn channel_messages(&self, channel_id: Id<ChannelMarker>) -> GetChannelMessages<'_> {
635        GetChannelMessages::new(self, channel_id)
636    }
637
638    pub const fn delete_channel_permission(
639        &self,
640        channel_id: Id<ChannelMarker>,
641    ) -> DeleteChannelPermission<'_> {
642        DeleteChannelPermission::new(self, channel_id)
643    }
644
645    /// Update the permissions for a role or a user in a channel.
646    ///
647    /// # Examples:
648    ///
649    /// Create permission overrides for a role to view the channel, but not send
650    /// messages:
651    ///
652    /// ```no_run
653    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
654    /// # use twilight_http::Client;
655    /// # let client = Client::new("my token".to_owned());
656    /// #
657    /// use twilight_model::{
658    ///     guild::Permissions,
659    ///     http::permission_overwrite::{PermissionOverwrite, PermissionOverwriteType},
660    ///     id::{Id, marker::RoleMarker},
661    /// };
662    ///
663    /// let channel_id = Id::new(123);
664    /// let role_id: Id<RoleMarker> = Id::new(432);
665    /// let permission_overwrite = PermissionOverwrite {
666    ///     allow: Some(Permissions::VIEW_CHANNEL),
667    ///     deny: Some(Permissions::SEND_MESSAGES),
668    ///     id: role_id.cast(),
669    ///     kind: PermissionOverwriteType::Role,
670    /// };
671    ///
672    /// client
673    ///     .update_channel_permission(channel_id, &permission_overwrite)
674    ///     .await?;
675    /// # Ok(()) }
676    /// ```
677    pub const fn update_channel_permission(
678        &self,
679        channel_id: Id<ChannelMarker>,
680        permission_overwrite: &PermissionOverwrite,
681    ) -> UpdateChannelPermission<'_> {
682        UpdateChannelPermission::new(self, channel_id, permission_overwrite)
683    }
684
685    /// Get all the webhooks of a channel.
686    pub const fn channel_webhooks(&self, channel_id: Id<ChannelMarker>) -> GetChannelWebhooks<'_> {
687        GetChannelWebhooks::new(self, channel_id)
688    }
689
690    /// Get information about the current user.
691    pub const fn current_user(&self) -> GetCurrentUser<'_> {
692        GetCurrentUser::new(self)
693    }
694
695    /// Get information about the current user in a guild.
696    pub const fn current_user_guild_member(
697        &self,
698        guild_id: Id<GuildMarker>,
699    ) -> GetCurrentUserGuildMember<'_> {
700        GetCurrentUserGuildMember::new(self, guild_id)
701    }
702
703    /// Get information about the current OAuth2 authorization.
704    pub const fn current_authorization(&self) -> GetCurrentAuthorizationInformation<'_> {
705        GetCurrentAuthorizationInformation::new(self)
706    }
707
708    /// Get information about the current bot application.
709    pub const fn current_user_application(&self) -> GetUserApplicationInfo<'_> {
710        GetUserApplicationInfo::new(self)
711    }
712
713    /// Update the current user's application.
714    pub const fn update_current_user_application(&self) -> UpdateCurrentUserApplication<'_> {
715        UpdateCurrentUserApplication::new(self)
716    }
717
718    /// Update the current user.
719    ///
720    /// All parameters are optional. If the username is changed, it may cause the discriminator to
721    /// be randomized.
722    pub const fn update_current_user(&self) -> UpdateCurrentUser<'_> {
723        UpdateCurrentUser::new(self)
724    }
725
726    /// Get voice state of the current user in a guild.
727    ///
728    /// # Caveats
729    ///
730    /// - Current user must already have joined a voice/stage channel in this guild.
731    pub const fn current_user_voice_state(
732        &self,
733        guild_id: Id<GuildMarker>,
734    ) -> GetCurrentUserVoiceState<'_> {
735        GetCurrentUserVoiceState::new(self, guild_id)
736    }
737
738    /// Update the current user's voice state.
739    ///
740    /// All parameters are optional.
741    ///
742    /// # Caveats
743    ///
744    /// - `channel_id` must currently point to a stage channel.
745    /// - Current user must have already joined `channel_id`.
746    pub const fn update_current_user_voice_state(
747        &self,
748        guild_id: Id<GuildMarker>,
749    ) -> UpdateCurrentUserVoiceState<'_> {
750        UpdateCurrentUserVoiceState::new(self, guild_id)
751    }
752
753    /// Get the current user's connections.
754    ///
755    /// Requires the `connections` `OAuth2` scope.
756    pub const fn current_user_connections(&self) -> GetCurrentUserConnections<'_> {
757        GetCurrentUserConnections::new(self)
758    }
759
760    /// Returns a list of guilds for the current user.
761    ///
762    /// # Examples
763    ///
764    /// Get the first 25 guilds with an ID after `300` and before
765    /// `400`:
766    ///
767    /// ```no_run
768    /// # use twilight_http::Client;
769    /// use twilight_model::id::Id;
770    ///
771    /// # #[tokio::main]
772    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
773    /// # let client = Client::new("my token".to_owned());
774    /// #
775    /// let after = Id::new(300);
776    /// let before = Id::new(400);
777    /// let guilds = client
778    ///     .current_user_guilds()
779    ///     .after(after)
780    ///     .before(before)
781    ///     .limit(25)
782    ///     .await?;
783    /// # Ok(()) }
784    /// ```
785    pub const fn current_user_guilds(&self) -> GetCurrentUserGuilds<'_> {
786        GetCurrentUserGuilds::new(self)
787    }
788
789    /// Get the emojis for a guild, by the guild's id.
790    ///
791    /// # Examples
792    ///
793    /// Get the emojis for guild `100`:
794    ///
795    /// ```no_run
796    /// # use twilight_http::Client;
797    /// # use twilight_model::id::Id;
798    /// #
799    /// # #[tokio::main]
800    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
801    /// # let client = Client::new("my token".to_owned());
802    /// #
803    /// let guild_id = Id::new(100);
804    ///
805    /// client.emojis(guild_id).await?;
806    /// # Ok(()) }
807    /// ```
808    pub const fn emojis(&self, guild_id: Id<GuildMarker>) -> GetEmojis<'_> {
809        GetEmojis::new(self, guild_id)
810    }
811
812    /// Get the entitlements for an application.
813    ///
814    /// # Examples
815    ///
816    /// Get entitlements for the application `100`:
817    ///
818    /// ```no_run
819    /// # use twilight_http::Client;
820    /// # use twilight_model::id::Id;
821    ///
822    /// # #[tokio::main]
823    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
824    /// # let client = Client::new("my token".to_owned());
825    /// #
826    /// let application_id = Id::new(100);
827    ///
828    /// client.entitlements(application_id).await?;
829    /// # Ok(()) }
830    /// ```
831    pub const fn entitlements(&self, application_id: Id<ApplicationMarker>) -> GetEntitlements<'_> {
832        GetEntitlements::new(self, application_id)
833    }
834
835    /// Get an entitlement.
836    pub const fn entitlement(
837        &self,
838        application_id: Id<ApplicationMarker>,
839        entitlement_id: Id<EntitlementMarker>,
840    ) -> GetEntitlement<'_> {
841        GetEntitlement::new(self, application_id, entitlement_id)
842    }
843
844    /// Get an emoji for a guild by the the guild's ID and emoji's ID.
845    ///
846    /// # Examples
847    ///
848    /// Get emoji `100` from guild `50`:
849    ///
850    /// ```no_run
851    /// # use twilight_http::Client;
852    /// # use twilight_model::id::Id;
853    /// #
854    /// # #[tokio::main]
855    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
856    /// # let client = Client::new("my token".to_owned());
857    /// #
858    /// let guild_id = Id::new(50);
859    /// let emoji_id = Id::new(100);
860    ///
861    /// client.emoji(guild_id, emoji_id).await?;
862    /// # Ok(()) }
863    /// ```
864    pub const fn emoji(
865        &self,
866        guild_id: Id<GuildMarker>,
867        emoji_id: Id<EmojiMarker>,
868    ) -> GetEmoji<'_> {
869        GetEmoji::new(self, guild_id, emoji_id)
870    }
871
872    /// Create an emoji in a guild.
873    ///
874    /// The emoji must be a Data URI, in the form of
875    /// `data:image/{type};base64,{data}` where `{type}` is the image MIME type
876    /// and `{data}` is the base64-encoded image. See [Discord Docs/Image Data].
877    ///
878    /// [Discord Docs/Image Data]: https://discord.com/developers/docs/reference#image-data
879    pub const fn create_emoji<'a>(
880        &'a self,
881        guild_id: Id<GuildMarker>,
882        name: &'a str,
883        image: &'a str,
884    ) -> CreateEmoji<'a> {
885        CreateEmoji::new(self, guild_id, name, image)
886    }
887
888    /// Delete an emoji in a guild, by id.
889    pub const fn delete_emoji(
890        &self,
891        guild_id: Id<GuildMarker>,
892        emoji_id: Id<EmojiMarker>,
893    ) -> DeleteEmoji<'_> {
894        DeleteEmoji::new(self, guild_id, emoji_id)
895    }
896
897    /// Update an emoji in a guild, by id.
898    pub const fn update_emoji(
899        &self,
900        guild_id: Id<GuildMarker>,
901        emoji_id: Id<EmojiMarker>,
902    ) -> UpdateEmoji<'_> {
903        UpdateEmoji::new(self, guild_id, emoji_id)
904    }
905
906    /// Get information about the gateway, optionally with additional information detailing the
907    /// number of shards to use and sessions remaining.
908    ///
909    /// # Examples
910    ///
911    /// Get the gateway connection URL without bot information:
912    ///
913    /// ```no_run
914    /// # use twilight_http::Client;
915    /// #
916    /// # #[tokio::main]
917    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
918    /// # let client = Client::new("my token".to_owned());
919    /// #
920    /// let info = client.gateway().await?;
921    /// # Ok(()) }
922    /// ```
923    ///
924    /// Get the gateway connection URL with additional shard and session information, which
925    /// requires specifying a bot token:
926    ///
927    /// ```no_run
928    /// # use twilight_http::Client;
929    /// #
930    /// # #[tokio::main]
931    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
932    /// # let client = Client::new("my token".to_owned());
933    /// #
934    /// let info = client.gateway().authed().await?.model().await?;
935    ///
936    /// println!("URL: {}", info.url);
937    /// println!("Recommended shards to use: {}", info.shards);
938    /// # Ok(()) }
939    /// ```
940    pub const fn gateway(&self) -> GetGateway<'_> {
941        GetGateway::new(self)
942    }
943
944    /// Get information about a guild.
945    pub const fn guild(&self, guild_id: Id<GuildMarker>) -> GetGuild<'_> {
946        GetGuild::new(self, guild_id)
947    }
948
949    /// Delete a guild permanently. The user must be the owner.
950    pub const fn delete_guild(&self, guild_id: Id<GuildMarker>) -> DeleteGuild<'_> {
951        DeleteGuild::new(self, guild_id)
952    }
953
954    /// Update a guild.
955    ///
956    /// All endpoints are optional. See [Discord Docs/Modify Guild].
957    ///
958    /// [Discord Docs/Modify Guild]: https://discord.com/developers/docs/resources/guild#modify-guild
959    pub const fn update_guild(&self, guild_id: Id<GuildMarker>) -> UpdateGuild<'_> {
960        UpdateGuild::new(self, guild_id)
961    }
962
963    /// Leave a guild by id.
964    pub const fn leave_guild(&self, guild_id: Id<GuildMarker>) -> LeaveGuild<'_> {
965        LeaveGuild::new(self, guild_id)
966    }
967
968    /// Get the channels in a guild.
969    pub const fn guild_channels(&self, guild_id: Id<GuildMarker>) -> GetGuildChannels<'_> {
970        GetGuildChannels::new(self, guild_id)
971    }
972
973    /// Create a new request to create a guild channel.
974    ///
975    /// All fields are optional except for name. The minimum length of the name
976    /// is 1 UTF-16 character and the maximum is 100 UTF-16 characters.
977    ///
978    /// # Errors
979    ///
980    /// Returns an error of type [`NameInvalid`] when the length of the name is
981    /// either fewer than 1 UTF-16 character or more than 100 UTF-16 characters.
982    ///
983    /// Returns an error of type [`RateLimitPerUserInvalid`] when the seconds of
984    /// the rate limit per user is more than 21600.
985    ///
986    /// Returns an error of type [`TopicInvalid`] when the length of the topic
987    /// is more than 1024 UTF-16 characters.
988    ///
989    /// [`NameInvalid`]: twilight_validate::channel::ChannelValidationErrorType::NameInvalid
990    /// [`RateLimitPerUserInvalid`]: twilight_validate::channel::ChannelValidationErrorType::RateLimitPerUserInvalid
991    /// [`TopicInvalid`]: twilight_validate::channel::ChannelValidationErrorType::TopicInvalid
992    pub fn create_guild_channel<'a>(
993        &'a self,
994        guild_id: Id<GuildMarker>,
995        name: &'a str,
996    ) -> CreateGuildChannel<'a> {
997        CreateGuildChannel::new(self, guild_id, name)
998    }
999
1000    /// Modify the guild onboarding flow.
1001    pub const fn update_guild_onboarding(
1002        &self,
1003        guild_id: Id<GuildMarker>,
1004        fields: UpdateGuildOnboardingFields,
1005    ) -> UpdateGuildOnboarding<'_> {
1006        UpdateGuildOnboarding::new(self, guild_id, fields)
1007    }
1008
1009    /// Modify the positions of the channels.
1010    ///
1011    /// The minimum amount of channels to modify, is a swap between two channels.
1012    pub const fn update_guild_channel_positions<'a>(
1013        &'a self,
1014        guild_id: Id<GuildMarker>,
1015        channel_positions: &'a [Position],
1016    ) -> UpdateGuildChannelPositions<'a> {
1017        UpdateGuildChannelPositions::new(self, guild_id, channel_positions)
1018    }
1019
1020    /// Get a guild's widget.
1021    ///
1022    /// See [Discord Docs/Get Guild Widget].
1023    ///
1024    /// [Discord Docs/Get Guild Widget]: https://discord.com/developers/docs/resources/guild#get-guild-widget
1025    pub const fn guild_widget(&self, guild_id: Id<GuildMarker>) -> GetGuildWidget<'_> {
1026        GetGuildWidget::new(self, guild_id)
1027    }
1028
1029    /// Get a guild's widget settings.
1030    ///
1031    /// See [Discord Docs/Get Guild Widget Settings].
1032    ///
1033    /// [Discord Docs/Get Guild Widget]: https://discord.com/developers/docs/resources/guild#get-guild-widget-settings
1034    pub const fn guild_widget_settings(
1035        &self,
1036        guild_id: Id<GuildMarker>,
1037    ) -> GetGuildWidgetSettings<'_> {
1038        GetGuildWidgetSettings::new(self, guild_id)
1039    }
1040
1041    /// Modify a guild's widget.
1042    ///
1043    /// See [Discord Docs/Modify Guild Widget].
1044    ///
1045    /// [Discord Docs/Modify Guild Widget]: https://discord.com/developers/docs/resources/guild#modify-guild-widget
1046    pub const fn update_guild_widget_settings(
1047        &self,
1048        guild_id: Id<GuildMarker>,
1049    ) -> UpdateGuildWidgetSettings<'_> {
1050        UpdateGuildWidgetSettings::new(self, guild_id)
1051    }
1052
1053    /// Get the guild's integrations.
1054    pub const fn guild_integrations(&self, guild_id: Id<GuildMarker>) -> GetGuildIntegrations<'_> {
1055        GetGuildIntegrations::new(self, guild_id)
1056    }
1057
1058    /// Delete an integration for a guild, by the integration's id.
1059    pub const fn delete_guild_integration(
1060        &self,
1061        guild_id: Id<GuildMarker>,
1062        integration_id: Id<IntegrationMarker>,
1063    ) -> DeleteGuildIntegration<'_> {
1064        DeleteGuildIntegration::new(self, guild_id, integration_id)
1065    }
1066
1067    /// Get information about the invites of a guild.
1068    ///
1069    /// Requires the [`MANAGE_GUILD`] permission.
1070    ///
1071    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
1072    pub const fn guild_invites(&self, guild_id: Id<GuildMarker>) -> GetGuildInvites<'_> {
1073        GetGuildInvites::new(self, guild_id)
1074    }
1075
1076    /// Update a guild's MFA level.
1077    pub const fn update_guild_mfa(
1078        &self,
1079        guild_id: Id<GuildMarker>,
1080        level: MfaLevel,
1081    ) -> UpdateGuildMfa<'_> {
1082        UpdateGuildMfa::new(self, guild_id, level)
1083    }
1084
1085    /// Get the members of a guild, by id.
1086    ///
1087    /// The upper limit to this request is 1000. If more than 1000 members are needed, the requests
1088    /// must be chained. Discord defaults the limit to 1.
1089    ///
1090    /// # Examples
1091    ///
1092    /// Get the first 500 members of guild `100` after user ID `3000`:
1093    ///
1094    /// ```no_run
1095    /// # use twilight_http::Client;
1096    /// use twilight_model::id::Id;
1097    /// #
1098    /// # #[tokio::main]
1099    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1100    /// # let client = Client::new("my token".to_owned());
1101    /// #
1102    /// let guild_id = Id::new(100);
1103    /// let user_id = Id::new(3000);
1104    /// let members = client
1105    ///     .guild_members(guild_id)
1106    ///     .after(user_id)
1107    ///     .limit(500)
1108    ///     .await?;
1109    /// # Ok(()) }
1110    /// ```
1111    ///
1112    /// # Errors
1113    ///
1114    /// Returns an error of type [`ValidationErrorType::GetGuildMembers`] if the
1115    /// limit is invalid.
1116    ///
1117    /// [`ValidationErrorType::GetGuildMembers`]: twilight_validate::request::ValidationErrorType::GetGuildMembers
1118    pub const fn guild_members(&self, guild_id: Id<GuildMarker>) -> GetGuildMembers<'_> {
1119        GetGuildMembers::new(self, guild_id)
1120    }
1121
1122    /// Search the members of a specific guild by a query.
1123    ///
1124    /// The upper limit to this request is 1000. Discord defaults the limit to 1.
1125    ///
1126    /// # Examples
1127    ///
1128    /// Get the first 10 members of guild `100` matching `Wumpus`:
1129    ///
1130    /// ```no_run
1131    /// use twilight_http::Client;
1132    /// use twilight_model::id::Id;
1133    ///
1134    /// # #[tokio::main]
1135    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1136    /// let client = Client::new("my token".to_owned());
1137    ///
1138    /// let guild_id = Id::new(100);
1139    /// let members = client
1140    ///     .search_guild_members(guild_id, "Wumpus")
1141    ///     .limit(10)
1142    ///     .await?;
1143    /// # Ok(()) }
1144    /// ```
1145    ///
1146    /// # Errors
1147    ///
1148    /// Returns an error of type [`ValidationErrorType::SearchGuildMembers`] if
1149    /// the limit is invalid.
1150    ///
1151    /// [`GUILD_MEMBERS`]: twilight_model::gateway::Intents::GUILD_MEMBERS
1152    /// [`ValidationErrorType::SearchGuildMembers`]: twilight_validate::request::ValidationErrorType::SearchGuildMembers
1153    pub const fn search_guild_members<'a>(
1154        &'a self,
1155        guild_id: Id<GuildMarker>,
1156        query: &'a str,
1157    ) -> SearchGuildMembers<'a> {
1158        SearchGuildMembers::new(self, guild_id, query)
1159    }
1160
1161    /// Get a member of a guild, by their id.
1162    pub const fn guild_member(
1163        &self,
1164        guild_id: Id<GuildMarker>,
1165        user_id: Id<UserMarker>,
1166    ) -> GetMember<'_> {
1167        GetMember::new(self, guild_id, user_id)
1168    }
1169
1170    /// Add a user to a guild.
1171    ///
1172    /// An access token for the user with `guilds.join` scope is required. All
1173    /// other fields are optional. See [Discord Docs/Add Guild Member].
1174    ///
1175    /// # Errors
1176    ///
1177    /// Returns an error of type [`ValidationErrorType::Nickname`] if the
1178    /// nickname is too short or too long.
1179    ///
1180    /// [`ValidationErrorType::Nickname`]: twilight_validate::request::ValidationErrorType::Nickname
1181    /// [Discord Docs/Add Guild Member]: https://discord.com/developers/docs/resources/guild#add-guild-member
1182    pub const fn add_guild_member<'a>(
1183        &'a self,
1184        guild_id: Id<GuildMarker>,
1185        user_id: Id<UserMarker>,
1186        access_token: &'a str,
1187    ) -> AddGuildMember<'a> {
1188        AddGuildMember::new(self, guild_id, user_id, access_token)
1189    }
1190
1191    /// Kick a member from a guild.
1192    pub const fn remove_guild_member(
1193        &self,
1194        guild_id: Id<GuildMarker>,
1195        user_id: Id<UserMarker>,
1196    ) -> RemoveMember<'_> {
1197        RemoveMember::new(self, guild_id, user_id)
1198    }
1199
1200    /// Update a guild member.
1201    ///
1202    /// All fields are optional. See [Discord Docs/Modify Guild Member].
1203    ///
1204    /// # Examples
1205    ///
1206    /// Update a member's nickname to "pinky pie" and server mute them:
1207    ///
1208    /// ```no_run
1209    /// use std::env;
1210    /// use twilight_http::Client;
1211    /// use twilight_model::id::Id;
1212    ///
1213    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1214    /// let client = Client::new(env::var("DISCORD_TOKEN")?);
1215    /// let member = client
1216    ///     .update_guild_member(Id::new(1), Id::new(2))
1217    ///     .mute(true)
1218    ///     .nick(Some("pinkie pie"))
1219    ///     .await?
1220    ///     .model()
1221    ///     .await?;
1222    ///
1223    /// println!(
1224    ///     "user {} now has the nickname '{:?}'",
1225    ///     member.user.id, member.nick,
1226    /// );
1227    /// # Ok(()) }
1228    /// ```
1229    ///
1230    /// # Errors
1231    ///
1232    /// Returns an error of type [`ValidationErrorType::Nickname`] if the
1233    /// nickname length is too short or too long.
1234    ///
1235    /// [`ValidationErrorType::Nickname`]: twilight_validate::request::ValidationErrorType::Nickname
1236    /// [Discord Docs/Modify Guild Member]: https://discord.com/developers/docs/resources/guild#modify-guild-member
1237    pub const fn update_guild_member(
1238        &self,
1239        guild_id: Id<GuildMarker>,
1240        user_id: Id<UserMarker>,
1241    ) -> UpdateGuildMember<'_> {
1242        UpdateGuildMember::new(self, guild_id, user_id)
1243    }
1244
1245    /// Update the user's member in a guild.
1246    pub const fn update_current_member(
1247        &self,
1248        guild_id: Id<GuildMarker>,
1249    ) -> UpdateCurrentMember<'_> {
1250        UpdateCurrentMember::new(self, guild_id)
1251    }
1252
1253    /// Add a role to a member in a guild.
1254    ///
1255    /// # Examples
1256    ///
1257    /// In guild `1`, add role `2` to user `3`, for the reason `"test"`:
1258    ///
1259    /// ```no_run
1260    /// # use twilight_http::{request::AuditLogReason, Client};
1261    /// use twilight_model::id::Id;
1262    /// #
1263    /// # #[tokio::main]
1264    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1265    /// # let client = Client::new("my token".to_owned());
1266    /// #
1267    /// let guild_id = Id::new(1);
1268    /// let role_id = Id::new(2);
1269    /// let user_id = Id::new(3);
1270    ///
1271    /// client
1272    ///     .add_guild_member_role(guild_id, user_id, role_id)
1273    ///     .reason("test")
1274    ///     .await?;
1275    /// # Ok(()) }
1276    /// ```
1277    pub const fn add_guild_member_role(
1278        &self,
1279        guild_id: Id<GuildMarker>,
1280        user_id: Id<UserMarker>,
1281        role_id: Id<RoleMarker>,
1282    ) -> AddRoleToMember<'_> {
1283        AddRoleToMember::new(self, guild_id, user_id, role_id)
1284    }
1285
1286    /// Remove a role from a member in a guild, by id.
1287    pub const fn remove_guild_member_role(
1288        &self,
1289        guild_id: Id<GuildMarker>,
1290        user_id: Id<UserMarker>,
1291        role_id: Id<RoleMarker>,
1292    ) -> RemoveRoleFromMember<'_> {
1293        RemoveRoleFromMember::new(self, guild_id, user_id, role_id)
1294    }
1295
1296    /// Retrieves the onboarding data for a guild.
1297    pub const fn guild_onboarding(&self, guild_id: Id<GuildMarker>) -> GetGuildOnboarding<'_> {
1298        GetGuildOnboarding::new(self, guild_id)
1299    }
1300
1301    /// For public guilds, get the guild preview.
1302    ///
1303    /// This works even if the user is not in the guild.
1304    pub const fn guild_preview(&self, guild_id: Id<GuildMarker>) -> GetGuildPreview<'_> {
1305        GetGuildPreview::new(self, guild_id)
1306    }
1307
1308    /// Get the counts of guild members to be pruned.
1309    pub const fn guild_prune_count(&self, guild_id: Id<GuildMarker>) -> GetGuildPruneCount<'_> {
1310        GetGuildPruneCount::new(self, guild_id)
1311    }
1312
1313    /// Begin a guild prune.
1314    ///
1315    /// See [Discord Docs/Begin Guild Prune].
1316    ///
1317    /// [Discord Docs/Begin Guild Prune]: https://discord.com/developers/docs/resources/guild#begin-guild-prune
1318    pub const fn create_guild_prune(&self, guild_id: Id<GuildMarker>) -> CreateGuildPrune<'_> {
1319        CreateGuildPrune::new(self, guild_id)
1320    }
1321
1322    /// Get a guild's vanity url, if there is one.
1323    pub const fn guild_vanity_url(&self, guild_id: Id<GuildMarker>) -> GetGuildVanityUrl<'_> {
1324        GetGuildVanityUrl::new(self, guild_id)
1325    }
1326
1327    /// Get voice region data for the guild.
1328    ///
1329    /// Can return VIP servers if the guild is VIP-enabled.
1330    pub const fn guild_voice_regions(&self, guild_id: Id<GuildMarker>) -> GetGuildVoiceRegions<'_> {
1331        GetGuildVoiceRegions::new(self, guild_id)
1332    }
1333
1334    /// Get the webhooks of a guild.
1335    pub const fn guild_webhooks(&self, guild_id: Id<GuildMarker>) -> GetGuildWebhooks<'_> {
1336        GetGuildWebhooks::new(self, guild_id)
1337    }
1338
1339    /// Get the guild's welcome screen.
1340    ///
1341    /// If the welcome screen is not enabled, this requires the [`MANAGE_GUILD`]
1342    /// permission.
1343    ///
1344    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
1345    pub const fn guild_welcome_screen(
1346        &self,
1347        guild_id: Id<GuildMarker>,
1348    ) -> GetGuildWelcomeScreen<'_> {
1349        GetGuildWelcomeScreen::new(self, guild_id)
1350    }
1351
1352    /// Update the guild's welcome screen.
1353    ///
1354    /// Requires the [`MANAGE_GUILD`] permission.
1355    ///
1356    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
1357    pub const fn update_guild_welcome_screen(
1358        &self,
1359        guild_id: Id<GuildMarker>,
1360    ) -> UpdateGuildWelcomeScreen<'_> {
1361        UpdateGuildWelcomeScreen::new(self, guild_id)
1362    }
1363
1364    /// Get information about an invite by its code.
1365    ///
1366    /// If [`with_counts`] is called, the returned invite will contain
1367    /// approximate member counts.  If [`with_expiration`] is called, it will
1368    /// contain the expiration date.
1369    ///
1370    /// # Examples
1371    ///
1372    /// ```no_run
1373    /// # use twilight_http::Client;
1374    /// #
1375    /// # #[tokio::main]
1376    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1377    /// # let client = Client::new("my token".to_owned());
1378    /// #
1379    /// let invite = client.invite("code").with_counts().await?;
1380    /// # Ok(()) }
1381    /// ```
1382    ///
1383    /// [`with_counts`]: crate::request::channel::invite::GetInvite::with_counts
1384    /// [`with_expiration`]: crate::request::channel::invite::GetInvite::with_expiration
1385    pub const fn invite<'a>(&'a self, code: &'a str) -> GetInvite<'a> {
1386        GetInvite::new(self, code)
1387    }
1388
1389    /// Create an invite, with options.
1390    ///
1391    /// Requires the [`CREATE_INVITE`] permission.
1392    ///
1393    /// # Examples
1394    ///
1395    /// ```no_run
1396    /// # use twilight_http::Client;
1397    /// # use twilight_model::id::Id;
1398    /// #
1399    /// # #[tokio::main]
1400    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1401    /// # let client = Client::new("my token".to_owned());
1402    /// #
1403    /// let channel_id = Id::new(123);
1404    /// let invite = client.create_invite(channel_id).max_uses(3).await?;
1405    /// # Ok(()) }
1406    /// ```
1407    ///
1408    /// [`CREATE_INVITE`]: twilight_model::guild::Permissions::CREATE_INVITE
1409    pub const fn create_invite(&self, channel_id: Id<ChannelMarker>) -> CreateInvite<'_> {
1410        CreateInvite::new(self, channel_id)
1411    }
1412
1413    /// Delete an invite by its code.
1414    ///
1415    /// Requires the [`MANAGE_CHANNELS`] permission on the channel this invite
1416    /// belongs to, or [`MANAGE_GUILD`] to remove any invite across the guild.
1417    ///
1418    /// [`MANAGE_CHANNELS`]: twilight_model::guild::Permissions::MANAGE_CHANNELS
1419    /// [`MANAGE_GUILD`]: twilight_model::guild::Permissions::MANAGE_GUILD
1420    pub const fn delete_invite<'a>(&'a self, code: &'a str) -> DeleteInvite<'a> {
1421        DeleteInvite::new(self, code)
1422    }
1423
1424    /// Get a message by [`Id<ChannelMarker>`] and [`Id<MessageMarker>`].
1425    pub const fn message(
1426        &self,
1427        channel_id: Id<ChannelMarker>,
1428        message_id: Id<MessageMarker>,
1429    ) -> GetMessage<'_> {
1430        GetMessage::new(self, channel_id, message_id)
1431    }
1432
1433    /// Send a message to a channel.
1434    ///
1435    /// The message must include at least one of [`attachments`],
1436    /// [`components`], [`content`], [`embeds`], or [`sticker_ids`].
1437    ///
1438    /// # Example
1439    ///
1440    /// ```no_run
1441    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1442    /// use twilight_http::Client;
1443    /// use twilight_model::id::Id;
1444    ///
1445    /// let client = Client::new("my token".to_owned());
1446    ///
1447    /// let channel_id = Id::new(123);
1448    /// let message = client
1449    ///     .create_message(channel_id)
1450    ///     .content("Twilight is best pony")
1451    ///     .tts(true)
1452    ///     .await?;
1453    /// # Ok(()) }
1454    /// ```
1455    ///
1456    /// [`attachments`]: CreateMessage::attachments
1457    /// [`components`]: CreateMessage::components
1458    /// [`content`]: CreateMessage::content
1459    /// [`embeds`]: CreateMessage::embeds
1460    /// [`sticker_ids`]: CreateMessage::sticker_ids
1461    pub const fn create_message(&self, channel_id: Id<ChannelMarker>) -> CreateMessage<'_> {
1462        CreateMessage::new(self, channel_id)
1463    }
1464
1465    /// Delete a message by [`Id<ChannelMarker>`] and [`Id<MessageMarker>`].
1466    pub const fn delete_message(
1467        &self,
1468        channel_id: Id<ChannelMarker>,
1469        message_id: Id<MessageMarker>,
1470    ) -> DeleteMessage<'_> {
1471        DeleteMessage::new(self, channel_id, message_id)
1472    }
1473
1474    /// Delete messages by [`Id<ChannelMarker>`] and Vec<[`Id<MessageMarker>`]>.
1475    ///
1476    /// The vec count can be between 2 and 100. If the supplied
1477    /// [`Id<MessageMarker>`]s are invalid, they still count towards the lower
1478    /// and upper limits. This method will not delete messages older than two
1479    /// weeks. See [Discord Docs/Bulk Delete Messages].
1480    ///
1481    /// # Errors
1482    ///
1483    /// Returns an error of type
1484    /// [`ChannelValidationErrorType::BulkDeleteMessagesInvalid`] when the number of
1485    /// messages to delete in bulk is invalid.
1486    ///
1487    /// [Discord Docs/Bulk Delete Messages]: https://discord.com/developers/docs/resources/channel#bulk-delete-messages
1488    /// [`ChannelValidationErrorType::BulkDeleteMessagesInvalid`]: twilight_validate::channel::ChannelValidationErrorType::BulkDeleteMessagesInvalid
1489    pub fn delete_messages<'a>(
1490        &'a self,
1491        channel_id: Id<ChannelMarker>,
1492        message_ids: &'a [Id<MessageMarker>],
1493    ) -> DeleteMessages<'a> {
1494        DeleteMessages::new(self, channel_id, message_ids)
1495    }
1496
1497    /// Update a message by [`Id<ChannelMarker>`] and [`Id<MessageMarker>`].
1498    ///
1499    /// You can pass [`None`] to any of the methods to remove the associated
1500    /// field. Pass [`None`] to [`content`] to remove the content. You must
1501    /// ensure that the message still contains at least one of [`attachments`],
1502    /// [`components`], [`content`], [`embeds`], or stickers.
1503    ///
1504    /// # Examples
1505    ///
1506    /// Replace the content with `"test update"`:
1507    ///
1508    /// ```no_run
1509    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1510    /// use twilight_http::Client;
1511    /// use twilight_model::id::Id;
1512    ///
1513    /// let client = Client::new("my token".to_owned());
1514    /// client
1515    ///     .update_message(Id::new(1), Id::new(2))
1516    ///     .content(Some("test update"))
1517    ///     .await?;
1518    /// # Ok(()) }
1519    /// ```
1520    ///
1521    /// Remove the message's content:
1522    ///
1523    /// ```no_run
1524    /// # use twilight_http::Client;
1525    /// # use twilight_model::id::Id;
1526    /// #
1527    /// # #[tokio::main]
1528    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1529    /// # let client = Client::new("my token".to_owned());
1530    /// client
1531    ///     .update_message(Id::new(1), Id::new(2))
1532    ///     .content(None)
1533    ///     .await?;
1534    /// # Ok(()) }
1535    /// ```
1536    ///
1537    /// [`attachments`]: UpdateMessage::attachments
1538    /// [`components`]: UpdateMessage::components
1539    /// [`content`]: UpdateMessage::content
1540    /// [`embeds`]: UpdateMessage::embeds
1541    pub const fn update_message(
1542        &self,
1543        channel_id: Id<ChannelMarker>,
1544        message_id: Id<MessageMarker>,
1545    ) -> UpdateMessage<'_> {
1546        UpdateMessage::new(self, channel_id, message_id)
1547    }
1548
1549    /// Crosspost a message by [`Id<ChannelMarker>`] and [`Id<MessageMarker>`].
1550    pub const fn crosspost_message(
1551        &self,
1552        channel_id: Id<ChannelMarker>,
1553        message_id: Id<MessageMarker>,
1554    ) -> CrosspostMessage<'_> {
1555        CrosspostMessage::new(self, channel_id, message_id)
1556    }
1557
1558    /// Get the pins of a channel.
1559    pub const fn pins(&self, channel_id: Id<ChannelMarker>) -> GetPins<'_> {
1560        GetPins::new(self, channel_id)
1561    }
1562
1563    /// Create a new pin in a channel, by ID.
1564    pub const fn create_pin(
1565        &self,
1566        channel_id: Id<ChannelMarker>,
1567        message_id: Id<MessageMarker>,
1568    ) -> CreatePin<'_> {
1569        CreatePin::new(self, channel_id, message_id)
1570    }
1571
1572    /// Delete a pin in a channel, by ID.
1573    pub const fn delete_pin(
1574        &self,
1575        channel_id: Id<ChannelMarker>,
1576        message_id: Id<MessageMarker>,
1577    ) -> DeletePin<'_> {
1578        DeletePin::new(self, channel_id, message_id)
1579    }
1580
1581    /// Get a list of users that reacted to a message with an `emoji`.
1582    ///
1583    /// This endpoint is limited to 100 users maximum, so if a message has more than 100 reactions,
1584    /// requests must be chained until all reactions are retrieved.
1585    pub const fn reactions<'a>(
1586        &'a self,
1587        channel_id: Id<ChannelMarker>,
1588        message_id: Id<MessageMarker>,
1589        emoji: &'a RequestReactionType<'a>,
1590    ) -> GetReactions<'a> {
1591        GetReactions::new(self, channel_id, message_id, emoji)
1592    }
1593
1594    /// Create a reaction in a [`Id<ChannelMarker>`] on a [`Id<MessageMarker>`].
1595    ///
1596    /// The reaction must be a variant of [`RequestReactionType`].
1597    ///
1598    /// # Examples
1599    /// ```no_run
1600    /// # use twilight_http::{Client, request::channel::reaction::RequestReactionType};
1601    /// # use twilight_model::id::Id;
1602    /// #
1603    /// # #[tokio::main]
1604    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1605    /// # let client = Client::new("my token".to_owned());
1606    /// #
1607    /// let channel_id = Id::new(123);
1608    /// let message_id = Id::new(456);
1609    /// let emoji = RequestReactionType::Unicode { name: "🌃" };
1610    ///
1611    /// let reaction = client
1612    ///     .create_reaction(channel_id, message_id, &emoji)
1613    ///     .await?;
1614    /// # Ok(()) }
1615    /// ```
1616    pub const fn create_reaction<'a>(
1617        &'a self,
1618        channel_id: Id<ChannelMarker>,
1619        message_id: Id<MessageMarker>,
1620        emoji: &'a RequestReactionType<'a>,
1621    ) -> CreateReaction<'a> {
1622        CreateReaction::new(self, channel_id, message_id, emoji)
1623    }
1624
1625    /// Delete the current user's (`@me`) reaction on a message.
1626    pub const fn delete_current_user_reaction<'a>(
1627        &'a self,
1628        channel_id: Id<ChannelMarker>,
1629        message_id: Id<MessageMarker>,
1630        emoji: &'a RequestReactionType<'a>,
1631    ) -> DeleteReaction<'a> {
1632        DeleteReaction::new(self, channel_id, message_id, emoji, TargetUser::Current)
1633    }
1634
1635    /// Delete a reaction by a user on a message.
1636    pub const fn delete_reaction<'a>(
1637        &'a self,
1638        channel_id: Id<ChannelMarker>,
1639        message_id: Id<MessageMarker>,
1640        emoji: &'a RequestReactionType<'a>,
1641        user_id: Id<UserMarker>,
1642    ) -> DeleteReaction<'a> {
1643        DeleteReaction::new(self, channel_id, message_id, emoji, TargetUser::Id(user_id))
1644    }
1645
1646    /// Remove all reactions on a message of an emoji.
1647    pub const fn delete_all_reaction<'a>(
1648        &'a self,
1649        channel_id: Id<ChannelMarker>,
1650        message_id: Id<MessageMarker>,
1651        emoji: &'a RequestReactionType<'a>,
1652    ) -> DeleteAllReaction<'a> {
1653        DeleteAllReaction::new(self, channel_id, message_id, emoji)
1654    }
1655
1656    /// Delete all reactions by all users on a message.
1657    pub const fn delete_all_reactions(
1658        &self,
1659        channel_id: Id<ChannelMarker>,
1660        message_id: Id<MessageMarker>,
1661    ) -> DeleteAllReactions<'_> {
1662        DeleteAllReactions::new(self, channel_id, message_id)
1663    }
1664
1665    /// Fire a Typing Start event in the channel.
1666    pub const fn create_typing_trigger(
1667        &self,
1668        channel_id: Id<ChannelMarker>,
1669    ) -> CreateTypingTrigger<'_> {
1670        CreateTypingTrigger::new(self, channel_id)
1671    }
1672
1673    /// Create a DM channel with a user.
1674    pub const fn create_private_channel(
1675        &self,
1676        recipient_id: Id<UserMarker>,
1677    ) -> CreatePrivateChannel<'_> {
1678        CreatePrivateChannel::new(self, recipient_id)
1679    }
1680
1681    /// Get the roles of a guild.
1682    pub const fn roles(&self, guild_id: Id<GuildMarker>) -> GetGuildRoles<'_> {
1683        GetGuildRoles::new(self, guild_id)
1684    }
1685
1686    /// Get the role member counts of a guild.
1687    pub const fn role_member_counts(
1688        &self,
1689        guild_id: Id<GuildMarker>,
1690    ) -> GetGuildRoleMemberCounts<'_> {
1691        GetGuildRoleMemberCounts::new(self, guild_id)
1692    }
1693
1694    /// Get a role of a guild.
1695    pub const fn role(&self, guild_id: Id<GuildMarker>, role_id: Id<RoleMarker>) -> GetRole<'_> {
1696        GetRole::new(self, guild_id, role_id)
1697    }
1698
1699    /// Create a role in a guild.
1700    ///
1701    /// # Examples
1702    ///
1703    /// ```no_run
1704    /// # use twilight_http::Client;
1705    /// use twilight_model::id::Id;
1706    ///
1707    /// # #[tokio::main]
1708    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
1709    /// # let client = Client::new("my token".to_owned());
1710    /// let guild_id = Id::new(234);
1711    ///
1712    /// client
1713    ///     .create_role(guild_id)
1714    ///     .color(0xd90083)
1715    ///     .name("Bright Pink")
1716    ///     .await?;
1717    /// # Ok(()) }
1718    /// ```
1719    pub const fn create_role(&self, guild_id: Id<GuildMarker>) -> CreateRole<'_> {
1720        CreateRole::new(self, guild_id)
1721    }
1722
1723    /// Delete a role in a guild, by id.
1724    pub const fn delete_role(
1725        &self,
1726        guild_id: Id<GuildMarker>,
1727        role_id: Id<RoleMarker>,
1728    ) -> DeleteRole<'_> {
1729        DeleteRole::new(self, guild_id, role_id)
1730    }
1731
1732    /// Update a role by guild id and its id.
1733    pub const fn update_role(
1734        &self,
1735        guild_id: Id<GuildMarker>,
1736        role_id: Id<RoleMarker>,
1737    ) -> UpdateRole<'_> {
1738        UpdateRole::new(self, guild_id, role_id)
1739    }
1740
1741    /// Modify the position of the roles.
1742    ///
1743    /// The minimum amount of roles to modify, is a swap between two roles.
1744    pub const fn update_role_positions<'a>(
1745        &'a self,
1746        guild_id: Id<GuildMarker>,
1747        roles: &'a [RolePosition],
1748    ) -> UpdateRolePositions<'a> {
1749        UpdateRolePositions::new(self, guild_id, roles)
1750    }
1751
1752    /// Create a new stage instance associated with a stage channel.
1753    ///
1754    /// Requires the user to be a moderator of the stage channel.
1755    ///
1756    /// # Errors
1757    ///
1758    /// Returns an error of type [`ValidationError::StageTopic`] when the topic
1759    /// is not between 1 and 120 characters in length.
1760    ///
1761    /// [`ValidationError::StageTopic`]: twilight_validate::request::ValidationErrorType::StageTopic
1762    pub fn create_stage_instance<'a>(
1763        &'a self,
1764        channel_id: Id<ChannelMarker>,
1765        topic: &'a str,
1766    ) -> CreateStageInstance<'a> {
1767        CreateStageInstance::new(self, channel_id, topic)
1768    }
1769
1770    /// Gets the stage instance associated with a stage channel, if it exists.
1771    pub const fn stage_instance(&self, channel_id: Id<ChannelMarker>) -> GetStageInstance<'_> {
1772        GetStageInstance::new(self, channel_id)
1773    }
1774
1775    /// Update fields of an existing stage instance.
1776    ///
1777    /// Requires the user to be a moderator of the stage channel.
1778    pub const fn update_stage_instance(
1779        &self,
1780        channel_id: Id<ChannelMarker>,
1781    ) -> UpdateStageInstance<'_> {
1782        UpdateStageInstance::new(self, channel_id)
1783    }
1784
1785    /// Delete the stage instance of a stage channel.
1786    ///
1787    /// Requires the user to be a moderator of the stage channel.
1788    pub const fn delete_stage_instance(
1789        &self,
1790        channel_id: Id<ChannelMarker>,
1791    ) -> DeleteStageInstance<'_> {
1792        DeleteStageInstance::new(self, channel_id)
1793    }
1794
1795    /// Create a new guild based on a template.
1796    ///
1797    /// This endpoint can only be used by bots in less than 10 guilds.
1798    ///
1799    /// # Errors
1800    ///
1801    /// Returns an error of type [`ValidationErrorType::TemplateName`] if the
1802    /// name is invalid.
1803    ///
1804    /// [`ValidationErrorType::TemplateName`]: twilight_validate::request::ValidationErrorType::TemplateName
1805    pub fn create_guild_from_template<'a>(
1806        &'a self,
1807        template_code: &'a str,
1808        name: &'a str,
1809    ) -> CreateGuildFromTemplate<'a> {
1810        CreateGuildFromTemplate::new(self, template_code, name)
1811    }
1812
1813    /// Create a template from the current state of the guild.
1814    ///
1815    /// Requires the `MANAGE_GUILD` permission. The name must be at least 1 and
1816    /// at most 100 characters in length.
1817    ///
1818    /// # Errors
1819    ///
1820    /// Returns an error of type [`ValidationErrorType::TemplateName`] if the
1821    /// name is invalid.
1822    ///
1823    /// [`ValidationErrorType::TemplateName`]: twilight_validate::request::ValidationErrorType::TemplateName
1824    pub fn create_template<'a>(
1825        &'a self,
1826        guild_id: Id<GuildMarker>,
1827        name: &'a str,
1828    ) -> CreateTemplate<'a> {
1829        CreateTemplate::new(self, guild_id, name)
1830    }
1831
1832    /// Delete a template by ID and code.
1833    pub const fn delete_template<'a>(
1834        &'a self,
1835        guild_id: Id<GuildMarker>,
1836        template_code: &'a str,
1837    ) -> DeleteTemplate<'a> {
1838        DeleteTemplate::new(self, guild_id, template_code)
1839    }
1840
1841    /// Get a template by its code.
1842    pub const fn get_template<'a>(&'a self, template_code: &'a str) -> GetTemplate<'a> {
1843        GetTemplate::new(self, template_code)
1844    }
1845
1846    /// Get a list of templates in a guild, by ID.
1847    pub const fn get_templates(&self, guild_id: Id<GuildMarker>) -> GetTemplates<'_> {
1848        GetTemplates::new(self, guild_id)
1849    }
1850
1851    /// Sync a template to the current state of the guild, by ID and code.
1852    pub const fn sync_template<'a>(
1853        &'a self,
1854        guild_id: Id<GuildMarker>,
1855        template_code: &'a str,
1856    ) -> SyncTemplate<'a> {
1857        SyncTemplate::new(self, guild_id, template_code)
1858    }
1859
1860    /// Update the template's metadata, by ID and code.
1861    pub const fn update_template<'a>(
1862        &'a self,
1863        guild_id: Id<GuildMarker>,
1864        template_code: &'a str,
1865    ) -> UpdateTemplate<'a> {
1866        UpdateTemplate::new(self, guild_id, template_code)
1867    }
1868
1869    /// Returns all active threads in the guild.
1870    ///
1871    /// Includes public and private threads. Threads are ordered by their ID in
1872    /// descending order.
1873    ///
1874    /// # Examples
1875    ///
1876    /// ```no_run
1877    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
1878    /// use twilight_http::Client;
1879    /// use twilight_model::id::Id;
1880    ///
1881    /// let client = Client::new("my token".to_owned());
1882    /// let guild_id = Id::new(234);
1883    ///
1884    /// let threads = client.active_threads(guild_id).await?.model().await?;
1885    /// # Ok(()) }
1886    /// ```
1887    pub const fn active_threads(&self, guild_id: Id<GuildMarker>) -> GetActiveThreads<'_> {
1888        GetActiveThreads::new(self, guild_id)
1889    }
1890
1891    /// Add another member to a thread.
1892    ///
1893    /// Requires the ability to send messages in the thread, and that the thread
1894    /// is not archived.
1895    pub const fn add_thread_member(
1896        &self,
1897        channel_id: Id<ChannelMarker>,
1898        user_id: Id<UserMarker>,
1899    ) -> AddThreadMember<'_> {
1900        AddThreadMember::new(self, channel_id, user_id)
1901    }
1902
1903    /// Start a thread in a forum channel.
1904    pub const fn create_forum_thread<'a>(
1905        &'a self,
1906        channel_id: Id<ChannelMarker>,
1907        name: &'a str,
1908    ) -> CreateForumThread<'a> {
1909        CreateForumThread::new(self, channel_id, name)
1910    }
1911
1912    /// Start a thread that is not connected to a message.
1913    ///
1914    /// Automatic archive durations are not locked behind the guild's boost
1915    /// level.
1916    ///
1917    /// To make a [`PrivateThread`], the guild must also have the
1918    /// `PRIVATE_THREADS` feature.
1919    ///
1920    /// # Errors
1921    ///
1922    /// Returns an error of type [`NameInvalid`] if the channel's name's length is
1923    /// incorrect.
1924    ///
1925    /// Returns an error of type [`TypeInvalid`] if the channel is not a thread.
1926    ///
1927    /// [`NameInvalid`]: twilight_validate::channel::ChannelValidationErrorType::NameInvalid
1928    /// [`PrivateThread`]: twilight_model::channel::ChannelType::PrivateThread
1929    /// [`TypeInvalid`]: twilight_validate::channel::ChannelValidationErrorType::TypeInvalid
1930    pub fn create_thread<'a>(
1931        &'a self,
1932        channel_id: Id<ChannelMarker>,
1933        name: &'a str,
1934        kind: ChannelType,
1935    ) -> CreateThread<'a> {
1936        CreateThread::new(self, channel_id, name, kind)
1937    }
1938
1939    /// Create a new thread from an existing message.
1940    ///
1941    /// When called on a [`GuildText`] channel, this creates a
1942    /// [`PublicThread`].
1943    ///
1944    /// When called on a [`GuildAnnouncement`] channel, this creates a
1945    /// [`AnnouncementThread`].
1946    ///
1947    /// Automatic archive durations are not locked behind the guild's boost
1948    /// level.
1949    ///
1950    /// The thread's ID will be the same as its parent message. This ensures
1951    /// only one thread can be created per message.
1952    ///
1953    /// # Errors
1954    ///
1955    /// Returns an error of type [`NameInvalid`] if the channel's name's length is
1956    /// incorrect.
1957    ///
1958    /// Returns an error of type [`TypeInvalid`] if the channel is not a thread.
1959    ///
1960    /// [`AnnouncementThread`]: twilight_model::channel::ChannelType::AnnouncementThread
1961    /// [`GuildAnnouncement`]: twilight_model::channel::ChannelType::GuildAnnouncement
1962    /// [`GuildText`]: twilight_model::channel::ChannelType::GuildText
1963    /// [`NameInvalid`]: twilight_validate::channel::ChannelValidationErrorType::NameInvalid
1964    /// [`PublicThread`]: twilight_model::channel::ChannelType::PublicThread
1965    /// [`TypeInvalid`]: twilight_validate::channel::ChannelValidationErrorType::TypeInvalid
1966    pub fn create_thread_from_message<'a>(
1967        &'a self,
1968        channel_id: Id<ChannelMarker>,
1969        message_id: Id<MessageMarker>,
1970        name: &'a str,
1971    ) -> CreateThreadFromMessage<'a> {
1972        CreateThreadFromMessage::new(self, channel_id, message_id, name)
1973    }
1974
1975    /// Add the current user to a thread.
1976    pub const fn join_thread(&self, channel_id: Id<ChannelMarker>) -> JoinThread<'_> {
1977        JoinThread::new(self, channel_id)
1978    }
1979
1980    /// Returns archived private threads in the channel that the current user
1981    /// has joined.
1982    ///
1983    /// Threads are ordered by their ID in descending order.
1984    pub const fn joined_private_archived_threads(
1985        &self,
1986        channel_id: Id<ChannelMarker>,
1987    ) -> GetJoinedPrivateArchivedThreads<'_> {
1988        GetJoinedPrivateArchivedThreads::new(self, channel_id)
1989    }
1990
1991    /// Remove the current user from a thread.
1992    ///
1993    /// Requires that the thread is not archived.
1994    pub const fn leave_thread(&self, channel_id: Id<ChannelMarker>) -> LeaveThread<'_> {
1995        LeaveThread::new(self, channel_id)
1996    }
1997
1998    /// Returns archived private threads in the channel.
1999    ///
2000    /// Requires both [`READ_MESSAGE_HISTORY`] and [`MANAGE_THREADS`].
2001    ///
2002    /// [`MANAGE_THREADS`]: twilight_model::guild::Permissions::MANAGE_THREADS
2003    /// [`READ_MESSAGE_HISTORY`]: twilight_model::guild::Permissions::READ_MESSAGE_HISTORY
2004    pub const fn private_archived_threads(
2005        &self,
2006        channel_id: Id<ChannelMarker>,
2007    ) -> GetPrivateArchivedThreads<'_> {
2008        GetPrivateArchivedThreads::new(self, channel_id)
2009    }
2010
2011    /// Returns archived public threads in the channel.
2012    ///
2013    /// Requires the [`READ_MESSAGE_HISTORY`] permission.
2014    ///
2015    /// Threads are ordered by [`archive_timestamp`] in descending order.
2016    ///
2017    /// When called in a [`GuildText`] channel, returns [`PublicThread`]s.
2018    ///
2019    /// When called in a [`GuildAnnouncement`] channel, returns [`AnnouncementThread`]s.
2020    ///
2021    /// [`AnnouncementThread`]: twilight_model::channel::ChannelType::AnnouncementThread
2022    /// [`archive_timestamp`]: twilight_model::channel::thread::ThreadMetadata::archive_timestamp
2023    /// [`GuildAnnouncement`]: twilight_model::channel::ChannelType::GuildAnnouncement
2024    /// [`GuildText`]: twilight_model::channel::ChannelType::GuildText
2025    /// [`PublicThread`]: twilight_model::channel::ChannelType::PublicThread
2026    /// [`READ_MESSAGE_HISTORY`]: twilight_model::guild::Permissions::READ_MESSAGE_HISTORY
2027    pub const fn public_archived_threads(
2028        &self,
2029        channel_id: Id<ChannelMarker>,
2030    ) -> GetPublicArchivedThreads<'_> {
2031        GetPublicArchivedThreads::new(self, channel_id)
2032    }
2033
2034    /// Remove another member from a thread.
2035    ///
2036    /// Requires that the thread is not archived.
2037    ///
2038    /// Requires the [`MANAGE_THREADS`] permission, unless both the thread is a
2039    /// [`PrivateThread`], and the current user is the creator of the
2040    /// thread.
2041    ///
2042    /// [`MANAGE_THREADS`]: twilight_model::guild::Permissions::MANAGE_THREADS
2043    /// [`PrivateThread`]: twilight_model::channel::ChannelType::PrivateThread
2044    pub const fn remove_thread_member(
2045        &self,
2046        channel_id: Id<ChannelMarker>,
2047        user_id: Id<UserMarker>,
2048    ) -> RemoveThreadMember<'_> {
2049        RemoveThreadMember::new(self, channel_id, user_id)
2050    }
2051
2052    /// Returns a [`ThreadMember`] in a thread.
2053    ///
2054    /// [`ThreadMember`]: twilight_model::channel::thread::ThreadMember
2055    pub const fn thread_member(
2056        &self,
2057        channel_id: Id<ChannelMarker>,
2058        user_id: Id<UserMarker>,
2059    ) -> GetThreadMember<'_> {
2060        GetThreadMember::new(self, channel_id, user_id)
2061    }
2062
2063    /// Returns the [`ThreadMember`]s of the thread.
2064    ///
2065    /// [`ThreadMember`]: twilight_model::channel::thread::ThreadMember
2066    pub const fn thread_members(&self, channel_id: Id<ChannelMarker>) -> GetThreadMembers<'_> {
2067        GetThreadMembers::new(self, channel_id)
2068    }
2069
2070    /// Update a thread.
2071    ///
2072    /// All fields are optional. The minimum length of the name is 1 UTF-16
2073    /// characters and the maximum is 100 UTF-16 characters.
2074    pub const fn update_thread(&self, channel_id: Id<ChannelMarker>) -> UpdateThread<'_> {
2075        UpdateThread::new(self, channel_id)
2076    }
2077
2078    /// Get a user's information by id.
2079    pub const fn user(&self, user_id: Id<UserMarker>) -> GetUser<'_> {
2080        GetUser::new(self, user_id)
2081    }
2082
2083    /// Get voice state of a user in a guild.
2084    ///
2085    /// # Caveats
2086    ///
2087    /// - User must already have joined a voice/stage channel in this guild.
2088    pub const fn user_voice_state(
2089        &self,
2090        guild_id: Id<GuildMarker>,
2091        user_id: Id<UserMarker>,
2092    ) -> GetUserVoiceState<'_> {
2093        GetUserVoiceState::new(self, guild_id, user_id)
2094    }
2095
2096    /// Update another user's voice state.
2097    ///
2098    /// # Caveats
2099    ///
2100    /// - `channel_id` must currently point to a stage channel.
2101    /// - User must already have joined `channel_id`.
2102    pub const fn update_user_voice_state(
2103        &self,
2104        guild_id: Id<GuildMarker>,
2105        user_id: Id<UserMarker>,
2106        channel_id: Id<ChannelMarker>,
2107    ) -> UpdateUserVoiceState<'_> {
2108        UpdateUserVoiceState::new(self, guild_id, user_id, channel_id)
2109    }
2110
2111    /// Get a list of voice regions that can be used when creating a guild.
2112    pub const fn voice_regions(&self) -> GetVoiceRegions<'_> {
2113        GetVoiceRegions::new(self)
2114    }
2115
2116    /// Get a webhook by ID.
2117    pub const fn webhook(&self, id: Id<WebhookMarker>) -> GetWebhook<'_> {
2118        GetWebhook::new(self, id)
2119    }
2120
2121    /// Create a webhook in a channel.
2122    ///
2123    /// # Examples
2124    ///
2125    /// ```no_run
2126    /// # use twilight_http::Client;
2127    /// # use twilight_model::id::Id;
2128    /// #
2129    /// # #[tokio::main]
2130    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2131    /// # let client = Client::new("my token".to_owned());
2132    /// let channel_id = Id::new(123);
2133    ///
2134    /// let webhook = client.create_webhook(channel_id, "Twily Bot").await?;
2135    /// # Ok(()) }
2136    /// ```
2137    ///
2138    /// # Errors
2139    ///
2140    /// Returns an error of type [`WebhookUsername`] if the webhook's name is
2141    /// invalid.
2142    ///
2143    /// [`WebhookUsername`]: twilight_validate::request::ValidationErrorType::WebhookUsername
2144    pub fn create_webhook<'a>(
2145        &'a self,
2146        channel_id: Id<ChannelMarker>,
2147        name: &'a str,
2148    ) -> CreateWebhook<'a> {
2149        CreateWebhook::new(self, channel_id, name)
2150    }
2151
2152    /// Delete a webhook by its ID.
2153    pub const fn delete_webhook(&self, id: Id<WebhookMarker>) -> DeleteWebhook<'_> {
2154        DeleteWebhook::new(self, id)
2155    }
2156
2157    /// Update a webhook by ID.
2158    pub const fn update_webhook(&self, webhook_id: Id<WebhookMarker>) -> UpdateWebhook<'_> {
2159        UpdateWebhook::new(self, webhook_id)
2160    }
2161
2162    /// Update a webhook, with a token, by ID.
2163    pub const fn update_webhook_with_token<'a>(
2164        &'a self,
2165        webhook_id: Id<WebhookMarker>,
2166        token: &'a str,
2167    ) -> UpdateWebhookWithToken<'a> {
2168        UpdateWebhookWithToken::new(self, webhook_id, token)
2169    }
2170
2171    /// Execute a webhook, sending a message to its channel.
2172    ///
2173    /// The message must include at least one of [`attachments`], [`components`]
2174    /// [`content`], or [`embeds`].
2175    ///
2176    /// # Examples
2177    ///
2178    /// ```no_run
2179    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
2180    /// use twilight_http::Client;
2181    /// use twilight_model::id::Id;
2182    ///
2183    /// let client = Client::new("my token".to_owned());
2184    /// let id = Id::new(432);
2185    ///
2186    /// let webhook = client
2187    ///     .execute_webhook(id, "webhook token")
2188    ///     .content("Pinkie...")
2189    ///     .await?;
2190    /// # Ok(()) }
2191    /// ```
2192    ///
2193    /// [`attachments`]: ExecuteWebhook::attachments
2194    /// [`components`]: ExecuteWebhook::components
2195    /// [`content`]: ExecuteWebhook::content
2196    /// [`embeds`]: ExecuteWebhook::embeds
2197    pub const fn execute_webhook<'a>(
2198        &'a self,
2199        webhook_id: Id<WebhookMarker>,
2200        token: &'a str,
2201    ) -> ExecuteWebhook<'a> {
2202        ExecuteWebhook::new(self, webhook_id, token)
2203    }
2204
2205    /// Get a webhook message by webhook ID, token, and message ID.
2206    pub const fn webhook_message<'a>(
2207        &'a self,
2208        webhook_id: Id<WebhookMarker>,
2209        token: &'a str,
2210        message_id: Id<MessageMarker>,
2211    ) -> GetWebhookMessage<'a> {
2212        GetWebhookMessage::new(self, webhook_id, token, message_id)
2213    }
2214
2215    /// Update a message executed by a webhook.
2216    ///
2217    /// You can pass [`None`] to any of the methods to remove the associated
2218    /// field. Pass [`None`] to [`content`] to remove the content. You must
2219    /// ensure that the message still contains at least one of [`attachments`],
2220    /// [`components`], [`content`], or [`embeds`].
2221    ///
2222    /// # Examples
2223    ///
2224    /// ```no_run
2225    /// # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
2226    /// use twilight_http::Client;
2227    /// use twilight_model::id::Id;
2228    ///
2229    /// let client = Client::new("token".to_owned());
2230    /// client
2231    ///     .update_webhook_message(Id::new(1), "token here", Id::new(2))
2232    ///     .content(Some("new message content"))
2233    ///     .await?;
2234    /// # Ok(()) }
2235    /// ```
2236    ///
2237    /// [`attachments`]: UpdateWebhookMessage::attachments
2238    /// [`components`]: UpdateWebhookMessage::components
2239    /// [`content`]: UpdateWebhookMessage::content
2240    /// [`embeds`]: UpdateWebhookMessage::embeds
2241    pub const fn update_webhook_message<'a>(
2242        &'a self,
2243        webhook_id: Id<WebhookMarker>,
2244        token: &'a str,
2245        message_id: Id<MessageMarker>,
2246    ) -> UpdateWebhookMessage<'a> {
2247        UpdateWebhookMessage::new(self, webhook_id, token, message_id)
2248    }
2249
2250    /// Delete a message executed by a webhook.
2251    ///
2252    /// # Examples
2253    ///
2254    /// ```no_run
2255    /// # use twilight_http::Client;
2256    /// use twilight_model::id::Id;
2257    ///
2258    /// # #[tokio::main]
2259    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2260    /// # let client = Client::new("token".to_owned());
2261    /// client
2262    ///     .delete_webhook_message(Id::new(1), "token here", Id::new(2))
2263    ///     .await?;
2264    /// # Ok(()) }
2265    /// ```
2266    pub const fn delete_webhook_message<'a>(
2267        &'a self,
2268        webhook_id: Id<WebhookMarker>,
2269        token: &'a str,
2270        message_id: Id<MessageMarker>,
2271    ) -> DeleteWebhookMessage<'a> {
2272        DeleteWebhookMessage::new(self, webhook_id, token, message_id)
2273    }
2274
2275    /// Delete a scheduled event in a guild.
2276    ///
2277    /// # Examples
2278    ///
2279    /// ```no_run
2280    /// # use twilight_http::Client;
2281    /// # use twilight_model::id::Id;
2282    /// # #[tokio::main]
2283    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2284    /// # let client = Client::new("token".to_owned());
2285    /// let guild_id = Id::new(1);
2286    /// let scheduled_event_id = Id::new(2);
2287    ///
2288    /// client
2289    ///     .delete_guild_scheduled_event(guild_id, scheduled_event_id)
2290    ///     .await?;
2291    /// # Ok(()) }
2292    /// ```
2293    pub const fn delete_guild_scheduled_event(
2294        &self,
2295        guild_id: Id<GuildMarker>,
2296        scheduled_event_id: Id<ScheduledEventMarker>,
2297    ) -> DeleteGuildScheduledEvent<'_> {
2298        DeleteGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
2299    }
2300
2301    /// Create a scheduled event in a guild.
2302    ///
2303    /// Once a guild is selected, you must choose one of three event types to
2304    /// create. The request builders will ensure you provide the correct data to
2305    /// Discord. See [Discord Docs/Create Guild Scheduled Event].
2306    ///
2307    /// The name must be between 1 and 100 characters in length. For external
2308    /// events, the location must be between 1 and 100 characters in length.
2309    ///
2310    /// # Examples
2311    ///
2312    /// Create an event in a stage instance:
2313    ///
2314    /// ```no_run
2315    /// # use twilight_http::Client;
2316    /// use twilight_model::{guild::scheduled_event::PrivacyLevel, id::Id, util::Timestamp};
2317    /// # #[tokio::main]
2318    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2319    /// # let client = Client::new("token".to_owned());
2320    /// let guild_id = Id::new(1);
2321    /// let channel_id = Id::new(2);
2322    /// let garfield_start_time = Timestamp::parse("2022-01-01T14:00:00+00:00")?;
2323    ///
2324    /// client
2325    ///     .create_guild_scheduled_event(guild_id, PrivacyLevel::GuildOnly)
2326    ///     .stage_instance(
2327    ///         channel_id,
2328    ///         "Garfield Appreciation Hour",
2329    ///         &garfield_start_time,
2330    ///     )
2331    ///     .description("Discuss: How important is Garfield to You?")
2332    ///     .await?;
2333    /// # Ok(()) }
2334    /// ```
2335    ///
2336    /// Create an external event:
2337    ///
2338    /// ```no_run
2339    /// # use twilight_http::Client;
2340    /// use twilight_model::{guild::scheduled_event::PrivacyLevel, id::Id, util::Timestamp};
2341    /// # #[tokio::main]
2342    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2343    /// # let client = Client::new("token".to_owned());
2344    /// let guild_id = Id::new(1);
2345    /// let garfield_con_start_time = Timestamp::parse("2022-01-04T08:00:00+00:00")?;
2346    /// let garfield_con_end_time = Timestamp::parse("2022-01-06T17:00:00+00:00")?;
2347    ///
2348    /// client
2349    ///     .create_guild_scheduled_event(guild_id, PrivacyLevel::GuildOnly)
2350    ///     .external(
2351    ///         "Garfield Con 2022",
2352    ///         "Baltimore Convention Center",
2353    ///         &garfield_con_start_time,
2354    ///         &garfield_con_end_time,
2355    ///     )
2356    ///     .description(
2357    ///         "In a spiritual successor to BronyCon, Garfield fans from \
2358    /// around the globe celebrate all things related to the loveable cat.",
2359    ///     )
2360    ///     .await?;
2361    /// # Ok(()) }
2362    /// ```
2363    ///
2364    /// [Discord Docs/Create Guild Scheduled Event]: https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event
2365    pub const fn create_guild_scheduled_event(
2366        &self,
2367        guild_id: Id<GuildMarker>,
2368        privacy_level: PrivacyLevel,
2369    ) -> CreateGuildScheduledEvent<'_> {
2370        CreateGuildScheduledEvent::new(self, guild_id, privacy_level)
2371    }
2372
2373    /// Get a scheduled event in a guild.
2374    pub const fn guild_scheduled_event(
2375        &self,
2376        guild_id: Id<GuildMarker>,
2377        scheduled_event_id: Id<ScheduledEventMarker>,
2378    ) -> GetGuildScheduledEvent<'_> {
2379        GetGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
2380    }
2381
2382    /// Get a list of users subscribed to a scheduled event.
2383    ///
2384    /// Users are returned in ascending order by `user_id`. [`before`] and
2385    /// [`after`] both take a user id. If both are specified, only [`before`] is
2386    /// respected. The default [`limit`] is 100. See
2387    /// [Discord Docs/Get Guild Scheduled Event Users].
2388    ///
2389    /// [`after`]: GetGuildScheduledEventUsers::after
2390    /// [`before`]: GetGuildScheduledEventUsers::before
2391    /// [`limit`]: GetGuildScheduledEventUsers::limit
2392    /// [Discord Docs/Get Guild Scheduled Event Users]: https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users
2393    pub const fn guild_scheduled_event_users(
2394        &self,
2395        guild_id: Id<GuildMarker>,
2396        scheduled_event_id: Id<ScheduledEventMarker>,
2397    ) -> GetGuildScheduledEventUsers<'_> {
2398        GetGuildScheduledEventUsers::new(self, guild_id, scheduled_event_id)
2399    }
2400
2401    /// Get a list of scheduled events in a guild.
2402    pub const fn guild_scheduled_events(
2403        &self,
2404        guild_id: Id<GuildMarker>,
2405    ) -> GetGuildScheduledEvents<'_> {
2406        GetGuildScheduledEvents::new(self, guild_id)
2407    }
2408
2409    /// Update a scheduled event in a guild.
2410    ///
2411    /// This endpoint supports changing the type of event. When changing the
2412    /// entity type to either [`EntityType::StageInstance`] or
2413    /// [`EntityType::Voice`], an [`Id<ChannelMarker>`] must be provided if it
2414    /// does not already exist.
2415    ///
2416    /// When changing the entity type to [`EntityType::External`], the
2417    /// `channel_id` field is cleared and the [`channel_id`] method has no
2418    /// effect. Additionally, you must set a location with [`location`].
2419    ///
2420    /// [`EntityType::External`]: twilight_model::guild::scheduled_event::EntityType::External
2421    /// [`EntityType::StageInstance`]: twilight_model::guild::scheduled_event::EntityType::StageInstance
2422    /// [`EntityType::Voice`]: twilight_model::guild::scheduled_event::EntityType::Voice
2423    /// [`channel_id`]: UpdateGuildScheduledEvent::channel_id
2424    /// [`location`]: UpdateGuildScheduledEvent::location
2425    pub const fn update_guild_scheduled_event(
2426        &self,
2427        guild_id: Id<GuildMarker>,
2428        scheduled_event_id: Id<ScheduledEventMarker>,
2429    ) -> UpdateGuildScheduledEvent<'_> {
2430        UpdateGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
2431    }
2432
2433    /// Returns a single sticker by its ID.
2434    ///
2435    /// # Examples
2436    ///
2437    /// ```no_run
2438    /// use twilight_http::Client;
2439    /// use twilight_model::id::Id;
2440    ///
2441    /// # #[tokio::main]
2442    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2443    /// let client = Client::new("my token".to_owned());
2444    ///
2445    /// let id = Id::new(123);
2446    /// let sticker = client.sticker(id).await?.model().await?;
2447    ///
2448    /// println!("{sticker:#?}");
2449    /// # Ok(()) }
2450    /// ```
2451    pub const fn sticker(&self, sticker_id: Id<StickerMarker>) -> GetSticker<'_> {
2452        GetSticker::new(self, sticker_id)
2453    }
2454
2455    /// Returns a list of sticker packs available to Nitro subscribers.
2456    ///
2457    /// # Examples
2458    ///
2459    /// ```no_run
2460    /// use twilight_http::Client;
2461    ///
2462    /// # #[tokio::main]
2463    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2464    /// let client = Client::new("my token".to_owned());
2465    ///
2466    /// let packs = client.nitro_sticker_packs().await?.model().await?;
2467    ///
2468    /// println!("{}", packs.sticker_packs.len());
2469    /// # Ok(()) }
2470    /// ```
2471    pub const fn nitro_sticker_packs(&self) -> GetNitroStickerPacks<'_> {
2472        GetNitroStickerPacks::new(self)
2473    }
2474
2475    /// Returns a list of stickers in a guild.
2476    ///
2477    /// # Examples
2478    ///
2479    /// ```no_run
2480    /// use twilight_http::Client;
2481    /// use twilight_model::id::Id;
2482    ///
2483    /// # #[tokio::main]
2484    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2485    /// let client = Client::new("my token".to_owned());
2486    ///
2487    /// let guild_id = Id::new(1);
2488    /// let stickers = client.guild_stickers(guild_id).await?.models().await?;
2489    ///
2490    /// println!("{}", stickers.len());
2491    /// # Ok(()) }
2492    /// ```
2493    pub const fn guild_stickers(&self, guild_id: Id<GuildMarker>) -> GetGuildStickers<'_> {
2494        GetGuildStickers::new(self, guild_id)
2495    }
2496
2497    /// Returns a guild sticker by the guild's ID and the sticker's ID.
2498    ///
2499    /// # Examples
2500    ///
2501    /// ```no_run
2502    /// use twilight_http::Client;
2503    /// use twilight_model::id::Id;
2504    ///
2505    /// # #[tokio::main]
2506    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2507    /// let client = Client::new("my token".to_owned());
2508    ///
2509    /// let guild_id = Id::new(1);
2510    /// let sticker_id = Id::new(2);
2511    /// let sticker = client
2512    ///     .guild_sticker(guild_id, sticker_id)
2513    ///     .await?
2514    ///     .model()
2515    ///     .await?;
2516    ///
2517    /// println!("{sticker:#?}");
2518    /// # Ok(()) }
2519    /// ```
2520    pub const fn guild_sticker(
2521        &self,
2522        guild_id: Id<GuildMarker>,
2523        sticker_id: Id<StickerMarker>,
2524    ) -> GetGuildSticker<'_> {
2525        GetGuildSticker::new(self, guild_id, sticker_id)
2526    }
2527
2528    /// Creates a sticker in a guild, and returns the created sticker.
2529    ///
2530    /// # Examples
2531    ///
2532    /// ```no_run
2533    /// use twilight_http::Client;
2534    /// use twilight_model::id::Id;
2535    ///
2536    /// # #[tokio::main]
2537    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2538    /// let client = Client::new("my token".to_owned());
2539    ///
2540    /// let guild_id = Id::new(1);
2541    /// let sticker = client
2542    ///     .create_guild_sticker(
2543    ///         guild_id,
2544    ///         &"sticker name",
2545    ///         &"sticker description",
2546    ///         &"sticker,tags",
2547    ///         &[23, 23, 23, 23],
2548    ///     )
2549    ///     .await?
2550    ///     .model()
2551    ///     .await?;
2552    ///
2553    /// println!("{sticker:#?}");
2554    /// # Ok(()) }
2555    /// ```
2556    ///
2557    /// # Errors
2558    ///
2559    /// Returns an error of type [`DescriptionInvalid`] if the length is invalid.
2560    ///
2561    /// Returns an error of type [`NameInvalid`] if the length is invalid.
2562    ///
2563    /// Returns an error of type [`TagsInvalid`] if the length is invalid.
2564    ///
2565    /// [`DescriptionInvalid`]: twilight_validate::sticker::StickerValidationErrorType::DescriptionInvalid
2566    /// [`NameInvalid`]: twilight_validate::sticker::StickerValidationErrorType::NameInvalid
2567    /// [`TagsInvalid`]: twilight_validate::sticker::StickerValidationErrorType::TagsInvalid
2568    pub fn create_guild_sticker<'a>(
2569        &'a self,
2570        guild_id: Id<GuildMarker>,
2571        name: &'a str,
2572        description: &'a str,
2573        tags: &'a str,
2574        file: &'a [u8],
2575    ) -> CreateGuildSticker<'a> {
2576        CreateGuildSticker::new(self, guild_id, name, description, tags, file)
2577    }
2578
2579    /// Updates a sticker in a guild, and returns the updated sticker.
2580    ///
2581    /// # Examples
2582    ///
2583    /// ```no_run
2584    /// use twilight_http::Client;
2585    /// use twilight_model::id::Id;
2586    ///
2587    /// # #[tokio::main]
2588    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2589    /// let client = Client::new("my token".to_owned());
2590    ///
2591    /// let guild_id = Id::new(1);
2592    /// let sticker_id = Id::new(2);
2593    /// let sticker = client
2594    ///     .update_guild_sticker(guild_id, sticker_id)
2595    ///     .description("new description")
2596    ///     .await?
2597    ///     .model()
2598    ///     .await?;
2599    ///
2600    /// println!("{sticker:#?}");
2601    /// # Ok(()) }
2602    /// ```
2603    pub const fn update_guild_sticker(
2604        &self,
2605        guild_id: Id<GuildMarker>,
2606        sticker_id: Id<StickerMarker>,
2607    ) -> UpdateGuildSticker<'_> {
2608        UpdateGuildSticker::new(self, guild_id, sticker_id)
2609    }
2610
2611    /// Deletes a guild sticker by the ID of the guild and its ID.
2612    ///
2613    /// # Examples
2614    ///
2615    /// ```no_run
2616    /// use twilight_http::Client;
2617    /// use twilight_model::id::Id;
2618    ///
2619    /// # #[tokio::main]
2620    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2621    /// let client = Client::new("my token".to_owned());
2622    ///
2623    /// let guild_id = Id::new(1);
2624    /// let sticker_id = Id::new(2);
2625    ///
2626    /// client.delete_guild_sticker(guild_id, sticker_id).await?;
2627    /// # Ok(()) }
2628    /// ```
2629    pub const fn delete_guild_sticker(
2630        &self,
2631        guild_id: Id<GuildMarker>,
2632        sticker_id: Id<StickerMarker>,
2633    ) -> DeleteGuildSticker<'_> {
2634        DeleteGuildSticker::new(self, guild_id, sticker_id)
2635    }
2636
2637    /// Creates a test entitlement to a given SKU for a given guild or user. Discord
2638    /// will act as though that user or guild has entitlement to your premium offering.
2639    ///
2640    /// # Examples
2641    ///
2642    /// ```no_run
2643    /// use twilight_http::{Client, request::application::monetization::CreateTestEntitlementOwner};
2644    /// use twilight_model::id::Id;
2645    ///
2646    /// # #[tokio::main]
2647    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2648    /// let client = Client::new("my token".to_owned());
2649    ///
2650    /// let application_id = Id::new(1);
2651    /// let sku_id = Id::new(2);
2652    /// let owner = CreateTestEntitlementOwner::Guild(Id::new(3));
2653    ///
2654    /// client.create_test_entitlement(
2655    ///    application_id,
2656    ///    sku_id,
2657    ///    owner,
2658    /// ).await?;
2659    ///
2660    /// # Ok(()) }
2661    pub const fn create_test_entitlement(
2662        &self,
2663        application_id: Id<ApplicationMarker>,
2664        sku_id: Id<SkuMarker>,
2665        owner: CreateTestEntitlementOwner,
2666    ) -> CreateTestEntitlement<'_> {
2667        CreateTestEntitlement::new(self, application_id, sku_id, owner)
2668    }
2669
2670    /// For One-Time Purchase consumable SKUs, marks a given entitlement for the
2671    /// user as consumed.
2672    ///
2673    /// The entitlement will have `consumed` as true when listing entitlements.
2674    pub const fn consume_entitlement(
2675        &self,
2676        application_id: Id<ApplicationMarker>,
2677        entitlement_id: Id<EntitlementMarker>,
2678    ) -> ConsumeEntitlement<'_> {
2679        ConsumeEntitlement::new(self, application_id, entitlement_id)
2680    }
2681
2682    /// Ends a poll in a channel.
2683    ///
2684    /// # Examples
2685    ///
2686    /// ```no_run
2687    /// use twilight_http::Client;
2688    /// use twilight_model::id::Id;
2689    ///
2690    /// # #[tokio::main]
2691    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2692    /// let client = Client::new("my token".to_owned());
2693    ///
2694    /// let channel_id = Id::new(1);
2695    /// let message_id = Id::new(2);
2696    ///
2697    /// client.end_poll(channel_id, message_id).await?;
2698    /// # Ok(()) }
2699    /// ```
2700    pub const fn end_poll(
2701        &self,
2702        channel_id: Id<ChannelMarker>,
2703        message_id: Id<MessageMarker>,
2704    ) -> EndPoll<'_> {
2705        EndPoll::new(self, channel_id, message_id)
2706    }
2707
2708    /// Deletes a currently-active test entitlement. Discord will act as though that user or
2709    /// guild no longer has entitlement to your premium offering.
2710    ///
2711    /// # Examples
2712    ///
2713    /// ```no_run
2714    /// use twilight_http::Client;
2715    /// use twilight_model::id::Id;
2716    ///
2717    /// # #[tokio::main]
2718    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2719    /// let client = Client::new("my token".to_owned());
2720    ///
2721    /// let application_id = Id::new(1);
2722    /// let entitlement_id = Id::new(2);
2723    ///
2724    /// client.delete_test_entitlement(
2725    ///   application_id,
2726    ///   entitlement_id,
2727    /// ).await?;
2728    ///
2729    /// # Ok(()) }
2730    pub const fn delete_test_entitlement(
2731        &self,
2732        application_id: Id<ApplicationMarker>,
2733        entitlement_id: Id<EntitlementMarker>,
2734    ) -> DeleteTestEntitlement<'_> {
2735        DeleteTestEntitlement::new(self, application_id, entitlement_id)
2736    }
2737
2738    /// /// Get the voters for an answer in a poll.
2739    ///
2740    /// # Examples
2741    ///
2742    /// ```no_run
2743    /// use twilight_http::Client;
2744    /// use twilight_model::id::Id;
2745    ///
2746    /// # #[tokio::main]
2747    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2748    /// let client = Client::new("my token".to_owned());
2749    ///
2750    /// let channel_id = Id::new(1);
2751    /// let message_id = Id::new(2);
2752    /// let answer_id = 1;
2753    ///
2754    /// let voters = client.get_answer_voters(channel_id, message_id, answer_id).await?;
2755    ///
2756    /// println!("{:?}", voters);
2757    /// # Ok(()) }
2758    pub const fn get_answer_voters(
2759        &self,
2760        channel_id: Id<ChannelMarker>,
2761        message_id: Id<MessageMarker>,
2762        answer_id: u8,
2763    ) -> GetAnswerVoters<'_> {
2764        GetAnswerVoters::new(self, channel_id, message_id, answer_id)
2765    }
2766
2767    /// Returns all SKUs for a given application.
2768    ///
2769    /// # Examples
2770    ///
2771    /// ```no_run
2772    /// use twilight_http::Client;
2773    /// use twilight_model::id::Id;
2774    ///
2775    /// # #[tokio::main]
2776    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2777    /// let client = Client::new("my token".to_owned());
2778    ///
2779    /// let application_id = Id::new(1);
2780    ///
2781    /// let skus = client.get_skus(application_id).await?;
2782    ///
2783    /// # Ok(()) }
2784    pub const fn get_skus(&self, application_id: Id<ApplicationMarker>) -> GetSKUs<'_> {
2785        GetSKUs::new(self, application_id)
2786    }
2787
2788    /// Returns all subscriptions containing the SKU, filtered by user.
2789    pub const fn get_sku_subscriptions(&self, sku_id: Id<SkuMarker>) -> GetSKUSubscriptions<'_> {
2790        GetSKUSubscriptions::new(self, sku_id)
2791    }
2792
2793    /// Get a subscription by SKU ID and Subscription ID.
2794    pub const fn get_sku_subscription(
2795        &self,
2796        sku_id: Id<SkuMarker>,
2797        subscription_id: Id<SubscriptionMarker>,
2798    ) -> GetSKUSubscription<'_> {
2799        GetSKUSubscription::new(self, sku_id, subscription_id)
2800    }
2801
2802    /// Gets all emojis associated with an application
2803    ///
2804    /// # Examples
2805    ///
2806    /// ```no_run
2807    /// use twilight_http::Client;
2808    /// use twilight_model::id::Id;
2809    ///
2810    /// # #[tokio::main]
2811    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2812    /// let client = Client::new("my token".to_owned());
2813    ///
2814    /// let application_id = Id::new(1);
2815    ///
2816    /// let emojis = client.get_application_emojis(application_id).await?;
2817    ///
2818    /// # Ok(()) }
2819    /// ```
2820    pub const fn get_application_emojis(
2821        &self,
2822        application_id: Id<ApplicationMarker>,
2823    ) -> ListApplicationEmojis<'_> {
2824        ListApplicationEmojis::new(self, application_id)
2825    }
2826
2827    /// Adds an emoji to an application
2828    ///
2829    /// Needs to be base64 encoded and prefixed and tagged.
2830    /// Can be up to 128x128 in size
2831    ///
2832    /// # Examples
2833    ///
2834    /// ```no_run
2835    /// use twilight_http::Client;
2836    /// use twilight_model::id::Id;
2837    ///
2838    /// # #[tokio::main]
2839    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2840    /// let client = Client::new("my token".to_owned());
2841    ///
2842    /// let application_id = Id::new(1);
2843    ///
2844    /// client
2845    ///     .add_application_emoji(application_id, "name", "data:image/png;base64,image_data")
2846    ///     .await?;
2847    ///
2848    /// # Ok(()) }
2849    /// ```
2850    pub const fn add_application_emoji<'a>(
2851        &'a self,
2852        application_id: Id<ApplicationMarker>,
2853        name: &'a str,
2854        image: &'a str,
2855    ) -> AddApplicationEmoji<'a> {
2856        AddApplicationEmoji::new(self, application_id, name, image)
2857    }
2858
2859    /// Updates an emoji associated with an application.
2860    ///
2861    /// # Examples
2862    ///
2863    /// ```no_run
2864    /// use twilight_http::Client;
2865    /// use twilight_model::id::Id;
2866    ///
2867    /// # #[tokio::main]
2868    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2869    /// let client = Client::new("my token".to_owned());
2870    ///
2871    /// let application_id = Id::new(1);
2872    /// let emoji_id = Id::new(2);
2873    ///
2874    /// client
2875    ///     .update_application_emoji(application_id, emoji_id, "new emoji name")
2876    ///     .await?;
2877    ///
2878    /// # Ok(()) }
2879    /// ```
2880    pub const fn update_application_emoji<'a>(
2881        &'a self,
2882        application_id: Id<ApplicationMarker>,
2883        emoji_id: Id<EmojiMarker>,
2884        name: &'a str,
2885    ) -> UpdateApplicationEmoji<'a> {
2886        UpdateApplicationEmoji::new(self, application_id, emoji_id, name)
2887    }
2888
2889    /// Deletes an emoji associated with an application.
2890    ///
2891    /// # Examples
2892    ///
2893    /// ```no_run
2894    /// use twilight_http::Client;
2895    /// use twilight_model::id::Id;
2896    ///
2897    /// # #[tokio::main]
2898    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
2899    /// let client = Client::new("my token".to_owned());
2900    ///
2901    /// let application_id = Id::new(1);
2902    /// let emoji_id = Id::new(2);
2903    ///
2904    /// client
2905    ///     .delete_application_emoji(application_id, emoji_id)
2906    ///     .await?;
2907    ///
2908    /// # Ok(()) }
2909    /// ```
2910    pub const fn delete_application_emoji(
2911        &self,
2912        application_id: Id<ApplicationMarker>,
2913        emoji_id: Id<EmojiMarker>,
2914    ) -> DeleteApplicationEmoji<'_> {
2915        DeleteApplicationEmoji::new(self, application_id, emoji_id)
2916    }
2917
2918    /// Execute a request, returning a future resolving to a [`Response`].
2919    ///
2920    /// # Errors
2921    ///
2922    /// Returns an [`ErrorType::Unauthorized`] error type if the configured
2923    /// token has become invalid due to expiration, revocation, etc.
2924    ///
2925    /// [`Response`]: super::response::Response
2926    pub fn request<T>(&self, request: Request) -> ResponseFuture<T> {
2927        match self.try_request::<T>(request) {
2928            Ok(future) => future,
2929            Err(source) => ResponseFuture::error(source),
2930        }
2931    }
2932
2933    fn try_request<T>(&self, request: Request) -> Result<ResponseFuture<T>, Error> {
2934        if let Some(token_invalidated) = self.token_invalidated.as_ref()
2935            && token_invalidated.load(Ordering::Relaxed)
2936        {
2937            return Err(Error {
2938                kind: ErrorType::Unauthorized,
2939                source: None,
2940            });
2941        }
2942
2943        let Request {
2944            body,
2945            form,
2946            headers: req_headers,
2947            method,
2948            mut path,
2949            use_authorization_token,
2950        } = request;
2951
2952        let protocol = if self.use_http { "http" } else { "https" };
2953        let host = self.proxy.as_deref().unwrap_or("discord.com");
2954
2955        let url = format!("{protocol}://{host}/api/v{API_VERSION}/{path}");
2956
2957        let mut builder = hyper::Request::builder().method(method.name()).uri(&url);
2958
2959        if use_authorization_token && let Some(token) = self.token.as_deref() {
2960            let value = HeaderValue::from_str(token).map_err(|source| {
2961                let name = AUTHORIZATION.to_string();
2962
2963                Error {
2964                    kind: ErrorType::CreatingHeader { name },
2965                    source: Some(Box::new(source)),
2966                }
2967            })?;
2968
2969            if let Some(headers) = builder.headers_mut() {
2970                headers.insert(AUTHORIZATION, value);
2971            }
2972        }
2973
2974        if let Some(headers) = builder.headers_mut() {
2975            if let Some(form) = &form {
2976                headers.insert(CONTENT_LENGTH, HeaderValue::from(form.len()));
2977                if let Ok(content_type) = HeaderValue::try_from(form.content_type()) {
2978                    headers.insert(CONTENT_TYPE, content_type);
2979                }
2980            } else if let Some(bytes) = &body {
2981                headers.insert(CONTENT_LENGTH, HeaderValue::from(bytes.len()));
2982                headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
2983            } else if matches!(method, Method::Put | Method::Post | Method::Patch) {
2984                headers.insert(CONTENT_LENGTH, HeaderValue::from(0));
2985            }
2986
2987            #[cfg(feature = "decompression")]
2988            headers.insert(
2989                hyper::header::ACCEPT_ENCODING,
2990                HeaderValue::from_static("br"),
2991            );
2992
2993            headers.insert(USER_AGENT, HeaderValue::from_static(TWILIGHT_USER_AGENT));
2994
2995            if let Some(req_headers) = req_headers {
2996                for (maybe_name, value) in req_headers {
2997                    if let Some(name) = maybe_name {
2998                        headers.insert(name, value);
2999                    }
3000                }
3001            }
3002
3003            if let Some(default_headers) = &self.default_headers {
3004                for (name, value) in default_headers {
3005                    headers.insert(name, value.clone());
3006                }
3007            }
3008        }
3009
3010        let try_req = if let Some(form) = form {
3011            builder.body(Full::from(form.build()))
3012        } else if let Some(bytes) = body {
3013            builder.body(Full::from(bytes))
3014        } else {
3015            builder.body(Full::default())
3016        };
3017
3018        let http_request = try_req.map_err(|source| Error {
3019            kind: ErrorType::BuildingRequest,
3020            source: Some(Box::new(source)),
3021        })?;
3022
3023        // For requests that don't use an authorization token we don't need to
3024        // remember whether the token is invalid. This may be for requests such
3025        // as webhooks and interactions.
3026        let invalid_token = use_authorization_token
3027            .then(|| self.token_invalidated.clone())
3028            .flatten();
3029
3030        if let Some(i) = path.find('?') {
3031            path.truncate(i);
3032        }
3033        let response = ResponseFuture::new(
3034            self.http.clone(),
3035            invalid_token,
3036            http_request,
3037            tracing::info_span!("request", method = method.name(), path),
3038            self.timeout,
3039            self.ratelimiter.clone(),
3040            Endpoint { method, path },
3041        );
3042
3043        Ok(response)
3044    }
3045}
3046
3047#[cfg(test)]
3048mod tests {
3049    use super::Client;
3050
3051    #[test]
3052    fn client_debug_with_token() {
3053        assert!(
3054            format!("{:?}", Client::new("Bot foo".to_owned())).contains("token: Some(<redacted>)")
3055        );
3056        assert!(format!("{:?}", Client::builder().build()).contains("token: None"));
3057    }
3058}