diff --git a/package.json b/package.json index d76630d..ee51d69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "telegram-api", - "version": "3.1.1", + "version": "3.0.0", "description": "Control Telegram bots easily using the new Telegram API", "main": "build/index.js", "scripts": { diff --git a/src/functions/api.js b/src/functions/api.js index b505f81..9ee952d 100644 --- a/src/functions/api.js +++ b/src/functions/api.js @@ -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,16 @@ 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 + return new Promise((resolve, reject) => { + this._queue.push({ method, data, resolve, reject }); + process.nextTick(this._runQueue.bind(this)); + }); }; });