1#![allow(clippy::missing_errors_doc)]
2
3use std::borrow::Cow;
4use std::num::NonZeroU64;
5use std::sync::atomic::{AtomicU64, Ordering};
6use std::sync::Arc;
7
8use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
9use reqwest::header::{HeaderMap as Headers, HeaderValue};
10#[cfg(feature = "utils")]
11use reqwest::Url;
12use reqwest::{Client, ClientBuilder, Response as ReqwestResponse, StatusCode};
13use secrecy::{ExposeSecret, SecretString};
14use serde::de::DeserializeOwned;
15use tracing::{debug, instrument, warn};
16
17use super::multipart::{Multipart, MultipartUpload};
18use super::ratelimiting::Ratelimiter;
19use super::request::Request;
20use super::routing::Route;
21use super::typing::Typing;
22use super::{
23 ErrorResponse,
24 GuildPagination,
25 HttpError,
26 LightMethod,
27 MessagePagination,
28 UserPagination,
29};
30use crate::builder::{CreateAllowedMentions, CreateAttachment};
31use crate::constants;
32use crate::internal::prelude::*;
33use crate::json::*;
34use crate::model::prelude::*;
35
36#[must_use]
53pub struct HttpBuilder {
54 client: Option<Client>,
55 ratelimiter: Option<Ratelimiter>,
56 ratelimiter_disabled: bool,
57 token: SecretString,
58 proxy: Option<String>,
59 application_id: Option<ApplicationId>,
60 default_allowed_mentions: Option<CreateAllowedMentions>,
61}
62
63impl HttpBuilder {
64 pub fn new(token: impl AsRef<str>) -> Self {
67 Self {
68 client: None,
69 ratelimiter: None,
70 ratelimiter_disabled: false,
71 token: SecretString::new(parse_token(token)),
72 proxy: None,
73 application_id: None,
74 default_allowed_mentions: None,
75 }
76 }
77
78 pub fn application_id(mut self, application_id: ApplicationId) -> Self {
80 self.application_id = Some(application_id);
81 self
82 }
83
84 pub fn token(mut self, token: impl AsRef<str>) -> Self {
87 self.token = SecretString::new(parse_token(token));
88 self
89 }
90
91 pub fn client(mut self, client: Client) -> Self {
93 self.client = Some(client);
94 self
95 }
96
97 pub fn ratelimiter(mut self, ratelimiter: Ratelimiter) -> Self {
99 self.ratelimiter = Some(ratelimiter);
100 self
101 }
102
103 pub fn ratelimiter_disabled(mut self, ratelimiter_disabled: bool) -> Self {
110 self.ratelimiter_disabled = ratelimiter_disabled;
111 self
112 }
113
114 pub fn proxy(mut self, proxy: impl Into<String>) -> Self {
129 self.proxy = Some(proxy.into());
130 self
131 }
132
133 pub fn default_allowed_mentions(mut self, allowed_mentions: CreateAllowedMentions) -> Self {
138 self.default_allowed_mentions = Some(allowed_mentions);
139 self
140 }
141
142 #[must_use]
144 pub fn build(self) -> Http {
145 let application_id = AtomicU64::new(self.application_id.map_or(0, ApplicationId::get));
146
147 let client = self.client.unwrap_or_else(|| {
148 let builder = configure_client_backend(Client::builder());
149 builder.build().expect("Cannot build reqwest::Client")
150 });
151
152 let ratelimiter = (!self.ratelimiter_disabled).then(|| {
153 self.ratelimiter
154 .unwrap_or_else(|| Ratelimiter::new(client.clone(), self.token.expose_secret()))
155 });
156
157 Http {
158 client,
159 ratelimiter,
160 proxy: self.proxy,
161 token: self.token,
162 application_id,
163 default_allowed_mentions: self.default_allowed_mentions,
164 }
165 }
166}
167
168fn parse_token(token: impl AsRef<str>) -> String {
169 let token = token.as_ref().trim();
170
171 if token.starts_with("Bot ") || token.starts_with("Bearer ") {
172 token.to_string()
173 } else {
174 format!("Bot {token}")
175 }
176}
177
178fn reason_into_header(reason: &str) -> Headers {
179 let mut headers = Headers::new();
180
181 let header_value = match Cow::from(utf8_percent_encode(reason, NON_ALPHANUMERIC)) {
184 Cow::Borrowed(value) => HeaderValue::from_str(value),
185 Cow::Owned(value) => HeaderValue::try_from(value),
186 }
187 .expect("Invalid header value even after percent encode");
188
189 headers.insert("X-Audit-Log-Reason", header_value);
190 headers
191}
192
193#[derive(Debug)]
196pub struct Http {
197 pub(crate) client: Client,
198 pub ratelimiter: Option<Ratelimiter>,
199 pub proxy: Option<String>,
200 token: SecretString,
201 application_id: AtomicU64,
202 pub default_allowed_mentions: Option<CreateAllowedMentions>,
203}
204
205impl Http {
206 #[must_use]
207 pub fn new(token: &str) -> Self {
208 HttpBuilder::new(token).build()
209 }
210
211 pub fn application_id(&self) -> Option<ApplicationId> {
212 let application_id = self.application_id.load(Ordering::Relaxed);
213 NonZeroU64::new(application_id).map(ApplicationId::from)
214 }
215
216 fn try_application_id(&self) -> Result<ApplicationId> {
217 self.application_id().ok_or_else(|| HttpError::ApplicationIdMissing.into())
218 }
219
220 pub fn set_application_id(&self, application_id: ApplicationId) {
221 self.application_id.store(application_id.get(), Ordering::Relaxed);
222 }
223
224 pub fn token(&self) -> &str {
225 self.token.expose_secret()
226 }
227
228 pub async fn add_guild_member(
232 &self,
233 guild_id: GuildId,
234 user_id: UserId,
235 map: &impl serde::Serialize,
236 ) -> Result<Option<Member>> {
237 let body = to_vec(map)?;
238
239 let response = self
240 .request(Request {
241 body: Some(body),
242 multipart: None,
243 headers: None,
244 method: LightMethod::Put,
245 route: Route::GuildMember {
246 guild_id,
247 user_id,
248 },
249 params: None,
250 })
251 .await?;
252
253 if response.status() == 204 {
254 Ok(None)
255 } else {
256 Ok(Some(decode_resp(response).await?))
257 }
258 }
259
260 pub async fn add_member_role(
266 &self,
267 guild_id: GuildId,
268 user_id: UserId,
269 role_id: RoleId,
270 audit_log_reason: Option<&str>,
271 ) -> Result<()> {
272 self.wind(204, Request {
273 body: None,
274 multipart: None,
275 headers: audit_log_reason.map(reason_into_header),
276 method: LightMethod::Put,
277 route: Route::GuildMemberRole {
278 guild_id,
279 role_id,
280 user_id,
281 },
282 params: None,
283 })
284 .await
285 }
286
287 pub async fn ban_user(
297 &self,
298 guild_id: GuildId,
299 user_id: UserId,
300 delete_message_days: u8,
301 reason: Option<&str>,
302 ) -> Result<()> {
303 let delete_message_seconds = u32::from(delete_message_days) * 86400;
304
305 self.wind(204, Request {
306 body: None,
307 multipart: None,
308 headers: reason.map(reason_into_header),
309 method: LightMethod::Put,
310 route: Route::GuildBan {
311 guild_id,
312 user_id,
313 },
314 params: Some(vec![("delete_message_seconds", delete_message_seconds.to_string())]),
315 })
316 .await
317 }
318
319 pub async fn bulk_ban_users(
324 &self,
325 guild_id: GuildId,
326 map: &impl serde::Serialize,
327 reason: Option<&str>,
328 ) -> Result<BulkBanResponse> {
329 self.fire(Request {
330 body: Some(to_vec(map)?),
331 multipart: None,
332 headers: reason.map(reason_into_header),
333 method: LightMethod::Post,
334 route: Route::GuildBulkBan {
335 guild_id,
336 },
337 params: None,
338 })
339 .await
340 }
341
342 pub async fn broadcast_typing(&self, channel_id: ChannelId) -> Result<()> {
350 self.wind(204, Request {
351 body: None,
352 multipart: None,
353 headers: None,
354 method: LightMethod::Post,
355 route: Route::ChannelTyping {
356 channel_id,
357 },
358 params: None,
359 })
360 .await
361 }
362
363 pub async fn create_channel(
372 &self,
373 guild_id: GuildId,
374 map: &impl serde::Serialize,
375 audit_log_reason: Option<&str>,
376 ) -> Result<GuildChannel> {
377 let body = to_vec(map)?;
378
379 self.fire(Request {
380 body: Some(body),
381 multipart: None,
382 headers: audit_log_reason.map(reason_into_header),
383 method: LightMethod::Post,
384 route: Route::GuildChannels {
385 guild_id,
386 },
387 params: None,
388 })
389 .await
390 }
391
392 pub async fn create_stage_instance(
394 &self,
395 map: &impl serde::Serialize,
396 audit_log_reason: Option<&str>,
397 ) -> Result<StageInstance> {
398 self.fire(Request {
399 body: Some(to_vec(map)?),
400 multipart: None,
401 headers: audit_log_reason.map(reason_into_header),
402 method: LightMethod::Post,
403 route: Route::StageInstances,
404 params: None,
405 })
406 .await
407 }
408
409 pub async fn create_thread_from_message(
411 &self,
412 channel_id: ChannelId,
413 message_id: MessageId,
414 map: &impl serde::Serialize,
415 audit_log_reason: Option<&str>,
416 ) -> Result<GuildChannel> {
417 let body = to_vec(map)?;
418
419 self.fire(Request {
420 body: Some(body),
421 multipart: None,
422 headers: audit_log_reason.map(reason_into_header),
423 method: LightMethod::Post,
424 route: Route::ChannelMessageThreads {
425 channel_id,
426 message_id,
427 },
428 params: None,
429 })
430 .await
431 }
432
433 pub async fn create_thread(
435 &self,
436 channel_id: ChannelId,
437 map: &impl serde::Serialize,
438 audit_log_reason: Option<&str>,
439 ) -> Result<GuildChannel> {
440 let body = to_vec(map)?;
441
442 self.fire(Request {
443 body: Some(body),
444 multipart: None,
445 headers: audit_log_reason.map(reason_into_header),
446 method: LightMethod::Post,
447 route: Route::ChannelThreads {
448 channel_id,
449 },
450 params: None,
451 })
452 .await
453 }
454
455 pub async fn create_forum_post(
457 &self,
458 channel_id: ChannelId,
459 map: &impl serde::Serialize,
460 audit_log_reason: Option<&str>,
461 ) -> Result<GuildChannel> {
462 self.create_forum_post_with_attachments(channel_id, map, vec![], audit_log_reason).await
463 }
464
465 pub async fn create_forum_post_with_attachments(
467 &self,
468 channel_id: ChannelId,
469 map: &impl serde::Serialize,
470 files: Vec<CreateAttachment>,
471 audit_log_reason: Option<&str>,
472 ) -> Result<GuildChannel> {
473 self.fire(Request {
474 body: None,
475 multipart: Some(Multipart {
476 upload: MultipartUpload::Attachments(files.into_iter().collect()),
477 payload_json: Some(to_string(map)?),
478 fields: vec![],
479 }),
480 headers: audit_log_reason.map(reason_into_header),
481 method: LightMethod::Post,
482 route: Route::ChannelForumPosts {
483 channel_id,
484 },
485 params: None,
486 })
487 .await
488 }
489
490 pub async fn create_emoji(
498 &self,
499 guild_id: GuildId,
500 map: &Value,
501 audit_log_reason: Option<&str>,
502 ) -> Result<Emoji> {
503 self.fire(Request {
504 body: Some(to_vec(map)?),
505 multipart: None,
506 headers: audit_log_reason.map(reason_into_header),
507 method: LightMethod::Post,
508 route: Route::GuildEmojis {
509 guild_id,
510 },
511 params: None,
512 })
513 .await
514 }
515
516 pub async fn create_application_emoji(&self, map: &impl serde::Serialize) -> Result<Emoji> {
522 self.fire(Request {
523 body: Some(to_vec(map)?),
524 multipart: None,
525 headers: None,
526 method: LightMethod::Post,
527 route: Route::Emojis {
528 application_id: self.try_application_id()?,
529 },
530 params: None,
531 })
532 .await
533 }
534
535 pub async fn create_followup_message(
539 &self,
540 interaction_token: &str,
541 map: &impl serde::Serialize,
542 files: Vec<CreateAttachment>,
543 ) -> Result<Message> {
544 let mut request = Request {
545 body: None,
546 multipart: None,
547 headers: None,
548 method: LightMethod::Post,
549 route: Route::WebhookFollowupMessages {
550 application_id: self.try_application_id()?,
551 token: interaction_token,
552 },
553 params: None,
554 };
555
556 if files.is_empty() {
557 request.body = Some(to_vec(map)?);
558 } else {
559 request.multipart = Some(Multipart {
560 upload: MultipartUpload::Attachments(files),
561 payload_json: Some(to_string(map)?),
562 fields: vec![],
563 });
564 }
565
566 self.fire(request).await
567 }
568
569 pub async fn create_global_command(&self, map: &impl serde::Serialize) -> Result<Command> {
580 self.fire(Request {
581 body: Some(to_vec(map)?),
582 multipart: None,
583 headers: None,
584 method: LightMethod::Post,
585 route: Route::Commands {
586 application_id: self.try_application_id()?,
587 },
588 params: None,
589 })
590 .await
591 }
592
593 pub async fn create_global_commands(
595 &self,
596 map: &impl serde::Serialize,
597 ) -> Result<Vec<Command>> {
598 self.fire(Request {
599 body: Some(to_vec(map)?),
600 multipart: None,
601 headers: None,
602 method: LightMethod::Put,
603 route: Route::Commands {
604 application_id: self.try_application_id()?,
605 },
606 params: None,
607 })
608 .await
609 }
610
611 pub async fn create_guild_commands(
613 &self,
614 guild_id: GuildId,
615 map: &impl serde::Serialize,
616 ) -> Result<Vec<Command>> {
617 self.fire(Request {
618 body: Some(to_vec(map)?),
619 multipart: None,
620 headers: None,
621 method: LightMethod::Put,
622 route: Route::GuildCommands {
623 application_id: self.try_application_id()?,
624 guild_id,
625 },
626 params: None,
627 })
628 .await
629 }
630
631 pub async fn create_guild(&self, map: &Value) -> Result<PartialGuild> {
665 self.fire(Request {
666 body: Some(to_vec(map)?),
667 multipart: None,
668 headers: None,
669 method: LightMethod::Post,
670 route: Route::Guilds,
671 params: None,
672 })
673 .await
674 }
675
676 pub async fn create_guild_command(
684 &self,
685 guild_id: GuildId,
686 map: &impl serde::Serialize,
687 ) -> Result<Command> {
688 self.fire(Request {
689 body: Some(to_vec(map)?),
690 multipart: None,
691 headers: None,
692 method: LightMethod::Post,
693 route: Route::GuildCommands {
694 application_id: self.try_application_id()?,
695 guild_id,
696 },
697 params: None,
698 })
699 .await
700 }
701
702 pub async fn create_guild_integration(
711 &self,
712 guild_id: GuildId,
713 integration_id: IntegrationId,
714 map: &Value,
715 audit_log_reason: Option<&str>,
716 ) -> Result<()> {
717 self.wind(204, Request {
718 body: Some(to_vec(map)?),
719 multipart: None,
720 headers: audit_log_reason.map(reason_into_header),
721 method: LightMethod::Post,
722 route: Route::GuildIntegration {
723 guild_id,
724 integration_id,
725 },
726 params: None,
727 })
728 .await
729 }
730
731 pub async fn create_interaction_response(
738 &self,
739 interaction_id: InteractionId,
740 interaction_token: &str,
741 map: &impl serde::Serialize,
742 files: Vec<CreateAttachment>,
743 ) -> Result<()> {
744 let mut request = Request {
745 body: None,
746 multipart: None,
747 headers: None,
748 method: LightMethod::Post,
749 route: Route::InteractionResponse {
750 interaction_id,
751 token: interaction_token,
752 },
753 params: None,
754 };
755
756 if files.is_empty() {
757 request.body = Some(to_vec(map)?);
758 } else {
759 request.multipart = Some(Multipart {
760 upload: MultipartUpload::Attachments(files),
761 payload_json: Some(to_string(map)?),
762 fields: vec![],
763 });
764 }
765
766 self.wind(204, request).await
767 }
768
769 pub async fn create_invite(
780 &self,
781 channel_id: ChannelId,
782 map: &impl serde::Serialize,
783 audit_log_reason: Option<&str>,
784 ) -> Result<RichInvite> {
785 let body = to_vec(map)?;
786
787 self.fire(Request {
788 body: Some(body),
789 multipart: None,
790 headers: audit_log_reason.map(reason_into_header),
791 method: LightMethod::Post,
792 route: Route::ChannelInvites {
793 channel_id,
794 },
795 params: None,
796 })
797 .await
798 }
799
800 pub async fn create_permission(
802 &self,
803 channel_id: ChannelId,
804 target_id: TargetId,
805 map: &impl serde::Serialize,
806 audit_log_reason: Option<&str>,
807 ) -> Result<()> {
808 let body = to_vec(map)?;
809
810 self.wind(204, Request {
811 body: Some(body),
812 multipart: None,
813 headers: audit_log_reason.map(reason_into_header),
814 method: LightMethod::Put,
815 route: Route::ChannelPermission {
816 channel_id,
817 target_id,
818 },
819 params: None,
820 })
821 .await
822 }
823
824 pub async fn create_private_channel(&self, map: &Value) -> Result<PrivateChannel> {
826 let body = to_vec(map)?;
827
828 self.fire(Request {
829 body: Some(body),
830 multipart: None,
831 headers: None,
832 method: LightMethod::Post,
833 route: Route::UserMeDmChannels,
834 params: None,
835 })
836 .await
837 }
838
839 async fn create_reaction_(
840 &self,
841 channel_id: ChannelId,
842 message_id: MessageId,
843 reaction_type: &ReactionType,
844 burst: bool,
845 ) -> Result<()> {
846 self.wind(204, Request {
847 body: None,
848 multipart: None,
849 headers: None,
850 method: LightMethod::Put,
851 route: Route::ChannelMessageReactionMe {
852 channel_id,
853 message_id,
854 reaction: &reaction_type.as_data(),
855 },
856 params: Some(vec![("burst", burst.to_string())]),
857 })
858 .await
859 }
860
861 pub async fn create_reaction(
863 &self,
864 channel_id: ChannelId,
865 message_id: MessageId,
866 reaction_type: &ReactionType,
867 ) -> Result<()> {
868 self.create_reaction_(channel_id, message_id, reaction_type, false).await
869 }
870
871 pub async fn create_super_reaction(
873 &self,
874 channel_id: ChannelId,
875 message_id: MessageId,
876 reaction_type: &ReactionType,
877 ) -> Result<()> {
878 self.create_reaction_(channel_id, message_id, reaction_type, true).await
879 }
880
881 pub async fn create_role(
883 &self,
884 guild_id: GuildId,
885 body: &impl serde::Serialize,
886 audit_log_reason: Option<&str>,
887 ) -> Result<Role> {
888 let mut value: Value = self
889 .fire(Request {
890 body: Some(to_vec(body)?),
891 multipart: None,
892 headers: audit_log_reason.map(reason_into_header),
893 method: LightMethod::Post,
894 route: Route::GuildRoles {
895 guild_id,
896 },
897 params: None,
898 })
899 .await?;
900
901 if let Some(map) = value.as_object_mut() {
902 map.insert("guild_id".to_string(), guild_id.get().into());
903 }
904
905 from_value(value).map_err(From::from)
906 }
907
908 pub async fn create_scheduled_event(
916 &self,
917 guild_id: GuildId,
918 map: &impl serde::Serialize,
919 audit_log_reason: Option<&str>,
920 ) -> Result<ScheduledEvent> {
921 let body = to_vec(map)?;
922 self.fire(Request {
923 body: Some(body),
924 multipart: None,
925 headers: audit_log_reason.map(reason_into_header),
926 method: LightMethod::Post,
927 route: Route::GuildScheduledEvents {
928 guild_id,
929 },
930 params: None,
931 })
932 .await
933 }
934
935 pub async fn create_sticker(
941 &self,
942 guild_id: GuildId,
943 map: impl IntoIterator<Item = (&'static str, String)>,
944 file: CreateAttachment,
945 audit_log_reason: Option<&str>,
946 ) -> Result<Sticker> {
947 self.fire(Request {
948 body: None,
949 multipart: Some(Multipart {
950 upload: MultipartUpload::File(file),
951 fields: map.into_iter().map(|(k, v)| (k.into(), v.into())).collect(),
952 payload_json: None,
953 }),
954 headers: audit_log_reason.map(reason_into_header),
955 method: LightMethod::Post,
956 route: Route::GuildStickers {
957 guild_id,
958 },
959 params: None,
960 })
961 .await
962 }
963
964 pub async fn create_test_entitlement(
968 &self,
969 sku_id: SkuId,
970 owner: EntitlementOwner,
971 ) -> Result<Entitlement> {
972 #[derive(serde::Serialize)]
973 struct TestEntitlement {
974 sku_id: SkuId,
975 owner_id: u64,
976 owner_type: u8,
977 }
978
979 let (owner_id, owner_type) = match owner {
980 EntitlementOwner::Guild(id) => (id.get(), 1),
981 EntitlementOwner::User(id) => (id.get(), 2),
982 };
983
984 let map = TestEntitlement {
985 sku_id,
986 owner_id,
987 owner_type,
988 };
989
990 self.fire(Request {
991 body: Some(to_vec(&map)?),
992 multipart: None,
993 headers: None,
994 method: LightMethod::Post,
995 route: Route::Entitlements {
996 application_id: self.try_application_id()?,
997 },
998 params: None,
999 })
1000 .await
1001 }
1002
1003 pub async fn create_webhook(
1030 &self,
1031 channel_id: ChannelId,
1032 map: &impl serde::Serialize,
1033 audit_log_reason: Option<&str>,
1034 ) -> Result<Webhook> {
1035 let body = to_vec(map)?;
1036
1037 self.fire(Request {
1038 body: Some(body),
1039 multipart: None,
1040 headers: audit_log_reason.map(reason_into_header),
1041 method: LightMethod::Post,
1042 route: Route::ChannelWebhooks {
1043 channel_id,
1044 },
1045 params: None,
1046 })
1047 .await
1048 }
1049
1050 pub async fn delete_channel(
1052 &self,
1053 channel_id: ChannelId,
1054 audit_log_reason: Option<&str>,
1055 ) -> Result<Channel> {
1056 self.fire(Request {
1057 body: None,
1058 multipart: None,
1059 headers: audit_log_reason.map(reason_into_header),
1060 method: LightMethod::Delete,
1061 route: Route::Channel {
1062 channel_id,
1063 },
1064 params: None,
1065 })
1066 .await
1067 }
1068
1069 pub async fn delete_stage_instance(
1071 &self,
1072 channel_id: ChannelId,
1073 audit_log_reason: Option<&str>,
1074 ) -> Result<()> {
1075 self.wind(204, Request {
1076 body: None,
1077 multipart: None,
1078 headers: audit_log_reason.map(reason_into_header),
1079 method: LightMethod::Delete,
1080 route: Route::StageInstance {
1081 channel_id,
1082 },
1083 params: None,
1084 })
1085 .await
1086 }
1087
1088 pub async fn delete_emoji(
1092 &self,
1093 guild_id: GuildId,
1094 emoji_id: EmojiId,
1095 audit_log_reason: Option<&str>,
1096 ) -> Result<()> {
1097 self.wind(204, Request {
1098 body: None,
1099 multipart: None,
1100 headers: audit_log_reason.map(reason_into_header),
1101 method: LightMethod::Delete,
1102 route: Route::GuildEmoji {
1103 guild_id,
1104 emoji_id,
1105 },
1106 params: None,
1107 })
1108 .await
1109 }
1110
1111 pub async fn delete_application_emoji(&self, emoji_id: EmojiId) -> Result<()> {
1113 self.wind(204, Request {
1114 body: None,
1115 multipart: None,
1116 headers: None,
1117 method: LightMethod::Delete,
1118 route: Route::Emoji {
1119 application_id: self.try_application_id()?,
1120 emoji_id,
1121 },
1122 params: None,
1123 })
1124 .await
1125 }
1126
1127 pub async fn delete_followup_message(
1129 &self,
1130 interaction_token: &str,
1131 message_id: MessageId,
1132 ) -> Result<()> {
1133 self.wind(204, Request {
1134 body: None,
1135 multipart: None,
1136 headers: None,
1137 method: LightMethod::Delete,
1138 route: Route::WebhookFollowupMessage {
1139 application_id: self.try_application_id()?,
1140 token: interaction_token,
1141 message_id,
1142 },
1143 params: None,
1144 })
1145 .await
1146 }
1147
1148 pub async fn delete_global_command(&self, command_id: CommandId) -> Result<()> {
1150 self.wind(204, Request {
1151 body: None,
1152 multipart: None,
1153 headers: None,
1154 method: LightMethod::Delete,
1155 route: Route::Command {
1156 application_id: self.try_application_id()?,
1157 command_id,
1158 },
1159 params: None,
1160 })
1161 .await
1162 }
1163
1164 pub async fn delete_guild(&self, guild_id: GuildId) -> Result<()> {
1166 self.wind(204, Request {
1167 body: None,
1168 multipart: None,
1169 headers: None,
1170 method: LightMethod::Delete,
1171 route: Route::Guild {
1172 guild_id,
1173 },
1174 params: None,
1175 })
1176 .await
1177 }
1178
1179 pub async fn delete_guild_command(
1181 &self,
1182 guild_id: GuildId,
1183 command_id: CommandId,
1184 ) -> Result<()> {
1185 self.wind(204, Request {
1186 body: None,
1187 multipart: None,
1188 headers: None,
1189 method: LightMethod::Delete,
1190 route: Route::GuildCommand {
1191 application_id: self.try_application_id()?,
1192 guild_id,
1193 command_id,
1194 },
1195 params: None,
1196 })
1197 .await
1198 }
1199
1200 pub async fn delete_guild_integration(
1202 &self,
1203 guild_id: GuildId,
1204 integration_id: IntegrationId,
1205 audit_log_reason: Option<&str>,
1206 ) -> Result<()> {
1207 self.wind(204, Request {
1208 body: None,
1209 multipart: None,
1210 headers: audit_log_reason.map(reason_into_header),
1211 method: LightMethod::Delete,
1212 route: Route::GuildIntegration {
1213 guild_id,
1214 integration_id,
1215 },
1216 params: None,
1217 })
1218 .await
1219 }
1220
1221 pub async fn delete_invite(
1223 &self,
1224 code: &str,
1225 audit_log_reason: Option<&str>,
1226 ) -> Result<Invite> {
1227 self.fire(Request {
1228 body: None,
1229 multipart: None,
1230 headers: audit_log_reason.map(reason_into_header),
1231 method: LightMethod::Delete,
1232 route: Route::Invite {
1233 code,
1234 },
1235 params: None,
1236 })
1237 .await
1238 }
1239
1240 pub async fn delete_message(
1242 &self,
1243 channel_id: ChannelId,
1244 message_id: MessageId,
1245 audit_log_reason: Option<&str>,
1246 ) -> Result<()> {
1247 self.wind(204, Request {
1248 body: None,
1249 multipart: None,
1250 headers: audit_log_reason.map(reason_into_header),
1251 method: LightMethod::Delete,
1252 route: Route::ChannelMessage {
1253 channel_id,
1254 message_id,
1255 },
1256 params: None,
1257 })
1258 .await
1259 }
1260
1261 pub async fn delete_messages(
1263 &self,
1264 channel_id: ChannelId,
1265 map: &Value,
1266 audit_log_reason: Option<&str>,
1267 ) -> Result<()> {
1268 self.wind(204, Request {
1269 body: Some(to_vec(map)?),
1270 multipart: None,
1271 headers: audit_log_reason.map(reason_into_header),
1272 method: LightMethod::Post,
1273 route: Route::ChannelMessagesBulkDelete {
1274 channel_id,
1275 },
1276 params: None,
1277 })
1278 .await
1279 }
1280
1281 pub async fn delete_message_reactions(
1300 &self,
1301 channel_id: ChannelId,
1302 message_id: MessageId,
1303 ) -> Result<()> {
1304 self.wind(204, Request {
1305 body: None,
1306 multipart: None,
1307 headers: None,
1308 method: LightMethod::Delete,
1309 route: Route::ChannelMessageReactions {
1310 channel_id,
1311 message_id,
1312 },
1313 params: None,
1314 })
1315 .await
1316 }
1317
1318 pub async fn delete_message_reaction_emoji(
1320 &self,
1321 channel_id: ChannelId,
1322 message_id: MessageId,
1323 reaction_type: &ReactionType,
1324 ) -> Result<()> {
1325 self.wind(204, Request {
1326 body: None,
1327 multipart: None,
1328 headers: None,
1329 method: LightMethod::Delete,
1330 route: Route::ChannelMessageReactionEmoji {
1331 channel_id,
1332 message_id,
1333 reaction: &reaction_type.as_data(),
1334 },
1335 params: None,
1336 })
1337 .await
1338 }
1339
1340 pub async fn delete_original_interaction_response(
1342 &self,
1343 interaction_token: &str,
1344 ) -> Result<()> {
1345 self.wind(204, Request {
1346 body: None,
1347 multipart: None,
1348 headers: None,
1349 method: LightMethod::Delete,
1350 route: Route::WebhookOriginalInteractionResponse {
1351 application_id: self.try_application_id()?,
1352 token: interaction_token,
1353 },
1354 params: None,
1355 })
1356 .await
1357 }
1358
1359 pub async fn delete_permission(
1361 &self,
1362 channel_id: ChannelId,
1363 target_id: TargetId,
1364 audit_log_reason: Option<&str>,
1365 ) -> Result<()> {
1366 self.wind(204, Request {
1367 body: None,
1368 multipart: None,
1369 headers: audit_log_reason.map(reason_into_header),
1370 method: LightMethod::Delete,
1371 route: Route::ChannelPermission {
1372 channel_id,
1373 target_id,
1374 },
1375 params: None,
1376 })
1377 .await
1378 }
1379
1380 pub async fn delete_reaction(
1382 &self,
1383 channel_id: ChannelId,
1384 message_id: MessageId,
1385 user_id: UserId,
1386 reaction_type: &ReactionType,
1387 ) -> Result<()> {
1388 self.wind(204, Request {
1389 body: None,
1390 multipart: None,
1391 headers: None,
1392 method: LightMethod::Delete,
1393 route: Route::ChannelMessageReaction {
1394 channel_id,
1395 message_id,
1396 user_id,
1397 reaction: &reaction_type.as_data(),
1398 },
1399 params: None,
1400 })
1401 .await
1402 }
1403
1404 pub async fn delete_reaction_me(
1406 &self,
1407 channel_id: ChannelId,
1408 message_id: MessageId,
1409 reaction_type: &ReactionType,
1410 ) -> Result<()> {
1411 self.wind(204, Request {
1412 body: None,
1413 multipart: None,
1414 headers: None,
1415 method: LightMethod::Delete,
1416 route: Route::ChannelMessageReactionMe {
1417 channel_id,
1418 message_id,
1419 reaction: &reaction_type.as_data(),
1420 },
1421 params: None,
1422 })
1423 .await
1424 }
1425
1426 pub async fn delete_role(
1428 &self,
1429 guild_id: GuildId,
1430 role_id: RoleId,
1431 audit_log_reason: Option<&str>,
1432 ) -> Result<()> {
1433 self.wind(204, Request {
1434 body: None,
1435 multipart: None,
1436 headers: audit_log_reason.map(reason_into_header),
1437 method: LightMethod::Delete,
1438 route: Route::GuildRole {
1439 guild_id,
1440 role_id,
1441 },
1442 params: None,
1443 })
1444 .await
1445 }
1446
1447 pub async fn delete_scheduled_event(
1454 &self,
1455 guild_id: GuildId,
1456 event_id: ScheduledEventId,
1457 ) -> Result<()> {
1458 self.wind(204, Request {
1459 body: None,
1460 multipart: None,
1461 headers: None,
1462 method: LightMethod::Delete,
1463 route: Route::GuildScheduledEvent {
1464 guild_id,
1465 event_id,
1466 },
1467 params: None,
1468 })
1469 .await
1470 }
1471
1472 pub async fn delete_sticker(
1476 &self,
1477 guild_id: GuildId,
1478 sticker_id: StickerId,
1479 audit_log_reason: Option<&str>,
1480 ) -> Result<()> {
1481 self.wind(204, Request {
1482 body: None,
1483 multipart: None,
1484 headers: audit_log_reason.map(reason_into_header),
1485 method: LightMethod::Delete,
1486 route: Route::GuildSticker {
1487 guild_id,
1488 sticker_id,
1489 },
1490 params: None,
1491 })
1492 .await
1493 }
1494
1495 pub async fn delete_test_entitlement(&self, entitlement_id: EntitlementId) -> Result<()> {
1498 self.wind(204, Request {
1499 body: None,
1500 multipart: None,
1501 headers: None,
1502 method: LightMethod::Delete,
1503 route: Route::Entitlement {
1504 application_id: self.try_application_id()?,
1505 entitlement_id,
1506 },
1507 params: None,
1508 })
1509 .await
1510 }
1511
1512 pub async fn delete_webhook(
1532 &self,
1533 webhook_id: WebhookId,
1534 audit_log_reason: Option<&str>,
1535 ) -> Result<()> {
1536 self.wind(204, Request {
1537 body: None,
1538 multipart: None,
1539 headers: audit_log_reason.map(reason_into_header),
1540 method: LightMethod::Delete,
1541 route: Route::Webhook {
1542 webhook_id,
1543 },
1544 params: None,
1545 })
1546 .await
1547 }
1548
1549 pub async fn delete_webhook_with_token(
1571 &self,
1572 webhook_id: WebhookId,
1573 token: &str,
1574 audit_log_reason: Option<&str>,
1575 ) -> Result<()> {
1576 self.wind(204, Request {
1577 body: None,
1578 multipart: None,
1579 headers: audit_log_reason.map(reason_into_header),
1580 method: LightMethod::Delete,
1581 route: Route::WebhookWithToken {
1582 webhook_id,
1583 token,
1584 },
1585 params: None,
1586 })
1587 .await
1588 }
1589
1590 pub async fn edit_channel(
1592 &self,
1593 channel_id: ChannelId,
1594 map: &impl serde::Serialize,
1595 audit_log_reason: Option<&str>,
1596 ) -> Result<GuildChannel> {
1597 let body = to_vec(map)?;
1598
1599 self.fire(Request {
1600 body: Some(body),
1601 multipart: None,
1602 headers: audit_log_reason.map(reason_into_header),
1603 method: LightMethod::Patch,
1604 route: Route::Channel {
1605 channel_id,
1606 },
1607 params: None,
1608 })
1609 .await
1610 }
1611
1612 pub async fn edit_stage_instance(
1614 &self,
1615 channel_id: ChannelId,
1616 map: &impl serde::Serialize,
1617 audit_log_reason: Option<&str>,
1618 ) -> Result<StageInstance> {
1619 self.fire(Request {
1620 body: Some(to_vec(map)?),
1621 multipart: None,
1622 headers: audit_log_reason.map(reason_into_header),
1623 method: LightMethod::Patch,
1624 route: Route::StageInstance {
1625 channel_id,
1626 },
1627 params: None,
1628 })
1629 .await
1630 }
1631
1632 pub async fn edit_emoji(
1636 &self,
1637 guild_id: GuildId,
1638 emoji_id: EmojiId,
1639 map: &Value,
1640 audit_log_reason: Option<&str>,
1641 ) -> Result<Emoji> {
1642 let body = to_vec(map)?;
1643
1644 self.fire(Request {
1645 body: Some(body),
1646 multipart: None,
1647 headers: audit_log_reason.map(reason_into_header),
1648 method: LightMethod::Patch,
1649 route: Route::GuildEmoji {
1650 guild_id,
1651 emoji_id,
1652 },
1653 params: None,
1654 })
1655 .await
1656 }
1657
1658 pub async fn edit_application_emoji(
1664 &self,
1665 emoji_id: EmojiId,
1666 map: &impl serde::Serialize,
1667 ) -> Result<Emoji> {
1668 self.fire(Request {
1669 body: Some(to_vec(map)?),
1670 multipart: None,
1671 headers: None,
1672 method: LightMethod::Patch,
1673 route: Route::Emoji {
1674 application_id: self.try_application_id()?,
1675 emoji_id,
1676 },
1677 params: None,
1678 })
1679 .await
1680 }
1681
1682 pub async fn edit_followup_message(
1688 &self,
1689 interaction_token: &str,
1690 message_id: MessageId,
1691 map: &impl serde::Serialize,
1692 new_attachments: Vec<CreateAttachment>,
1693 ) -> Result<Message> {
1694 let mut request = Request {
1695 body: None,
1696 multipart: None,
1697 headers: None,
1698 method: LightMethod::Patch,
1699 route: Route::WebhookFollowupMessage {
1700 application_id: self.try_application_id()?,
1701 token: interaction_token,
1702 message_id,
1703 },
1704 params: None,
1705 };
1706
1707 if new_attachments.is_empty() {
1708 request.body = Some(to_vec(map)?);
1709 } else {
1710 request.multipart = Some(Multipart {
1711 upload: MultipartUpload::Attachments(new_attachments),
1712 payload_json: Some(to_string(map)?),
1713 fields: vec![],
1714 });
1715 }
1716
1717 self.fire(request).await
1718 }
1719
1720 pub async fn get_followup_message(
1726 &self,
1727 interaction_token: &str,
1728 message_id: MessageId,
1729 ) -> Result<Message> {
1730 self.fire(Request {
1731 body: None,
1732 multipart: None,
1733 headers: None,
1734 method: LightMethod::Get,
1735 route: Route::WebhookFollowupMessage {
1736 application_id: self.try_application_id()?,
1737 token: interaction_token,
1738 message_id,
1739 },
1740 params: None,
1741 })
1742 .await
1743 }
1744
1745 pub async fn edit_global_command(
1753 &self,
1754 command_id: CommandId,
1755 map: &impl serde::Serialize,
1756 ) -> Result<Command> {
1757 self.fire(Request {
1758 body: Some(to_vec(map)?),
1759 multipart: None,
1760 headers: None,
1761 method: LightMethod::Patch,
1762 route: Route::Command {
1763 application_id: self.try_application_id()?,
1764 command_id,
1765 },
1766 params: None,
1767 })
1768 .await
1769 }
1770
1771 pub async fn edit_guild(
1773 &self,
1774 guild_id: GuildId,
1775 map: &impl serde::Serialize,
1776 audit_log_reason: Option<&str>,
1777 ) -> Result<PartialGuild> {
1778 let body = to_vec(map)?;
1779
1780 self.fire(Request {
1781 body: Some(body),
1782 multipart: None,
1783 headers: audit_log_reason.map(reason_into_header),
1784 method: LightMethod::Patch,
1785 route: Route::Guild {
1786 guild_id,
1787 },
1788 params: None,
1789 })
1790 .await
1791 }
1792
1793 pub async fn edit_guild_command(
1801 &self,
1802 guild_id: GuildId,
1803 command_id: CommandId,
1804 map: &impl serde::Serialize,
1805 ) -> Result<Command> {
1806 self.fire(Request {
1807 body: Some(to_vec(map)?),
1808 multipart: None,
1809 headers: None,
1810 method: LightMethod::Patch,
1811 route: Route::GuildCommand {
1812 application_id: self.try_application_id()?,
1813 guild_id,
1814 command_id,
1815 },
1816 params: None,
1817 })
1818 .await
1819 }
1820
1821 pub async fn edit_guild_command_permissions(
1829 &self,
1830 guild_id: GuildId,
1831 command_id: CommandId,
1832 map: &impl serde::Serialize,
1833 ) -> Result<CommandPermissions> {
1834 self.fire(Request {
1835 body: Some(to_vec(map)?),
1836 multipart: None,
1837 headers: None,
1838 method: LightMethod::Put,
1839 route: Route::GuildCommandPermissions {
1840 application_id: self.try_application_id()?,
1841 guild_id,
1842 command_id,
1843 },
1844 params: None,
1845 })
1846 .await
1847 }
1848
1849 pub async fn edit_guild_channel_positions(
1851 &self,
1852 guild_id: GuildId,
1853 value: &Value,
1854 ) -> Result<()> {
1855 let body = to_vec(value)?;
1856
1857 self.wind(204, Request {
1858 body: Some(body),
1859 multipart: None,
1860 headers: None,
1861 method: LightMethod::Patch,
1862 route: Route::GuildChannels {
1863 guild_id,
1864 },
1865 params: None,
1866 })
1867 .await
1868 }
1869
1870 pub async fn edit_guild_mfa_level(
1872 &self,
1873 guild_id: GuildId,
1874 value: &Value,
1875 audit_log_reason: Option<&str>,
1876 ) -> Result<MfaLevel> {
1877 #[derive(Deserialize)]
1878 struct GuildMfaLevel {
1879 level: MfaLevel,
1880 }
1881
1882 let body = to_vec(value)?;
1883
1884 self.fire(Request {
1885 body: Some(body),
1886 multipart: None,
1887 headers: audit_log_reason.map(reason_into_header),
1888 method: LightMethod::Post,
1889 route: Route::GuildMfa {
1890 guild_id,
1891 },
1892 params: None,
1893 })
1894 .await
1895 .map(|mfa: GuildMfaLevel| mfa.level)
1896 }
1897
1898 pub async fn edit_guild_widget(
1900 &self,
1901 guild_id: GuildId,
1902 map: &impl serde::Serialize,
1903 audit_log_reason: Option<&str>,
1904 ) -> Result<GuildWidget> {
1905 let body = to_vec(map)?;
1906
1907 self.fire(Request {
1908 body: Some(body),
1909 multipart: None,
1910 headers: audit_log_reason.map(reason_into_header),
1911 method: LightMethod::Patch,
1912 route: Route::GuildWidget {
1913 guild_id,
1914 },
1915 params: None,
1916 })
1917 .await
1918 }
1919
1920 pub async fn edit_guild_welcome_screen(
1922 &self,
1923 guild_id: GuildId,
1924 map: &impl serde::Serialize,
1925 audit_log_reason: Option<&str>,
1926 ) -> Result<GuildWelcomeScreen> {
1927 let body = to_vec(map)?;
1928
1929 self.fire(Request {
1930 body: Some(body),
1931 multipart: None,
1932 headers: audit_log_reason.map(reason_into_header),
1933 method: LightMethod::Patch,
1934 route: Route::GuildWelcomeScreen {
1935 guild_id,
1936 },
1937 params: None,
1938 })
1939 .await
1940 }
1941
1942 pub async fn edit_member(
1944 &self,
1945 guild_id: GuildId,
1946 user_id: UserId,
1947 map: &impl serde::Serialize,
1948 audit_log_reason: Option<&str>,
1949 ) -> Result<Member> {
1950 let body = to_vec(map)?;
1951
1952 let mut value: Value = self
1953 .fire(Request {
1954 body: Some(body),
1955 multipart: None,
1956 headers: audit_log_reason.map(reason_into_header),
1957 method: LightMethod::Patch,
1958 route: Route::GuildMember {
1959 guild_id,
1960 user_id,
1961 },
1962 params: None,
1963 })
1964 .await?;
1965
1966 if let Some(map) = value.as_object_mut() {
1967 map.insert("guild_id".to_string(), guild_id.get().into());
1968 }
1969
1970 from_value::<Member>(value).map_err(From::from)
1971 }
1972
1973 pub async fn edit_message(
1977 &self,
1978 channel_id: ChannelId,
1979 message_id: MessageId,
1980 map: &impl serde::Serialize,
1981 new_attachments: Vec<CreateAttachment>,
1982 ) -> Result<Message> {
1983 let mut request = Request {
1984 body: None,
1985 multipart: None,
1986 headers: None,
1987 method: LightMethod::Patch,
1988 route: Route::ChannelMessage {
1989 channel_id,
1990 message_id,
1991 },
1992 params: None,
1993 };
1994
1995 if new_attachments.is_empty() {
1996 request.body = Some(to_vec(map)?);
1997 } else {
1998 request.multipart = Some(Multipart {
1999 upload: MultipartUpload::Attachments(new_attachments),
2000 payload_json: Some(to_string(map)?),
2001 fields: vec![],
2002 });
2003 }
2004
2005 self.fire(request).await
2006 }
2007
2008 pub async fn crosspost_message(
2012 &self,
2013 channel_id: ChannelId,
2014 message_id: MessageId,
2015 ) -> Result<Message> {
2016 self.fire(Request {
2017 body: None,
2018 multipart: None,
2019 headers: None,
2020 method: LightMethod::Post,
2021 route: Route::ChannelMessageCrosspost {
2022 channel_id,
2023 message_id,
2024 },
2025 params: None,
2026 })
2027 .await
2028 }
2029
2030 pub async fn edit_member_me(
2032 &self,
2033 guild_id: GuildId,
2034 map: &JsonMap,
2035 audit_log_reason: Option<&str>,
2036 ) -> Result<Member> {
2037 let body = to_vec(map)?;
2038
2039 self.fire(Request {
2040 body: Some(body),
2041 multipart: None,
2042 headers: audit_log_reason.map(reason_into_header),
2043 method: LightMethod::Patch,
2044 route: Route::GuildMemberMe {
2045 guild_id,
2046 },
2047 params: None,
2048 })
2049 .await
2050 }
2051
2052 pub async fn edit_nickname(
2056 &self,
2057 guild_id: GuildId,
2058 new_nickname: Option<&str>,
2059 audit_log_reason: Option<&str>,
2060 ) -> Result<()> {
2061 let map = json!({ "nick": new_nickname });
2062 let body = to_vec(&map)?;
2063
2064 self.wind(200, Request {
2065 body: Some(body),
2066 multipart: None,
2067 headers: audit_log_reason.map(reason_into_header),
2068 method: LightMethod::Patch,
2069 route: Route::GuildMemberMe {
2070 guild_id,
2071 },
2072 params: None,
2073 })
2074 .await
2075 }
2076
2077 pub async fn follow_news_channel(
2079 &self,
2080 news_channel_id: ChannelId,
2081 target_channel_id: ChannelId,
2082 ) -> Result<FollowedChannel> {
2083 let map = json!({ "webhook_channel_id": target_channel_id });
2084 let body = to_vec(&map)?;
2085
2086 self.fire(Request {
2087 body: Some(body),
2088 multipart: None,
2089 headers: None,
2090 method: LightMethod::Post,
2091 route: Route::ChannelFollowNews {
2092 channel_id: news_channel_id,
2093 },
2094 params: None,
2095 })
2096 .await
2097 }
2098
2099 pub async fn get_original_interaction_response(
2101 &self,
2102 interaction_token: &str,
2103 ) -> Result<Message> {
2104 self.fire(Request {
2105 body: None,
2106 multipart: None,
2107 headers: None,
2108 method: LightMethod::Get,
2109 route: Route::WebhookOriginalInteractionResponse {
2110 application_id: self.try_application_id()?,
2111 token: interaction_token,
2112 },
2113 params: None,
2114 })
2115 .await
2116 }
2117
2118 pub async fn edit_original_interaction_response(
2124 &self,
2125 interaction_token: &str,
2126 map: &impl serde::Serialize,
2127 new_attachments: Vec<CreateAttachment>,
2128 ) -> Result<Message> {
2129 let mut request = Request {
2130 body: None,
2131 multipart: None,
2132 headers: None,
2133 method: LightMethod::Patch,
2134 route: Route::WebhookOriginalInteractionResponse {
2135 application_id: self.try_application_id()?,
2136 token: interaction_token,
2137 },
2138 params: None,
2139 };
2140
2141 if new_attachments.is_empty() {
2142 request.body = Some(to_vec(map)?);
2143 } else {
2144 request.multipart = Some(Multipart {
2145 upload: MultipartUpload::Attachments(new_attachments.into_iter().collect()),
2146 payload_json: Some(to_string(map)?),
2147 fields: vec![],
2148 });
2149 }
2150
2151 self.fire(request).await
2152 }
2153
2154 pub async fn edit_profile(&self, map: &impl serde::Serialize) -> Result<CurrentUser> {
2156 let body = to_vec(map)?;
2157
2158 self.fire(Request {
2159 body: Some(body),
2160 multipart: None,
2161 headers: None,
2162 method: LightMethod::Patch,
2163 route: Route::UserMe,
2164 params: None,
2165 })
2166 .await
2167 }
2168
2169 pub async fn edit_role(
2171 &self,
2172 guild_id: GuildId,
2173 role_id: RoleId,
2174 map: &impl serde::Serialize,
2175 audit_log_reason: Option<&str>,
2176 ) -> Result<Role> {
2177 let mut value: Value = self
2178 .fire(Request {
2179 body: Some(to_vec(map)?),
2180 multipart: None,
2181 headers: audit_log_reason.map(reason_into_header),
2182 method: LightMethod::Patch,
2183 route: Route::GuildRole {
2184 guild_id,
2185 role_id,
2186 },
2187 params: None,
2188 })
2189 .await?;
2190
2191 if let Some(map) = value.as_object_mut() {
2192 map.insert("guild_id".to_string(), guild_id.get().into());
2193 }
2194
2195 from_value(value).map_err(From::from)
2196 }
2197
2198 pub async fn edit_role_position(
2200 &self,
2201 guild_id: GuildId,
2202 role_id: RoleId,
2203 position: u16,
2204 audit_log_reason: Option<&str>,
2205 ) -> Result<Vec<Role>> {
2206 let map = json!([{
2207 "id": role_id,
2208 "position": position,
2209 }]);
2210 let body = to_vec(&map)?;
2211
2212 let mut value: Value = self
2213 .fire(Request {
2214 body: Some(body),
2215 multipart: None,
2216 headers: audit_log_reason.map(reason_into_header),
2217 method: LightMethod::Patch,
2218 route: Route::GuildRoles {
2219 guild_id,
2220 },
2221 params: None,
2222 })
2223 .await?;
2224
2225 if let Some(array) = value.as_array_mut() {
2226 for role in array {
2227 if let Some(map) = role.as_object_mut() {
2228 map.insert("guild_id".to_string(), guild_id.get().into());
2229 }
2230 }
2231 }
2232
2233 from_value(value).map_err(From::from)
2234 }
2235
2236 pub async fn edit_scheduled_event(
2242 &self,
2243 guild_id: GuildId,
2244 event_id: ScheduledEventId,
2245 map: &impl serde::Serialize,
2246 audit_log_reason: Option<&str>,
2247 ) -> Result<ScheduledEvent> {
2248 let body = to_vec(map)?;
2249 self.fire(Request {
2250 body: Some(body),
2251 multipart: None,
2252 headers: audit_log_reason.map(reason_into_header),
2253 method: LightMethod::Patch,
2254 route: Route::GuildScheduledEvent {
2255 guild_id,
2256 event_id,
2257 },
2258 params: None,
2259 })
2260 .await
2261 }
2262
2263 pub async fn edit_sticker(
2267 &self,
2268 guild_id: GuildId,
2269 sticker_id: StickerId,
2270 map: &impl serde::Serialize,
2271 audit_log_reason: Option<&str>,
2272 ) -> Result<Sticker> {
2273 let body = to_vec(&map)?;
2274
2275 let mut value: Value = self
2276 .fire(Request {
2277 body: Some(body),
2278 multipart: None,
2279 headers: audit_log_reason.map(reason_into_header),
2280 method: LightMethod::Patch,
2281 route: Route::GuildSticker {
2282 guild_id,
2283 sticker_id,
2284 },
2285 params: None,
2286 })
2287 .await?;
2288
2289 if let Some(map) = value.as_object_mut() {
2290 map.insert("guild_id".to_string(), guild_id.get().into());
2291 }
2292
2293 from_value(value).map_err(From::from)
2294 }
2295
2296 pub async fn edit_thread(
2298 &self,
2299 channel_id: ChannelId,
2300 map: &impl serde::Serialize,
2301 audit_log_reason: Option<&str>,
2302 ) -> Result<GuildChannel> {
2303 self.fire(Request {
2304 body: Some(to_vec(map)?),
2305 multipart: None,
2306 headers: audit_log_reason.map(reason_into_header),
2307 method: LightMethod::Patch,
2308 route: Route::Channel {
2309 channel_id,
2310 },
2311 params: None,
2312 })
2313 .await
2314 }
2315
2316 pub async fn edit_voice_state(
2347 &self,
2348 guild_id: GuildId,
2349 user_id: UserId,
2350 map: &impl serde::Serialize,
2351 ) -> Result<()> {
2352 self.wind(204, Request {
2353 body: Some(to_vec(map)?),
2354 multipart: None,
2355 headers: None,
2356 method: LightMethod::Patch,
2357 route: Route::GuildVoiceStates {
2358 guild_id,
2359 user_id,
2360 },
2361 params: None,
2362 })
2363 .await
2364 }
2365
2366 pub async fn edit_voice_state_me(
2400 &self,
2401 guild_id: GuildId,
2402 map: &impl serde::Serialize,
2403 ) -> Result<()> {
2404 self.wind(204, Request {
2405 body: Some(to_vec(map)?),
2406 multipart: None,
2407 headers: None,
2408 method: LightMethod::Patch,
2409 route: Route::GuildVoiceStateMe {
2410 guild_id,
2411 },
2412 params: None,
2413 })
2414 .await
2415 }
2416
2417 pub async fn edit_voice_status(
2419 &self,
2420 channel_id: ChannelId,
2421 map: &impl serde::Serialize,
2422 audit_log_reason: Option<&str>,
2423 ) -> Result<()> {
2424 let body = to_vec(map)?;
2425
2426 self.wind(204, Request {
2427 body: Some(body),
2428 multipart: None,
2429 headers: audit_log_reason.map(reason_into_header),
2430 method: LightMethod::Put,
2431 route: Route::ChannelVoiceStatus {
2432 channel_id,
2433 },
2434 params: None,
2435 })
2436 .await
2437 }
2438
2439 pub async fn edit_webhook(
2472 &self,
2473 webhook_id: WebhookId,
2474 map: &impl serde::Serialize,
2475 audit_log_reason: Option<&str>,
2476 ) -> Result<Webhook> {
2477 self.fire(Request {
2478 body: Some(to_vec(map)?),
2479 multipart: None,
2480 headers: audit_log_reason.map(reason_into_header),
2481 method: LightMethod::Patch,
2482 route: Route::Webhook {
2483 webhook_id,
2484 },
2485 params: None,
2486 })
2487 .await
2488 }
2489
2490 pub async fn edit_webhook_with_token(
2516 &self,
2517 webhook_id: WebhookId,
2518 token: &str,
2519 map: &impl serde::Serialize,
2520 audit_log_reason: Option<&str>,
2521 ) -> Result<Webhook> {
2522 let body = to_vec(map)?;
2523
2524 self.fire(Request {
2525 body: Some(body),
2526 multipart: None,
2527 headers: audit_log_reason.map(reason_into_header),
2528 method: LightMethod::Patch,
2529 route: Route::WebhookWithToken {
2530 webhook_id,
2531 token,
2532 },
2533 params: None,
2534 })
2535 .await
2536 }
2537
2538 pub async fn execute_webhook(
2589 &self,
2590 webhook_id: WebhookId,
2591 thread_id: Option<ChannelId>,
2592 token: &str,
2593 wait: bool,
2594 files: Vec<CreateAttachment>,
2595 map: &impl serde::Serialize,
2596 ) -> Result<Option<Message>> {
2597 let mut params = vec![("wait", wait.to_string())];
2598 if let Some(thread_id) = thread_id {
2599 params.push(("thread_id", thread_id.to_string()));
2600 }
2601
2602 let mut request = Request {
2603 body: None,
2604 multipart: None,
2605 headers: None,
2606 method: LightMethod::Post,
2607 route: Route::WebhookWithToken {
2608 webhook_id,
2609 token,
2610 },
2611 params: Some(params),
2612 };
2613
2614 if files.is_empty() {
2615 request.body = Some(to_vec(map)?);
2616 } else {
2617 request.multipart = Some(Multipart {
2618 upload: MultipartUpload::Attachments(files.into_iter().collect()),
2619 payload_json: Some(to_string(map)?),
2620 fields: vec![],
2621 });
2622 }
2623
2624 let response = self.request(request).await?;
2625
2626 Ok(if response.status() == StatusCode::NO_CONTENT {
2627 None
2628 } else {
2629 decode_resp(response).await?
2630 })
2631 }
2632
2633 pub async fn get_webhook_message(
2635 &self,
2636 webhook_id: WebhookId,
2637 thread_id: Option<ChannelId>,
2638 token: &str,
2639 message_id: MessageId,
2640 ) -> Result<Message> {
2641 self.fire(Request {
2642 body: None,
2643 multipart: None,
2644 headers: None,
2645 method: LightMethod::Get,
2646 route: Route::WebhookMessage {
2647 webhook_id,
2648 token,
2649 message_id,
2650 },
2651 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2652 })
2653 .await
2654 }
2655
2656 pub async fn edit_webhook_message(
2658 &self,
2659 webhook_id: WebhookId,
2660 thread_id: Option<ChannelId>,
2661 token: &str,
2662 message_id: MessageId,
2663 map: &impl serde::Serialize,
2664 new_attachments: Vec<CreateAttachment>,
2665 ) -> Result<Message> {
2666 let mut request = Request {
2667 body: None,
2668 multipart: None,
2669 headers: None,
2670 method: LightMethod::Patch,
2671 route: Route::WebhookMessage {
2672 webhook_id,
2673 token,
2674 message_id,
2675 },
2676 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2677 };
2678
2679 if new_attachments.is_empty() {
2680 request.body = Some(to_vec(map)?);
2681 } else {
2682 request.multipart = Some(Multipart {
2683 upload: MultipartUpload::Attachments(new_attachments),
2684 payload_json: Some(to_string(map)?),
2685 fields: vec![],
2686 });
2687 }
2688
2689 self.fire(request).await
2690 }
2691
2692 pub async fn delete_webhook_message(
2694 &self,
2695 webhook_id: WebhookId,
2696 thread_id: Option<ChannelId>,
2697 token: &str,
2698 message_id: MessageId,
2699 ) -> Result<()> {
2700 self.wind(204, Request {
2701 body: None,
2702 multipart: None,
2703 headers: None,
2704 method: LightMethod::Delete,
2705 route: Route::WebhookMessage {
2706 webhook_id,
2707 token,
2708 message_id,
2709 },
2710 params: thread_id.map(|thread_id| vec![("thread_id", thread_id.to_string())]),
2711 })
2712 .await
2713 }
2714
2715 pub async fn get_active_maintenances(&self) -> Result<Vec<Maintenance>> {
2719 #[derive(Deserialize)]
2720 struct StatusResponse {
2721 #[serde(default)]
2722 scheduled_maintenances: Vec<Maintenance>,
2723 }
2724
2725 let status: StatusResponse = self
2726 .fire(Request {
2727 body: None,
2728 multipart: None,
2729 headers: None,
2730 method: LightMethod::Get,
2731 route: Route::StatusMaintenancesActive,
2732 params: None,
2733 })
2734 .await?;
2735
2736 Ok(status.scheduled_maintenances)
2737 }
2738
2739 pub async fn get_bans(
2750 &self,
2751 guild_id: GuildId,
2752 target: Option<UserPagination>,
2753 limit: Option<u8>,
2754 ) -> Result<Vec<Ban>> {
2755 let mut params = vec![];
2756
2757 if let Some(limit) = limit {
2758 params.push(("limit", limit.to_string()));
2759 }
2760
2761 if let Some(target) = target {
2762 match target {
2763 UserPagination::After(id) => params.push(("after", id.to_string())),
2764 UserPagination::Before(id) => params.push(("before", id.to_string())),
2765 }
2766 }
2767
2768 self.fire(Request {
2769 body: None,
2770 multipart: None,
2771 headers: None,
2772 method: LightMethod::Get,
2773 route: Route::GuildBans {
2774 guild_id,
2775 },
2776 params: Some(params),
2777 })
2778 .await
2779 }
2780
2781 pub async fn get_audit_logs(
2783 &self,
2784 guild_id: GuildId,
2785 action_type: Option<audit_log::Action>,
2786 user_id: Option<UserId>,
2787 before: Option<AuditLogEntryId>,
2788 limit: Option<u8>,
2789 ) -> Result<AuditLogs> {
2790 let mut params = vec![];
2791 if let Some(action_type) = action_type {
2792 params.push(("action_type", action_type.num().to_string()));
2793 }
2794 if let Some(before) = before {
2795 params.push(("before", before.to_string()));
2796 }
2797 if let Some(limit) = limit {
2798 params.push(("limit", limit.to_string()));
2799 }
2800 if let Some(user_id) = user_id {
2801 params.push(("user_id", user_id.to_string()));
2802 }
2803
2804 self.fire(Request {
2805 body: None,
2806 multipart: None,
2807 headers: None,
2808 method: LightMethod::Get,
2809 route: Route::GuildAuditLogs {
2810 guild_id,
2811 },
2812 params: Some(params),
2813 })
2814 .await
2815 }
2816
2817 pub async fn get_automod_rules(&self, guild_id: GuildId) -> Result<Vec<Rule>> {
2821 self.fire(Request {
2822 body: None,
2823 multipart: None,
2824 headers: None,
2825 method: LightMethod::Get,
2826 route: Route::GuildAutomodRules {
2827 guild_id,
2828 },
2829 params: None,
2830 })
2831 .await
2832 }
2833
2834 pub async fn get_automod_rule(&self, guild_id: GuildId, rule_id: RuleId) -> Result<Rule> {
2838 self.fire(Request {
2839 body: None,
2840 multipart: None,
2841 headers: None,
2842 method: LightMethod::Get,
2843 route: Route::GuildAutomodRule {
2844 guild_id,
2845 rule_id,
2846 },
2847 params: None,
2848 })
2849 .await
2850 }
2851
2852 pub async fn create_automod_rule(
2856 &self,
2857 guild_id: GuildId,
2858 map: &impl serde::Serialize,
2859 audit_log_reason: Option<&str>,
2860 ) -> Result<Rule> {
2861 let body = to_vec(map)?;
2862
2863 self.fire(Request {
2864 body: Some(body),
2865 multipart: None,
2866 headers: audit_log_reason.map(reason_into_header),
2867 method: LightMethod::Post,
2868 route: Route::GuildAutomodRules {
2869 guild_id,
2870 },
2871 params: None,
2872 })
2873 .await
2874 }
2875
2876 pub async fn edit_automod_rule(
2880 &self,
2881 guild_id: GuildId,
2882 rule_id: RuleId,
2883 map: &impl serde::Serialize,
2884 audit_log_reason: Option<&str>,
2885 ) -> Result<Rule> {
2886 let body = to_vec(map)?;
2887
2888 self.fire(Request {
2889 body: Some(body),
2890 multipart: None,
2891 headers: audit_log_reason.map(reason_into_header),
2892 method: LightMethod::Patch,
2893 route: Route::GuildAutomodRule {
2894 guild_id,
2895 rule_id,
2896 },
2897 params: None,
2898 })
2899 .await
2900 }
2901
2902 pub async fn delete_automod_rule(
2906 &self,
2907 guild_id: GuildId,
2908 rule_id: RuleId,
2909 audit_log_reason: Option<&str>,
2910 ) -> Result<()> {
2911 self.wind(204, Request {
2912 body: None,
2913 multipart: None,
2914 headers: audit_log_reason.map(reason_into_header),
2915 method: LightMethod::Delete,
2916 route: Route::GuildAutomodRule {
2917 guild_id,
2918 rule_id,
2919 },
2920 params: None,
2921 })
2922 .await
2923 }
2924
2925 pub async fn get_bot_gateway(&self) -> Result<BotGateway> {
2927 self.fire(Request {
2928 body: None,
2929 multipart: None,
2930 headers: None,
2931 method: LightMethod::Get,
2932 route: Route::GatewayBot,
2933 params: None,
2934 })
2935 .await
2936 }
2937
2938 pub async fn get_channel_invites(&self, channel_id: ChannelId) -> Result<Vec<RichInvite>> {
2940 self.fire(Request {
2941 body: None,
2942 multipart: None,
2943 headers: None,
2944 method: LightMethod::Get,
2945 route: Route::ChannelInvites {
2946 channel_id,
2947 },
2948 params: None,
2949 })
2950 .await
2951 }
2952
2953 pub async fn get_channel_thread_members(
2955 &self,
2956 channel_id: ChannelId,
2957 ) -> Result<Vec<ThreadMember>> {
2958 self.fire(Request {
2959 body: None,
2960 multipart: None,
2961 headers: None,
2962 method: LightMethod::Get,
2963 route: Route::ChannelThreadMembers {
2964 channel_id,
2965 },
2966 params: None,
2967 })
2968 .await
2969 }
2970
2971 pub async fn get_guild_active_threads(&self, guild_id: GuildId) -> Result<ThreadsData> {
2973 self.fire(Request {
2974 body: None,
2975 multipart: None,
2976 headers: None,
2977 method: LightMethod::Get,
2978 route: Route::GuildThreadsActive {
2979 guild_id,
2980 },
2981 params: None,
2982 })
2983 .await
2984 }
2985
2986 pub async fn get_channel_archived_public_threads(
2988 &self,
2989 channel_id: ChannelId,
2990 before: Option<u64>,
2991 limit: Option<u64>,
2992 ) -> Result<ThreadsData> {
2993 let mut params = vec![];
2994 if let Some(before) = before {
2995 params.push(("before", before.to_string()));
2996 }
2997 if let Some(limit) = limit {
2998 params.push(("limit", limit.to_string()));
2999 }
3000
3001 self.fire(Request {
3002 body: None,
3003 multipart: None,
3004 method: LightMethod::Get,
3005 headers: None,
3006 route: Route::ChannelArchivedPublicThreads {
3007 channel_id,
3008 },
3009 params: Some(params),
3010 })
3011 .await
3012 }
3013
3014 pub async fn get_channel_archived_private_threads(
3016 &self,
3017 channel_id: ChannelId,
3018 before: Option<u64>,
3019 limit: Option<u64>,
3020 ) -> Result<ThreadsData> {
3021 let mut params = vec![];
3022 if let Some(before) = before {
3023 params.push(("before", before.to_string()));
3024 }
3025 if let Some(limit) = limit {
3026 params.push(("limit", limit.to_string()));
3027 }
3028
3029 self.fire(Request {
3030 body: None,
3031 multipart: None,
3032 headers: None,
3033 method: LightMethod::Get,
3034 route: Route::ChannelArchivedPrivateThreads {
3035 channel_id,
3036 },
3037 params: Some(params),
3038 })
3039 .await
3040 }
3041
3042 pub async fn get_channel_joined_archived_private_threads(
3044 &self,
3045 channel_id: ChannelId,
3046 before: Option<u64>,
3047 limit: Option<u64>,
3048 ) -> Result<ThreadsData> {
3049 let mut params = vec![];
3050 if let Some(before) = before {
3051 params.push(("before", before.to_string()));
3052 }
3053 if let Some(limit) = limit {
3054 params.push(("limit", limit.to_string()));
3055 }
3056
3057 self.fire(Request {
3058 body: None,
3059 multipart: None,
3060 headers: None,
3061 method: LightMethod::Get,
3062 route: Route::ChannelJoinedPrivateThreads {
3063 channel_id,
3064 },
3065 params: Some(params),
3066 })
3067 .await
3068 }
3069
3070 pub async fn join_thread_channel(&self, channel_id: ChannelId) -> Result<()> {
3072 self.wind(204, Request {
3073 body: None,
3074 multipart: None,
3075 headers: None,
3076 method: LightMethod::Put,
3077 route: Route::ChannelThreadMemberMe {
3078 channel_id,
3079 },
3080 params: None,
3081 })
3082 .await
3083 }
3084
3085 pub async fn leave_thread_channel(&self, channel_id: ChannelId) -> Result<()> {
3087 self.wind(204, Request {
3088 body: None,
3089 multipart: None,
3090 headers: None,
3091 method: LightMethod::Delete,
3092 route: Route::ChannelThreadMemberMe {
3093 channel_id,
3094 },
3095 params: None,
3096 })
3097 .await
3098 }
3099
3100 pub async fn add_thread_channel_member(
3102 &self,
3103 channel_id: ChannelId,
3104 user_id: UserId,
3105 ) -> Result<()> {
3106 self.wind(204, Request {
3107 body: None,
3108 multipart: None,
3109 headers: None,
3110 method: LightMethod::Put,
3111 route: Route::ChannelThreadMember {
3112 channel_id,
3113 user_id,
3114 },
3115 params: None,
3116 })
3117 .await
3118 }
3119
3120 pub async fn remove_thread_channel_member(
3122 &self,
3123 channel_id: ChannelId,
3124 user_id: UserId,
3125 ) -> Result<()> {
3126 self.wind(204, Request {
3127 body: None,
3128 multipart: None,
3129 headers: None,
3130 method: LightMethod::Delete,
3131 route: Route::ChannelThreadMember {
3132 channel_id,
3133 user_id,
3134 },
3135 params: None,
3136 })
3137 .await
3138 }
3139
3140 pub async fn get_thread_channel_member(
3141 &self,
3142 channel_id: ChannelId,
3143 user_id: UserId,
3144 with_member: bool,
3145 ) -> Result<ThreadMember> {
3146 self.fire(Request {
3147 body: None,
3148 multipart: None,
3149 headers: None,
3150 method: LightMethod::Get,
3151 route: Route::ChannelThreadMember {
3152 channel_id,
3153 user_id,
3154 },
3155 params: Some(vec![("with_member", with_member.to_string())]),
3156 })
3157 .await
3158 }
3159
3160 pub async fn get_channel_webhooks(&self, channel_id: ChannelId) -> Result<Vec<Webhook>> {
3181 self.fire(Request {
3182 body: None,
3183 multipart: None,
3184 headers: None,
3185 method: LightMethod::Get,
3186 route: Route::ChannelWebhooks {
3187 channel_id,
3188 },
3189 params: None,
3190 })
3191 .await
3192 }
3193
3194 pub async fn get_channel(&self, channel_id: ChannelId) -> Result<Channel> {
3196 self.fire(Request {
3197 body: None,
3198 multipart: None,
3199 headers: None,
3200 method: LightMethod::Get,
3201 route: Route::Channel {
3202 channel_id,
3203 },
3204 params: None,
3205 })
3206 .await
3207 }
3208
3209 pub async fn get_channels(&self, guild_id: GuildId) -> Result<Vec<GuildChannel>> {
3211 self.fire(Request {
3212 body: None,
3213 multipart: None,
3214 headers: None,
3215 method: LightMethod::Get,
3216 route: Route::GuildChannels {
3217 guild_id,
3218 },
3219 params: None,
3220 })
3221 .await
3222 }
3223
3224 pub async fn get_stage_instance(&self, channel_id: ChannelId) -> Result<StageInstance> {
3226 self.fire(Request {
3227 body: None,
3228 multipart: None,
3229 headers: None,
3230 method: LightMethod::Get,
3231 route: Route::StageInstance {
3232 channel_id,
3233 },
3234 params: None,
3235 })
3236 .await
3237 }
3238
3239 pub async fn get_poll_answer_voters(
3241 &self,
3242 channel_id: ChannelId,
3243 message_id: MessageId,
3244 answer_id: AnswerId,
3245 after: Option<UserId>,
3246 limit: Option<u8>,
3247 ) -> Result<Vec<User>> {
3248 #[derive(Deserialize)]
3249 struct VotersResponse {
3250 users: Vec<User>,
3251 }
3252
3253 let mut params = Vec::with_capacity(2);
3254 if let Some(after) = after {
3255 params.push(("after", after.to_string()));
3256 }
3257
3258 if let Some(limit) = limit {
3259 params.push(("limit", limit.to_string()));
3260 }
3261
3262 let resp: VotersResponse = self
3263 .fire(Request {
3264 body: None,
3265 multipart: None,
3266 headers: None,
3267 method: LightMethod::Get,
3268 route: Route::ChannelPollGetAnswerVoters {
3269 channel_id,
3270 message_id,
3271 answer_id,
3272 },
3273 params: Some(params),
3274 })
3275 .await?;
3276
3277 Ok(resp.users)
3278 }
3279
3280 pub async fn expire_poll(
3281 &self,
3282 channel_id: ChannelId,
3283 message_id: MessageId,
3284 ) -> Result<Message> {
3285 self.fire(Request {
3286 body: None,
3287 multipart: None,
3288 headers: None,
3289 method: LightMethod::Post,
3290 route: Route::ChannelPollExpire {
3291 channel_id,
3292 message_id,
3293 },
3294 params: None,
3295 })
3296 .await
3297 }
3298
3299 pub async fn get_current_application_info(&self) -> Result<CurrentApplicationInfo> {
3303 self.fire(Request {
3304 body: None,
3305 multipart: None,
3306 headers: None,
3307 method: LightMethod::Get,
3308 route: Route::Oauth2ApplicationCurrent,
3309 params: None,
3310 })
3311 .await
3312 }
3313
3314 pub async fn get_current_user(&self) -> Result<CurrentUser> {
3316 self.fire(Request {
3317 body: None,
3318 multipart: None,
3319 headers: None,
3320 method: LightMethod::Get,
3321 route: Route::UserMe,
3322 params: None,
3323 })
3324 .await
3325 }
3326
3327 pub async fn get_emojis(&self, guild_id: GuildId) -> Result<Vec<Emoji>> {
3329 self.fire(Request {
3330 body: None,
3331 multipart: None,
3332 headers: None,
3333 method: LightMethod::Get,
3334 route: Route::GuildEmojis {
3335 guild_id,
3336 },
3337 params: None,
3338 })
3339 .await
3340 }
3341
3342 pub async fn get_emoji(&self, guild_id: GuildId, emoji_id: EmojiId) -> Result<Emoji> {
3344 self.fire(Request {
3345 body: None,
3346 multipart: None,
3347 headers: None,
3348 method: LightMethod::Get,
3349 route: Route::GuildEmoji {
3350 guild_id,
3351 emoji_id,
3352 },
3353 params: None,
3354 })
3355 .await
3356 }
3357
3358 pub async fn get_application_emojis(&self) -> Result<Vec<Emoji>> {
3360 #[derive(Deserialize)]
3362 struct ApplicationEmojis {
3363 items: Vec<Emoji>,
3364 }
3365
3366 let result: ApplicationEmojis = self
3367 .fire(Request {
3368 body: None,
3369 multipart: None,
3370 headers: None,
3371 method: LightMethod::Get,
3372 route: Route::Emojis {
3373 application_id: self.try_application_id()?,
3374 },
3375 params: None,
3376 })
3377 .await?;
3378
3379 Ok(result.items)
3380 }
3381
3382 pub async fn get_application_emoji(&self, emoji_id: EmojiId) -> Result<Emoji> {
3384 self.fire(Request {
3385 body: None,
3386 multipart: None,
3387 headers: None,
3388 method: LightMethod::Get,
3389 route: Route::Emoji {
3390 application_id: self.try_application_id()?,
3391 emoji_id,
3392 },
3393 params: None,
3394 })
3395 .await
3396 }
3397
3398 #[allow(clippy::too_many_arguments)]
3399 pub async fn get_entitlements(
3401 &self,
3402 user_id: Option<UserId>,
3403 sku_ids: Option<Vec<SkuId>>,
3404 before: Option<EntitlementId>,
3405 after: Option<EntitlementId>,
3406 limit: Option<u8>,
3407 guild_id: Option<GuildId>,
3408 exclude_ended: Option<bool>,
3409 ) -> Result<Vec<Entitlement>> {
3410 let mut params = vec![];
3411 if let Some(user_id) = user_id {
3412 params.push(("user_id", user_id.to_string()));
3413 }
3414 if let Some(sku_ids) = sku_ids {
3415 params.push((
3416 "sku_ids",
3417 sku_ids.iter().map(ToString::to_string).collect::<Vec<_>>().join(","),
3418 ));
3419 }
3420 if let Some(before) = before {
3421 params.push(("before", before.to_string()));
3422 }
3423 if let Some(after) = after {
3424 params.push(("after", after.to_string()));
3425 }
3426 if let Some(limit) = limit {
3427 params.push(("limit", limit.to_string()));
3428 }
3429 if let Some(guild_id) = guild_id {
3430 params.push(("guild_id", guild_id.to_string()));
3431 }
3432 if let Some(exclude_ended) = exclude_ended {
3433 params.push(("exclude_ended", exclude_ended.to_string()));
3434 }
3435
3436 self.fire(Request {
3437 body: None,
3438 multipart: None,
3439 headers: None,
3440 method: LightMethod::Get,
3441 route: Route::Entitlements {
3442 application_id: self.try_application_id()?,
3443 },
3444 params: Some(params),
3445 })
3446 .await
3447 }
3448
3449 pub async fn get_gateway(&self) -> Result<Gateway> {
3451 self.fire(Request {
3452 body: None,
3453 multipart: None,
3454 headers: None,
3455 method: LightMethod::Get,
3456 route: Route::Gateway,
3457 params: None,
3458 })
3459 .await
3460 }
3461
3462 pub async fn get_global_commands(&self) -> Result<Vec<Command>> {
3464 self.fire(Request {
3465 body: None,
3466 multipart: None,
3467 headers: None,
3468 method: LightMethod::Get,
3469 route: Route::Commands {
3470 application_id: self.try_application_id()?,
3471 },
3472 params: None,
3473 })
3474 .await
3475 }
3476
3477 pub async fn get_global_commands_with_localizations(&self) -> Result<Vec<Command>> {
3479 self.fire(Request {
3480 body: None,
3481 multipart: None,
3482 headers: None,
3483 method: LightMethod::Get,
3484 route: Route::Commands {
3485 application_id: self.try_application_id()?,
3486 },
3487 params: Some(vec![("with_localizations", true.to_string())]),
3488 })
3489 .await
3490 }
3491
3492 pub async fn get_global_command(&self, command_id: CommandId) -> Result<Command> {
3494 self.fire(Request {
3495 body: None,
3496 multipart: None,
3497 headers: None,
3498 method: LightMethod::Get,
3499 route: Route::Command {
3500 application_id: self.try_application_id()?,
3501 command_id,
3502 },
3503 params: None,
3504 })
3505 .await
3506 }
3507
3508 pub async fn get_guild(&self, guild_id: GuildId) -> Result<PartialGuild> {
3510 self.fire(Request {
3511 body: None,
3512 multipart: None,
3513 headers: None,
3514 method: LightMethod::Get,
3515 route: Route::Guild {
3516 guild_id,
3517 },
3518 params: None,
3519 })
3520 .await
3521 }
3522
3523 pub async fn get_guild_with_counts(&self, guild_id: GuildId) -> Result<PartialGuild> {
3525 self.fire(Request {
3526 body: None,
3527 multipart: None,
3528 headers: None,
3529 method: LightMethod::Get,
3530 route: Route::Guild {
3531 guild_id,
3532 },
3533 params: Some(vec![("with_counts", true.to_string())]),
3534 })
3535 .await
3536 }
3537
3538 pub async fn get_guild_commands(&self, guild_id: GuildId) -> Result<Vec<Command>> {
3540 self.fire(Request {
3541 body: None,
3542 multipart: None,
3543 headers: None,
3544 method: LightMethod::Get,
3545 route: Route::GuildCommands {
3546 application_id: self.try_application_id()?,
3547 guild_id,
3548 },
3549 params: None,
3550 })
3551 .await
3552 }
3553
3554 pub async fn get_guild_commands_with_localizations(
3557 &self,
3558 guild_id: GuildId,
3559 ) -> Result<Vec<Command>> {
3560 self.fire(Request {
3561 body: None,
3562 multipart: None,
3563 headers: None,
3564 method: LightMethod::Get,
3565 route: Route::GuildCommands {
3566 application_id: self.try_application_id()?,
3567 guild_id,
3568 },
3569 params: Some(vec![("with_localizations", true.to_string())]),
3570 })
3571 .await
3572 }
3573
3574 pub async fn get_guild_command(
3576 &self,
3577 guild_id: GuildId,
3578 command_id: CommandId,
3579 ) -> Result<Command> {
3580 self.fire(Request {
3581 body: None,
3582 multipart: None,
3583 headers: None,
3584 method: LightMethod::Get,
3585 route: Route::GuildCommand {
3586 application_id: self.try_application_id()?,
3587 guild_id,
3588 command_id,
3589 },
3590 params: None,
3591 })
3592 .await
3593 }
3594
3595 pub async fn get_guild_commands_permissions(
3597 &self,
3598 guild_id: GuildId,
3599 ) -> Result<Vec<CommandPermissions>> {
3600 self.fire(Request {
3601 body: None,
3602 multipart: None,
3603 headers: None,
3604 method: LightMethod::Get,
3605 route: Route::GuildCommandsPermissions {
3606 application_id: self.try_application_id()?,
3607 guild_id,
3608 },
3609 params: None,
3610 })
3611 .await
3612 }
3613
3614 pub async fn get_guild_command_permissions(
3616 &self,
3617 guild_id: GuildId,
3618 command_id: CommandId,
3619 ) -> Result<CommandPermissions> {
3620 self.fire(Request {
3621 body: None,
3622 multipart: None,
3623 headers: None,
3624 method: LightMethod::Get,
3625 route: Route::GuildCommandPermissions {
3626 application_id: self.try_application_id()?,
3627 guild_id,
3628 command_id,
3629 },
3630 params: None,
3631 })
3632 .await
3633 }
3634
3635 pub async fn get_guild_widget(&self, guild_id: GuildId) -> Result<GuildWidget> {
3639 self.fire(Request {
3640 body: None,
3641 multipart: None,
3642 headers: None,
3643 method: LightMethod::Get,
3644 route: Route::GuildWidget {
3645 guild_id,
3646 },
3647 params: None,
3648 })
3649 .await
3650 }
3651
3652 pub async fn get_guild_preview(&self, guild_id: GuildId) -> Result<GuildPreview> {
3654 self.fire(Request {
3655 body: None,
3656 multipart: None,
3657 headers: None,
3658 method: LightMethod::Get,
3659 route: Route::GuildPreview {
3660 guild_id,
3661 },
3662 params: None,
3663 })
3664 .await
3665 }
3666
3667 pub async fn get_guild_welcome_screen(&self, guild_id: GuildId) -> Result<GuildWelcomeScreen> {
3669 self.fire(Request {
3670 body: None,
3671 multipart: None,
3672 headers: None,
3673 method: LightMethod::Get,
3674 route: Route::GuildWelcomeScreen {
3675 guild_id,
3676 },
3677 params: None,
3678 })
3679 .await
3680 }
3681
3682 pub async fn get_guild_integrations(&self, guild_id: GuildId) -> Result<Vec<Integration>> {
3684 self.fire(Request {
3685 body: None,
3686 multipart: None,
3687 headers: None,
3688 method: LightMethod::Get,
3689 route: Route::GuildIntegrations {
3690 guild_id,
3691 },
3692 params: None,
3693 })
3694 .await
3695 }
3696
3697 pub async fn get_guild_invites(&self, guild_id: GuildId) -> Result<Vec<RichInvite>> {
3699 self.fire(Request {
3700 body: None,
3701 multipart: None,
3702 headers: None,
3703 method: LightMethod::Get,
3704 route: Route::GuildInvites {
3705 guild_id,
3706 },
3707 params: None,
3708 })
3709 .await
3710 }
3711
3712 pub async fn get_guild_vanity_url(&self, guild_id: GuildId) -> Result<String> {
3714 #[derive(Deserialize)]
3715 struct GuildVanityUrl {
3716 code: String,
3717 }
3718
3719 self.fire::<GuildVanityUrl>(Request {
3720 body: None,
3721 multipart: None,
3722 headers: None,
3723 method: LightMethod::Get,
3724 route: Route::GuildVanityUrl {
3725 guild_id,
3726 },
3727 params: None,
3728 })
3729 .await
3730 .map(|x| x.code)
3731 }
3732
3733 pub async fn get_guild_members(
3736 &self,
3737 guild_id: GuildId,
3738 limit: Option<u64>,
3739 after: Option<u64>,
3740 ) -> Result<Vec<Member>> {
3741 if let Some(l) = limit {
3742 if !(1..=constants::MEMBER_FETCH_LIMIT).contains(&l) {
3743 return Err(Error::NotInRange("limit", l, 1, constants::MEMBER_FETCH_LIMIT));
3744 }
3745 }
3746
3747 let mut params =
3748 vec![("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string())];
3749 if let Some(after) = after {
3750 params.push(("after", after.to_string()));
3751 }
3752
3753 let mut value: Value = self
3754 .fire(Request {
3755 body: None,
3756 multipart: None,
3757 headers: None,
3758 method: LightMethod::Get,
3759 route: Route::GuildMembers {
3760 guild_id,
3761 },
3762 params: Some(params),
3763 })
3764 .await?;
3765
3766 if let Some(values) = value.as_array_mut() {
3767 for value in values {
3768 if let Some(element) = value.as_object_mut() {
3769 element.insert("guild_id".to_string(), guild_id.get().into());
3770 }
3771 }
3772 }
3773
3774 from_value(value).map_err(From::from)
3775 }
3776
3777 pub async fn get_guild_prune_count(&self, guild_id: GuildId, days: u8) -> Result<GuildPrune> {
3779 self.fire(Request {
3780 body: None,
3781 multipart: None,
3782 headers: None,
3783 method: LightMethod::Get,
3784 route: Route::GuildPrune {
3785 guild_id,
3786 },
3787 params: Some(vec![("days", days.to_string())]),
3788 })
3789 .await
3790 }
3791
3792 pub async fn get_guild_regions(&self, guild_id: GuildId) -> Result<Vec<VoiceRegion>> {
3795 self.fire(Request {
3796 body: None,
3797 multipart: None,
3798 headers: None,
3799 method: LightMethod::Get,
3800 route: Route::GuildRegions {
3801 guild_id,
3802 },
3803 params: None,
3804 })
3805 .await
3806 }
3807
3808 pub async fn get_guild_role(&self, guild_id: GuildId, role_id: RoleId) -> Result<Role> {
3810 let mut value: Value = self
3811 .fire(Request {
3812 body: None,
3813 multipart: None,
3814 headers: None,
3815 method: LightMethod::Get,
3816 route: Route::GuildRole {
3817 guild_id,
3818 role_id,
3819 },
3820 params: None,
3821 })
3822 .await?;
3823
3824 if let Some(map) = value.as_object_mut() {
3825 map.insert("guild_id".to_string(), guild_id.get().into());
3826 }
3827
3828 from_value(value).map_err(From::from)
3829 }
3830
3831 pub async fn get_guild_roles(&self, guild_id: GuildId) -> Result<Vec<Role>> {
3833 let mut value: Value = self
3834 .fire(Request {
3835 body: None,
3836 multipart: None,
3837 headers: None,
3838 method: LightMethod::Get,
3839 route: Route::GuildRoles {
3840 guild_id,
3841 },
3842 params: None,
3843 })
3844 .await?;
3845
3846 if let Some(array) = value.as_array_mut() {
3847 for sticker in array {
3848 if let Some(map) = sticker.as_object_mut() {
3849 map.insert("guild_id".to_string(), guild_id.get().into());
3850 }
3851 }
3852 }
3853
3854 from_value(value).map_err(From::from)
3855 }
3856
3857 pub async fn get_scheduled_event(
3863 &self,
3864 guild_id: GuildId,
3865 event_id: ScheduledEventId,
3866 with_user_count: bool,
3867 ) -> Result<ScheduledEvent> {
3868 self.fire(Request {
3869 body: None,
3870 multipart: None,
3871 headers: None,
3872 method: LightMethod::Get,
3873 route: Route::GuildScheduledEvent {
3874 guild_id,
3875 event_id,
3876 },
3877 params: Some(vec![("with_user_count", with_user_count.to_string())]),
3878 })
3879 .await
3880 }
3881
3882 pub async fn get_scheduled_events(
3888 &self,
3889 guild_id: GuildId,
3890 with_user_count: bool,
3891 ) -> Result<Vec<ScheduledEvent>> {
3892 self.fire(Request {
3893 body: None,
3894 multipart: None,
3895 headers: None,
3896 method: LightMethod::Get,
3897 route: Route::GuildScheduledEvents {
3898 guild_id,
3899 },
3900 params: Some(vec![("with_user_count", with_user_count.to_string())]),
3901 })
3902 .await
3903 }
3904
3905 pub async fn get_scheduled_event_users(
3922 &self,
3923 guild_id: GuildId,
3924 event_id: ScheduledEventId,
3925 limit: Option<u64>,
3926 target: Option<UserPagination>,
3927 with_member: Option<bool>,
3928 ) -> Result<Vec<ScheduledEventUser>> {
3929 let mut params = vec![];
3930 if let Some(limit) = limit {
3931 params.push(("limit", limit.to_string()));
3932 }
3933 if let Some(with_member) = with_member {
3934 params.push(("with_member", with_member.to_string()));
3935 }
3936 if let Some(target) = target {
3937 match target {
3938 UserPagination::After(id) => params.push(("after", id.to_string())),
3939 UserPagination::Before(id) => params.push(("before", id.to_string())),
3940 }
3941 }
3942
3943 self.fire(Request {
3944 body: None,
3945 multipart: None,
3946 headers: None,
3947 method: LightMethod::Get,
3948 route: Route::GuildScheduledEventUsers {
3949 guild_id,
3950 event_id,
3951 },
3952 params: Some(params),
3953 })
3954 .await
3955 }
3956
3957 pub async fn get_guild_stickers(&self, guild_id: GuildId) -> Result<Vec<Sticker>> {
3959 let mut value: Value = self
3960 .fire(Request {
3961 body: None,
3962 multipart: None,
3963 headers: None,
3964 method: LightMethod::Get,
3965 route: Route::GuildStickers {
3966 guild_id,
3967 },
3968 params: None,
3969 })
3970 .await?;
3971
3972 if let Some(array) = value.as_array_mut() {
3973 for role in array {
3974 if let Some(map) = role.as_object_mut() {
3975 map.insert("guild_id".to_string(), guild_id.get().into());
3976 }
3977 }
3978 }
3979
3980 from_value(value).map_err(From::from)
3981 }
3982
3983 pub async fn get_guild_sticker(
3985 &self,
3986 guild_id: GuildId,
3987 sticker_id: StickerId,
3988 ) -> Result<Sticker> {
3989 let mut value: Value = self
3990 .fire(Request {
3991 body: None,
3992 multipart: None,
3993 headers: None,
3994 method: LightMethod::Get,
3995 route: Route::GuildSticker {
3996 guild_id,
3997 sticker_id,
3998 },
3999 params: None,
4000 })
4001 .await?;
4002
4003 if let Some(map) = value.as_object_mut() {
4004 map.insert("guild_id".to_string(), guild_id.get().into());
4005 }
4006
4007 from_value(value).map_err(From::from)
4008 }
4009
4010 pub async fn get_guild_webhooks(&self, guild_id: GuildId) -> Result<Vec<Webhook>> {
4031 self.fire(Request {
4032 body: None,
4033 multipart: None,
4034 headers: None,
4035 method: LightMethod::Get,
4036 route: Route::GuildWebhooks {
4037 guild_id,
4038 },
4039 params: None,
4040 })
4041 .await
4042 }
4043
4044 pub async fn get_guilds(
4071 &self,
4072 target: Option<GuildPagination>,
4073 limit: Option<u64>,
4074 ) -> Result<Vec<GuildInfo>> {
4075 let mut params = vec![];
4076 if let Some(limit) = limit {
4077 params.push(("limit", limit.to_string()));
4078 }
4079 if let Some(target) = target {
4080 match target {
4081 GuildPagination::After(id) => params.push(("after", id.to_string())),
4082 GuildPagination::Before(id) => params.push(("before", id.to_string())),
4083 }
4084 }
4085
4086 self.fire(Request {
4087 body: None,
4088 multipart: None,
4089 headers: None,
4090 method: LightMethod::Get,
4091 route: Route::UserMeGuilds,
4092 params: Some(params),
4093 })
4094 .await
4095 }
4096
4097 pub async fn get_current_user_guild_member(&self, guild_id: GuildId) -> Result<Member> {
4127 let mut value: Value = self
4128 .fire(Request {
4129 body: None,
4130 multipart: None,
4131 headers: None,
4132 method: LightMethod::Get,
4133 route: Route::UserMeGuildMember {
4134 guild_id,
4135 },
4136 params: None,
4137 })
4138 .await?;
4139
4140 if let Some(map) = value.as_object_mut() {
4141 map.insert("guild_id".to_string(), guild_id.get().into());
4142 }
4143
4144 from_value(value).map_err(From::from)
4145 }
4146
4147 pub async fn get_invite(
4159 &self,
4160 code: &str,
4161 member_counts: bool,
4162 expiration: bool,
4163 event_id: Option<ScheduledEventId>,
4164 ) -> Result<Invite> {
4165 #[cfg(feature = "utils")]
4166 let code = crate::utils::parse_invite(code);
4167
4168 let mut params = vec![
4169 ("member_counts", member_counts.to_string()),
4170 ("expiration", expiration.to_string()),
4171 ];
4172 if let Some(event_id) = event_id {
4173 params.push(("event_id", event_id.to_string()));
4174 }
4175
4176 self.fire(Request {
4177 body: None,
4178 multipart: None,
4179 headers: None,
4180 method: LightMethod::Get,
4181 route: Route::Invite {
4182 code,
4183 },
4184 params: Some(params),
4185 })
4186 .await
4187 }
4188
4189 pub async fn get_member(&self, guild_id: GuildId, user_id: UserId) -> Result<Member> {
4191 let mut value: Value = self
4192 .fire(Request {
4193 body: None,
4194 multipart: None,
4195 headers: None,
4196 method: LightMethod::Get,
4197 route: Route::GuildMember {
4198 guild_id,
4199 user_id,
4200 },
4201 params: None,
4202 })
4203 .await?;
4204
4205 if let Some(map) = value.as_object_mut() {
4206 map.insert("guild_id".to_string(), guild_id.get().into());
4207 }
4208
4209 from_value(value).map_err(From::from)
4210 }
4211
4212 pub async fn get_message(
4214 &self,
4215 channel_id: ChannelId,
4216 message_id: MessageId,
4217 ) -> Result<Message> {
4218 self.fire(Request {
4219 body: None,
4220 multipart: None,
4221 headers: None,
4222 method: LightMethod::Get,
4223 route: Route::ChannelMessage {
4224 channel_id,
4225 message_id,
4226 },
4227 params: None,
4228 })
4229 .await
4230 }
4231
4232 pub async fn get_messages(
4234 &self,
4235 channel_id: ChannelId,
4236 target: Option<MessagePagination>,
4237 limit: Option<u8>,
4238 ) -> Result<Vec<Message>> {
4239 let mut params = vec![];
4240 if let Some(limit) = limit {
4241 params.push(("limit", limit.to_string()));
4242 }
4243 if let Some(target) = target {
4244 match target {
4245 MessagePagination::After(id) => params.push(("after", id.to_string())),
4246 MessagePagination::Around(id) => params.push(("around", id.to_string())),
4247 MessagePagination::Before(id) => params.push(("before", id.to_string())),
4248 }
4249 }
4250
4251 self.fire(Request {
4252 body: None,
4253 multipart: None,
4254 headers: None,
4255 method: LightMethod::Get,
4256 route: Route::ChannelMessages {
4257 channel_id,
4258 },
4259 params: Some(params),
4260 })
4261 .await
4262 }
4263
4264 pub async fn get_sticker_pack(&self, sticker_pack_id: StickerPackId) -> Result<StickerPack> {
4266 self.fire(Request {
4267 body: None,
4268 multipart: None,
4269 headers: None,
4270 method: LightMethod::Get,
4271 route: Route::StickerPack {
4272 sticker_pack_id,
4273 },
4274 params: None,
4275 })
4276 .await
4277 }
4278
4279 pub async fn get_nitro_stickers(&self) -> Result<Vec<StickerPack>> {
4281 #[derive(Deserialize)]
4282 struct StickerPacks {
4283 sticker_packs: Vec<StickerPack>,
4284 }
4285
4286 self.fire::<StickerPacks>(Request {
4287 body: None,
4288 multipart: None,
4289 headers: None,
4290 method: LightMethod::Get,
4291 route: Route::StickerPacks,
4292 params: None,
4293 })
4294 .await
4295 .map(|s| s.sticker_packs)
4296 }
4297
4298 pub async fn get_pins(&self, channel_id: ChannelId) -> Result<Vec<Message>> {
4300 self.fire(Request {
4301 body: None,
4302 multipart: None,
4303 headers: None,
4304 method: LightMethod::Get,
4305 route: Route::ChannelPins {
4306 channel_id,
4307 },
4308 params: None,
4309 })
4310 .await
4311 }
4312
4313 pub async fn get_reaction_users(
4315 &self,
4316 channel_id: ChannelId,
4317 message_id: MessageId,
4318 reaction_type: &ReactionType,
4319 limit: u8,
4320 after: Option<u64>,
4321 ) -> Result<Vec<User>> {
4322 let mut params = vec![("limit", limit.to_string())];
4323 if let Some(after) = after {
4324 params.push(("after", after.to_string()));
4325 }
4326 self.fire(Request {
4327 body: None,
4328 multipart: None,
4329 headers: None,
4330 method: LightMethod::Get,
4331 route: Route::ChannelMessageReactionEmoji {
4332 channel_id,
4333 message_id,
4334 reaction: &reaction_type.as_data(),
4335 },
4336 params: Some(params),
4337 })
4338 .await
4339 }
4340
4341 pub async fn get_skus(&self) -> Result<Vec<Sku>> {
4343 self.fire(Request {
4344 body: None,
4345 multipart: None,
4346 headers: None,
4347 method: LightMethod::Get,
4348 route: Route::Skus {
4349 application_id: self.try_application_id()?,
4350 },
4351 params: None,
4352 })
4353 .await
4354 }
4355
4356 pub async fn get_sticker(&self, sticker_id: StickerId) -> Result<Sticker> {
4358 self.fire(Request {
4359 body: None,
4360 multipart: None,
4361 headers: None,
4362 method: LightMethod::Get,
4363 route: Route::Sticker {
4364 sticker_id,
4365 },
4366 params: None,
4367 })
4368 .await
4369 }
4370
4371 pub async fn get_unresolved_incidents(&self) -> Result<Vec<Incident>> {
4375 #[derive(Deserialize)]
4376 struct StatusResponse {
4377 #[serde(default)]
4378 incidents: Vec<Incident>,
4379 }
4380
4381 let status: StatusResponse = self
4382 .fire(Request {
4383 body: None,
4384 multipart: None,
4385 headers: None,
4386 method: LightMethod::Get,
4387 route: Route::StatusIncidentsUnresolved,
4388 params: None,
4389 })
4390 .await?;
4391
4392 Ok(status.incidents)
4393 }
4394
4395 pub async fn get_upcoming_maintenances(&self) -> Result<Vec<Maintenance>> {
4399 #[derive(Deserialize)]
4400 struct StatusResponse {
4401 #[serde(default)]
4402 scheduled_maintenances: Vec<Maintenance>,
4403 }
4404
4405 let status: StatusResponse = self
4406 .fire(Request {
4407 body: None,
4408 multipart: None,
4409 headers: None,
4410 method: LightMethod::Get,
4411 route: Route::StatusMaintenancesUpcoming,
4412 params: None,
4413 })
4414 .await?;
4415
4416 Ok(status.scheduled_maintenances)
4417 }
4418
4419 pub async fn get_user(&self, user_id: UserId) -> Result<User> {
4421 self.fire(Request {
4422 body: None,
4423 multipart: None,
4424 headers: None,
4425 method: LightMethod::Get,
4426 route: Route::User {
4427 user_id,
4428 },
4429 params: None,
4430 })
4431 .await
4432 }
4433
4434 pub async fn get_user_connections(&self) -> Result<Vec<Connection>> {
4440 self.fire(Request {
4441 body: None,
4442 multipart: None,
4443 headers: None,
4444 method: LightMethod::Get,
4445 route: Route::UserMeConnections,
4446 params: None,
4447 })
4448 .await
4449 }
4450
4451 pub async fn get_user_dm_channels(&self) -> Result<Vec<PrivateChannel>> {
4453 self.fire(Request {
4454 body: None,
4455 multipart: None,
4456 headers: None,
4457 method: LightMethod::Get,
4458 route: Route::UserMeDmChannels,
4459 params: None,
4460 })
4461 .await
4462 }
4463
4464 pub async fn get_voice_regions(&self) -> Result<Vec<VoiceRegion>> {
4466 self.fire(Request {
4467 body: None,
4468 multipart: None,
4469 headers: None,
4470 method: LightMethod::Get,
4471 route: Route::VoiceRegions,
4472 params: None,
4473 })
4474 .await
4475 }
4476
4477 pub async fn get_webhook(&self, webhook_id: WebhookId) -> Result<Webhook> {
4498 self.fire(Request {
4499 body: None,
4500 multipart: None,
4501 headers: None,
4502 method: LightMethod::Get,
4503 route: Route::Webhook {
4504 webhook_id,
4505 },
4506 params: None,
4507 })
4508 .await
4509 }
4510
4511 pub async fn get_webhook_with_token(
4533 &self,
4534 webhook_id: WebhookId,
4535 token: &str,
4536 ) -> Result<Webhook> {
4537 self.fire(Request {
4538 body: None,
4539 multipart: None,
4540 headers: None,
4541 method: LightMethod::Get,
4542 route: Route::WebhookWithToken {
4543 webhook_id,
4544 token,
4545 },
4546 params: None,
4547 })
4548 .await
4549 }
4550
4551 #[cfg(feature = "utils")]
4570 pub async fn get_webhook_from_url(&self, url: &str) -> Result<Webhook> {
4571 let url = Url::parse(url).map_err(HttpError::Url)?;
4572 let (webhook_id, token) =
4573 crate::utils::parse_webhook(&url).ok_or(HttpError::InvalidWebhook)?;
4574 self.fire(Request {
4575 body: None,
4576 multipart: None,
4577 headers: None,
4578 method: LightMethod::Get,
4579 route: Route::WebhookWithToken {
4580 webhook_id,
4581 token,
4582 },
4583 params: None,
4584 })
4585 .await
4586 }
4587
4588 pub async fn kick_member(
4590 &self,
4591 guild_id: GuildId,
4592 user_id: UserId,
4593 reason: Option<&str>,
4594 ) -> Result<()> {
4595 self.wind(204, Request {
4596 body: None,
4597 multipart: None,
4598 headers: reason.map(reason_into_header),
4599 method: LightMethod::Delete,
4600 route: Route::GuildMember {
4601 guild_id,
4602 user_id,
4603 },
4604 params: None,
4605 })
4606 .await
4607 }
4608
4609 pub async fn leave_guild(&self, guild_id: GuildId) -> Result<()> {
4611 self.wind(204, Request {
4612 body: None,
4613 multipart: None,
4614 headers: None,
4615 method: LightMethod::Delete,
4616 route: Route::UserMeGuild {
4617 guild_id,
4618 },
4619 params: None,
4620 })
4621 .await
4622 }
4623
4624 pub async fn send_message(
4630 &self,
4631 channel_id: ChannelId,
4632 files: Vec<CreateAttachment>,
4633 map: &impl serde::Serialize,
4634 ) -> Result<Message> {
4635 let mut request = Request {
4636 body: None,
4637 multipart: None,
4638 headers: None,
4639 method: LightMethod::Post,
4640 route: Route::ChannelMessages {
4641 channel_id,
4642 },
4643 params: None,
4644 };
4645
4646 if files.is_empty() {
4647 request.body = Some(to_vec(map)?);
4648 } else {
4649 request.multipart = Some(Multipart {
4650 upload: MultipartUpload::Attachments(files.into_iter().collect()),
4651 payload_json: Some(to_string(map)?),
4652 fields: vec![],
4653 });
4654 }
4655
4656 self.fire(request).await
4657 }
4658
4659 pub async fn pin_message(
4661 &self,
4662 channel_id: ChannelId,
4663 message_id: MessageId,
4664 audit_log_reason: Option<&str>,
4665 ) -> Result<()> {
4666 self.wind(204, Request {
4667 body: None,
4668 multipart: None,
4669 headers: audit_log_reason.map(reason_into_header),
4670 method: LightMethod::Put,
4671 route: Route::ChannelPin {
4672 channel_id,
4673 message_id,
4674 },
4675 params: None,
4676 })
4677 .await
4678 }
4679
4680 pub async fn remove_ban(
4682 &self,
4683 guild_id: GuildId,
4684 user_id: UserId,
4685 audit_log_reason: Option<&str>,
4686 ) -> Result<()> {
4687 self.wind(204, Request {
4688 body: None,
4689 multipart: None,
4690 headers: audit_log_reason.map(reason_into_header),
4691 method: LightMethod::Delete,
4692 route: Route::GuildBan {
4693 guild_id,
4694 user_id,
4695 },
4696 params: None,
4697 })
4698 .await
4699 }
4700
4701 pub async fn remove_member_role(
4707 &self,
4708 guild_id: GuildId,
4709 user_id: UserId,
4710 role_id: RoleId,
4711 audit_log_reason: Option<&str>,
4712 ) -> Result<()> {
4713 self.wind(204, Request {
4714 body: None,
4715 multipart: None,
4716 headers: audit_log_reason.map(reason_into_header),
4717 method: LightMethod::Delete,
4718 route: Route::GuildMemberRole {
4719 guild_id,
4720 user_id,
4721 role_id,
4722 },
4723 params: None,
4724 })
4725 .await
4726 }
4727
4728 pub async fn search_guild_members(
4731 &self,
4732 guild_id: GuildId,
4733 query: &str,
4734 limit: Option<u64>,
4735 ) -> Result<Vec<Member>> {
4736 let mut value: Value = self
4737 .fire(Request {
4738 body: None,
4739 multipart: None,
4740 headers: None,
4741 method: LightMethod::Get,
4742 route: Route::GuildMembersSearch {
4743 guild_id,
4744 },
4745 params: Some(vec![
4746 ("query", query.to_string()),
4747 ("limit", limit.unwrap_or(constants::MEMBER_FETCH_LIMIT).to_string()),
4748 ]),
4749 })
4750 .await?;
4751
4752 if let Some(members) = value.as_array_mut() {
4753 for member in members {
4754 if let Some(map) = member.as_object_mut() {
4755 map.insert("guild_id".to_string(), guild_id.get().into());
4756 }
4757 }
4758 }
4759
4760 from_value(value).map_err(From::from)
4761 }
4762
4763 pub async fn start_guild_prune(
4765 &self,
4766 guild_id: GuildId,
4767 days: u8,
4768 audit_log_reason: Option<&str>,
4769 ) -> Result<GuildPrune> {
4770 self.fire(Request {
4771 body: None,
4772 multipart: None,
4773 headers: audit_log_reason.map(reason_into_header),
4774 method: LightMethod::Post,
4775 route: Route::GuildPrune {
4776 guild_id,
4777 },
4778 params: Some(vec![("days", days.to_string())]),
4779 })
4780 .await
4781 }
4782
4783 pub async fn start_integration_sync(
4785 &self,
4786 guild_id: GuildId,
4787 integration_id: IntegrationId,
4788 ) -> Result<()> {
4789 self.wind(204, Request {
4790 body: None,
4791 multipart: None,
4792 headers: None,
4793 method: LightMethod::Post,
4794 route: Route::GuildIntegrationSync {
4795 guild_id,
4796 integration_id,
4797 },
4798 params: None,
4799 })
4800 .await
4801 }
4802
4803 pub fn start_typing(self: &Arc<Self>, channel_id: ChannelId) -> Typing {
4840 Typing::start(Arc::clone(self), channel_id)
4841 }
4842
4843 pub async fn unpin_message(
4845 &self,
4846 channel_id: ChannelId,
4847 message_id: MessageId,
4848 audit_log_reason: Option<&str>,
4849 ) -> Result<()> {
4850 self.wind(204, Request {
4851 body: None,
4852 multipart: None,
4853 headers: audit_log_reason.map(reason_into_header),
4854 method: LightMethod::Delete,
4855 route: Route::ChannelPin {
4856 channel_id,
4857 message_id,
4858 },
4859 params: None,
4860 })
4861 .await
4862 }
4863
4864 pub async fn fire<T: DeserializeOwned>(&self, req: Request<'_>) -> Result<T> {
4902 let response = self.request(req).await?;
4903 decode_resp(response).await
4904 }
4905
4906 #[instrument]
4938 pub async fn request(&self, req: Request<'_>) -> Result<ReqwestResponse> {
4939 let method = req.method.reqwest_method();
4940 let response = if let Some(ratelimiter) = &self.ratelimiter {
4941 ratelimiter.perform(req).await?
4942 } else {
4943 let request = req.build(&self.client, self.token(), self.proxy.as_deref())?.build()?;
4944 self.client.execute(request).await?
4945 };
4946
4947 if response.status().is_success() {
4948 Ok(response)
4949 } else {
4950 Err(Error::Http(HttpError::UnsuccessfulRequest(
4951 ErrorResponse::from_response(response, method).await,
4952 )))
4953 }
4954 }
4955
4956 pub(super) async fn wind(&self, expected: u16, req: Request<'_>) -> Result<()> {
4962 let route = req.route;
4963 let method = req.method.reqwest_method();
4964 let response = self.request(req).await?;
4965
4966 if response.status().is_success() {
4967 let response_status = response.status().as_u16();
4968 if response_status != expected {
4969 let route = route.path();
4970 warn!("Mismatched successful response status from {route}! Expected {expected} but got {response_status}");
4971 }
4972
4973 return Ok(());
4974 }
4975
4976 debug!("Unsuccessful response: {response:?}");
4977 Err(Error::Http(HttpError::UnsuccessfulRequest(
4978 ErrorResponse::from_response(response, method).await,
4979 )))
4980 }
4981}
4982
4983#[cfg(not(feature = "native_tls_backend"))]
4984fn configure_client_backend(builder: ClientBuilder) -> ClientBuilder {
4985 builder.use_rustls_tls()
4986}
4987
4988#[cfg(feature = "native_tls_backend")]
4989fn configure_client_backend(builder: ClientBuilder) -> ClientBuilder {
4990 builder.use_native_tls()
4991}
4992
4993impl AsRef<Http> for Http {
4994 fn as_ref(&self) -> &Http {
4995 self
4996 }
4997}