Skip to main content

twilight_http/client/
mod.rs

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