Skip to content

Commit

Permalink
Uniquely ratelimit message deletions
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Zeyla Hellyer committed Feb 12, 2017
1 parent 7e254c5 commit 01f6872
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
25 changes: 22 additions & 3 deletions src/client/rest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 8 additions & 2 deletions src/client/rest/ratelimiting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 01f6872

Please sign in to comment.