mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
Add Rate Limiting, see hammerandchisel/discord-api-docs#20
This commit is contained in:
@@ -12,14 +12,57 @@ class RESTManager{
|
||||
this.queue = [];
|
||||
this.userAgentManager = new UserAgentManager(this);
|
||||
this.methods = new RESTMethods(this);
|
||||
this.rateLimitedEndpoints = {};
|
||||
}
|
||||
|
||||
makeRequest(method, url, auth, data, file) {
|
||||
addRequestToQueue(method, url, auth, data, file, resolve, reject) {
|
||||
let endpoint = url.replace(/\/[0-9]+/g, '/:id');
|
||||
|
||||
let rateLimitedEndpoint = this.rateLimitedEndpoints[endpoint];
|
||||
|
||||
rateLimitedEndpoint.queue = rateLimitedEndpoint.queue || [];
|
||||
|
||||
rateLimitedEndpoint.queue.push({
|
||||
method, url, auth, data, file, resolve, reject,
|
||||
});
|
||||
}
|
||||
|
||||
processQueue(endpoint) {
|
||||
let rateLimitedEndpoint = this.rateLimitedEndpoints[endpoint];
|
||||
|
||||
// prevent multiple queue processes
|
||||
if (!rateLimitedEndpoint.timeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
// lock the queue
|
||||
clearTimeout(rateLimitedEndpoint.timeout);
|
||||
rateLimitedEndpoint.timeout = null;
|
||||
|
||||
for (let item of rateLimitedEndpoint.queue) {
|
||||
this.makeRequest(item.method, item.url, item.auth, item.data, item.file)
|
||||
.then(item.resolve)
|
||||
.catch(item.reject);
|
||||
}
|
||||
|
||||
rateLimitedEndpoint.queue = [];
|
||||
}
|
||||
|
||||
makeRequest(method, url, auth, data, file, fromQueue) {
|
||||
/*
|
||||
file is {file, name}
|
||||
*/
|
||||
let apiRequest = request[method](url);
|
||||
|
||||
let endpoint = url.replace(/\/[0-9]+/g, '/:id');
|
||||
|
||||
if (this.rateLimitedEndpoints[endpoint] && this.rateLimitedEndpoints[endpoint].timeout) {
|
||||
console.log('adding to queue');
|
||||
return new Promise((resolve, reject) => {
|
||||
this.addRequestToQueue(method, url, auth, data, file, resolve, reject);
|
||||
});
|
||||
}
|
||||
|
||||
if (auth) {
|
||||
if (this.client.store.token) {
|
||||
apiRequest.set('authorization', this.client.store.token);
|
||||
@@ -41,6 +84,16 @@ class RESTManager{
|
||||
return new Promise((resolve, reject) => {
|
||||
apiRequest.end((err, res) => {
|
||||
if (err) {
|
||||
let retry = res.headers['retry-after'] || res.headers['Retry-After'];
|
||||
if (retry) {
|
||||
this.rateLimitedEndpoints[endpoint] = {};
|
||||
this.addRequestToQueue(method, url, auth, data, file, resolve, reject);
|
||||
this.rateLimitedEndpoints[endpoint].timeout = setTimeout(() => {
|
||||
this.processQueue(endpoint);
|
||||
}, retry);
|
||||
return;
|
||||
}
|
||||
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(res ? res.body || {} : {});
|
||||
|
||||
@@ -70,7 +70,7 @@ client.on('typingStop.', (channel, user, data) => {
|
||||
|
||||
client.on('message', message => {
|
||||
if (message.author.username === 'hydrabolt')
|
||||
message.channel.sendMessage('hydrabolt said: ' + message.content).then(console.log).catch(console.log);
|
||||
message.channel.sendMessage('hydrabolt said: ' + message.content).then(m => console.log(m.content)).catch(console.log);
|
||||
});
|
||||
|
||||
client.on('messageDelete', message => {
|
||||
|
||||
Reference in New Issue
Block a user