twilight_http/client/
mod.rs

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