1#![allow(clippy::missing_errors_doc)]
2
3use std::borrow::Cow;
4use std::collections::HashMap;
5use std::num::NonZeroU64;
6use std::sync::atomic::{AtomicU64, Ordering};
7use std::sync::Arc;
8
9use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
10use reqwest::header::{HeaderMap as Headers, HeaderValue};
11#[cfg(feature = "utils")]
12use reqwest::Url;
13use reqwest::{Client, ClientBuilder, Response as ReqwestResponse, StatusCode};
14use secrecy::{ExposeSecret, SecretString};
15use serde::de::DeserializeOwned;
16use tracing::{debug, instrument, warn};
17
18use super::multipart::{Multipart, MultipartUpload};
19use super::ratelimiting::Ratelimiter;
20use super::request::Request;
21use super::routing::Route;
22use super::typing::Typing;
23use super::{
24 ErrorResponse,
25 GuildPagination,
26 HttpError,
27 LightMethod,
28 MessagePagination,
29 UserPagination,
30};
31use crate::builder::{CreateAllowedMentions, CreateAttachment};
32use crate::constants;
33use crate::internal::prelude::*;
34use crate::json::*;
35use crate::model::prelude::*;
36
37#[must_use]
54pub struct HttpBuilder {
55 client: Option<Client>,
56 ratelimiter: Option<Ratelimiter>,
57 ratelimiter_disabled: bool,
58 token: SecretString,
59 proxy: Option<String>,
60 application_id: Option<ApplicationId>,
61 default_allowed_mentions: Option<CreateAllowedMentions>,
62}
63
64impl HttpBuilder {
65 pub fn new(token: impl AsRef<str>) -> Self {
68 Self {
69 client: None,
70 ratelimiter: None,
71 ratelimiter_disabled: false,
72 token: SecretString::new(parse_token(token)),
73 proxy: None,
74 application_id: None,
75 default_allowed_mentions: None,
76 }
77 }
78
79 pub fn application_id(mut self, application_id: ApplicationId) -> Self {
81 self.application_id = Some(application_id);
82 self
83 }
84
85 pub fn token(mut self, token: impl AsRef<str>) -> Self {
88 self.token = SecretString::new(parse_token(token));
89 self
90 }
91
92 pub fn client(mut self, client: Client) -> Self {
94 self.client = Some(client);
95 self
96 }
97
98 pub fn ratelimiter(mut self, ratelimiter: Ratelimiter) -> Self {
100 self.ratelimiter = Some(ratelimiter);
101 self
102 }
103
104 pub fn ratelimiter_disabled(mut self, ratelimiter_disabled: bool) -> Self {
111 self.ratelimiter_disabled = ratelimiter_disabled;
112 self
113 }
114
115 pub fn proxy(mut self, proxy: impl Into<String>) -> Self {
130 self.proxy = Some(proxy.into());
131 self
132 }
133
134 pub fn default_allowed_mentions(mut self, allowed_mentions: CreateAllowedMentions) -> Self {
139 self.default_allowed_mentions = Some(allowed_mentions);
140 self
141 }
142
143 #[must_use]
145 pub fn build(self) -> Http {
146 let application_id = AtomicU64::new(self.application_id.map_or(0, ApplicationId::get));
147
148 let client = self.client.unwrap_or_else(|| {
149 let builder = configure_client_backend(Client::builder());
150 builder.build().expect("Cannot build reqwest::Client")
151 });
152
153 let ratelimiter = (!self.ratelimiter_disabled).then(|| {
154 self.ratelimiter
155 .unwrap_or_else(|| Ratelimiter::new(client.clone(), self.token.expose_secret()))
156 });
157
158 Http {
159 client,
160 ratelimiter,
161 proxy: self.proxy,
162 token: self.token,
163 application_id,
164 default_allowed_mentions: self.default_allowed_mentions,
165 }
166 }
167}
168
169fn parse_token(token: impl AsRef<str>) -> String {
170 let token = token.as_ref().trim();
171
172 if token.starts_with("Bot ") || token.starts_with("Bearer ") {
173 token.to_string()
174 } else {
175 format!("Bot {token}")
176 }
177}
178
179fn reason_into_header(reason: &str) -> Headers {
180 let mut headers = Headers::new();
181
182 let header_value = match Cow::from(utf8_percent_encode(reason, NON_ALPHANUMERIC)) {
185 Cow::Borrowed(value) => HeaderValue::from_str(value),
186 Cow::Owned(value) => HeaderValue::try_from(value),
187 }
188 .expect("Invalid header value even after percent encode");
189
190 headers.insert("X-Audit-Log-Reason", header_value);
191 headers
192}
193
194#[derive(Debug)]
197pub struct Http {
198 pub(crate) client: Client,
199 pub ratelimiter: Option<Ratelimiter>,
200 pub proxy: Option<String>,
201 token: SecretString,
202 application_id: AtomicU64,
203 pub default_allowed_mentions: Option<CreateAllowedMentions>,
204}
205
206impl Http {
207 #[must_use]
208 pub fn new(token: &str) -> Self {
209 HttpBuilder::new(token).build()
210 }
211
212 pub fn application_id(&self) -> Option<ApplicationId> {
213 let application_id = self.application_id.load(Ordering::Acquire);
214 NonZeroU64::new(application_id).map(ApplicationId::from)
215 }
216
217 fn try_application_id(&self) -> Result<ApplicationId> {
218 self.application_id().ok_or_else(|| HttpError::ApplicationIdMissing.into())
219 }
220
221 pub fn set_application_id(&self, application_id: ApplicationId) {
222 self.application_id.store(application_id.get(), Ordering::Release);
223 }
224
225 pub fn token(&self) -> &str {
226 self.token.expose_secret()
227 }
228
229 pub async fn add_guild_member(
233 &self,
234 guild_id: GuildId,
235 user_id: UserId,
236 map: &impl serde::Serialize,
237 ) -> Result<Option<Member>> {
238 let body = to_vec(map)?;
239
240 let response = self
241 .request(Request {
242 body: Some(body),
243 multipart: None,
244 headers: None,
245 method: LightMethod::Put,
246 route: Route::GuildMember {
247 guild_id,
248 user_id,
249 },
250 params: None,
251 })
252 .await?;
253
254 if response.status() == 204 {
255 Ok(None)
256 } else {
257 Ok(Some(decode_resp(response).await?))
258 }
259 }
260
261 pub async fn add_member_role(
267 &self,
268 guild_id: GuildId,
269 user_id: UserId,
270 role_id: RoleId,
271 audit_log_reason: Option<&str>,
272 ) -> Result<()> {
273 self.wind(204, Request {
274 body: None,
275 multipart: None,
276 headers: audit_log_reason.map(reason_into_header),
277 method: LightMethod::Put,
278 route: Route::GuildMemberRole {
279 guild_id,
280 role_id,
281 user_id,
282 },
283 params: None,
284 })
285 .await
286 }
287
288 pub async fn ban_user(
298 &self,
299 guild_id: GuildId,
300 user_id: UserId,
301 delete_message_days: u8,
302 reason: Option<&str>,
303 ) -> Result<()> {
304 let delete_message_seconds = u32::from(delete_message_days) * 86400;
305
306 self.wind(204, Request {
307 body: None,
308 multipart: None,
309 headers: reason.map(reason_into_header),
310 method: LightMethod::Put,
311 route: Route::GuildBan {
312 guild_id,
313 user_id,
314 },
315 params: Some(vec![("delete_message_seconds", delete_message_seconds.to_string())]),
316 })
317 .await
318 }
319
320 pub async fn bulk_ban_users(
325 &self,
326 guild_id: GuildId,
327 map: &impl serde::Serialize,
328 reason: Option<&str>,
329 ) -> Result<BulkBanResponse> {
330 self.fire(Request {
331 body: Some(to_vec(map)?),
332 multipart: None,
333 headers: reason.map(reason_into_header),
334 method: LightMethod::Post,
335 route: Route::GuildBulkBan {
336 guild_id,
337 },
338 params: None,
339 })
340 .await
341 }
342
343 pub async fn broadcast_typing(&self, channel_id: ChannelId) -> Result<()> {
351 self.wind(204, Request {
352 body: None,
353 multipart: None,
354 headers: None,
355 method: LightMethod::Post,
356 route: Route::ChannelTyping {
357 channel_id,
358 },
359 params: None,
360 })
361 .await
362 }
363
364 pub async fn create_channel(
373 &self,
374 guild_id: GuildId,
375 map: &impl serde::Serialize,
376 audit_log_reason: Option<&str>,
377 ) -> Result<GuildChannel> {
378 let body = to_vec(map)?;
379
380 self.fire(Request {
381 body: Some(body),
382 multipart: None,
383 headers: audit_log_reason.map(reason_into_header),
384 method: LightMethod::Post,
385 route: Route::GuildChannels {
386 guild_id,
387 },
388 params: None,
389 })
390 .await
391 }
392
393 pub async fn create_stage_instance(
395 &self,
396 map: &impl serde::Serialize,
397 audit_log_reason: Option<&str>,
398 ) -> Result<StageInstance> {
399 self.fire(Request {
400 body: Some(to_vec(map)?),
401 multipart: None,
402 headers: audit_log_reason.map(reason_into_header),
403 method: LightMethod::Post,
404 route: Route::StageInstances,
405 params: None,
406 })
407 .await
408 }
409
410 pub async fn create_thread_from_message(
412 &self,
413 channel_id: ChannelId,
414 message_id: MessageId,
415 map: &impl serde::Serialize,
416 audit_log_reason: Option<&str>,
417 ) -> Result<GuildChannel> {
418 let body = to_vec(map)?;
419
420 self.fire(Request {
421 body: Some(body),
422 multipart: None,
423 headers: audit_log_reason.map(reason_into_header),
424 method: LightMethod::Post,
425 route: Route::ChannelMessageThreads {
426 channel_id,
427 message_id,
428 },
429 params: None,
430 })
431 .await
432 }
433
434 pub async fn create_thread(
436 &self,
437 channel_id: ChannelId,
438 map: &impl serde::Serialize,
439 audit_log_reason: Option<&str>,
440 ) -> Result<GuildChannel> {
441 let body = to_vec(map)?;
442
443 self.fire(Request {
444 body: Some(body),
445 multipart: None,
446 headers: audit_log_reason.map(reason_into_header),
447 method: LightMethod::Post,
448 route: Route::ChannelThreads {
449 channel_id,
450 },
451 params: None,
452 })
453 .await
454 }
455
456 pub async fn create_forum_post(
458 &self,
459 channel_id: ChannelId,
460 map: &impl serde::Serialize,
461 audit_log_reason: Option<&str>,
462 ) -> Result<GuildChannel> {
463 self.create_forum_post_with_attachments(channel_id, map, vec![], audit_log_reason).await
464 }
465
466 pub async fn create_forum_post_with_attachments(
468 &self,
469 channel_id: ChannelId,
470 map: &impl serde::Serialize,
471 files: Vec<CreateAttachment>,
472 audit_log_reason: Option<&str>,
473 ) -> Result<GuildChannel> {
474 self.fire(Request {
475 body: None,
476 multipart: Some(Multipart {
477 upload: MultipartUpload::Attachments(files.into_iter().collect()),
478 payload_json: Some(to_string(map)?),
479 fields: vec![],
480 }),
481 headers: audit_log_reason.map(reason_into_header),
482 method: LightMethod::Post,
483 route: Route::ChannelForumPosts {
484 channel_id,
485 },
486 params: None,
487 })
488 .await
489 }
490
491 pub async fn create_emoji(
499 &self,
500 guild_id: GuildId,
501 map: &Value,
502 audit_log_reason: Option<&str>,
503 ) -> Result<Emoji> {
504 self.fire(Request {
505 body: Some(to_vec(map)?),
506 multipart: None,
507 headers: audit_log_reason.map(reason_into_header),
508 method: LightMethod::Post,
509 route: Route::GuildEmojis {
510 guild_id,
511 },
512 params: None,
513 })
514 .await
515 }
516
517 pub async fn create_application_emoji(&self, map: &impl serde::Serialize) -> Result<Emoji> {
523 self.fire(Request {
524 body: Some(to_vec(map)?),
525 multipart: None,
526 headers: None,
527 method: LightMethod::Post,
528 route: Route::Emojis {
529 application_id: self.try_application_id()?,
530 },
531 params: None,
532 })
533 .await
534 }
535
536 pub async fn create_followup_message(
540 &self,
541 interaction_token: &str,
542 map: &impl serde::Serialize,
543 files: Vec<CreateAttachment>,
544 ) -> Result<Message> {
545 let mut request = Request {
546 body: None,
547 multipart: None,
548 headers: None,
549 method: LightMethod::Post,
550 route: Route::WebhookFollowupMessages {
551 application_id: self.try_application_id()?,
552 token: interaction_token,
553 },
554 params: None,
555 };
556
557 if files.is_empty() {
558 request.body = Some(to_vec(map)?);
559 } else {
560 request.multipart = Some(Multipart {
561 upload: MultipartUpload::Attachments(files),
562 payload_json: Some(to_string(map)?),
563 fields: vec![],
564 });
565 }
566
567 self.fire(request).await
568 }
569
570 pub async fn create_global_command(&self, map: &impl serde::Serialize) -> Result<Command> {
581 self.fire(Request {
582 body: Some(to_vec(map)?),
583 multipart: None,
584 headers: None,
585 method: LightMethod::Post,
586 route: Route::Commands {
587 application_id: self.try_application_id()?,
588 },
589 params: None,
590 })
591 .await
592 }
593
594 pub async fn create_global_commands(
596 &self,
597 map: &impl serde::Serialize,
598 ) -> Result<Vec<Command>> {
599 self.fire(Request {
600 body: Some(to_vec(map)?),
601 multipart: None,
602 headers: None,
603 method: LightMethod::Put,
604 route: Route::Commands {
605 application_id: self.try_application_id()?,
606 },
607 params: None,
608 })
609 .await
610 }
611
612 pub async fn create_guild_commands(
614 &self,
615 guild_id: GuildId,
616 map: &impl serde::Serialize,
617 ) -> Result<Vec<Command>> {
618 self.fire(Request {
619 body: Some(to_vec(map)?),
620 multipart: None,
621 headers: None,
622 method: LightMethod::Put,
623 route: Route::GuildCommands {
624 application_id: self.try_application_id()?,
625 guild_id,
626 },
627 params: None,
628 })
629 .await
630 }
631
632 #[deprecated = "This endpoint has been deprecated by Discord and will stop functioning after July 15, 2025. For more information, see: https://discord.com/developers/docs/change-log#deprecating-guild-creation-by-apps"]
666 pub async fn create_guild(&self, map: &Value) -> Result<PartialGuild> {
667 self.fire(Request {
668 body: Some(to_vec(map)?),
669 multipart: None,
670 headers: None,
671 method: LightMethod::Post,
672 route: Route::Guilds,
673 params: None,
674 })
675 .await
676 }
677
678 pub async fn create_guild_command(
686 &self,
687 guild_id: GuildId,
688 map: &impl serde::Serialize,
689 ) -> Result<Command> {
690 self.fire(Request {
691 body: Some(to_vec(map)?),
692 multipart: None,
693 headers: None,
694 method: LightMethod::Post,
695 route: Route::GuildCommands {
696 application_id: self.try_application_id()?,
697 guild_id,
698 },
699 params: None,
700 })
701 .await
702 }
703
704 pub async fn create_guild_integration(
713 &self,
714 guild_id: GuildId,
715 integration_id: IntegrationId,
716 map: &Value,
717 audit_log_reason: Option<&str>,
718 ) -> Result<()> {
719 self.wind(204, Request {
720 body: Some(to_vec(map)?),
721 multipart: None,
722 headers: audit_log_reason.map(reason_into_header),
723 method: LightMethod::Post,
724 route: Route::GuildIntegration {
725 guild_id,
726 integration_id,
727 },
728 params: None,
729 })
730 .await
731 }
732
733 pub async fn create_interaction_response(
740 &self,
741 interaction_id: InteractionId,
742 interaction_token: &str,
743 map: &impl serde::Serialize,
744 files: Vec<CreateAttachment>,
745 ) -> Result<()> {
746 let mut request = Request {
747 body: None,
748 multipart: None,
749 headers: None,
750 method: LightMethod::Post,
751 route: Route::InteractionResponse {
752 interaction_id,
753 token: interaction_token,
754 },
755 params: None,
756 };
757
758 if files.is_empty() {
759 request.body = Some(to_vec(map)?);
760 } else {
761 request.multipart = Some(Multipart {
762 upload: MultipartUpload::Attachments(files),
763 payload_json: Some(to_string(map)?),
764 fields: vec![],
765 });
766 }
767
768 self.wind(204, request).await
769 }
770
771 pub async fn create_invite(
782 &self,
783 channel_id: ChannelId,
784 map: &impl serde::Serialize,
785 audit_log_reason: Option<&str>,
786 ) -> Result<RichInvite> {
787 let body = to_vec(map)?;
788
789 self.fire(Request {
790 body: Some(body),
791 multipart: None,
792 headers: audit_log_reason.map(reason_into_header),
793 method: LightMethod::Post,
794 route: Route::ChannelInvites {
795 channel_id,
796 },
797 params: None,
798 })
799 .await
800 }
801
802 pub async fn create_permission(
804 &self,
805 channel_id: ChannelId,
806 target_id: TargetId,
807 map: &impl serde::Serialize,
808 audit_log_reason: Option<&str>,
809 ) -> Result<()> {
810 let body = to_vec(map)?;
811
812 self.wind(204, Request {
813 body: Some(body),
814 multipart: None,
815 headers: audit_log_reason.map(reason_into_header),
816 method: LightMethod::Put,
817 route: Route::ChannelPermission {
818 channel_id,
819 target_id,
820 },
821 params: None,
822 })
823 .await
824 }
825
826 pub async fn create_private_channel(&self, map: &Value) -> Result<PrivateChannel> {
828 let body = to_vec(map)?;
829
830 self.fire(Request {
831 body: Some(body),
832 multipart: None,
833 headers: None,
834 method: LightMethod::Post,
835 route: Route::UserMeDmChannels,
836 params: None,
837 })
838 .await
839 }
840
841 pub async fn create_reaction(
843 &self,
844 channel_id: ChannelId,
845 message_id: MessageId,
846 reaction_type: &ReactionType,
847 ) -> Result<()> {
848 self.wind(204, Request {
849 body: None,
850 multipart: None,
851 headers: None,
852 method: LightMethod::Put,
853 route: Route::ChannelMessageReactionMe {
854 channel_id,
855 message_id,
856 reaction: &reaction_type.as_data(),
857 },
858 params: None,
859 })
860 .await
861 }
862 pub async fn create_role(
864 &self,
865 guild_id: GuildId,
866 body: &impl serde::Serialize,
867 audit_log_reason: Option<&str>,
868 ) -> Result<Role> {
869 let mut value: Value = self
870 .fire(Request {
871 body: Some(to_vec(body)?),
872 multipart: None,
873 headers: audit_log_reason.map(reason_into_header),
874 method: LightMethod::Post,
875 route: Route::GuildRoles {
876 guild_id,
877 },
878 params: None,
879 })
880 .await?;
881
882 if let Some(map) = value.as_object_mut() {
883 map.insert("guild_id".to_string(), guild_id.get().into());
884 }
885
886 from_value(value)
887 }
888
889 pub async fn create_scheduled_event(
897 &self,
898 guild_id: GuildId,
899 map: &impl serde::Serialize,
900 audit_log_reason: Option<&str>,
901 ) -> Result<ScheduledEvent> {
902 let body = to_vec(map)?;
903 self.fire(Request {
904 body: Some(body),
905 multipart: None,
906 headers: audit_log_reason.map(reason_into_header),
907 method: LightMethod::Post,
908 route: Route::GuildScheduledEvents {
909 guild_id,
910 },
911 params: None,
912 })
913 .await
914 }
915
916 pub async fn create_sticker(
922 &self,
923 guild_id: GuildId,
924 map: impl IntoIterator<Item = (&'static str, String)>,
925 file: CreateAttachment,
926 audit_log_reason: Option<&str>,
927 ) -> Result<Sticker> {
928 self.fire(Request {
929 body: None,
930 multipart: Some(Multipart {
931 upload: MultipartUpload::File(file),
932 fields: map.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
933 payload_json: None,
934 }),
935 headers: audit_log_reason.map(reason_into_header),
936 method: LightMethod::Post,
937 route: Route::GuildStickers {
938 guild_id,
939 },
940 params: None,
941 })
942 .await
943 }
944
945 pub async fn create_test_entitlement(
949 &self,
950 sku_id: SkuId,
951 owner: EntitlementOwner,
952 ) -> Result<Entitlement> {
953 #[derive(serde::Serialize)]
954 struct TestEntitlement {
955 sku_id: SkuId,
956 owner_id: u64,
957 owner_type: u8,
958 }
959
960 let (owner_id, owner_type) = match owner {
961 EntitlementOwner::Guild(id) => (id.get(), 1),
962 EntitlementOwner::User(id) => (id.get(), 2),
963 };
964
965 let map = TestEntitlement {
966 sku_id,
967 owner_id,
968 owner_type,
969 };
970
971 self.fire(Request {
972 body: Some(to_vec(&map)?),
973 multipart: None,
974 headers: None,
975 method: LightMethod::Post,
976 route: Route::Entitlements {
977 application_id: self.try_application_id()?,
978 },
979 params: None,
980 })
981 .await
982 }
983
984 pub async fn create_webhook(
1011 &self,
1012 channel_id: ChannelId,
1013 map: &impl serde::Serialize,
1014 audit_log_reason: Option<&str>,
1015 ) -> Result<Webhook> {
1016 let body = to_vec(map)?;
1017
1018 self.fire(Request {
1019 body: Some(body),
1020 multipart: None,
1021 headers: audit_log_reason.map(reason_into_header),
1022 method: LightMethod::Post,
1023 route: Route::ChannelWebhooks {
1024 channel_id,
1025 },
1026 params: None,
1027 })
1028 .await
1029 }
1030
1031 pub async fn delete_channel(
1033 &self,
1034 channel_id: ChannelId,
1035 audit_log_reason: Option<&str>,
1036 ) -> Result<Channel> {
1037 self.fire(Request {
1038 body: None,
1039 multipart: None,
1040 headers: audit_log_reason.map(reason_into_header),
1041 method: LightMethod::Delete,
1042 route: Route::Channel {
1043 channel_id,
1044 },
1045 params: None,
1046 })
1047 .await
1048 }
1049
1050 pub async fn delete_stage_instance(
1052 &self,
1053 channel_id: ChannelId,
1054 audit_log_reason: Option<&str>,
1055 ) -> Result<()> {
1056 self.wind(204, Request {
1057 body: None,
1058 multipart: None,
1059 headers: audit_log_reason.map(reason_into_header),
1060 method: LightMethod::Delete,
1061 route: Route::StageInstance {
1062 channel_id,
1063 },
1064 params: None,
1065 })
1066 .await
1067 }
1068
1069 pub async fn delete_emoji(
1073 &self,
1074 guild_id: GuildId,
1075 emoji_id: EmojiId,
1076 audit_log_reason: Option<&str>,
1077 ) -> Result<()> {
1078 self.wind(204, Request {
1079 body: None,
1080 multipart: None,
1081 headers: audit_log_reason.map(reason_into_header),
1082 method: LightMethod::Delete,
1083 route: Route::GuildEmoji {
1084 guild_id,
1085 emoji_id,
1086 },
1087 params: None,
1088 })
1089 .await
1090 }
1091
1092 pub async fn delete_application_emoji(&self, emoji_id: EmojiId) -> Result<()> {
1094 self.wind(204, Request {
1095 body: None,
1096 multipart: None,
1097 headers: None,
1098 method: LightMethod::Delete,
1099 route: Route::Emoji {
1100 application_id: self.try_application_id()?,
1101 emoji_id,
1102 },
1103 params: None,
1104 })
1105 .await
1106 }
1107
1108 pub async fn delete_followup_message(
1110 &self,
1111 interaction_token: &str,
1112 message_id: MessageId,
1113 ) -> Result<()> {
1114 self.wind(204, Request {
1115 body: None,
1116 multipart: None,
1117 headers: None,
1118 method: LightMethod::Delete,
1119 route: Route::WebhookFollowupMessage {
1120 application_id: self.try_application_id()?,
1121 token: interaction_token,
1122 message_id,
1123 },
1124 params: None,
1125 })
1126 .await
1127 }
1128
1129 pub async fn delete_global_command(&self, command_id: CommandId) -> Result<()> {
1131 self.wind(204, Request {
1132 body: None,
1133 multipart: None,
1134 headers: None,
1135 method: LightMethod::Delete,
1136 route: Route::Command {
1137 application_id: self.try_application_id()?,
1138 command_id,
1139 },
1140 params: None,
1141 })
1142 .await
1143 }
1144
1145 pub async fn delete_guild(&self, guild_id: GuildId) -> Result<()> {
1147 self.wind(204, Request {
1148 body: None,
1149 multipart: None,
1150 headers: None,
1151 method: LightMethod::Delete,
1152 route: Route::Guild {
1153 guild_id,
1154 },
1155 params: None,
1156 })
1157 .await
1158 }
1159
1160 pub async fn delete_guild_command(
1162 &self,
1163 guild_id: GuildId,
1164 command_id: CommandId,
1165 ) -> Result<()> {
1166 self.wind(204, Request {
1167 body: None,
1168 multipart: None,
1169 headers: None,
1170 method: LightMethod::Delete,
1171 route: Route::GuildCommand {
1172 application_id: self.try_application_id()?,
1173 guild_id,
1174 command_id,
1175 },
1176 params: None,
1177 })
1178 .await
1179 }
1180
1181 pub async fn delete_guild_integration(
1183 &self,
1184 guild_id: GuildId,
1185 integration_id: IntegrationId,
1186 audit_log_reason: Option<&str>,
1187 ) -> Result<()> {
1188 self.wind(204, Request {
1189 body: None,
1190 multipart: None,
1191 headers: audit_log_reason.map(reason_into_header),
1192 method: LightMethod::Delete,
1193 route: Route::GuildIntegration {
1194 guild_id,
1195 integration_id,
1196 },
1197 params: None,
1198 })
1199 .await
1200 }
1201
1202 pub async fn delete_invite(
1204 &self,
1205 code: &str,
1206 audit_log_reason: Option<&str>,
1207 ) -> Result<Invite> {
1208 self.fire(Request {
1209 body: None,
1210 multipart: None,
1211 headers: audit_log_reason.map(reason_into_header),
1212 method: LightMethod::Delete,
1213 route: Route::Invite {
1214 code,
1215 },
1216 params: None,
1217 })
1218 .await
1219 }
1220
1221 pub async fn delete_message(
1223 &self,
1224 channel_id: ChannelId,
1225 message_id: MessageId,
1226 audit_log_reason: Option<&str>,
1227 ) -> Result<()> {
1228 self.wind(204, Request {
1229 body: None,
1230 multipart: None,
1231 headers: audit_log_reason.map(reason_into_header),
1232 method: LightMethod::Delete,
1233 route: Route::ChannelMessage {
1234 channel_id,
1235 message_id,
1236 },
1237 params: None,
1238 })
1239 .await
1240 }
1241
1242 pub async fn delete_messages(
1244 &self,
1245 channel_id: ChannelId,
1246 map: &Value,
1247 audit_log_reason: Option<&str>,
1248 ) -> Result<()> {
1249 self.wind(204, Request {
1250 body: Some(to_vec(map)?),
1251 multipart: None,
1252 headers: audit_log_reason.map(reason_into_header),
1253 method: LightMethod::Post,
1254 route: Route::ChannelMessagesBulkDelete {
1255 channel_id,
1256 },
1257 params: None,
1258 })
1259 .await
1260 }
1261
1262 pub async fn delete_message_reactions(
1281 &self,
1282 channel_id: ChannelId,
1283 message_id: MessageId,
1284 ) -> Result<()> {
1285 self.wind(204, Request {
1286 body: None,
1287 multipart: None,
1288 headers: None,
1289 method: LightMethod::Delete,
1290 route: Route::ChannelMessageReactions {
1291 channel_id,
1292 message_id,
1293 },
1294 params: None,
1295 })
1296 .await
1297 }
1298
1299 pub async fn delete_message_reaction_emoji(
1301 &self,
1302 channel_id: ChannelId,
1303 message_id: MessageId,
1304 reaction_type: &ReactionType,
1305 ) -> Result<()> {
1306 self.wind(204, Request {
1307 body: None,
1308 multipart: None,
1309 headers: None,
1310 method: LightMethod::Delete,
1311 route: Route::ChannelMessageReactionEmoji {
1312 channel_id,
1313 message_id,
1314 reaction: &reaction_type.as_data(),
1315 },
1316 params: None,
1317 })
1318 .await
1319 }
1320
1321 pub async fn delete_original_interaction_response(
1323 &self,
1324 interaction_token: &str,
1325 ) -> Result<()> {
1326 self.wind(204, Request {
1327 body: None,
1328 multipart: None,
1329 headers: None,
1330 method: LightMethod::Delete,
1331 route: Route::WebhookOriginalInteractionResponse {
1332 application_id: self.try_application_id()?,
1333 token: interaction_token,
1334 },
1335 params: None,
1336 })
1337 .await
1338 }
1339
1340 pub async fn delete_permission(
1342 &self,
1343 channel_id: ChannelId,
1344 target_id: TargetId,
1345 audit_log_reason: Option<&str>,
1346 ) -> Result<()> {
1347 self.wind(204, Request {
1348 body: None,
1349 multipart: None,
1350 headers: audit_log_reason.map(reason_into_header),
1351 method: LightMethod::Delete,
1352 route: Route::ChannelPermission {
1353 channel_id,
1354 target_id,
1355 },
1356 params: None,
1357 })
1358 .await
1359 }
1360
1361 pub async fn delete_reaction(
1363 &self,
1364 channel_id: ChannelId,
1365 message_id: MessageId,
1366 user_id: UserId,
1367 reaction_type: &ReactionType,
1368 ) -> Result<()> {
1369 self.wind(204, Request {
1370 body: None,
1371 multipart: None,
1372 headers: None,
1373 method: LightMethod::Delete,
1374 route: Route::ChannelMessageReaction {
1375 channel_id,
1376 message_id,
1377 user_id,
1378 reaction: &reaction_type.as_data(),
1379 },
1380 params: None,
1381 })
1382 .await
1383 }
1384
1385 pub async fn delete_reaction_me(
1387 &self,
1388 channel_id: ChannelId,
1389 message_id: MessageId,
1390 reaction_type: &ReactionType,
1391 ) -> Result<()> {
1392 self.wind(204, Request {
1393 body: None,
1394 multipart: None,
1395 headers: None,
1396 method: LightMethod::Delete,
1397 route: Route::ChannelMessageReactionMe {
1398 channel_id,
1399 message_id,
1400 reaction: &reaction_type.as_data(),
1401 },
1402 params: None,
1403 })
1404 .await
1405 }
1406
1407 pub async fn delete_role(
1409 &self,
1410 guild_id: GuildId,
1411 role_id: RoleId,
1412 audit_log_reason: Option<&str>,
1413 ) -> Result<()> {
1414 self.wind(204, Request {
1415 body: None,
1416 multipart: None,
1417 headers: audit_log_reason.map(reason_into_header),
1418 method: LightMethod::Delete,
1419 route: Route::GuildRole {
1420 guild_id,
1421 role_id,
1422 },
1423 params: None,
1424 })
1425 .await
1426 }
1427
1428 pub async fn delete_scheduled_event(
1435 &self,
1436 guild_id: GuildId,
1437 event_id: ScheduledEventId,
1438 ) -> Result<()> {
1439 self.wind(204, Request {
1440 body: None,
1441 multipart: None,
1442 headers: None,
1443 method: LightMethod::Delete,
1444 route: Route::GuildScheduledEvent {
1445 guild_id,
1446 event_id,
1447 },
1448 params: None,
1449 })
1450 .await
1451 }
1452
1453 pub async fn delete_sticker(
1457 &self,
1458 guild_id: GuildId,
1459 sticker_id: StickerId,
1460 audit_log_reason: Option<&str>,
1461 ) -> Result<()> {
1462 self.wind(204, Request {
1463 body: None,
1464 multipart: None,
1465 headers: audit_log_reason.map(reason_into_header),
1466 method: LightMethod::Delete,
1467 route: Route::GuildSticker {
1468 guild_id,
1469 sticker_id,
1470 },
1471 params: None,
1472 })
1473 .await
1474 }
1475
1476 pub async fn delete_test_entitlement(&self, entitlement_id: EntitlementId) -> Result<()> {
1479 self.wind(204, Request {
1480 body: None,
1481 multipart: None,
1482 headers: None,
1483 method: LightMethod::Delete,
1484 route: Route::Entitlement {
1485 application_id: self.try_application_id()?,
1486 entitlement_id,
1487 },
1488 params: None,
1489 })
1490 .await
1491 }
1492
1493 pub async fn delete_webhook(
1513 &self,
1514 webhook_id: WebhookId,
1515 audit_log_reason: Option<&str>,
1516 ) -> Result<()> {
1517 self.wind(204, Request {
1518 body: None,
1519 multipart: None,
1520 headers: audit_log_reason.map(reason_into_header),
1521 method: LightMethod::Delete,
1522 route: Route::Webhook {
1523 webhook_id,
1524 },
1525 params: None,
1526 })
1527 .await
1528 }
1529
1530 pub async fn delete_webhook_with_token(
1552 &self,
1553 webhook_id: WebhookId,
1554 token: &str,
1555 audit_log_reason: Option<&str>,
1556 ) -> Result<()> {
1557 self.wind(204, Request {
1558 body: None,
1559 multipart: None,
1560 headers: audit_log_reason.map(reason_into_header),
1561 method: LightMethod::Delete,
1562 route: Route::WebhookWithToken {
1563 webhook_id,
1564 token,
1565 },
1566 params: None,
1567 })
1568 .await
1569 }
1570
1571 pub async fn edit_channel(
1573 &self,
1574 channel_id: ChannelId,
1575 map: &impl serde::Serialize,
1576 audit_log_reason: Option<&str>,
1577 ) -> Result<GuildChannel> {
1578 let body = to_vec(map)?;
1579
1580 self.fire(Request {
1581 body: Some(body),
1582 multipart: None,
1583 headers: audit_log_reason.map(reason_into_header),
1584 method: LightMethod::Patch,
1585 route: Route::Channel {
1586 channel_id,
1587 },
1588 params: None,
1589 })
1590 .await
1591 }
1592
1593 pub async fn edit_stage_instance(
1595 &self,
1596 channel_id: ChannelId,
1597 map: &impl serde::Serialize,
1598 audit_log_reason: Option<&str>,
1599 ) -> Result<StageInstance> {
1600 self.fire(Request {
1601 body: Some(to_vec(map)?),
1602 multipart: None,
1603 headers: audit_log_reason.map(reason_into_header),
1604 method: LightMethod::Patch,
1605 route: Route::StageInstance {
1606 channel_id,
1607 },
1608 params: None,
1609 })
1610 .await
1611 }
1612
1613 pub async fn edit_emoji(
1617 &self,
1618 guild_id: GuildId,
1619 emoji_id: EmojiId,
1620 map: &Value,
1621 audit_log_reason: Option<&str>,
1622 ) -> Result<Emoji> {
1623 let body = to_vec(map)?;
1624
1625 self.fire(Request {
1626 body: Some(body),
1627 multipart: None,
1628 headers: audit_log_reason.map(reason_into_header),
1629 method: LightMethod::Patch,
1630 route: Route::GuildEmoji {
1631 guild_id,
1632 emoji_id,
1633 },
1634 params: None,
1635 })
1636 .await
1637 }
1638
1639 pub async fn edit_application_emoji(
1645 &self,
1646 emoji_id: EmojiId,
1647 map: &impl serde::Serialize,
1648 ) -> Result<Emoji> {
1649 self.fire(Request {
1650 body: Some(to_vec(map)?),
1651 multipart: None,
1652 headers: None,
1653 method: LightMethod::Patch,
1654 route: Route::Emoji {
1655 application_id: self.try_application_id()?,
1656 emoji_id,
1657 },
1658 params: None,
1659 })
1660 .await
1661 }
1662
1663 pub async fn edit_followup_message(
1669 &self,
1670 interaction_token: &str,
1671 message_id: MessageId,
1672 map: &impl serde::Serialize,
1673 new_attachments: Vec<CreateAttachment>,
1674 ) -> Result<Message> {
1675 let mut request = Request {
1676 body: None,
1677 multipart: None,
1678 headers: None,
1679 method: LightMethod::Patch,
1680 route: Route::WebhookFollowupMessage {
1681 application_id: self.try_application_id()?,
1682 token: interaction_token,
1683 message_id,
1684 },
1685 params: None,
1686 };
1687
1688 if new_attachments.is_empty() {
1689 request.body = Some(to_vec(map)?);
1690 } else {
1691 request.multipart = Some(Multipart {
1692 upload: MultipartUpload::Attachments(new_attachments),
1693 payload_json: Some(to_string(map)?),
1694 fields: vec![],
1695 });
1696 }
1697
1698 self.fire(request).await
1699 }
1700
1701 pub async fn get_followup_message(
1707 &self,
1708 interaction_token: &str,
1709 message_id: MessageId,
1710 ) -> Result<Message> {
1711 self.fire(Request {
1712 body: None,
1713 multipart: None,
1714 headers: None,
1715 method: LightMethod::Get,
1716 route: Route::WebhookFollowupMessage {
1717 application_id: self.try_application_id()?,
1718 token: interaction_token,
1719 message_id,
1720 },
1721 params: None,
1722 })
1723 .await
1724 }
1725
1726 pub async fn edit_global_command(
1734 &self,
1735 command_id: CommandId,
1736 map: &impl serde::Serialize,
1737 ) -> Result<Command> {
1738 self.fire(Request {
1739 body: Some(to_vec(map)?),
1740 multipart: None,
1741 headers: None,
1742 method: LightMethod::Patch,
1743 route: Route::Command {
1744 application_id: self.try_application_id()?,
1745 command_id,
1746 },
1747 params: None,
1748 })
1749 .await
1750 }
1751
1752 pub async fn edit_guild(
1754 &self,
1755 guild_id: GuildId,
1756 map: &impl serde::Serialize,
1757 audit_log_reason: Option<&str>,
1758 ) -> Result<PartialGuild> {
1759 let body = to_vec(map)?;
1760
1761 self.fire(Request {
1762 body: Some(body),
1763 multipart: None,
1764 headers: audit_log_reason.map(reason_into_header),
1765 method: LightMethod::Patch,
1766 route: Route::Guild {
1767 guild_id,
1768 },
1769 params: None,
1770 })
1771 .await
1772 }
1773
1774 pub async fn edit_guild_command(
1782 &self,
1783 guild_id: GuildId,
1784 command_id: CommandId,
1785 map: &impl serde::Serialize,
1786 ) -> Result<Command> {
1787 self.fire(Request {
1788 body: Some(to_vec(map)?),
1789 multipart: None,
1790 headers: None,
1791 method: LightMethod::Patch,
1792 route: Route::GuildCommand {
1793 application_id: self.try_application_id()?,
1794 guild_id,
1795 command_id,
1796 },
1797 params: None,
1798 })
1799 .await
1800 }
1801
1802 pub async fn edit_guild_command_permissions(
1810 &self,
1811 guild_id: GuildId,
1812 command_id: CommandId,
1813 map: &impl serde::Serialize,
1814 ) -> Result<CommandPermissions> {
1815 self.fire(Request {
1816 body: Some(to_vec(map)?),
1817 multipart: None,
1818 headers: None,
1819 method: LightMethod::Put,
1820 route: Route::GuildCommandPermissions {
1821 application_id: self.try_application_id()?,
1822 guild_id,
1823 command_id,
1824 },
1825 params: None,
1826 })
1827 .await
1828 }
1829
1830 pub async fn edit_guild_channel_positions(
1832 &self,
1833 guild_id: GuildId,
1834 value: &Value,
1835 ) -> Result<()> {
1836 let body = to_vec(value)?;
1837
1838 self.wind(204, Request {
1839 body: Some(body),
1840 multipart: None,
1841 headers: None,
1842 method: LightMethod::Patch,
1843 route: Route::GuildChannels {
1844 guild_id,
1845 },
1846 params: None,
1847 })
1848 .await
1849 }
1850
1851 pub async fn edit_guild_mfa_level(
1853 &self,
1854 guild_id: GuildId,
1855 value: &Value,
1856 audit_log_reason: Option<&str>,
1857 ) -> Result<MfaLevel> {
1858 #[derive(Deserialize)]
1859 struct GuildMfaLevel {
1860 level: MfaLevel,
1861 }
1862
1863 let body = to_vec(value)?;
1864
1865 self.fire(Request {
1866 body: Some(body),
1867 multipart: None,
1868 headers: audit_log_reason.map(reason_into_header),
1869 method: LightMethod::Post,
1870 route: Route::GuildMfa {
1871 guild_id,
1872 },
1873 params: None,
1874 })
1875 .await
1876 .map(|mfa: GuildMfaLevel| mfa.level)
1877 }
1878
1879 pub async fn edit_guild_widget(
1881 &self,
1882 guild_id: GuildId,
1883 map: &impl serde::Serialize,
1884 audit_log_reason: Option<&str>,
1885 ) -> Result<GuildWidget> {
1886 let body = to_vec(map)?;
1887
1888 self.fire(Request {
1889 body: Some(body),
1890 multipart: None,
1891 headers: audit_log_reason.map(reason_into_header),
1892 method: LightMethod::Patch,
1893 route: Route::GuildWidget {
1894 guild_id,
1895 },
1896 params: None,
1897 })
1898 .await
1899 }
1900
1901 pub async fn edit_guild_welcome_screen(
1903 &self,
1904 guild_id: GuildId,
1905 map: &impl serde::Serialize,
1906 audit_log_reason: Option<&str>,
1907 ) -> Result<GuildWelcomeScreen> {
1908 let body = to_vec(map)?;
1909
1910 self.fire(Request {
1911 body: Some(body),
1912 multipart: None,
1913 headers: audit_log_reason.map(reason_into_header),
1914 method: LightMethod::Patch,
1915 route: Route::GuildWelcomeScreen {
1916 guild_id,
1917 },
1918 params: None,
1919 })
1920 .await
1921 }
1922
1923 pub async fn edit_member(
1925 &self,
1926 guild_id: GuildId,
1927 user_id: UserId,
1928 map: &impl serde::Serialize,
1929 audit_log_reason: Option<&str>,
1930 ) -> Result<Member> {
1931 let body = to_vec(map)?;
1932
1933 let mut value: Value = self
1934 .fire(Request {
1935 body: Some(body),
1936 multipart: None,
1937 headers: audit_log_reason.map(reason_into_header),
1938 method: LightMethod::Patch,
1939 route: Route::GuildMember {
1940 guild_id,
1941 user_id,
1942 },
1943 params: None,
1944 })
1945 .await?;
1946
1947 if let Some(map) = value.as_object_mut() {
1948 map.insert("guild_id".to_string(), guild_id.get().into());
1949 }
1950
1951 from_value::<Member>(value)
1952 }
1953
1954 pub async fn edit_message(
1958 &self,
1959 channel_id: ChannelId,
1960 message_id: MessageId,
1961 map: &impl serde::Serialize,
1962 new_attachments: Vec<CreateAttachment>,
1963 ) -> Result<Message> {
1964 let mut request = Request {
1965 body: None,
1966 multipart: None,
1967 headers: None,
1968 method: LightMethod::Patch,
1969 route: Route::ChannelMessage {
1970 channel_id,
1971 message_id,
1972 },
1973 params: None,
1974 };
1975
1976 if new_attachments.is_empty() {
1977 request.body = Some(to_vec(map)?);
1978 } else {
1979 request.multipart = Some(Multipart {
1980 upload: MultipartUpload::Attachments(new_attachments),
1981 payload_json: Some(to_string(map)?),
1982 fields: vec![],
1983 });
1984 }
1985
1986 self.fire(request).await
1987 }
1988
1989 pub async fn crosspost_message(
1993 &self,
1994 channel_id: ChannelId,
1995 message_id: MessageId,
1996 ) -> Result<Message> {
1997 self.fire(Request {
1998 body: None,
1999 multipart: None,
2000 headers: None,
2001 method: LightMethod::Post,
2002 route: Route::ChannelMessageCrosspost {
2003 channel_id,
2004 message_id,
2005 },
2006 params: None,
2007 })
2008 .await
2009 }
2010
2011 pub async fn edit_member_me(
2013 &self,
2014 guild_id: GuildId,
2015 map: &JsonMap,
2016 audit_log_reason: Option<&str>,
2017 ) -> Result<Member> {
2018 let body = to_vec(map)?;
2019
2020 self.fire(Request {
2021 body: Some(body),
2022 multipart: None,
2023 headers: audit_log_reason.map(reason_into_header),
2024 method: LightMethod::Patch,
2025 route: Route::GuildMemberMe {
2026 guild_id,
2027 },
2028 params: None,
2029 })
2030 .await
2031 }
2032
2033 pub async fn edit_nickname(
2037 &self,
2038 guild_id: GuildId,
2039 new_nickname: Option<&str>,
2040 audit_log_reason: Option<&str>,
2041 ) -> Result<()> {
2042 let map = json!({ "nick": new_nickname });
2043 let body = to_vec(&map)?;
2044
2045 self.wind(200, Request {
2046 body: Some(body),
2047 multipart: None,
2048 headers: audit_log_reason.map(reason_into_header),
2049 method: LightMethod::Patch,
2050 route: Route::GuildMemberMe {
2051 guild_id,
2052 },
2053 params: None,
2054 })
2055 .await
2056 }
2057
2058 pub async fn follow_news_channel(
2060 &self,
2061 news_channel_id: ChannelId,
2062 target_channel_id: ChannelId,
2063 ) -> Result<FollowedChannel> {
2064 let map = json!({ "webhook_channel_id": target_channel_id });
2065 let body = to_vec(&map)?;
2066
2067 self.fire(Request {
2068 body: Some(body),
2069 multipart: None,
2070 headers: None,
2071 method: LightMethod::Post,
2072 route: Route::ChannelFollowNews {
2073 channel_id: news_channel_id,
2074 },
2075 params: None,
2076 })
2077 .await
2078 }
2079
2080 pub async fn get_original_interaction_response(
2082 &self,
2083 interaction_token: &str,
2084 ) -> Result<Message> {
2085 self.fire(Request {
2086 body: None,
2087 multipart: None,
2088 headers: None,
2089 method: LightMethod::Get,
2090 route: Route::WebhookOriginalInteractionResponse {
2091 application_id: self.try_application_id()?,
2092 token: interaction_token,
2093 },
2094 params: None,
2095 })
2096 .await
2097 }
2098
2099 pub async fn edit_original_interaction_response(
2105 &self,
2106 interaction_token: &str,
2107 map: &impl serde::Serialize,
2108 new_attachments: Vec<CreateAttachment>,
2109 ) -> Result<Message> {
2110 let mut request = Request {
2111 body: None,
2112 multipart: None,
2113 headers: None,
2114 method: LightMethod::Patch,
2115 route: Route::WebhookOriginalInteractionResponse {
2116 application_id: self.try_application_id()?,
2117 token: interaction_token,
2118 },
2119 params: None,
2120 };
2121
2122 if new_attachments.is_empty() {
2123 request.body = Some(to_vec(map)?);
2124 } else {
2125 request.multipart = Some(Multipart {
2126 upload: MultipartUpload::Attachments(new_attachments.into_iter().collect()),
2127 payload_json: Some(to_string(map)?),
2128 fields: vec![],
2129 });
2130 }
2131
2132 self.fire(request).await
2133 }
2134
2135 pub async fn edit_profile(&self, map: &impl serde::Serialize) -> Result<CurrentUser> {
2137 let body = to_vec(map)?;
2138
2139 self.fire(Request {
2140 body: Some(body),
2141 multipart: None,
2142 headers: None,
2143 method: LightMethod::Patch,
2144 route: Route::UserMe,
2145 params: None,
2146 })
2147 .await
2148 }
2149
2150 pub async fn edit_role(
2152 &self,
2153 guild_id: GuildId,
2154 role_id: RoleId,
2155 map: &impl serde::Serialize,
2156 audit_log_reason: Option<&str>,
2157 ) -> Result<Role> {
2158 let mut value: Value = self
2159 .fire(Request {
2160 body: Some(to_vec(map)?),
2161 multipart: None,
2162 headers: audit_log_reason.map(reason_into_header),
2163 method: LightMethod::Patch,
2164 route: Route::GuildRole {
2165 guild_id,
2166 role_id,
2167 },
2168 params: None,
2169 })
2170 .await?;
2171
2172 if let Some(map) = value.as_object_mut() {
2173 map.insert("guild_id".to_string(), guild_id.get().into());
2174 }
2175
2176 from_value(value)
2177 }
2178
2179 pub async fn edit_role_position(
2181 &self,
2182 guild_id: GuildId,
2183 role_id: RoleId,
2184 position: u16,
2185 audit_log_reason: Option<&str>,
2186 ) -> Result<Vec<Role>> {
2187 let map = json!([{
2188 "id": role_id,
2189 "position": position,
2190 }]);
2191 let body = to_vec(&map)?;
2192
2193 let mut value: Value = self
2194 .fire(Request {
2195 body: Some(body),
2196 multipart: None,
2197 headers: audit_log_reason.map(reason_into_header),
2198 method: LightMethod::Patch,
2199 route: Route::GuildRoles {
2200 guild_id,
2201 },
2202 params: None,
2203 })
2204 .await?;
2205
2206 if let Some(array) = value.as_array_mut() {
2207 for role in array {
2208 if let Some(map) = role.as_object_mut() {
2209 map.insert("guild_id".to_string(), guild_id.get().into());
2210 }
2211 }
2212 }
2213
2214 from_value(value)
2215 }
2216
2217 pub async fn edit_scheduled_event(
2223 &self,
2224 guild_id: GuildId,
2225 event_id: ScheduledEventId,
2226 map: &impl serde::Serialize,
2227 audit_log_reason: Option<&str>,
2228 ) -> Result<ScheduledEvent> {
2229 let body = to_vec(map)?;
2230 self.fire(Request {
2231 body: Some(body),
2232 multipart: None,
2233 headers: audit_log_reason.map(reason_into_header),
2234 method: LightMethod::Patch,
2235 route: Route::GuildScheduledEvent {
2236 guild_id,
2237 event_id,
2238 },
2239 params: None,
2240 })
2241 .await
2242 }
2243
2244 pub async fn edit_sticker(
2248 &self,
2249 guild_id: GuildId,
2250 sticker_id: StickerId,
2251 map: &impl serde::Serialize,
2252 audit_log_reason: Option<&str>,
2253 ) -> Result<Sticker> {
2254 let body = to_vec(&map)?;
2255
2256 let mut value: Value = self
2257 .fire(Request {
2258 body: Some(body),
2259 multipart: None,
2260 headers: audit_log_reason.map(reason_into_header),
2261 method: LightMethod::Patch,
2262 route: Route::GuildSticker {
2263 guild_id,
2264 sticker_id,
2265 },
2266 params: None,
2267 })
2268 .await?;
2269
2270 if let Some(map) = value.as_object_mut() {
2271 map.insert("guild_id".to_string(), guild_id.get().into());
2272 }
2273
2274 from_value(value)
2275 }
2276
2277 pub async fn edit_thread(
2279 &self,
2280 channel_id: ChannelId,
2281 map: &impl serde::Serialize,
2282 audit_log_reason: Option<&str>,
2283 ) -> Result<GuildChannel> {
2284 self.fire(Request {
2285 body: Some(to_vec(map)?),
2286 multipart: None,
2287 headers: audit_log_reason.map(reason_into_header),
2288 method: LightMethod::Patch,
2289 route: Route::Channel {
2290 channel_id,
2291 },
2292 params: None,
2293 })
2294 .await
2295 }
2296
2297 pub async fn edit_voice_state(
2328 &self,
2329 guild_id: GuildId,
2330 user_id: UserId,
2331 map: &impl serde::Serialize,
2332 ) -> Result<()> {
2333 self.wind(204, Request {
2334 body: Some(to_vec(map)?),
2335 multipart: None,
2336 headers: None,
2337 method: LightMethod::Patch,
2338 route: Route::GuildVoiceStates {
2339 guild_id,
2340 user_id,
2341 },
2342 params: None,
2343 })
2344 .await
2345 }
2346
2347 pub async fn edit_voice_state_me(
2381 &self,
2382 guild_id: GuildId,
2383 map: &impl serde::Serialize,
2384 ) -> Result<()> {
2385 self.wind(204, Request {
2386 body: Some(to_vec(map)?),
2387 multipart: None,
2388 headers: None,
2389 method: LightMethod::Patch,
2390 route: Route::GuildVoiceStateMe {
2391 guild_id,
2392 },
2393 params: None,
2394 })
2395 .await
2396 }
2397
2398 pub async fn edit_voice_status(
2400 &self,
2401 channel_id: ChannelId,
2402 map: &impl serde::Serialize,
2403 audit_log_reason: Option<&str>,
2404 ) -> Result<()> {
2405 let body = to_vec(map)?;
2406
2407 self.wind(204, Request {
2408 body: Some(body),
2409 multipart: None,
2410 headers: audit_log_reason.map(reason_into_header),
2411 method: LightMethod::Put,
2412 route: Route::ChannelVoiceStatus {
2413 channel_id,
2414 },
2415 params: None,
2416 })
2417 .await
2418 }
2419
2420 pub async fn edit_webhook(
2453 &self,
2454 webhook_id: WebhookId,
2455 map: &impl serde::Serialize,
2456 audit_log_reason: Option<&str>,
2457 ) -> Result<Webhook> {
2458 self.fire(Request {
2459 body: Some(to_vec(map)?),
2460 multipart: None,
2461 headers: audit_log_reason.map(reason_into_header),
2462 method: LightMethod::Patch,
2463 route: Route::Webhook {
2464 webhook_id,
2465 },
2466 params: None,
2467 })
2468 .await
2469 }
2470
2471 pub async fn edit_webhook_with_token(
2497 &self,
2498 webhook_id: WebhookId,
2499 token: &str,
2500 map: &impl serde::Serialize,
2501 audit_log_reason: Option<&str>,
2502 ) -> Result<Webhook> {
2503 let body = to_vec(map)?;
2504
2505 self.fire(Request {
2506 body: Some(body),
2507 multipart: None,
2508 headers: audit_log_reason.map(reason_into_header),
2509 method: LightMethod::Patch,
2510 route: Route::WebhookWithToken {
2511 webhook_id,
2512 token,
2513 },
2514 params: None,
2515 })
2516 .await
2517 }
2518
2519 pub async fn execute_webhook(
2570 &self,
2571 webhook_id: WebhookId,
2572 thread_id: Option<ChannelId>,
2573 token: &str,
2574 wait: bool,
2575 files: Vec<CreateAttachment>,
2576 map: &impl serde::Serialize,
2577 ) -> Result<Option<Message>> {
2578 self.execute_webhook_(webhook_id, thread_id, token, wait, files, map, false).await
2579 }
2580
2581 pub async fn execute_webhook_with_components(
2588 &self,
2589 webhook_id: WebhookId,
2590 thread_id: Option<ChannelId>,
2591 token: &str,
2592 wait: bool,
2593 files: Vec<CreateAttachment>,
2594 map: &impl serde::Serialize,
2595 ) -> Result<Option<Message>> {
2596 self.execute_webhook_(webhook_id, thread_id, token, wait, files, map, true).await
2597 }
2598
2599 #[allow(clippy::too_many_arguments)]
2600 async fn execute_webhook_(
2601 &self,
2602 webhook_id: WebhookId,
2603 thread_id: Option<ChannelId>,
2604 token: &str,
2605 wait: bool,
2606 files: Vec<CreateAttachment>,
2607 map: &impl serde::Serialize,
2608 with_components: bool,
2609 ) -> Result<Option<Message>> {
2610 let mut params = vec![("wait", wait.to_string())];
2611 if let Some(thread_id) = thread_id {
2612 params.push(("thread_id", thread_id.to_string()));
2613 }
2614
2615 if with_components {
2616 params.push(("with_components", with_components.to_string()));
2617 }
2618
2619 let mut request = Request {
2620 body: None,
2621 multipart: None,
2622 headers: None,
2623 method: LightMethod::Post,
2624 route: Route::WebhookWithToken {
2625 webhook_id,
2626 token,
2627 },
2628 params: Some(params),
2629 };
2630
2631 if files.is_empty() {
2632 request.body = Some(to_vec(map)?);
2633 } else {
2634 request.multipart = Some(Multipart {
2635 upload: MultipartUpload::Attachments(files.into_iter().collect()),
2636 payload_json: Some(to_string(map)?),
2637 fields: vec![],
2638 });
2639 }
2640
2641 let response = self.request(request).await?;
2642
2643 Ok(if response.status() == StatusCode::NO_CONTENT {
2644 None
2645 } else {
2646 decode_resp(response).await?
2647 })
2648 }
2649
2650 pub async fn get_webhook_message(
2652 &self,
2653 webhook_id: WebhookId,
2654 thread_id: Option<ChannelId>,
2655 token: &str,
2656 message_id: MessageId,
2657 ) -> Result<Message> {
2658 self.fire(Request {
2659 body: None,
2660 multipart: None,
2661 headers: None,
2662 method: LightMethod::Get,
2663 route: Route::WebhookMessage {
2664 webhook_id,
2665 token,
2666 message_id,
2667 },
2668 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2669 })
2670 .await
2671 }
2672
2673 pub async fn edit_webhook_message(
2675 &self,
2676 webhook_id: WebhookId,
2677 thread_id: Option<ChannelId>,
2678 token: &str,
2679 message_id: MessageId,
2680 map: &impl serde::Serialize,
2681 new_attachments: Vec<CreateAttachment>,
2682 ) -> Result<Message> {
2683 let mut request = Request {
2684 body: None,
2685 multipart: None,
2686 headers: None,
2687 method: LightMethod::Patch,
2688 route: Route::WebhookMessage {
2689 webhook_id,
2690 token,
2691 message_id,
2692 },
2693 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2694 };
2695
2696 if new_attachments.is_empty() {
2697 request.body = Some(to_vec(map)?);
2698 } else {
2699 request.multipart = Some(Multipart {
2700 upload: MultipartUpload::Attachments(new_attachments),
2701 payload_json: Some(to_string(map)?),
2702 fields: vec![],
2703 });
2704 }
2705
2706 self.fire(request).await
2707 }
2708
2709 pub async fn delete_webhook_message(
2711 &self,
2712 webhook_id: WebhookId,
2713 thread_id: Option<ChannelId>,
2714 token: &str,
2715 message_id: MessageId,
2716 ) -> Result<()> {
2717 self.wind(204, Request {
2718 body: None,
2719 multipart: None,
2720 headers: None,
2721 method: LightMethod::Delete,
2722 route: Route::WebhookMessage {
2723 webhook_id,
2724 token,
2725 message_id,
2726 },
2727 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2728 })
2729 .await
2730 }
2731
2732 pub async fn get_active_maintenances(&self) -> Result<Vec<Maintenance>> {
2736 #[derive(Deserialize)]
2737 struct StatusResponse {
2738 #[serde(default)]
2739 scheduled_maintenances: Vec<Maintenance>,
2740 }
2741
2742 let status: StatusResponse = self
2743 .fire(Request {
2744 body: None,
2745 multipart: None,
2746 headers: None,
2747 method: LightMethod::Get,
2748 route: Route::StatusMaintenancesActive,
2749 params: None,
2750 })
2751 .await?;
2752
2753 Ok(status.scheduled_maintenances)
2754 }
2755
2756 pub async fn get_bans(
2767 &self,
2768 guild_id: GuildId,
2769 target: Option<UserPagination>,
2770 limit: Option<u8>,
2771 ) -> Result<Vec<Ban>> {
2772 let mut params = vec![];
2773
2774 if let Some(limit) = limit {
2775 params.push(("limit", limit.to_string()));
2776 }
2777
2778 if let Some(target) = target {
2779 match target {
2780 UserPagination::After(id) => params.push(("after", id.to_string())),
2781 UserPagination::Before(id) => params.push(("before", id.to_string())),
2782 }
2783 }
2784
2785 self.fire(Request {
2786 body: None,
2787 multipart: None,
2788 headers: None,
2789 method: LightMethod::Get,
2790 route: Route::GuildBans {
2791 guild_id,
2792 },
2793 params: Some(params),
2794 })
2795 .await
2796 }
2797
2798 pub async fn get_ban(&self, guild_id: GuildId, user_id: UserId) -> Result<Option<Ban>> {
2809 let result = self
2810 .fire(Request {
2811 body: None,
2812 multipart: None,
2813 headers: None,
2814 method: LightMethod::Get,
2815 route: Route::GuildBan {
2816 guild_id,
2817 user_id,
2818 },
2819 params: None,
2820 })
2821 .await;
2822
2823 match result {
2824 Ok(ban) => Ok(Some(ban)),
2825 Err(Error::Http(ref err)) if err.status_code() == Some(StatusCode::NOT_FOUND) => {
2826 Ok(None)
2827 },
2828 Err(e) => Err(e),
2829 }
2830 }
2831
2832 pub async fn get_audit_logs(
2834 &self,
2835 guild_id: GuildId,
2836 action_type: Option<audit_log::Action>,
2837 user_id: Option<UserId>,
2838 before: Option<AuditLogEntryId>,
2839 limit: Option<u8>,
2840 ) -> Result<AuditLogs> {
2841 let mut params = vec![];
2842 if let Some(action_type) = action_type {
2843 params.push(("action_type", action_type.num().to_string()));
2844 }
2845 if let Some(before) = before {
2846 params.push(("before", before.to_string()));
2847 }
2848 if let Some(limit) = limit {
2849 params.push(("limit", limit.to_string()));
2850 }
2851 if let Some(user_id) = user_id {
2852 params.push(("user_id", user_id.to_string()));
2853 }
2854
2855 self.fire(Request {
2856 body: None,
2857 multipart: None,
2858 headers: None,
2859 method: LightMethod::Get,
2860 route: Route::GuildAuditLogs {
2861 guild_id,
2862 },
2863 params: Some(params),
2864 })
2865 .await
2866 }
2867
2868 pub async fn get_automod_rules(&self, guild_id: GuildId) -> Result<Vec<Rule>> {
2872 self.fire(Request {
2873 body: None,
2874 multipart: None,
2875 headers: None,
2876 method: LightMethod::Get,
2877 route: Route::GuildAutomodRules {
2878 guild_id,
2879 },
2880 params: None,
2881 })
2882 .await
2883 }
2884
2885 pub async fn get_automod_rule(&self, guild_id: GuildId, rule_id: RuleId) -> Result<Rule> {
2889 self.fire(Request {
2890 body: None,
2891 multipart: None,
2892 headers: None,
2893 method: LightMethod::Get,
2894 route: Route::GuildAutomodRule {
2895 guild_id,
2896 rule_id,
2897 },
2898 params: None,
2899 })
2900 .await
2901 }
2902
2903 pub async fn create_automod_rule(
2907 &self,
2908 guild_id: GuildId,
2909 map: &impl serde::Serialize,
2910 audit_log_reason: Option<&str>,
2911 ) -> Result<Rule> {
2912 let body = to_vec(map)?;
2913
2914 self.fire(Request {
2915 body: Some(body),
2916 multipart: None,
2917 headers: audit_log_reason.map(reason_into_header),
2918 method: LightMethod::Post,
2919 route: Route::GuildAutomodRules {
2920 guild_id,
2921 },
2922 params: None,
2923 })
2924 .await
2925 }
2926
2927 pub async fn edit_automod_rule(
2931 &self,
2932 guild_id: GuildId,
2933 rule_id: RuleId,
2934 map: &impl serde::Serialize,
2935 audit_log_reason: Option<&str>,
2936 ) -> Result<Rule> {
2937 let body = to_vec(map)?;
2938
2939 self.fire(Request {
2940 body: Some(body),
2941 multipart: None,
2942 headers: audit_log_reason.map(reason_into_header),
2943 method: LightMethod::Patch,
2944 route: Route::GuildAutomodRule {
2945 guild_id,
2946 rule_id,
2947 },
2948 params: None,
2949 })
2950 .await
2951 }
2952
2953 pub async fn delete_automod_rule(
2957 &self,
2958 guild_id: GuildId,
2959 rule_id: RuleId,
2960 audit_log_reason: Option<&str>,
2961 ) -> Result<()> {
2962 self.wind(204, Request {
2963 body: None,
2964 multipart: None,
2965 headers: audit_log_reason.map(reason_into_header),
2966 method: LightMethod::Delete,
2967 route: Route::GuildAutomodRule {
2968 guild_id,
2969 rule_id,
2970 },
2971 params: None,
2972 })
2973 .await
2974 }
2975
2976 pub async fn get_bot_gateway(&self) -> Result<BotGateway> {
2978 self.fire(Request {
2979 body: None,
2980 multipart: None,
2981 headers: None,
2982 method: LightMethod::Get,
2983 route: Route::GatewayBot,
2984 params: None,
2985 })
2986 .await
2987 }
2988
2989 pub async fn get_channel_invites(&self, channel_id: ChannelId) -> Result<Vec<RichInvite>> {
2991 self.fire(Request {
2992 body: None,
2993 multipart: None,
2994 headers: None,
2995 method: LightMethod::Get,
2996 route: Route::ChannelInvites {
2997 channel_id,
2998 },
2999 params: None,
3000 })
3001 .await
3002 }
3003
3004 pub async fn get_channel_thread_members(
3006 &self,
3007 channel_id: ChannelId,
3008 ) -> Result<Vec<ThreadMember>> {
3009 self.fire(Request {
3010 body: None,
3011 multipart: None,
3012 headers: None,
3013 method: LightMethod::Get,
3014 route: Route::ChannelThreadMembers {
3015 channel_id,
3016 },
3017 params: None,
3018 })
3019 .await
3020 }
3021
3022 pub async fn get_guild_active_threads(&self, guild_id: GuildId) -> Result<ThreadsData> {
3024 self.fire(Request {
3025 body: None,
3026 multipart: None,
3027 headers: None,
3028 method: LightMethod::Get,
3029 route: Route::GuildThreadsActive {
3030 guild_id,
3031 },
3032 params: None,
3033 })
3034 .await
3035 }
3036
3037 pub async fn get_channel_archived_public_threads(
3039 &self,
3040 channel_id: ChannelId,
3041 before: Option<u64>,
3042 limit: Option<u64>,
3043 ) -> Result<ThreadsData> {
3044 let mut params = vec![];
3045 if let Some(before) = before {
3046 params.push(("before", before.to_string()));
3047 }
3048 if let Some(limit) = limit {
3049 params.push(("limit", limit.to_string()));
3050 }
3051
3052 self.fire(Request {
3053 body: None,
3054 multipart: None,
3055 method: LightMethod::Get,
3056 headers: None,
3057 route: Route::ChannelArchivedPublicThreads {
3058 channel_id,
3059 },
3060 params: Some(params),
3061 })
3062 .await
3063 }
3064
3065 pub async fn get_channel_archived_private_threads(
3067 &self,
3068 channel_id: ChannelId,
3069 before: Option<u64>,
3070 limit: Option<u64>,
3071 ) -> Result<ThreadsData> {
3072 let mut params = vec![];
3073 if let Some(before) = before {
3074 params.push(("before", before.to_string()));
3075 }
3076 if let Some(limit) = limit {
3077 params.push(("limit", limit.to_string()));
3078 }
3079
3080 self.fire(Request {
3081 body: None,
3082 multipart: None,
3083 headers: None,
3084 method: LightMethod::Get,
3085 route: Route::ChannelArchivedPrivateThreads {
3086 channel_id,
3087 },
3088 params: Some(params),
3089 })
3090 .await
3091 }
3092
3093 pub async fn get_channel_joined_archived_private_threads(
3095 &self,
3096 channel_id: ChannelId,
3097 before: Option<u64>,
3098 limit: Option<u64>,
3099 ) -> Result<ThreadsData> {
3100 let mut params = vec![];
3101 if let Some(before) = before {
3102 params.push(("before", before.to_string()));
3103 }
3104 if let Some(limit) = limit {
3105 params.push(("limit", limit.to_string()));
3106 }
3107
3108 self.fire(Request {
3109 body: None,
3110 multipart: None,
3111 headers: None,
3112 method: LightMethod::Get,
3113 route: Route::ChannelJoinedPrivateThreads {
3114 channel_id,
3115 },
3116 params: Some(params),
3117 })
3118 .await
3119 }
3120
3121 pub async fn join_thread_channel(&self, channel_id: ChannelId) -> Result<()> {
3123 self.wind(204, Request {
3124 body: None,
3125 multipart: None,
3126 headers: None,
3127 method: LightMethod::Put,
3128 route: Route::ChannelThreadMemberMe {
3129 channel_id,
3130 },
3131 params: None,
3132 })
3133 .await
3134 }
3135
3136 pub async fn leave_thread_channel(&self, channel_id: ChannelId) -> Result<()> {
3138 self.wind(204, Request {
3139 body: None,
3140 multipart: None,
3141 headers: None,
3142 method: LightMethod::Delete,
3143 route: Route::ChannelThreadMemberMe {
3144 channel_id,
3145 },
3146 params: None,
3147 })
3148 .await
3149 }
3150
3151 pub async fn add_thread_channel_member(
3153 &self,
3154 channel_id: ChannelId,
3155 user_id: UserId,
3156 ) -> Result<()> {
3157 self.wind(204, Request {
3158 body: None,
3159 multipart: None,
3160 headers: None,
3161 method: LightMethod::Put,
3162 route: Route::ChannelThreadMember {
3163 channel_id,
3164 user_id,
3165 },
3166 params: None,
3167 })
3168 .await
3169 }
3170
3171 pub async fn remove_thread_channel_member(
3173 &self,
3174 channel_id: ChannelId,
3175 user_id: UserId,
3176 ) -> Result<()> {
3177 self.wind(204, Request {
3178 body: None,
3179 multipart: None,
3180 headers: None,
3181 method: LightMethod::Delete,
3182 route: Route::ChannelThreadMember {
3183 channel_id,
3184 user_id,
3185 },
3186 params: None,
3187 })
3188 .await
3189 }
3190
3191 pub async fn get_thread_channel_member(
3192 &self,
3193 channel_id: ChannelId,
3194 user_id: UserId,
3195 with_member: bool,
3196 ) -> Result<ThreadMember> {
3197 self.fire(Request {
3198 body: None,
3199 multipart: None,
3200 headers: None,
3201 method: LightMethod::Get,
3202 route: Route::ChannelThreadMember {
3203 channel_id,
3204 user_id,
3205 },
3206 params: Some(vec![("with_member", with_member.to_string())]),
3207 })
3208 .await
3209 }
3210
3211 pub async fn get_channel_webhooks(&self, channel_id: ChannelId) -> Result<Vec<Webhook>> {
3232 self.fire(Request {
3233 body: None,
3234 multipart: None,
3235 headers: None,
3236 method: LightMethod::Get,
3237 route: Route::ChannelWebhooks {
3238 channel_id,
3239 },
3240 params: None,
3241 })
3242 .await
3243 }
3244
3245 pub async fn get_channel(&self, channel_id: ChannelId) -> Result<Channel> {
3247 self.fire(Request {
3248 body: None,
3249 multipart: None,
3250 headers: None,
3251 method: LightMethod::Get,
3252 route: Route::Channel {
3253 channel_id,
3254 },
3255 params: None,
3256 })
3257 .await
3258 }
3259
3260 pub async fn get_channels(&self, guild_id: GuildId) -> Result<Vec<GuildChannel>> {
3262 self.fire(Request {
3263 body: None,
3264 multipart: None,
3265 headers: None,
3266 method: LightMethod::Get,
3267 route: Route::GuildChannels {
3268 guild_id,
3269 },
3270 params: None,
3271 })
3272 .await
3273 }
3274
3275 pub async fn get_stage_instance(&self, channel_id: ChannelId) -> Result<StageInstance> {
3277 self.fire(Request {
3278 body: None,
3279 multipart: None,
3280 headers: None,
3281 method: LightMethod::Get,
3282 route: Route::StageInstance {
3283 channel_id,
3284 },
3285 params: None,
3286 })
3287 .await
3288 }
3289
3290 pub async fn get_poll_answer_voters(
3292 &self,
3293 channel_id: ChannelId,
3294 message_id: MessageId,
3295 answer_id: AnswerId,
3296 after: Option<UserId>,
3297 limit: Option<u8>,
3298 ) -> Result<Vec<User>> {
3299 #[derive(Deserialize)]
3300 struct VotersResponse {
3301 users: Vec<User>,
3302 }
3303
3304 let mut params = Vec::with_capacity(2);
3305 if let Some(after) = after {
3306 params.push(("after", after.to_string()));
3307 }
3308
3309 if let Some(limit) = limit {
3310 params.push(("limit", limit.to_string()));
3311 }
3312
3313 let resp: VotersResponse = self
3314 .fire(Request {
3315 body: None,
3316 multipart: None,
3317 headers: None,
3318 method: LightMethod::Get,
3319 route: Route::ChannelPollGetAnswerVoters {
3320 channel_id,
3321 message_id,
3322 answer_id,
3323 },
3324 params: Some(params),
3325 })
3326 .await?;
3327
3328 Ok(resp.users)
3329 }
3330
3331 pub async fn expire_poll(
3332 &self,
3333 channel_id: ChannelId,
3334 message_id: MessageId,
3335 ) -> Result<Message> {
3336 self.fire(Request {
3337 body: None,
3338 multipart: None,
3339 headers: None,
3340 method: LightMethod::Post,
3341 route: Route::ChannelPollExpire {
3342 channel_id,
3343 message_id,
3344 },
3345 params: None,
3346 })
3347 .await
3348 }
3349
3350 pub async fn get_current_application_info(&self) -> Result<CurrentApplicationInfo> {
3354 self.fire(Request {
3355 body: None,
3356 multipart: None,
3357 headers: None,
3358 method: LightMethod::Get,
3359 route: Route::Oauth2ApplicationCurrent,
3360 params: None,
3361 })
3362 .await
3363 }
3364
3365 pub async fn get_current_user(&self) -> Result<CurrentUser> {
3367 self.fire(Request {
3368 body: None,
3369 multipart: None,
3370 headers: None,
3371 method: LightMethod::Get,
3372 route: Route::UserMe,
3373 params: None,
3374 })
3375 .await
3376 }
3377
3378 pub async fn get_emojis(&self, guild_id: GuildId) -> Result<Vec<Emoji>> {
3380 self.fire(Request {
3381 body: None,
3382 multipart: None,
3383 headers: None,
3384 method: LightMethod::Get,
3385 route: Route::GuildEmojis {
3386 guild_id,
3387 },
3388 params: None,
3389 })
3390 .await
3391 }
3392
3393 pub async fn get_emoji(&self, guild_id: GuildId, emoji_id: EmojiId) -> Result<Emoji> {
3395 self.fire(Request {
3396 body: None,
3397 multipart: None,
3398 headers: None,
3399 method: LightMethod::Get,
3400 route: Route::GuildEmoji {
3401 guild_id,
3402 emoji_id,
3403 },
3404 params: None,
3405 })
3406 .await
3407 }
3408
3409 pub async fn get_application_emojis(&self) -> Result<Vec<Emoji>> {
3411 #[derive(Deserialize)]
3413 struct ApplicationEmojis {
3414 items: Vec<Emoji>,
3415 }
3416
3417 let result: ApplicationEmojis = self
3418 .fire(Request {
3419 body: None,
3420 multipart: None,
3421 headers: None,
3422 method: LightMethod::Get,
3423 route: Route::Emojis {
3424 application_id: self.try_application_id()?,
3425 },
3426 params: None,
3427 })
3428 .await?;
3429
3430 Ok(result.items)
3431 }
3432
3433 pub async fn get_application_emoji(&self, emoji_id: EmojiId) -> Result<Emoji> {
3435 self.fire(Request {
3436 body: None,
3437 multipart: None,
3438 headers: None,
3439 method: LightMethod::Get,
3440 route: Route::Emoji {
3441 application_id: self.try_application_id()?,
3442 emoji_id,
3443 },
3444 params: None,
3445 })
3446 .await
3447 }
3448
3449 pub async fn consume_entitlement(&self, entitlement_id: EntitlementId) -> Result<()> {
3457 self.wind(204, Request {
3458 body: None,
3459 multipart: None,
3460 headers: None,
3461 method: LightMethod::Post,
3462 route: Route::ConsumeEntitlement {
3463 application_id: self.try_application_id()?,
3464 entitlement_id,
3465 },
3466 params: None,
3467 })
3468 .await
3469 }
3470
3471 #[allow(clippy::too_many_arguments)]
3472 pub async fn get_entitlements(
3474 &self,
3475 user_id: Option<UserId>,
3476 sku_ids: Option<Vec<SkuId>>,
3477 before: Option<EntitlementId>,
3478 after: Option<EntitlementId>,
3479 limit: Option<u8>,
3480 guild_id: Option<GuildId>,
3481 exclude_ended: Option<bool>,
3482 ) -> Result<Vec<Entitlement>> {
3483 let mut params = vec![];
3484 if let Some(user_id) = user_id {
3485 params.push(("user_id", user_id.to_string()));
3486 }
3487 if let Some(sku_ids) = sku_ids {
3488 params.push((
3489 "sku_ids",
3490 sku_ids.iter().map(ToString::to_string).collect::<Vec<_>>().join(","),
3491 ));
3492 }
3493 if let Some(before) = before {
3494 params.push(("before", before.to_string()));
3495 }
3496 if let Some(after) = after {
3497 params.push(("after", after.to_string()));
3498 }
3499 if let Some(limit) = limit {
3500 params.push(("limit", limit.to_string()));
3501 }
3502 if let Some(guild_id) = guild_id {
3503 params.push(("guild_id", guild_id.to_string()));
3504 }
3505 if let Some(exclude_ended) = exclude_ended {
3506 params.push(("exclude_ended", exclude_ended.to_string()));
3507 }
3508
3509 self.fire(Request {
3510 body: None,
3511 multipart: None,
3512 headers: None,
3513 method: LightMethod::Get,
3514 route: Route::Entitlements {
3515 application_id: self.try_application_id()?,
3516 },
3517 params: Some(params),
3518 })
3519 .await
3520 }
3521
3522 pub async fn get_gateway(&self) -> Result<Gateway> {
3524 self.fire(Request {
3525 body: None,
3526 multipart: None,
3527 headers: None,
3528 method: LightMethod::Get,
3529 route: Route::Gateway,
3530 params: None,
3531 })
3532 .await
3533 }
3534
3535 pub async fn get_global_commands(&self) -> Result<Vec<Command>> {
3537 self.fire(Request {
3538 body: None,
3539 multipart: None,
3540 headers: None,
3541 method: LightMethod::Get,
3542 route: Route::Commands {
3543 application_id: self.try_application_id()?,
3544 },
3545 params: None,
3546 })
3547 .await
3548 }
3549
3550 pub async fn get_global_commands_with_localizations(&self) -> Result<Vec<Command>> {
3552 self.fire(Request {
3553 body: None,
3554 multipart: None,
3555 headers: None,
3556 method: LightMethod::Get,
3557 route: Route::Commands {
3558 application_id: self.try_application_id()?,
3559 },
3560 params: Some(vec![("with_localizations", true.to_string())]),
3561 })
3562 .await
3563 }
3564
3565 pub async fn get_global_command(&self, command_id: CommandId) -> Result<Command> {
3567 self.fire(Request {
3568 body: None,
3569 multipart: None,
3570 headers: None,
3571 method: LightMethod::Get,
3572 route: Route::Command {
3573 application_id: self.try_application_id()?,
3574 command_id,
3575 },
3576 params: None,
3577 })
3578 .await
3579 }
3580
3581 pub async fn get_guild(&self, guild_id: GuildId) -> Result<PartialGuild> {
3583 self.fire(Request {
3584 body: None,
3585 multipart: None,
3586 headers: None,
3587 method: LightMethod::Get,
3588 route: Route::Guild {
3589 guild_id,
3590 },
3591 params: None,
3592 })
3593 .await
3594 }
3595
3596 pub async fn get_guild_with_counts(&self, guild_id: GuildId) -> Result<PartialGuild> {
3598 self.fire(Request {
3599 body: None,
3600 multipart: None,
3601 headers: None,
3602 method: LightMethod::Get,
3603 route: Route::Guild {
3604 guild_id,
3605 },
3606 params: Some(vec![("with_counts", true.to_string())]),
3607 })
3608 .await
3609 }
3610
3611 pub async fn get_guild_commands(&self, guild_id: GuildId) -> Result<Vec<Command>> {
3613 self.fire(Request {
3614 body: None,
3615 multipart: None,
3616 headers: None,
3617 method: LightMethod::Get,
3618 route: Route::GuildCommands {
3619 application_id: self.try_application_id()?,
3620 guild_id,
3621 },
3622 params: None,
3623 })
3624 .await
3625 }
3626
3627 pub async fn get_guild_commands_with_localizations(
3630 &self,
3631 guild_id: GuildId,
3632 ) -> Result<Vec<Command>> {
3633 self.fire(Request {
3634 body: None,
3635 multipart: None,
3636 headers: None,
3637 method: LightMethod::Get,
3638 route: Route::GuildCommands {
3639 application_id: self.try_application_id()?,
3640 guild_id,
3641 },
3642 params: Some(vec![("with_localizations", true.to_string())]),
3643 })
3644 .await
3645 }
3646
3647 pub async fn get_guild_command(
3649 &self,
3650 guild_id: GuildId,
3651 command_id: CommandId,
3652 ) -> Result<Command> {
3653 self.fire(Request {
3654 body: None,
3655 multipart: None,
3656 headers: None,
3657 method: LightMethod::Get,
3658 route: Route::GuildCommand {
3659 application_id: self.try_application_id()?,
3660 guild_id,
3661 command_id,
3662 },
3663 params: None,
3664 })
3665 .await
3666 }
3667
3668 pub async fn get_guild_commands_permissions(
3670 &self,
3671 guild_id: GuildId,
3672 ) -> Result<Vec<CommandPermissions>> {
3673 self.fire(Request {
3674 body: None,
3675 multipart: None,
3676 headers: None,
3677 method: LightMethod::Get,
3678 route: Route::GuildCommandsPermissions {
3679 application_id: self.try_application_id()?,
3680 guild_id,
3681 },
3682 params: None,
3683 })
3684 .await
3685 }
3686
3687 pub async fn get_guild_command_permissions(
3689 &self,
3690 guild_id: GuildId,
3691 command_id: CommandId,
3692 ) -> Result<CommandPermissions> {
3693 self.fire(Request {
3694 body: None,
3695 multipart: None,
3696 headers: None,
3697 method: LightMethod::Get,
3698 route: Route::GuildCommandPermissions {
3699 application_id: self.try_application_id()?,
3700 guild_id,
3701 command_id,
3702 },
3703 params: None,
3704 })
3705 .await
3706 }
3707
3708 pub async fn get_guild_widget(&self, guild_id: GuildId) -> Result<GuildWidget> {
3712 self.fire(Request {
3713 body: None,
3714 multipart: None,
3715 headers: None,
3716 method: LightMethod::Get,
3717 route: Route::GuildWidget {
3718 guild_id,
3719 },
3720 params: None,
3721 })
3722 .await
3723 }
3724
3725 pub async fn get_guild_preview(&self, guild_id: GuildId) -> Result<GuildPreview> {
3727 self.fire(Request {
3728 body: None,
3729 multipart: None,
3730 headers: None,
3731 method: LightMethod::Get,
3732 route: Route::GuildPreview {
3733 guild_id,
3734 },
3735 params: None,
3736 })
3737 .await
3738 }
3739
3740 pub async fn get_guild_welcome_screen(&self, guild_id: GuildId) -> Result<GuildWelcomeScreen> {
3742 self.fire(Request {
3743 body: None,
3744 multipart: None,
3745 headers: None,
3746 method: LightMethod::Get,
3747 route: Route::GuildWelcomeScreen {
3748 guild_id,
3749 },
3750 params: None,
3751 })
3752 .await
3753 }
3754
3755 pub async fn get_guild_integrations(&self, guild_id: GuildId) -> Result<Vec<Integration>> {
3757 self.fire(Request {
3758 body: None,
3759 multipart: None,
3760 headers: None,
3761 method: LightMethod::Get,
3762 route: Route::GuildIntegrations {
3763 guild_id,
3764 },
3765 params: None,
3766 })
3767 .await
3768 }
3769
3770 pub async fn get_guild_invites(&self, guild_id: GuildId) -> Result<Vec<RichInvite>> {
3772 self.fire(Request {
3773 body: None,
3774 multipart: None,
3775 headers: None,
3776 method: LightMethod::Get,
3777 route: Route::GuildInvites {
3778 guild_id,
3779 },
3780 params: None,
3781 })
3782 .await
3783 }
3784
3785 pub async fn get_guild_vanity_url(&self, guild_id: GuildId) -> Result<String> {
3787 #[derive(Deserialize)]
3788 struct GuildVanityUrl {
3789 code: String,
3790 }
3791
3792 self.fire::<GuildVanityUrl>(Request {
3793 body: None,
3794 multipart: None,
3795 headers: None,
3796 method: LightMethod::Get,
3797 route: Route::GuildVanityUrl {
3798 guild_id,
3799 },
3800 params: None,
3801 })
3802 .await
3803 .map(|x| x.code)
3804 }
3805
3806 pub async fn get_guild_members(
3809 &self,
3810 guild_id: GuildId,
3811 limit: Option<u64>,
3812 after: Option<u64>,
3813 ) -> Result<Vec<Member>> {
3814 if let Some(l) = limit {
3815 if !(1..=constants::MEMBER_FETCH_LIMIT).contains(&l) {
3816 return Err(Error::NotInRange("limit", l, 1, constants::MEMBER_FETCH_LIMIT));
3817 }
3818 }
3819
3820 let mut params =
3821 vec![("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string())];
3822 if let Some(after) = after {
3823 params.push(("after", after.to_string()));
3824 }
3825
3826 let mut value: Value = self
3827 .fire(Request {
3828 body: None,
3829 multipart: None,
3830 headers: None,
3831 method: LightMethod::Get,
3832 route: Route::GuildMembers {
3833 guild_id,
3834 },
3835 params: Some(params),
3836 })
3837 .await?;
3838
3839 if let Some(values) = value.as_array_mut() {
3840 for value in values {
3841 if let Some(element) = value.as_object_mut() {
3842 element.insert("guild_id".to_string(), guild_id.get().into());
3843 }
3844 }
3845 }
3846
3847 from_value(value)
3848 }
3849
3850 pub async fn get_guild_prune_count(&self, guild_id: GuildId, days: u8) -> Result<GuildPrune> {
3852 self.fire(Request {
3853 body: None,
3854 multipart: None,
3855 headers: None,
3856 method: LightMethod::Get,
3857 route: Route::GuildPrune {
3858 guild_id,
3859 },
3860 params: Some(vec![("days", days.to_string())]),
3861 })
3862 .await
3863 }
3864
3865 pub async fn get_guild_regions(&self, guild_id: GuildId) -> Result<Vec<VoiceRegion>> {
3868 self.fire(Request {
3869 body: None,
3870 multipart: None,
3871 headers: None,
3872 method: LightMethod::Get,
3873 route: Route::GuildRegions {
3874 guild_id,
3875 },
3876 params: None,
3877 })
3878 .await
3879 }
3880
3881 pub async fn get_guild_role(&self, guild_id: GuildId, role_id: RoleId) -> Result<Role> {
3883 let mut value: Value = self
3884 .fire(Request {
3885 body: None,
3886 multipart: None,
3887 headers: None,
3888 method: LightMethod::Get,
3889 route: Route::GuildRole {
3890 guild_id,
3891 role_id,
3892 },
3893 params: None,
3894 })
3895 .await?;
3896
3897 if let Some(map) = value.as_object_mut() {
3898 map.insert("guild_id".to_string(), guild_id.get().into());
3899 }
3900
3901 from_value(value)
3902 }
3903
3904 pub async fn get_guild_role_member_counts(
3906 &self,
3907 guild_id: GuildId,
3908 ) -> Result<HashMap<RoleId, u32>> {
3909 let value: Value = self
3910 .fire(Request {
3911 body: None,
3912 multipart: None,
3913 headers: None,
3914 method: LightMethod::Get,
3915 route: Route::GuildRoleMemberCounts {
3916 guild_id,
3917 },
3918 params: None,
3919 })
3920 .await?;
3921
3922 from_value(value)
3923 }
3924
3925 pub async fn get_guild_roles(&self, guild_id: GuildId) -> Result<Vec<Role>> {
3927 let mut value: Value = self
3928 .fire(Request {
3929 body: None,
3930 multipart: None,
3931 headers: None,
3932 method: LightMethod::Get,
3933 route: Route::GuildRoles {
3934 guild_id,
3935 },
3936 params: None,
3937 })
3938 .await?;
3939
3940 if let Some(array) = value.as_array_mut() {
3941 for sticker in array {
3942 if let Some(map) = sticker.as_object_mut() {
3943 map.insert("guild_id".to_string(), guild_id.get().into());
3944 }
3945 }
3946 }
3947
3948 from_value(value)
3949 }
3950
3951 pub async fn get_scheduled_event(
3957 &self,
3958 guild_id: GuildId,
3959 event_id: ScheduledEventId,
3960 with_user_count: bool,
3961 ) -> Result<ScheduledEvent> {
3962 self.fire(Request {
3963 body: None,
3964 multipart: None,
3965 headers: None,
3966 method: LightMethod::Get,
3967 route: Route::GuildScheduledEvent {
3968 guild_id,
3969 event_id,
3970 },
3971 params: Some(vec![("with_user_count", with_user_count.to_string())]),
3972 })
3973 .await
3974 }
3975
3976 pub async fn get_scheduled_events(
3982 &self,
3983 guild_id: GuildId,
3984 with_user_count: bool,
3985 ) -> Result<Vec<ScheduledEvent>> {
3986 self.fire(Request {
3987 body: None,
3988 multipart: None,
3989 headers: None,
3990 method: LightMethod::Get,
3991 route: Route::GuildScheduledEvents {
3992 guild_id,
3993 },
3994 params: Some(vec![("with_user_count", with_user_count.to_string())]),
3995 })
3996 .await
3997 }
3998
3999 pub async fn get_scheduled_event_users(
4016 &self,
4017 guild_id: GuildId,
4018 event_id: ScheduledEventId,
4019 limit: Option<u64>,
4020 target: Option<UserPagination>,
4021 with_member: Option<bool>,
4022 ) -> Result<Vec<ScheduledEventUser>> {
4023 let mut params = vec![];
4024 if let Some(limit) = limit {
4025 params.push(("limit", limit.to_string()));
4026 }
4027 if let Some(with_member) = with_member {
4028 params.push(("with_member", with_member.to_string()));
4029 }
4030 if let Some(target) = target {
4031 match target {
4032 UserPagination::After(id) => params.push(("after", id.to_string())),
4033 UserPagination::Before(id) => params.push(("before", id.to_string())),
4034 }
4035 }
4036
4037 self.fire(Request {
4038 body: None,
4039 multipart: None,
4040 headers: None,
4041 method: LightMethod::Get,
4042 route: Route::GuildScheduledEventUsers {
4043 guild_id,
4044 event_id,
4045 },
4046 params: Some(params),
4047 })
4048 .await
4049 }
4050
4051 pub async fn get_guild_stickers(&self, guild_id: GuildId) -> Result<Vec<Sticker>> {
4053 let mut value: Value = self
4054 .fire(Request {
4055 body: None,
4056 multipart: None,
4057 headers: None,
4058 method: LightMethod::Get,
4059 route: Route::GuildStickers {
4060 guild_id,
4061 },
4062 params: None,
4063 })
4064 .await?;
4065
4066 if let Some(array) = value.as_array_mut() {
4067 for role in array {
4068 if let Some(map) = role.as_object_mut() {
4069 map.insert("guild_id".to_string(), guild_id.get().into());
4070 }
4071 }
4072 }
4073
4074 from_value(value)
4075 }
4076
4077 pub async fn get_guild_sticker(
4079 &self,
4080 guild_id: GuildId,
4081 sticker_id: StickerId,
4082 ) -> Result<Sticker> {
4083 let mut value: Value = self
4084 .fire(Request {
4085 body: None,
4086 multipart: None,
4087 headers: None,
4088 method: LightMethod::Get,
4089 route: Route::GuildSticker {
4090 guild_id,
4091 sticker_id,
4092 },
4093 params: None,
4094 })
4095 .await?;
4096
4097 if let Some(map) = value.as_object_mut() {
4098 map.insert("guild_id".to_string(), guild_id.get().into());
4099 }
4100
4101 from_value(value)
4102 }
4103
4104 pub async fn get_guild_webhooks(&self, guild_id: GuildId) -> Result<Vec<Webhook>> {
4125 self.fire(Request {
4126 body: None,
4127 multipart: None,
4128 headers: None,
4129 method: LightMethod::Get,
4130 route: Route::GuildWebhooks {
4131 guild_id,
4132 },
4133 params: None,
4134 })
4135 .await
4136 }
4137
4138 pub async fn get_guilds(
4165 &self,
4166 target: Option<GuildPagination>,
4167 limit: Option<u64>,
4168 ) -> Result<Vec<GuildInfo>> {
4169 let mut params = vec![];
4170 if let Some(limit) = limit {
4171 params.push(("limit", limit.to_string()));
4172 }
4173 if let Some(target) = target {
4174 match target {
4175 GuildPagination::After(id) => params.push(("after", id.to_string())),
4176 GuildPagination::Before(id) => params.push(("before", id.to_string())),
4177 }
4178 }
4179
4180 self.fire(Request {
4181 body: None,
4182 multipart: None,
4183 headers: None,
4184 method: LightMethod::Get,
4185 route: Route::UserMeGuilds,
4186 params: Some(params),
4187 })
4188 .await
4189 }
4190
4191 pub async fn get_current_user_guild_member(&self, guild_id: GuildId) -> Result<Member> {
4221 let mut value: Value = self
4222 .fire(Request {
4223 body: None,
4224 multipart: None,
4225 headers: None,
4226 method: LightMethod::Get,
4227 route: Route::UserMeGuildMember {
4228 guild_id,
4229 },
4230 params: None,
4231 })
4232 .await?;
4233
4234 if let Some(map) = value.as_object_mut() {
4235 map.insert("guild_id".to_string(), guild_id.get().into());
4236 }
4237
4238 from_value(value)
4239 }
4240
4241 pub async fn get_invite(
4253 &self,
4254 code: &str,
4255 member_counts: bool,
4256 expiration: bool,
4257 event_id: Option<ScheduledEventId>,
4258 ) -> Result<Invite> {
4259 #[cfg(feature = "utils")]
4260 let code = crate::utils::parse_invite(code);
4261
4262 let mut params = vec![
4263 ("with_counts", member_counts.to_string()),
4264 ("with_expiration", expiration.to_string()),
4265 ];
4266 if let Some(event_id) = event_id {
4267 params.push(("guild_scheduled_event_id", event_id.to_string()));
4268 }
4269
4270 self.fire(Request {
4271 body: None,
4272 multipart: None,
4273 headers: None,
4274 method: LightMethod::Get,
4275 route: Route::Invite {
4276 code,
4277 },
4278 params: Some(params),
4279 })
4280 .await
4281 }
4282
4283 pub async fn get_member(&self, guild_id: GuildId, user_id: UserId) -> Result<Member> {
4285 let mut value: Value = self
4286 .fire(Request {
4287 body: None,
4288 multipart: None,
4289 headers: None,
4290 method: LightMethod::Get,
4291 route: Route::GuildMember {
4292 guild_id,
4293 user_id,
4294 },
4295 params: None,
4296 })
4297 .await?;
4298
4299 if let Some(map) = value.as_object_mut() {
4300 map.insert("guild_id".to_string(), guild_id.get().into());
4301 }
4302
4303 from_value(value)
4304 }
4305
4306 pub async fn get_message(
4308 &self,
4309 channel_id: ChannelId,
4310 message_id: MessageId,
4311 ) -> Result<Message> {
4312 self.fire(Request {
4313 body: None,
4314 multipart: None,
4315 headers: None,
4316 method: LightMethod::Get,
4317 route: Route::ChannelMessage {
4318 channel_id,
4319 message_id,
4320 },
4321 params: None,
4322 })
4323 .await
4324 }
4325
4326 pub async fn get_messages(
4328 &self,
4329 channel_id: ChannelId,
4330 target: Option<MessagePagination>,
4331 limit: Option<u8>,
4332 ) -> Result<Vec<Message>> {
4333 let mut params = vec![];
4334 if let Some(limit) = limit {
4335 params.push(("limit", limit.to_string()));
4336 }
4337 if let Some(target) = target {
4338 match target {
4339 MessagePagination::After(id) => params.push(("after", id.to_string())),
4340 MessagePagination::Around(id) => params.push(("around", id.to_string())),
4341 MessagePagination::Before(id) => params.push(("before", id.to_string())),
4342 }
4343 }
4344
4345 self.fire(Request {
4346 body: None,
4347 multipart: None,
4348 headers: None,
4349 method: LightMethod::Get,
4350 route: Route::ChannelMessages {
4351 channel_id,
4352 },
4353 params: Some(params),
4354 })
4355 .await
4356 }
4357
4358 pub async fn get_sticker_pack(&self, sticker_pack_id: StickerPackId) -> Result<StickerPack> {
4360 self.fire(Request {
4361 body: None,
4362 multipart: None,
4363 headers: None,
4364 method: LightMethod::Get,
4365 route: Route::StickerPack {
4366 sticker_pack_id,
4367 },
4368 params: None,
4369 })
4370 .await
4371 }
4372
4373 pub async fn get_nitro_stickers(&self) -> Result<Vec<StickerPack>> {
4375 #[derive(Deserialize)]
4376 struct StickerPacks {
4377 sticker_packs: Vec<StickerPack>,
4378 }
4379
4380 self.fire::<StickerPacks>(Request {
4381 body: None,
4382 multipart: None,
4383 headers: None,
4384 method: LightMethod::Get,
4385 route: Route::StickerPacks,
4386 params: None,
4387 })
4388 .await
4389 .map(|s| s.sticker_packs)
4390 }
4391
4392 pub async fn get_pins(&self, channel_id: ChannelId) -> Result<Vec<Message>> {
4394 self.fire(Request {
4395 body: None,
4396 multipart: None,
4397 headers: None,
4398 method: LightMethod::Get,
4399 route: Route::ChannelPins {
4400 channel_id,
4401 },
4402 params: None,
4403 })
4404 .await
4405 }
4406
4407 pub async fn get_reaction_users(
4409 &self,
4410 channel_id: ChannelId,
4411 message_id: MessageId,
4412 reaction_type: &ReactionType,
4413 limit: u8,
4414 after: Option<u64>,
4415 ) -> Result<Vec<User>> {
4416 let mut params = vec![("limit", limit.to_string())];
4417 if let Some(after) = after {
4418 params.push(("after", after.to_string()));
4419 }
4420 self.fire(Request {
4421 body: None,
4422 multipart: None,
4423 headers: None,
4424 method: LightMethod::Get,
4425 route: Route::ChannelMessageReactionEmoji {
4426 channel_id,
4427 message_id,
4428 reaction: &reaction_type.as_data(),
4429 },
4430 params: Some(params),
4431 })
4432 .await
4433 }
4434
4435 pub async fn get_skus(&self) -> Result<Vec<Sku>> {
4437 self.fire(Request {
4438 body: None,
4439 multipart: None,
4440 headers: None,
4441 method: LightMethod::Get,
4442 route: Route::Skus {
4443 application_id: self.try_application_id()?,
4444 },
4445 params: None,
4446 })
4447 .await
4448 }
4449
4450 pub async fn get_sticker(&self, sticker_id: StickerId) -> Result<Sticker> {
4452 self.fire(Request {
4453 body: None,
4454 multipart: None,
4455 headers: None,
4456 method: LightMethod::Get,
4457 route: Route::Sticker {
4458 sticker_id,
4459 },
4460 params: None,
4461 })
4462 .await
4463 }
4464
4465 pub async fn get_unresolved_incidents(&self) -> Result<Vec<Incident>> {
4469 #[derive(Deserialize)]
4470 struct StatusResponse {
4471 #[serde(default)]
4472 incidents: Vec<Incident>,
4473 }
4474
4475 let status: StatusResponse = self
4476 .fire(Request {
4477 body: None,
4478 multipart: None,
4479 headers: None,
4480 method: LightMethod::Get,
4481 route: Route::StatusIncidentsUnresolved,
4482 params: None,
4483 })
4484 .await?;
4485
4486 Ok(status.incidents)
4487 }
4488
4489 pub async fn get_upcoming_maintenances(&self) -> Result<Vec<Maintenance>> {
4493 #[derive(Deserialize)]
4494 struct StatusResponse {
4495 #[serde(default)]
4496 scheduled_maintenances: Vec<Maintenance>,
4497 }
4498
4499 let status: StatusResponse = self
4500 .fire(Request {
4501 body: None,
4502 multipart: None,
4503 headers: None,
4504 method: LightMethod::Get,
4505 route: Route::StatusMaintenancesUpcoming,
4506 params: None,
4507 })
4508 .await?;
4509
4510 Ok(status.scheduled_maintenances)
4511 }
4512
4513 pub async fn get_user(&self, user_id: UserId) -> Result<User> {
4515 self.fire(Request {
4516 body: None,
4517 multipart: None,
4518 headers: None,
4519 method: LightMethod::Get,
4520 route: Route::User {
4521 user_id,
4522 },
4523 params: None,
4524 })
4525 .await
4526 }
4527
4528 pub async fn get_user_connections(&self) -> Result<Vec<Connection>> {
4534 self.fire(Request {
4535 body: None,
4536 multipart: None,
4537 headers: None,
4538 method: LightMethod::Get,
4539 route: Route::UserMeConnections,
4540 params: None,
4541 })
4542 .await
4543 }
4544
4545 pub async fn get_user_dm_channels(&self) -> Result<Vec<PrivateChannel>> {
4547 self.fire(Request {
4548 body: None,
4549 multipart: None,
4550 headers: None,
4551 method: LightMethod::Get,
4552 route: Route::UserMeDmChannels,
4553 params: None,
4554 })
4555 .await
4556 }
4557
4558 pub async fn get_voice_regions(&self) -> Result<Vec<VoiceRegion>> {
4560 self.fire(Request {
4561 body: None,
4562 multipart: None,
4563 headers: None,
4564 method: LightMethod::Get,
4565 route: Route::VoiceRegions,
4566 params: None,
4567 })
4568 .await
4569 }
4570
4571 pub async fn get_user_voice_state(
4574 &self,
4575 guild_id: GuildId,
4576 user_id: UserId,
4577 ) -> Result<VoiceState> {
4578 self.fire(Request {
4579 body: None,
4580 multipart: None,
4581 headers: None,
4582 method: LightMethod::Get,
4583 route: Route::GuildVoiceStates {
4584 guild_id,
4585 user_id,
4586 },
4587 params: None,
4588 })
4589 .await
4590 }
4591
4592 pub async fn get_webhook(&self, webhook_id: WebhookId) -> Result<Webhook> {
4613 self.fire(Request {
4614 body: None,
4615 multipart: None,
4616 headers: None,
4617 method: LightMethod::Get,
4618 route: Route::Webhook {
4619 webhook_id,
4620 },
4621 params: None,
4622 })
4623 .await
4624 }
4625
4626 pub async fn get_webhook_with_token(
4648 &self,
4649 webhook_id: WebhookId,
4650 token: &str,
4651 ) -> Result<Webhook> {
4652 self.fire(Request {
4653 body: None,
4654 multipart: None,
4655 headers: None,
4656 method: LightMethod::Get,
4657 route: Route::WebhookWithToken {
4658 webhook_id,
4659 token,
4660 },
4661 params: None,
4662 })
4663 .await
4664 }
4665
4666 #[cfg(feature = "utils")]
4685 pub async fn get_webhook_from_url(&self, url: &str) -> Result<Webhook> {
4686 let url = Url::parse(url).map_err(HttpError::Url)?;
4687 let (webhook_id, token) =
4688 crate::utils::parse_webhook(&url).ok_or(HttpError::InvalidWebhook)?;
4689 self.fire(Request {
4690 body: None,
4691 multipart: None,
4692 headers: None,
4693 method: LightMethod::Get,
4694 route: Route::WebhookWithToken {
4695 webhook_id,
4696 token,
4697 },
4698 params: None,
4699 })
4700 .await
4701 }
4702
4703 pub async fn kick_member(
4705 &self,
4706 guild_id: GuildId,
4707 user_id: UserId,
4708 reason: Option<&str>,
4709 ) -> Result<()> {
4710 self.wind(204, Request {
4711 body: None,
4712 multipart: None,
4713 headers: reason.map(reason_into_header),
4714 method: LightMethod::Delete,
4715 route: Route::GuildMember {
4716 guild_id,
4717 user_id,
4718 },
4719 params: None,
4720 })
4721 .await
4722 }
4723
4724 pub async fn leave_guild(&self, guild_id: GuildId) -> Result<()> {
4726 self.wind(204, Request {
4727 body: None,
4728 multipart: None,
4729 headers: None,
4730 method: LightMethod::Delete,
4731 route: Route::UserMeGuild {
4732 guild_id,
4733 },
4734 params: None,
4735 })
4736 .await
4737 }
4738
4739 pub async fn send_message(
4745 &self,
4746 channel_id: ChannelId,
4747 files: Vec<CreateAttachment>,
4748 map: &impl serde::Serialize,
4749 ) -> Result<Message> {
4750 let mut request = Request {
4751 body: None,
4752 multipart: None,
4753 headers: None,
4754 method: LightMethod::Post,
4755 route: Route::ChannelMessages {
4756 channel_id,
4757 },
4758 params: None,
4759 };
4760
4761 if files.is_empty() {
4762 request.body = Some(to_vec(map)?);
4763 } else {
4764 request.multipart = Some(Multipart {
4765 upload: MultipartUpload::Attachments(files.into_iter().collect()),
4766 payload_json: Some(to_string(map)?),
4767 fields: vec![],
4768 });
4769 }
4770
4771 self.fire(request).await
4772 }
4773
4774 pub async fn pin_message(
4776 &self,
4777 channel_id: ChannelId,
4778 message_id: MessageId,
4779 audit_log_reason: Option<&str>,
4780 ) -> Result<()> {
4781 self.wind(204, Request {
4782 body: None,
4783 multipart: None,
4784 headers: audit_log_reason.map(reason_into_header),
4785 method: LightMethod::Put,
4786 route: Route::ChannelPin {
4787 channel_id,
4788 message_id,
4789 },
4790 params: None,
4791 })
4792 .await
4793 }
4794
4795 pub async fn remove_ban(
4797 &self,
4798 guild_id: GuildId,
4799 user_id: UserId,
4800 audit_log_reason: Option<&str>,
4801 ) -> Result<()> {
4802 self.wind(204, Request {
4803 body: None,
4804 multipart: None,
4805 headers: audit_log_reason.map(reason_into_header),
4806 method: LightMethod::Delete,
4807 route: Route::GuildBan {
4808 guild_id,
4809 user_id,
4810 },
4811 params: None,
4812 })
4813 .await
4814 }
4815
4816 pub async fn remove_member_role(
4822 &self,
4823 guild_id: GuildId,
4824 user_id: UserId,
4825 role_id: RoleId,
4826 audit_log_reason: Option<&str>,
4827 ) -> Result<()> {
4828 self.wind(204, Request {
4829 body: None,
4830 multipart: None,
4831 headers: audit_log_reason.map(reason_into_header),
4832 method: LightMethod::Delete,
4833 route: Route::GuildMemberRole {
4834 guild_id,
4835 user_id,
4836 role_id,
4837 },
4838 params: None,
4839 })
4840 .await
4841 }
4842
4843 pub async fn search_guild_members(
4846 &self,
4847 guild_id: GuildId,
4848 query: &str,
4849 limit: Option<u64>,
4850 ) -> Result<Vec<Member>> {
4851 let mut value: Value = self
4852 .fire(Request {
4853 body: None,
4854 multipart: None,
4855 headers: None,
4856 method: LightMethod::Get,
4857 route: Route::GuildMembersSearch {
4858 guild_id,
4859 },
4860 params: Some(vec![
4861 ("query", query.to_string()),
4862 ("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string()),
4863 ]),
4864 })
4865 .await?;
4866
4867 if let Some(members) = value.as_array_mut() {
4868 for member in members {
4869 if let Some(map) = member.as_object_mut() {
4870 map.insert("guild_id".to_string(), guild_id.get().into());
4871 }
4872 }
4873 }
4874
4875 from_value(value)
4876 }
4877
4878 pub async fn start_guild_prune(
4880 &self,
4881 guild_id: GuildId,
4882 days: u8,
4883 audit_log_reason: Option<&str>,
4884 ) -> Result<GuildPrune> {
4885 self.fire(Request {
4886 body: None,
4887 multipart: None,
4888 headers: audit_log_reason.map(reason_into_header),
4889 method: LightMethod::Post,
4890 route: Route::GuildPrune {
4891 guild_id,
4892 },
4893 params: Some(vec![("days", days.to_string())]),
4894 })
4895 .await
4896 }
4897
4898 pub async fn start_integration_sync(
4900 &self,
4901 guild_id: GuildId,
4902 integration_id: IntegrationId,
4903 ) -> Result<()> {
4904 self.wind(204, Request {
4905 body: None,
4906 multipart: None,
4907 headers: None,
4908 method: LightMethod::Post,
4909 route: Route::GuildIntegrationSync {
4910 guild_id,
4911 integration_id,
4912 },
4913 params: None,
4914 })
4915 .await
4916 }
4917
4918 pub async fn edit_guild_incident_actions(
4924 &self,
4925 guild_id: GuildId,
4926 map: &impl serde::Serialize,
4927 ) -> Result<IncidentsData> {
4928 self.fire(Request {
4929 body: Some(to_vec(map)?),
4930 multipart: None,
4931 headers: None,
4932 method: LightMethod::Put,
4933 route: Route::GuildIncidentActions {
4934 guild_id,
4935 },
4936 params: None,
4937 })
4938 .await
4939 }
4940
4941 pub fn start_typing(self: &Arc<Self>, channel_id: ChannelId) -> Typing {
4978 Typing::start(Arc::clone(self), channel_id)
4979 }
4980
4981 pub async fn unpin_message(
4983 &self,
4984 channel_id: ChannelId,
4985 message_id: MessageId,
4986 audit_log_reason: Option<&str>,
4987 ) -> Result<()> {
4988 self.wind(204, Request {
4989 body: None,
4990 multipart: None,
4991 headers: audit_log_reason.map(reason_into_header),
4992 method: LightMethod::Delete,
4993 route: Route::ChannelPin {
4994 channel_id,
4995 message_id,
4996 },
4997 params: None,
4998 })
4999 .await
5000 }
5001
5002 pub async fn send_soundboard_sound(
5004 &self,
5005 channel_id: ChannelId,
5006 map: &impl serde::Serialize,
5007 ) -> Result<()> {
5008 self.wind(204, Request {
5009 body: Some(to_vec(map)?),
5010 multipart: None,
5011 headers: None,
5012 method: LightMethod::Post,
5013 route: Route::SoundboardSend {
5014 channel_id,
5015 },
5016 params: None,
5017 })
5018 .await
5019 }
5020
5021 pub async fn list_default_soundboard_sounds(&self) -> Result<Vec<Soundboard>> {
5023 self.fire(Request {
5024 body: None,
5025 multipart: None,
5026 headers: None,
5027 method: LightMethod::Get,
5028 route: Route::SoundboardDefaultSounds,
5029 params: None,
5030 })
5031 .await
5032 }
5033
5034 pub async fn get_guild_soundboards(&self, guild_id: GuildId) -> Result<Vec<Soundboard>> {
5036 #[derive(serde::Deserialize)]
5037 struct SoundboardList {
5038 items: Vec<Soundboard>,
5039 }
5040
5041 let result = self
5042 .fire::<SoundboardList>(Request {
5043 body: None,
5044 multipart: None,
5045 headers: None,
5046 method: LightMethod::Get,
5047 route: Route::GuildSoundboards {
5048 guild_id,
5049 },
5050 params: None,
5051 })
5052 .await?;
5053
5054 Ok(result.items)
5055 }
5056
5057 pub async fn get_guild_soundboard(
5059 &self,
5060 guild_id: GuildId,
5061 sound_id: SoundId,
5062 ) -> Result<Soundboard> {
5063 self.fire(Request {
5064 body: None,
5065 multipart: None,
5066 headers: None,
5067 method: LightMethod::Get,
5068 route: Route::GuildSoundboard {
5069 guild_id,
5070 sound_id,
5071 },
5072 params: None,
5073 })
5074 .await
5075 }
5076
5077 pub async fn create_guild_soundboard(
5079 &self,
5080 guild_id: GuildId,
5081 map: &impl serde::Serialize,
5082 audit_log_reason: Option<&str>,
5083 ) -> Result<Soundboard> {
5084 self.fire(Request {
5085 body: Some(to_vec(map)?),
5086 multipart: None,
5087 headers: audit_log_reason.map(reason_into_header),
5088 method: LightMethod::Post,
5089 route: Route::GuildSoundboards {
5090 guild_id,
5091 },
5092 params: None,
5093 })
5094 .await
5095 }
5096
5097 pub async fn edit_guild_soundboard(
5099 &self,
5100 guild_id: GuildId,
5101 sound_id: SoundId,
5102 map: &impl serde::Serialize,
5103 audit_log_reason: Option<&str>,
5104 ) -> Result<Soundboard> {
5105 self.fire(Request {
5106 body: Some(to_vec(map)?),
5107 multipart: None,
5108 headers: audit_log_reason.map(reason_into_header),
5109 method: LightMethod::Patch,
5110 route: Route::GuildSoundboard {
5111 guild_id,
5112 sound_id,
5113 },
5114 params: None,
5115 })
5116 .await
5117 }
5118
5119 pub async fn delete_guild_soundboard(
5121 &self,
5122 guild_id: GuildId,
5123 sound_id: SoundId,
5124 audit_log_reason: Option<&str>,
5125 ) -> Result<()> {
5126 self.wind(204, Request {
5127 body: None,
5128 multipart: None,
5129 headers: audit_log_reason.map(reason_into_header),
5130 method: LightMethod::Delete,
5131 route: Route::GuildSoundboard {
5132 guild_id,
5133 sound_id,
5134 },
5135 params: None,
5136 })
5137 .await
5138 }
5139
5140 pub async fn fire<T: DeserializeOwned>(&self, req: Request<'_>) -> Result<T> {
5178 let response = self.request(req).await?;
5179 decode_resp(response).await
5180 }
5181
5182 #[instrument]
5214 pub async fn request(&self, req: Request<'_>) -> Result<ReqwestResponse> {
5215 let method = req.method.reqwest_method();
5216 let response = if let Some(ratelimiter) = &self.ratelimiter {
5217 ratelimiter.perform(req).await?
5218 } else {
5219 let request = req.build(&self.client, self.token(), self.proxy.as_deref())?.build()?;
5220 self.client.execute(request).await?
5221 };
5222
5223 if response.status().is_success() {
5224 Ok(response)
5225 } else {
5226 Err(Error::Http(HttpError::UnsuccessfulRequest(
5227 ErrorResponse::from_response(response, method).await,
5228 )))
5229 }
5230 }
5231
5232 pub(super) async fn wind(&self, expected: u16, req: Request<'_>) -> Result<()> {
5238 let route = req.route;
5239 let method = req.method.reqwest_method();
5240 let response = self.request(req).await?;
5241
5242 if response.status().is_success() {
5243 let response_status = response.status().as_u16();
5244 if response_status != expected {
5245 let route = route.path();
5246 warn!("Mismatched successful response status from {route}! Expected {expected} but got {response_status}");
5247 }
5248
5249 return Ok(());
5250 }
5251
5252 debug!("Unsuccessful response: {response:?}");
5253 Err(Error::Http(HttpError::UnsuccessfulRequest(
5254 ErrorResponse::from_response(response, method).await,
5255 )))
5256 }
5257}
5258
5259#[cfg(not(feature = "native_tls_backend"))]
5260fn configure_client_backend(builder: ClientBuilder) -> ClientBuilder {
5261 builder.use_rustls_tls()
5262}
5263
5264#[cfg(feature = "native_tls_backend")]
5265fn configure_client_backend(builder: ClientBuilder) -> ClientBuilder {
5266 builder.use_native_tls()
5267}
5268
5269impl AsRef<Http> for Http {
5270 fn as_ref(&self) -> &Http {
5271 self
5272 }
5273}