twilight_http/client/
mod.rs

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