diff options
| author | Zeyla Hellyer <[email protected]> | 2017-02-12 09:23:07 -0800 |
|---|---|---|
| committer | Zeyla Hellyer <[email protected]> | 2017-02-12 09:23:07 -0800 |
| commit | 01f687204dd9d5564ec4bdc860f11bfd5e01454f (patch) | |
| tree | b7b14cf34418cf8265e1a0d1fabf6b54335103ff /src | |
| parent | Handle unsuccessful responses before decoding (diff) | |
| download | serenity-01f687204dd9d5564ec4bdc860f11bfd5e01454f.tar.xz serenity-01f687204dd9d5564ec4bdc860f11bfd5e01454f.zip | |
Uniquely ratelimit message deletions
Message deletions fall under a separate ratelimit apart from the route's
global ratelimit, and so the DELETE verb for the route is now separately
handled.
This is documented [here] as the following (at the time of this
writing):
> There is currently a single exception to the above rule regarding
> different HTTP methods sharing the same rate limit, and that is for
> the deletion of messages. Deleting messages falls under a separate,
> higher rate limit so that bots are able to more quickly delete content
> from channels (which is useful for moderation bots).
[here]: https://discordapp.com/developers/docs/topics/rate-limits#rate-limits
Diffstat (limited to 'src')
| -rw-r--r-- | src/client/rest/mod.rs | 25 | ||||
| -rw-r--r-- | src/client/rest/ratelimiting.rs | 10 |
2 files changed, 30 insertions, 5 deletions
diff --git a/src/client/rest/mod.rs b/src/client/rest/mod.rs index 253f0f9..a49ba43 100644 --- a/src/client/rest/mod.rs +++ b/src/client/rest/mod.rs @@ -49,6 +49,25 @@ use ::internal::prelude::*; use ::model::*; use ::utils::decode_array; +/// An method used for ratelimiting special routes. +/// +/// This is needed because `hyper`'s `Method` enum does not derive Copy. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub enum LightMethod { + /// Indicates that a route is for "any" method. + Any, + /// Indicates that a route is for the `DELETE` method only. + Delete, + /// Indicates that a route is for the `GET` method only. + Get, + /// Indicates that a route is for the `PATCH` method only. + Patch, + /// Indicates that a route is for the `POST` method only. + Post, + /// Indicates that a route is for the `PUT` method only. + Put, +} + lazy_static! { static ref TOKEN: Arc<Mutex<String>> = Arc::new(Mutex::new(String::default())); } @@ -450,7 +469,7 @@ pub fn delete_invite(code: &str) -> Result<Invite> { /// Deletes a message if created by us or we have /// specific permissions. pub fn delete_message(channel_id: u64, message_id: u64) -> Result<()> { - verify(204, request!(Route::ChannelsIdMessagesId(channel_id), + verify(204, request!(Route::ChannelsIdMessagesId(LightMethod::Delete, channel_id), delete, "/channels/{}/messages/{}", channel_id, @@ -641,7 +660,7 @@ pub fn edit_member(guild_id: u64, user_id: u64, map: Value) -> Result<()> { /// **Note**: Only the author of a message can modify it. pub fn edit_message(channel_id: u64, message_id: u64, map: Value) -> Result<Message> { let body = serde_json::to_string(&map)?; - let response = request!(Route::ChannelsIdMessagesId(channel_id), + let response = request!(Route::ChannelsIdMessagesId(LightMethod::Any, channel_id), patch(body), "/channels/{}/messages/{}", channel_id, @@ -1197,7 +1216,7 @@ pub fn get_member(guild_id: u64, user_id: u64) -> Result<Member> { /// Gets a message by an Id, bots only. pub fn get_message(channel_id: u64, message_id: u64) -> Result<Message> { - let response = request!(Route::ChannelsIdMessagesId(channel_id), + let response = request!(Route::ChannelsIdMessagesId(LightMethod::Any, channel_id), get, "/channels/{}/messages/{}", channel_id, diff --git a/src/client/rest/ratelimiting.rs b/src/client/rest/ratelimiting.rs index 26f35d6..f232759 100644 --- a/src/client/rest/ratelimiting.rs +++ b/src/client/rest/ratelimiting.rs @@ -46,6 +46,7 @@ use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Duration; use std::{str, thread}; +use super::LightMethod; use time; use ::internal::prelude::*; @@ -101,7 +102,13 @@ pub enum Route { ChannelsIdInvites(u64), ChannelsIdMessages(u64), ChannelsIdMessagesBulkDelete(u64), - ChannelsIdMessagesId(u64), + // This route is a unique case. The ratelimit for message _deletions_ is + // different than the overall route ratelimit. + // + // Refer to the docs on [Rate Limits] in the yellow warning section. + // + // [Rate Limits]: https://discordapp.com/developers/docs/topics/rate-limits + ChannelsIdMessagesId(LightMethod, u64), ChannelsIdMessagesIdAck(u64), ChannelsIdMessagesIdReactions(u64), ChannelsIdMessagesIdReactionsUserIdType(u64), @@ -150,7 +157,6 @@ pub enum Route { #[doc(hidden)] pub fn perform<'a, F>(route: Route, f: F) -> Result<Response> where F: Fn() -> RequestBuilder<'a> { - loop { { // This will block if another thread already has the global |