mod builder;
pub(crate) mod connector;
mod interaction;
pub use self::{builder::ClientBuilder, interaction::InteractionClient};
use crate::request::{
application::{
emoji::{
AddApplicationEmoji, DeleteApplicationEmoji, ListApplicationEmojis,
UpdateApplicationEmoji,
},
monetization::{
CreateTestEntitlement, CreateTestEntitlementOwner, DeleteTestEntitlement,
GetEntitlements, GetSKUs,
},
},
guild::user::{GetCurrentUserVoiceState, GetUserVoiceState},
};
#[allow(deprecated)]
use crate::{
API_VERSION,
client::connector::Connector,
error::{Error, ErrorType},
request::{
GetCurrentAuthorizationInformation, GetGateway, GetUserApplicationInfo, GetVoiceRegions,
Method, Request, UpdateCurrentUserApplication,
channel::{
CreatePin, CreateTypingTrigger, DeleteChannel, DeleteChannelPermission, DeletePin,
FollowNewsChannel, GetChannel, GetPins, UpdateChannel, UpdateChannelPermission,
invite::{CreateInvite, DeleteInvite, GetChannelInvites, GetInvite},
message::{
CreateMessage, CrosspostMessage, DeleteMessage, DeleteMessages, GetChannelMessages,
GetMessage, UpdateMessage,
},
reaction::{
CreateReaction, DeleteAllReaction, DeleteAllReactions, DeleteReaction,
GetReactions, RequestReactionType, delete_reaction::TargetUser,
},
stage::{
CreateStageInstance, DeleteStageInstance, GetStageInstance, UpdateStageInstance,
},
thread::{
AddThreadMember, CreateForumThread, CreateThread, CreateThreadFromMessage,
GetJoinedPrivateArchivedThreads, GetPrivateArchivedThreads,
GetPublicArchivedThreads, GetThreadMember, GetThreadMembers, JoinThread,
LeaveThread, RemoveThreadMember, UpdateThread,
},
webhook::{
CreateWebhook, DeleteWebhook, DeleteWebhookMessage, ExecuteWebhook,
GetChannelWebhooks, GetWebhook, GetWebhookMessage, UpdateWebhook,
UpdateWebhookMessage, UpdateWebhookWithToken,
},
},
guild::{
CreateGuildChannel, CreateGuildPrune, DeleteGuild, GetActiveThreads, GetAuditLog,
GetGuild, GetGuildChannels, GetGuildInvites, GetGuildOnboarding, GetGuildPreview,
GetGuildPruneCount, GetGuildVanityUrl, GetGuildVoiceRegions, GetGuildWebhooks,
GetGuildWelcomeScreen, GetGuildWidget, GetGuildWidgetSettings, UpdateCurrentMember,
UpdateGuild, UpdateGuildChannelPositions, UpdateGuildMfa, UpdateGuildWelcomeScreen,
UpdateGuildWidgetSettings,
auto_moderation::{
CreateAutoModerationRule, DeleteAutoModerationRule, GetAutoModerationRule,
GetGuildAutoModerationRules, UpdateAutoModerationRule,
},
ban::{CreateBan, DeleteBan, GetBan, GetBans},
emoji::{CreateEmoji, DeleteEmoji, GetEmoji, GetEmojis, UpdateEmoji},
integration::{DeleteGuildIntegration, GetGuildIntegrations},
member::{
AddGuildMember, AddRoleToMember, GetGuildMembers, GetMember, RemoveMember,
RemoveRoleFromMember, SearchGuildMembers, UpdateGuildMember,
},
role::{
CreateRole, DeleteRole, GetGuildRoleMemberCounts, GetGuildRoles, GetRole,
UpdateRole, UpdateRolePositions,
},
sticker::{
CreateGuildSticker, DeleteGuildSticker, GetGuildSticker, GetGuildStickers,
UpdateGuildSticker,
},
update_guild_onboarding::{UpdateGuildOnboarding, UpdateGuildOnboardingFields},
user::{UpdateCurrentUserVoiceState, UpdateUserVoiceState},
},
poll::{EndPoll, GetAnswerVoters},
scheduled_event::{
CreateGuildScheduledEvent, DeleteGuildScheduledEvent, GetGuildScheduledEvent,
GetGuildScheduledEventUsers, GetGuildScheduledEvents, UpdateGuildScheduledEvent,
},
sticker::{GetNitroStickerPacks, GetSticker},
template::{
CreateGuildFromTemplate, CreateTemplate, DeleteTemplate, GetTemplate, GetTemplates,
SyncTemplate, UpdateTemplate,
},
user::{
CreatePrivateChannel, GetCurrentUser, GetCurrentUserConnections,
GetCurrentUserGuildMember, GetCurrentUserGuilds, GetUser, LeaveGuild,
UpdateCurrentUser,
},
},
response::ResponseFuture,
};
use http::header::{
AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE, HeaderMap, HeaderValue, USER_AGENT,
};
use http_body_util::Full;
use hyper::body::Bytes;
use hyper_util::client::legacy::Client as HyperClient;
use std::{
fmt::{Debug, Formatter, Result as FmtResult},
ops::Deref,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
time::Duration,
};
use twilight_http_ratelimiting::{Endpoint, RateLimiter};
use twilight_model::{
channel::{ChannelType, message::AllowedMentions},
guild::{
MfaLevel, RolePosition, auto_moderation::AutoModerationEventType,
scheduled_event::PrivacyLevel,
},
http::{channel_position::Position, permission_overwrite::PermissionOverwrite},
id::{
Id,
marker::{
ApplicationMarker, AutoModerationRuleMarker, ChannelMarker, EmojiMarker,
EntitlementMarker, GuildMarker, IntegrationMarker, MessageMarker, RoleMarker,
ScheduledEventMarker, SkuMarker, StickerMarker, UserMarker, WebhookMarker,
},
},
};
const TWILIGHT_USER_AGENT: &str = concat!(
"DiscordBot (",
env!("CARGO_PKG_HOMEPAGE"),
", ",
env!("CARGO_PKG_VERSION"),
") Twilight-rs",
);
#[derive(Default)]
struct Token {
inner: Box<str>,
}
impl Token {
const fn new(token: Box<str>) -> Self {
Self { inner: token }
}
}
impl Debug for Token {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str("<redacted>")
}
}
impl Deref for Token {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Debug)]
pub struct Client {
pub(crate) default_allowed_mentions: Option<AllowedMentions>,
default_headers: Option<HeaderMap>,
http: HyperClient<Connector, Full<Bytes>>,
proxy: Option<Box<str>>,
ratelimiter: Option<RateLimiter>,
timeout: Duration,
token_invalidated: Option<Arc<AtomicBool>>,
token: Option<Token>,
use_http: bool,
}
impl Client {
pub fn new(token: String) -> Self {
ClientBuilder::default().token(token).build()
}
pub fn builder() -> ClientBuilder {
ClientBuilder::new()
}
pub fn token(&self) -> Option<&str> {
self.token.as_deref()
}
pub const fn interaction(
&self,
application_id: Id<ApplicationMarker>,
) -> InteractionClient<'_> {
InteractionClient::new(self, application_id)
}
pub const fn default_allowed_mentions(&self) -> Option<&AllowedMentions> {
self.default_allowed_mentions.as_ref()
}
pub const fn ratelimiter(&self) -> Option<&RateLimiter> {
self.ratelimiter.as_ref()
}
pub const fn auto_moderation_rule(
&self,
guild_id: Id<GuildMarker>,
auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
) -> GetAutoModerationRule<'_> {
GetAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
}
pub const fn auto_moderation_rules(
&self,
guild_id: Id<GuildMarker>,
) -> GetGuildAutoModerationRules<'_> {
GetGuildAutoModerationRules::new(self, guild_id)
}
pub const fn create_auto_moderation_rule<'a>(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
event_type: AutoModerationEventType,
) -> CreateAutoModerationRule<'a> {
CreateAutoModerationRule::new(self, guild_id, name, event_type)
}
pub const fn delete_auto_moderation_rule(
&self,
guild_id: Id<GuildMarker>,
auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
) -> DeleteAutoModerationRule<'_> {
DeleteAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
}
pub const fn update_auto_moderation_rule(
&self,
guild_id: Id<GuildMarker>,
auto_moderation_rule_id: Id<AutoModerationRuleMarker>,
) -> UpdateAutoModerationRule<'_> {
UpdateAutoModerationRule::new(self, guild_id, auto_moderation_rule_id)
}
pub const fn audit_log(&self, guild_id: Id<GuildMarker>) -> GetAuditLog<'_> {
GetAuditLog::new(self, guild_id)
}
pub const fn bans(&self, guild_id: Id<GuildMarker>) -> GetBans<'_> {
GetBans::new(self, guild_id)
}
pub const fn ban(&self, guild_id: Id<GuildMarker>, user_id: Id<UserMarker>) -> GetBan<'_> {
GetBan::new(self, guild_id, user_id)
}
pub const fn create_ban(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> CreateBan<'_> {
CreateBan::new(self, guild_id, user_id)
}
pub const fn delete_ban(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> DeleteBan<'_> {
DeleteBan::new(self, guild_id, user_id)
}
pub const fn channel(&self, channel_id: Id<ChannelMarker>) -> GetChannel<'_> {
GetChannel::new(self, channel_id)
}
pub const fn delete_channel(&self, channel_id: Id<ChannelMarker>) -> DeleteChannel<'_> {
DeleteChannel::new(self, channel_id)
}
pub const fn update_channel(&self, channel_id: Id<ChannelMarker>) -> UpdateChannel<'_> {
UpdateChannel::new(self, channel_id)
}
pub const fn follow_news_channel(
&self,
channel_id: Id<ChannelMarker>,
webhook_channel_id: Id<ChannelMarker>,
) -> FollowNewsChannel<'_> {
FollowNewsChannel::new(self, channel_id, webhook_channel_id)
}
pub const fn channel_invites(&self, channel_id: Id<ChannelMarker>) -> GetChannelInvites<'_> {
GetChannelInvites::new(self, channel_id)
}
pub const fn channel_messages(&self, channel_id: Id<ChannelMarker>) -> GetChannelMessages<'_> {
GetChannelMessages::new(self, channel_id)
}
pub const fn delete_channel_permission(
&self,
channel_id: Id<ChannelMarker>,
) -> DeleteChannelPermission<'_> {
DeleteChannelPermission::new(self, channel_id)
}
pub const fn update_channel_permission(
&self,
channel_id: Id<ChannelMarker>,
permission_overwrite: &PermissionOverwrite,
) -> UpdateChannelPermission<'_> {
UpdateChannelPermission::new(self, channel_id, permission_overwrite)
}
pub const fn channel_webhooks(&self, channel_id: Id<ChannelMarker>) -> GetChannelWebhooks<'_> {
GetChannelWebhooks::new(self, channel_id)
}
pub const fn current_user(&self) -> GetCurrentUser<'_> {
GetCurrentUser::new(self)
}
pub const fn current_user_guild_member(
&self,
guild_id: Id<GuildMarker>,
) -> GetCurrentUserGuildMember<'_> {
GetCurrentUserGuildMember::new(self, guild_id)
}
pub const fn current_authorization(&self) -> GetCurrentAuthorizationInformation<'_> {
GetCurrentAuthorizationInformation::new(self)
}
pub const fn current_user_application(&self) -> GetUserApplicationInfo<'_> {
GetUserApplicationInfo::new(self)
}
pub const fn update_current_user_application(&self) -> UpdateCurrentUserApplication<'_> {
UpdateCurrentUserApplication::new(self)
}
pub const fn update_current_user(&self) -> UpdateCurrentUser<'_> {
UpdateCurrentUser::new(self)
}
pub const fn current_user_voice_state(
&self,
guild_id: Id<GuildMarker>,
) -> GetCurrentUserVoiceState<'_> {
GetCurrentUserVoiceState::new(self, guild_id)
}
pub const fn update_current_user_voice_state(
&self,
guild_id: Id<GuildMarker>,
) -> UpdateCurrentUserVoiceState<'_> {
UpdateCurrentUserVoiceState::new(self, guild_id)
}
pub const fn current_user_connections(&self) -> GetCurrentUserConnections<'_> {
GetCurrentUserConnections::new(self)
}
pub const fn current_user_guilds(&self) -> GetCurrentUserGuilds<'_> {
GetCurrentUserGuilds::new(self)
}
pub const fn emojis(&self, guild_id: Id<GuildMarker>) -> GetEmojis<'_> {
GetEmojis::new(self, guild_id)
}
pub const fn entitlements(&self, application_id: Id<ApplicationMarker>) -> GetEntitlements<'_> {
GetEntitlements::new(self, application_id)
}
pub const fn emoji(
&self,
guild_id: Id<GuildMarker>,
emoji_id: Id<EmojiMarker>,
) -> GetEmoji<'_> {
GetEmoji::new(self, guild_id, emoji_id)
}
pub const fn create_emoji<'a>(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
image: &'a str,
) -> CreateEmoji<'a> {
CreateEmoji::new(self, guild_id, name, image)
}
pub const fn delete_emoji(
&self,
guild_id: Id<GuildMarker>,
emoji_id: Id<EmojiMarker>,
) -> DeleteEmoji<'_> {
DeleteEmoji::new(self, guild_id, emoji_id)
}
pub const fn update_emoji(
&self,
guild_id: Id<GuildMarker>,
emoji_id: Id<EmojiMarker>,
) -> UpdateEmoji<'_> {
UpdateEmoji::new(self, guild_id, emoji_id)
}
pub const fn gateway(&self) -> GetGateway<'_> {
GetGateway::new(self)
}
pub const fn guild(&self, guild_id: Id<GuildMarker>) -> GetGuild<'_> {
GetGuild::new(self, guild_id)
}
pub const fn delete_guild(&self, guild_id: Id<GuildMarker>) -> DeleteGuild<'_> {
DeleteGuild::new(self, guild_id)
}
pub const fn update_guild(&self, guild_id: Id<GuildMarker>) -> UpdateGuild<'_> {
UpdateGuild::new(self, guild_id)
}
pub const fn leave_guild(&self, guild_id: Id<GuildMarker>) -> LeaveGuild<'_> {
LeaveGuild::new(self, guild_id)
}
pub const fn guild_channels(&self, guild_id: Id<GuildMarker>) -> GetGuildChannels<'_> {
GetGuildChannels::new(self, guild_id)
}
pub fn create_guild_channel<'a>(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
) -> CreateGuildChannel<'a> {
CreateGuildChannel::new(self, guild_id, name)
}
pub const fn update_guild_onboarding(
&self,
guild_id: Id<GuildMarker>,
fields: UpdateGuildOnboardingFields,
) -> UpdateGuildOnboarding<'_> {
UpdateGuildOnboarding::new(self, guild_id, fields)
}
pub const fn update_guild_channel_positions<'a>(
&'a self,
guild_id: Id<GuildMarker>,
channel_positions: &'a [Position],
) -> UpdateGuildChannelPositions<'a> {
UpdateGuildChannelPositions::new(self, guild_id, channel_positions)
}
pub const fn guild_widget(&self, guild_id: Id<GuildMarker>) -> GetGuildWidget<'_> {
GetGuildWidget::new(self, guild_id)
}
pub const fn guild_widget_settings(
&self,
guild_id: Id<GuildMarker>,
) -> GetGuildWidgetSettings<'_> {
GetGuildWidgetSettings::new(self, guild_id)
}
pub const fn update_guild_widget_settings(
&self,
guild_id: Id<GuildMarker>,
) -> UpdateGuildWidgetSettings<'_> {
UpdateGuildWidgetSettings::new(self, guild_id)
}
pub const fn guild_integrations(&self, guild_id: Id<GuildMarker>) -> GetGuildIntegrations<'_> {
GetGuildIntegrations::new(self, guild_id)
}
pub const fn delete_guild_integration(
&self,
guild_id: Id<GuildMarker>,
integration_id: Id<IntegrationMarker>,
) -> DeleteGuildIntegration<'_> {
DeleteGuildIntegration::new(self, guild_id, integration_id)
}
pub const fn guild_invites(&self, guild_id: Id<GuildMarker>) -> GetGuildInvites<'_> {
GetGuildInvites::new(self, guild_id)
}
pub const fn update_guild_mfa(
&self,
guild_id: Id<GuildMarker>,
level: MfaLevel,
) -> UpdateGuildMfa<'_> {
UpdateGuildMfa::new(self, guild_id, level)
}
pub const fn guild_members(&self, guild_id: Id<GuildMarker>) -> GetGuildMembers<'_> {
GetGuildMembers::new(self, guild_id)
}
pub const fn search_guild_members<'a>(
&'a self,
guild_id: Id<GuildMarker>,
query: &'a str,
) -> SearchGuildMembers<'a> {
SearchGuildMembers::new(self, guild_id, query)
}
pub const fn guild_member(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> GetMember<'_> {
GetMember::new(self, guild_id, user_id)
}
pub const fn add_guild_member<'a>(
&'a self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
access_token: &'a str,
) -> AddGuildMember<'a> {
AddGuildMember::new(self, guild_id, user_id, access_token)
}
pub const fn remove_guild_member(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> RemoveMember<'_> {
RemoveMember::new(self, guild_id, user_id)
}
pub const fn update_guild_member(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> UpdateGuildMember<'_> {
UpdateGuildMember::new(self, guild_id, user_id)
}
pub const fn update_current_member(
&self,
guild_id: Id<GuildMarker>,
) -> UpdateCurrentMember<'_> {
UpdateCurrentMember::new(self, guild_id)
}
pub const fn add_guild_member_role(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
role_id: Id<RoleMarker>,
) -> AddRoleToMember<'_> {
AddRoleToMember::new(self, guild_id, user_id, role_id)
}
pub const fn remove_guild_member_role(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
role_id: Id<RoleMarker>,
) -> RemoveRoleFromMember<'_> {
RemoveRoleFromMember::new(self, guild_id, user_id, role_id)
}
pub const fn guild_onboarding(&self, guild_id: Id<GuildMarker>) -> GetGuildOnboarding<'_> {
GetGuildOnboarding::new(self, guild_id)
}
pub const fn guild_preview(&self, guild_id: Id<GuildMarker>) -> GetGuildPreview<'_> {
GetGuildPreview::new(self, guild_id)
}
pub const fn guild_prune_count(&self, guild_id: Id<GuildMarker>) -> GetGuildPruneCount<'_> {
GetGuildPruneCount::new(self, guild_id)
}
pub const fn create_guild_prune(&self, guild_id: Id<GuildMarker>) -> CreateGuildPrune<'_> {
CreateGuildPrune::new(self, guild_id)
}
pub const fn guild_vanity_url(&self, guild_id: Id<GuildMarker>) -> GetGuildVanityUrl<'_> {
GetGuildVanityUrl::new(self, guild_id)
}
pub const fn guild_voice_regions(&self, guild_id: Id<GuildMarker>) -> GetGuildVoiceRegions<'_> {
GetGuildVoiceRegions::new(self, guild_id)
}
pub const fn guild_webhooks(&self, guild_id: Id<GuildMarker>) -> GetGuildWebhooks<'_> {
GetGuildWebhooks::new(self, guild_id)
}
pub const fn guild_welcome_screen(
&self,
guild_id: Id<GuildMarker>,
) -> GetGuildWelcomeScreen<'_> {
GetGuildWelcomeScreen::new(self, guild_id)
}
pub const fn update_guild_welcome_screen(
&self,
guild_id: Id<GuildMarker>,
) -> UpdateGuildWelcomeScreen<'_> {
UpdateGuildWelcomeScreen::new(self, guild_id)
}
pub const fn invite<'a>(&'a self, code: &'a str) -> GetInvite<'a> {
GetInvite::new(self, code)
}
pub const fn create_invite(&self, channel_id: Id<ChannelMarker>) -> CreateInvite<'_> {
CreateInvite::new(self, channel_id)
}
pub const fn delete_invite<'a>(&'a self, code: &'a str) -> DeleteInvite<'a> {
DeleteInvite::new(self, code)
}
pub const fn message(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> GetMessage<'_> {
GetMessage::new(self, channel_id, message_id)
}
pub const fn create_message(&self, channel_id: Id<ChannelMarker>) -> CreateMessage<'_> {
CreateMessage::new(self, channel_id)
}
pub const fn delete_message(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> DeleteMessage<'_> {
DeleteMessage::new(self, channel_id, message_id)
}
pub fn delete_messages<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_ids: &'a [Id<MessageMarker>],
) -> DeleteMessages<'a> {
DeleteMessages::new(self, channel_id, message_ids)
}
pub const fn update_message(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> UpdateMessage<'_> {
UpdateMessage::new(self, channel_id, message_id)
}
pub const fn crosspost_message(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> CrosspostMessage<'_> {
CrosspostMessage::new(self, channel_id, message_id)
}
pub const fn pins(&self, channel_id: Id<ChannelMarker>) -> GetPins<'_> {
GetPins::new(self, channel_id)
}
pub const fn create_pin(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> CreatePin<'_> {
CreatePin::new(self, channel_id, message_id)
}
pub const fn delete_pin(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> DeletePin<'_> {
DeletePin::new(self, channel_id, message_id)
}
pub const fn reactions<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
emoji: &'a RequestReactionType<'a>,
) -> GetReactions<'a> {
GetReactions::new(self, channel_id, message_id, emoji)
}
pub const fn create_reaction<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
emoji: &'a RequestReactionType<'a>,
) -> CreateReaction<'a> {
CreateReaction::new(self, channel_id, message_id, emoji)
}
pub const fn delete_current_user_reaction<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
emoji: &'a RequestReactionType<'a>,
) -> DeleteReaction<'a> {
DeleteReaction::new(self, channel_id, message_id, emoji, TargetUser::Current)
}
pub const fn delete_reaction<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
emoji: &'a RequestReactionType<'a>,
user_id: Id<UserMarker>,
) -> DeleteReaction<'a> {
DeleteReaction::new(self, channel_id, message_id, emoji, TargetUser::Id(user_id))
}
pub const fn delete_all_reaction<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
emoji: &'a RequestReactionType<'a>,
) -> DeleteAllReaction<'a> {
DeleteAllReaction::new(self, channel_id, message_id, emoji)
}
pub const fn delete_all_reactions(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> DeleteAllReactions<'_> {
DeleteAllReactions::new(self, channel_id, message_id)
}
pub const fn create_typing_trigger(
&self,
channel_id: Id<ChannelMarker>,
) -> CreateTypingTrigger<'_> {
CreateTypingTrigger::new(self, channel_id)
}
pub const fn create_private_channel(
&self,
recipient_id: Id<UserMarker>,
) -> CreatePrivateChannel<'_> {
CreatePrivateChannel::new(self, recipient_id)
}
pub const fn roles(&self, guild_id: Id<GuildMarker>) -> GetGuildRoles<'_> {
GetGuildRoles::new(self, guild_id)
}
pub const fn role_member_counts(
&self,
guild_id: Id<GuildMarker>,
) -> GetGuildRoleMemberCounts<'_> {
GetGuildRoleMemberCounts::new(self, guild_id)
}
pub const fn role(&self, guild_id: Id<GuildMarker>, role_id: Id<RoleMarker>) -> GetRole<'_> {
GetRole::new(self, guild_id, role_id)
}
pub const fn create_role(&self, guild_id: Id<GuildMarker>) -> CreateRole<'_> {
CreateRole::new(self, guild_id)
}
pub const fn delete_role(
&self,
guild_id: Id<GuildMarker>,
role_id: Id<RoleMarker>,
) -> DeleteRole<'_> {
DeleteRole::new(self, guild_id, role_id)
}
pub const fn update_role(
&self,
guild_id: Id<GuildMarker>,
role_id: Id<RoleMarker>,
) -> UpdateRole<'_> {
UpdateRole::new(self, guild_id, role_id)
}
pub const fn update_role_positions<'a>(
&'a self,
guild_id: Id<GuildMarker>,
roles: &'a [RolePosition],
) -> UpdateRolePositions<'a> {
UpdateRolePositions::new(self, guild_id, roles)
}
pub fn create_stage_instance<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
topic: &'a str,
) -> CreateStageInstance<'a> {
CreateStageInstance::new(self, channel_id, topic)
}
pub const fn stage_instance(&self, channel_id: Id<ChannelMarker>) -> GetStageInstance<'_> {
GetStageInstance::new(self, channel_id)
}
pub const fn update_stage_instance(
&self,
channel_id: Id<ChannelMarker>,
) -> UpdateStageInstance<'_> {
UpdateStageInstance::new(self, channel_id)
}
pub const fn delete_stage_instance(
&self,
channel_id: Id<ChannelMarker>,
) -> DeleteStageInstance<'_> {
DeleteStageInstance::new(self, channel_id)
}
pub fn create_guild_from_template<'a>(
&'a self,
template_code: &'a str,
name: &'a str,
) -> CreateGuildFromTemplate<'a> {
CreateGuildFromTemplate::new(self, template_code, name)
}
pub fn create_template<'a>(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
) -> CreateTemplate<'a> {
CreateTemplate::new(self, guild_id, name)
}
pub const fn delete_template<'a>(
&'a self,
guild_id: Id<GuildMarker>,
template_code: &'a str,
) -> DeleteTemplate<'a> {
DeleteTemplate::new(self, guild_id, template_code)
}
pub const fn get_template<'a>(&'a self, template_code: &'a str) -> GetTemplate<'a> {
GetTemplate::new(self, template_code)
}
pub const fn get_templates(&self, guild_id: Id<GuildMarker>) -> GetTemplates<'_> {
GetTemplates::new(self, guild_id)
}
pub const fn sync_template<'a>(
&'a self,
guild_id: Id<GuildMarker>,
template_code: &'a str,
) -> SyncTemplate<'a> {
SyncTemplate::new(self, guild_id, template_code)
}
pub const fn update_template<'a>(
&'a self,
guild_id: Id<GuildMarker>,
template_code: &'a str,
) -> UpdateTemplate<'a> {
UpdateTemplate::new(self, guild_id, template_code)
}
pub const fn active_threads(&self, guild_id: Id<GuildMarker>) -> GetActiveThreads<'_> {
GetActiveThreads::new(self, guild_id)
}
pub const fn add_thread_member(
&self,
channel_id: Id<ChannelMarker>,
user_id: Id<UserMarker>,
) -> AddThreadMember<'_> {
AddThreadMember::new(self, channel_id, user_id)
}
pub const fn create_forum_thread<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
name: &'a str,
) -> CreateForumThread<'a> {
CreateForumThread::new(self, channel_id, name)
}
pub fn create_thread<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
name: &'a str,
kind: ChannelType,
) -> CreateThread<'a> {
CreateThread::new(self, channel_id, name, kind)
}
pub fn create_thread_from_message<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
name: &'a str,
) -> CreateThreadFromMessage<'a> {
CreateThreadFromMessage::new(self, channel_id, message_id, name)
}
pub const fn join_thread(&self, channel_id: Id<ChannelMarker>) -> JoinThread<'_> {
JoinThread::new(self, channel_id)
}
pub const fn joined_private_archived_threads(
&self,
channel_id: Id<ChannelMarker>,
) -> GetJoinedPrivateArchivedThreads<'_> {
GetJoinedPrivateArchivedThreads::new(self, channel_id)
}
pub const fn leave_thread(&self, channel_id: Id<ChannelMarker>) -> LeaveThread<'_> {
LeaveThread::new(self, channel_id)
}
pub const fn private_archived_threads(
&self,
channel_id: Id<ChannelMarker>,
) -> GetPrivateArchivedThreads<'_> {
GetPrivateArchivedThreads::new(self, channel_id)
}
pub const fn public_archived_threads(
&self,
channel_id: Id<ChannelMarker>,
) -> GetPublicArchivedThreads<'_> {
GetPublicArchivedThreads::new(self, channel_id)
}
pub const fn remove_thread_member(
&self,
channel_id: Id<ChannelMarker>,
user_id: Id<UserMarker>,
) -> RemoveThreadMember<'_> {
RemoveThreadMember::new(self, channel_id, user_id)
}
pub const fn thread_member(
&self,
channel_id: Id<ChannelMarker>,
user_id: Id<UserMarker>,
) -> GetThreadMember<'_> {
GetThreadMember::new(self, channel_id, user_id)
}
pub const fn thread_members(&self, channel_id: Id<ChannelMarker>) -> GetThreadMembers<'_> {
GetThreadMembers::new(self, channel_id)
}
pub const fn update_thread(&self, channel_id: Id<ChannelMarker>) -> UpdateThread<'_> {
UpdateThread::new(self, channel_id)
}
pub const fn user(&self, user_id: Id<UserMarker>) -> GetUser<'_> {
GetUser::new(self, user_id)
}
pub const fn user_voice_state(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
) -> GetUserVoiceState<'_> {
GetUserVoiceState::new(self, guild_id, user_id)
}
pub const fn update_user_voice_state(
&self,
guild_id: Id<GuildMarker>,
user_id: Id<UserMarker>,
channel_id: Id<ChannelMarker>,
) -> UpdateUserVoiceState<'_> {
UpdateUserVoiceState::new(self, guild_id, user_id, channel_id)
}
pub const fn voice_regions(&self) -> GetVoiceRegions<'_> {
GetVoiceRegions::new(self)
}
pub const fn webhook(&self, id: Id<WebhookMarker>) -> GetWebhook<'_> {
GetWebhook::new(self, id)
}
pub fn create_webhook<'a>(
&'a self,
channel_id: Id<ChannelMarker>,
name: &'a str,
) -> CreateWebhook<'a> {
CreateWebhook::new(self, channel_id, name)
}
pub const fn delete_webhook(&self, id: Id<WebhookMarker>) -> DeleteWebhook<'_> {
DeleteWebhook::new(self, id)
}
pub const fn update_webhook(&self, webhook_id: Id<WebhookMarker>) -> UpdateWebhook<'_> {
UpdateWebhook::new(self, webhook_id)
}
pub const fn update_webhook_with_token<'a>(
&'a self,
webhook_id: Id<WebhookMarker>,
token: &'a str,
) -> UpdateWebhookWithToken<'a> {
UpdateWebhookWithToken::new(self, webhook_id, token)
}
pub const fn execute_webhook<'a>(
&'a self,
webhook_id: Id<WebhookMarker>,
token: &'a str,
) -> ExecuteWebhook<'a> {
ExecuteWebhook::new(self, webhook_id, token)
}
pub const fn webhook_message<'a>(
&'a self,
webhook_id: Id<WebhookMarker>,
token: &'a str,
message_id: Id<MessageMarker>,
) -> GetWebhookMessage<'a> {
GetWebhookMessage::new(self, webhook_id, token, message_id)
}
pub const fn update_webhook_message<'a>(
&'a self,
webhook_id: Id<WebhookMarker>,
token: &'a str,
message_id: Id<MessageMarker>,
) -> UpdateWebhookMessage<'a> {
UpdateWebhookMessage::new(self, webhook_id, token, message_id)
}
pub const fn delete_webhook_message<'a>(
&'a self,
webhook_id: Id<WebhookMarker>,
token: &'a str,
message_id: Id<MessageMarker>,
) -> DeleteWebhookMessage<'a> {
DeleteWebhookMessage::new(self, webhook_id, token, message_id)
}
pub const fn delete_guild_scheduled_event(
&self,
guild_id: Id<GuildMarker>,
scheduled_event_id: Id<ScheduledEventMarker>,
) -> DeleteGuildScheduledEvent<'_> {
DeleteGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
}
pub const fn create_guild_scheduled_event(
&self,
guild_id: Id<GuildMarker>,
privacy_level: PrivacyLevel,
) -> CreateGuildScheduledEvent<'_> {
CreateGuildScheduledEvent::new(self, guild_id, privacy_level)
}
pub const fn guild_scheduled_event(
&self,
guild_id: Id<GuildMarker>,
scheduled_event_id: Id<ScheduledEventMarker>,
) -> GetGuildScheduledEvent<'_> {
GetGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
}
pub const fn guild_scheduled_event_users(
&self,
guild_id: Id<GuildMarker>,
scheduled_event_id: Id<ScheduledEventMarker>,
) -> GetGuildScheduledEventUsers<'_> {
GetGuildScheduledEventUsers::new(self, guild_id, scheduled_event_id)
}
pub const fn guild_scheduled_events(
&self,
guild_id: Id<GuildMarker>,
) -> GetGuildScheduledEvents<'_> {
GetGuildScheduledEvents::new(self, guild_id)
}
pub const fn update_guild_scheduled_event(
&self,
guild_id: Id<GuildMarker>,
scheduled_event_id: Id<ScheduledEventMarker>,
) -> UpdateGuildScheduledEvent<'_> {
UpdateGuildScheduledEvent::new(self, guild_id, scheduled_event_id)
}
pub const fn sticker(&self, sticker_id: Id<StickerMarker>) -> GetSticker<'_> {
GetSticker::new(self, sticker_id)
}
pub const fn nitro_sticker_packs(&self) -> GetNitroStickerPacks<'_> {
GetNitroStickerPacks::new(self)
}
pub const fn guild_stickers(&self, guild_id: Id<GuildMarker>) -> GetGuildStickers<'_> {
GetGuildStickers::new(self, guild_id)
}
pub const fn guild_sticker(
&self,
guild_id: Id<GuildMarker>,
sticker_id: Id<StickerMarker>,
) -> GetGuildSticker<'_> {
GetGuildSticker::new(self, guild_id, sticker_id)
}
pub fn create_guild_sticker<'a>(
&'a self,
guild_id: Id<GuildMarker>,
name: &'a str,
description: &'a str,
tags: &'a str,
file: &'a [u8],
) -> CreateGuildSticker<'a> {
CreateGuildSticker::new(self, guild_id, name, description, tags, file)
}
pub const fn update_guild_sticker(
&self,
guild_id: Id<GuildMarker>,
sticker_id: Id<StickerMarker>,
) -> UpdateGuildSticker<'_> {
UpdateGuildSticker::new(self, guild_id, sticker_id)
}
pub const fn delete_guild_sticker(
&self,
guild_id: Id<GuildMarker>,
sticker_id: Id<StickerMarker>,
) -> DeleteGuildSticker<'_> {
DeleteGuildSticker::new(self, guild_id, sticker_id)
}
pub const fn create_test_entitlement(
&self,
application_id: Id<ApplicationMarker>,
sku_id: Id<SkuMarker>,
owner: CreateTestEntitlementOwner,
) -> CreateTestEntitlement<'_> {
CreateTestEntitlement::new(self, application_id, sku_id, owner)
}
pub const fn end_poll(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
) -> EndPoll<'_> {
EndPoll::new(self, channel_id, message_id)
}
pub const fn delete_test_entitlement(
&self,
application_id: Id<ApplicationMarker>,
entitlement_id: Id<EntitlementMarker>,
) -> DeleteTestEntitlement<'_> {
DeleteTestEntitlement::new(self, application_id, entitlement_id)
}
pub const fn get_answer_voters(
&self,
channel_id: Id<ChannelMarker>,
message_id: Id<MessageMarker>,
answer_id: u8,
) -> GetAnswerVoters<'_> {
GetAnswerVoters::new(self, channel_id, message_id, answer_id)
}
pub const fn get_skus(&self, application_id: Id<ApplicationMarker>) -> GetSKUs<'_> {
GetSKUs::new(self, application_id)
}
pub const fn get_application_emojis(
&self,
application_id: Id<ApplicationMarker>,
) -> ListApplicationEmojis<'_> {
ListApplicationEmojis::new(self, application_id)
}
pub const fn add_application_emoji<'a>(
&'a self,
application_id: Id<ApplicationMarker>,
name: &'a str,
image: &'a str,
) -> AddApplicationEmoji<'a> {
AddApplicationEmoji::new(self, application_id, name, image)
}
pub const fn update_application_emoji<'a>(
&'a self,
application_id: Id<ApplicationMarker>,
emoji_id: Id<EmojiMarker>,
name: &'a str,
) -> UpdateApplicationEmoji<'a> {
UpdateApplicationEmoji::new(self, application_id, emoji_id, name)
}
pub const fn delete_application_emoji(
&self,
application_id: Id<ApplicationMarker>,
emoji_id: Id<EmojiMarker>,
) -> DeleteApplicationEmoji<'_> {
DeleteApplicationEmoji::new(self, application_id, emoji_id)
}
pub fn request<T>(&self, request: Request) -> ResponseFuture<T> {
match self.try_request::<T>(request) {
Ok(future) => future,
Err(source) => ResponseFuture::error(source),
}
}
fn try_request<T>(&self, request: Request) -> Result<ResponseFuture<T>, Error> {
if let Some(token_invalidated) = self.token_invalidated.as_ref()
&& token_invalidated.load(Ordering::Relaxed)
{
return Err(Error {
kind: ErrorType::Unauthorized,
source: None,
});
}
let Request {
body,
form,
headers: req_headers,
method,
mut path,
use_authorization_token,
} = request;
let protocol = if self.use_http { "http" } else { "https" };
let host = self.proxy.as_deref().unwrap_or("discord.com");
let url = format!("{protocol}://{host}/api/v{API_VERSION}/{path}");
let mut builder = hyper::Request::builder().method(method.name()).uri(&url);
if use_authorization_token && let Some(token) = self.token.as_deref() {
let value = HeaderValue::from_str(token).map_err(|source| {
let name = AUTHORIZATION.to_string();
Error {
kind: ErrorType::CreatingHeader { name },
source: Some(Box::new(source)),
}
})?;
if let Some(headers) = builder.headers_mut() {
headers.insert(AUTHORIZATION, value);
}
}
if let Some(headers) = builder.headers_mut() {
if let Some(form) = &form {
headers.insert(CONTENT_LENGTH, HeaderValue::from(form.len()));
if let Ok(content_type) = HeaderValue::try_from(form.content_type()) {
headers.insert(CONTENT_TYPE, content_type);
}
} else if let Some(bytes) = &body {
headers.insert(CONTENT_LENGTH, HeaderValue::from(bytes.len()));
headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
} else if matches!(method, Method::Put | Method::Post | Method::Patch) {
headers.insert(CONTENT_LENGTH, HeaderValue::from(0));
}
#[cfg(feature = "decompression")]
headers.insert(
hyper::header::ACCEPT_ENCODING,
HeaderValue::from_static("br"),
);
headers.insert(USER_AGENT, HeaderValue::from_static(TWILIGHT_USER_AGENT));
if let Some(req_headers) = req_headers {
for (maybe_name, value) in req_headers {
if let Some(name) = maybe_name {
headers.insert(name, value);
}
}
}
if let Some(default_headers) = &self.default_headers {
for (name, value) in default_headers {
headers.insert(name, value.clone());
}
}
}
let try_req = if let Some(form) = form {
builder.body(Full::from(form.build()))
} else if let Some(bytes) = body {
builder.body(Full::from(bytes))
} else {
builder.body(Full::default())
};
let http_request = try_req.map_err(|source| Error {
kind: ErrorType::BuildingRequest,
source: Some(Box::new(source)),
})?;
let invalid_token = use_authorization_token
.then(|| self.token_invalidated.clone())
.flatten();
if let Some(i) = path.find('?') {
path.truncate(i);
}
let response = ResponseFuture::new(
self.http.clone(),
invalid_token,
http_request,
tracing::info_span!("req", method = method.name(), url = url),
self.timeout,
self.ratelimiter.clone(),
Endpoint { method, path },
);
Ok(response)
}
}
#[cfg(test)]
mod tests {
use super::Client;
#[test]
fn client_debug_with_token() {
assert!(
format!("{:?}", Client::new("Bot foo".to_owned())).contains("token: Some(<redacted>)")
);
assert!(format!("{:?}", Client::builder().build()).contains("token: None"));
}
}