Skip to main content

twilight_http/client/
mod.rs

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