Introduce internal API call queueing mechanism to send messages sequentially (no more random order)
This commit is contained in:
parent
f6beebe241
commit
8d280e157c
@ -1,6 +1,17 @@
|
||||
// API methods
|
||||
import fetch from './fetch';
|
||||
|
||||
/**
|
||||
* Simple replacement for Bluebird's Promise.mapSeries() implementation
|
||||
* @param {Array} tasks to run serially
|
||||
* @param {Function} task function to execute
|
||||
* @return {Promise}
|
||||
*/
|
||||
function sequence(tasks, fn) {
|
||||
return tasks.reduce((promise, task) => promise.then(() => fn(task)), Promise.resolve());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* API class, has a function for each method of the Telegram API which take
|
||||
* an object argument, and send request to the API server
|
||||
@ -8,6 +19,7 @@ import fetch from './fetch';
|
||||
* Methods: getMe, sendMessage, forwardMessage, sendPhoto, sendAudio,
|
||||
* sendDocument, sendSticker, sendVideo, sendLocation, sendChatAction,
|
||||
* getUserProfilePhotos, getUpdates
|
||||
*
|
||||
*/
|
||||
export default class API {
|
||||
/**
|
||||
@ -16,6 +28,29 @@ export default class API {
|
||||
*/
|
||||
constructor(token) {
|
||||
this.token = token;
|
||||
this._queue = [];
|
||||
this._inUseQueue = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Telegram API calls serially using internal queueing mechanism
|
||||
* @private
|
||||
*/
|
||||
_runQueue() {
|
||||
// implementation taken from https://github.com/yagop/node-telegram-bot-api/issues/192#issuecomment-249488807
|
||||
if (this._inUseQueue.length || !this._queue.length) return;
|
||||
|
||||
this._inUseQueue = this._queue;
|
||||
this._queue = [];
|
||||
|
||||
sequence(this._inUseQueue, request => { //eslint-disable-line
|
||||
return this.request(request.method, request.data)
|
||||
.then(request.resolve)
|
||||
.catch(request.reject);
|
||||
}).then(() => {
|
||||
this._inUseQueue = [];
|
||||
this._runQueue();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,12 +59,24 @@ API.prototype.request = function request(method, data) {
|
||||
};
|
||||
|
||||
const methods = ['getMe', 'sendMessage', 'forwardMessage', 'sendPhoto',
|
||||
'sendAudio', 'sendDocument', 'sendSticker', 'sendVideo',
|
||||
'sendLocation', 'sendChatAction', 'getUserProfilePhotos',
|
||||
'getUpdates', 'setWebhook', 'deleteMessage'];
|
||||
'sendAudio', 'sendDocument', 'sendSticker', 'sendVideo',
|
||||
'sendLocation', 'sendChatAction', 'getUserProfilePhotos',
|
||||
'getUpdates', 'setWebhook', 'deleteMessage'];
|
||||
|
||||
methods.forEach(method => {
|
||||
API.prototype[method] = function(data) { //eslint-disable-line
|
||||
return this.request(method, data);
|
||||
API.prototype[method] = function (data) { //eslint-disable-line
|
||||
// implementation taken from https://github.com/yagop/node-telegram-bot-api/issues/192#issuecomment-249488807
|
||||
let resolve;
|
||||
let reject;
|
||||
|
||||
const promise = new Promise((_resolve, _reject) => {
|
||||
resolve = _resolve;
|
||||
reject = _reject;
|
||||
});
|
||||
|
||||
this._queue.push({ method, data, resolve, reject });
|
||||
process.nextTick(this._runQueue.bind(this));
|
||||
|
||||
return promise;
|
||||
};
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user