From b71e553584dd04653866b35e35356794ccb4bde5 Mon Sep 17 00:00:00 2001 From: GochoMugo Date: Wed, 21 Dec 2016 09:50:17 +0300 Subject: [PATCH] Ensure consistency of methods signatures Bug: The library assumes signatures of methods to be, somewhat: methodName(requiredParam1, requiredParam2, form = {}) where 'requiredParam1' ('requiredParam2', ..., 'requiredParamN') are parameters that MUST be provided, and 'form' is an optional object allowing supplying any additional, optional parameters that the Bot API allows. This allows any new parameters added by Telegram to be readily-supported by our library. --- README.md | 28 +++++++-------- src/telegram.js | 90 +++++++++++++++++++++++++++++++------------------ 2 files changed, 70 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 3b3262c6..bf9af9e5 100644 --- a/README.md +++ b/README.md @@ -73,11 +73,11 @@ TelegramBot * [new TelegramBot(token, [options])](#new_TelegramBot_new) * [.stopPolling()](#TelegramBot+stopPolling) ⇒ Promise * [.getMe()](#TelegramBot+getMe) ⇒ Promise - * [.setWebHook(url, [cert])](#TelegramBot+setWebHook) - * [.getUpdates([timeout], [limit], [offset])](#TelegramBot+getUpdates) ⇒ Promise + * [.setWebHook(url, [options])](#TelegramBot+setWebHook) + * [.getUpdates([options])](#TelegramBot+getUpdates) ⇒ Promise * [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ Promise * [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ Promise - * [.forwardMessage(chatId, fromChatId, messageId)](#TelegramBot+forwardMessage) ⇒ Promise + * [.forwardMessage(chatId, fromChatId, messageId, [options])](#TelegramBot+forwardMessage) ⇒ Promise * [.sendPhoto(chatId, photo, [options])](#TelegramBot+sendPhoto) ⇒ Promise * [.sendAudio(chatId, audio, [options])](#TelegramBot+sendAudio) ⇒ Promise * [.sendDocument(chatId, doc, [options], [fileOpts])](#TelegramBot+sendDocument) ⇒ Promise @@ -91,7 +91,7 @@ TelegramBot * [.editMessageText(text, [options])](#TelegramBot+editMessageText) ⇒ Promise * [.editMessageCaption(caption, [options])](#TelegramBot+editMessageCaption) ⇒ Promise * [.editMessageReplyMarkup(replyMarkup, [options])](#TelegramBot+editMessageReplyMarkup) ⇒ Promise - * [.getUserProfilePhotos(userId, [offset], [limit])](#TelegramBot+getUserProfilePhotos) ⇒ Promise + * [.getUserProfilePhotos(userId, [options])](#TelegramBot+getUserProfilePhotos) ⇒ Promise * [.sendLocation(chatId, latitude, longitude, [options])](#TelegramBot+sendLocation) ⇒ Promise * [.sendVenue(chatId, latitude, longitude, title, address, [options])](#TelegramBot+sendVenue) ⇒ Promise * [.sendContact(chatId, phoneNumber, firstName, [options])](#TelegramBot+sendContact) ⇒ Promise @@ -146,7 +146,7 @@ Returns basic information about the bot in form of a `User` object. **See**: https://core.telegram.org/bots/api#getme -### telegramBot.setWebHook(url, [cert]) +### telegramBot.setWebHook(url, [options]) Specify an url to receive incoming updates via an outgoing webHook. **Kind**: instance method of [TelegramBot](#TelegramBot) @@ -155,22 +155,20 @@ Specify an url to receive incoming updates via an outgoing webHook. | Param | Type | Description | | --- | --- | --- | | url | String | URL where Telegram will make HTTP Post. Leave empty to delete webHook. | -| [cert] | String | stream.Stream | PEM certificate key (public). | +| [options] | Object | Additional Telegram query options | +| [options.certificate] | String | stream.Stream | PEM certificate key (public). | -### telegramBot.getUpdates([timeout], [limit], [offset]) ⇒ Promise +### telegramBot.getUpdates([options]) ⇒ Promise Use this method to receive incoming updates using long polling **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Promise - Updates **See**: https://core.telegram.org/bots/api#getupdates | Param | Type | Description | | --- | --- | --- | -| [timeout] | Number | String | Timeout in seconds for long polling. | -| [limit] | Number | String | Limits the number of updates to be retrieved. | -| [offset] | Number | String | Identifier of the first update to be returned. | +| [options] | Object | Additional Telegram query options | @@ -202,7 +200,7 @@ Send answers to an inline query. -### telegramBot.forwardMessage(chatId, fromChatId, messageId) ⇒ Promise +### telegramBot.forwardMessage(chatId, fromChatId, messageId, [options]) ⇒ Promise Forward messages of any kind. **Kind**: instance method of [TelegramBot](#TelegramBot) @@ -212,6 +210,7 @@ Forward messages of any kind. | chatId | Number | String | Unique identifier for the message recipient | | fromChatId | Number | String | Unique identifier for the chat where the original message was sent | | messageId | Number | String | Unique message identifier | +| [options] | Object | Additional Telegram query options | @@ -422,7 +421,7 @@ inline_message_id in your request. -### telegramBot.getUserProfilePhotos(userId, [offset], [limit]) ⇒ Promise +### telegramBot.getUserProfilePhotos(userId, [options]) ⇒ Promise Use this method to get a list of profile pictures for a user. Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object. @@ -432,8 +431,7 @@ Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephot | Param | Type | Description | | --- | --- | --- | | userId | Number | String | Unique identifier of the target user | -| [offset] | Number | Sequential number of the first photo to be returned. By default, all photos are returned. | -| [limit] | Number | Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. | +| [options] | Object | Additional Telegram query options | diff --git a/src/telegram.js b/src/telegram.js index 1f65f0c4..38d64827 100644 --- a/src/telegram.js +++ b/src/telegram.js @@ -139,7 +139,7 @@ class TelegramBot extends EventEmitter { } } else if (channelPost) { debug('Process Update channel_post %j', channelPost); - this.emit('channel_post', channelPost); + this.emit('channel_post', channelPost); } else if (editedChannelPost) { debug('Process Update edited_channel_post %j', editedChannelPost); this.emit('edited_channel_post', editedChannelPost); @@ -148,7 +148,7 @@ class TelegramBot extends EventEmitter { } if (editedChannelPost.caption) { this.emit('edited_channel_post_caption', editedChannelPost); - } + } } else if (inlineQuery) { debug('Process Update inline_query %j', inlineQuery); this.emit('inline_query', inlineQuery); @@ -241,14 +241,29 @@ class TelegramBot extends EventEmitter { /** * Specify an url to receive incoming updates via an outgoing webHook. - * @param {String} url URL where Telegram will make HTTP Post. Leave empty to + * @param {String} url URL where Telegram will make HTTP Post. Leave empty to * delete webHook. - * @param {String|stream.Stream} [cert] PEM certificate key (public). + * @param {Object} [options] Additional Telegram query options + * @param {String|stream.Stream} [options.certificate] PEM certificate key (public). * @see https://core.telegram.org/bots/api#setwebhook */ - setWebHook(url, cert) { - const _path = 'setWebHook'; - const opts = { qs: { url } }; + setWebHook(url, options = {}) { + /* The older method signature was setWebHook(url, cert). + * We need to ensure backwards-compatibility while maintaining + * consistency of the method signatures throughout the library */ + let cert; + // Note: 'options' could be an object, if a stream was provided (in place of 'cert') + if (typeof options !== 'object' || options instanceof stream.Stream) { + cert = options; + options = {}; // eslint-disable-line no-param-reassign + } else { + cert = options.certificate; + } + + const opts = { + qs: options, + }; + opts.qs.url = url; if (cert) { const [formData, certificate] = this._formatSendData('certificate', cert); @@ -256,7 +271,7 @@ class TelegramBot extends EventEmitter { opts.qs.certificate = certificate; } - return this._request(_path, opts) + return this._request('setWebHook', opts) .then(resp => { if (!resp) { throw new Error(resp); @@ -268,18 +283,23 @@ class TelegramBot extends EventEmitter { /** * Use this method to receive incoming updates using long polling - * @param {Number|String} [timeout] Timeout in seconds for long polling. - * @param {Number|String} [limit] Limits the number of updates to be retrieved. - * @param {Number|String} [offset] Identifier of the first update to be returned. - * @return {Promise} Updates + * @param {Object} [options] Additional Telegram query options + * @return {Promise} * @see https://core.telegram.org/bots/api#getupdates */ - getUpdates(timeout, limit, offset) { - const form = { - offset, - limit, - timeout, - }; + getUpdates(form = {}) { + /* The older method signature was getUpdates(timeout, limit, offset). + * We need to ensure backwards-compatibility while maintaining + * consistency of the method signatures throughout the library */ + if (typeof form !== 'object') { + /* eslint-disable no-param-reassign, prefer-rest-params */ + form = { + timeout: arguments[0], + limit: arguments[1], + offset: arguments[2], + }; + /* eslint-enable no-param-reassign, prefer-rest-params */ + } return this._request('getUpdates', { form }); } @@ -318,15 +338,13 @@ class TelegramBot extends EventEmitter { * @param {Number|String} fromChatId Unique identifier for the chat where the * original message was sent * @param {Number|String} messageId Unique message identifier + * @param {Object} [options] Additional Telegram query options * @return {Promise} */ - forwardMessage(chatId, fromChatId, messageId) { - const form = { - chat_id: chatId, - from_chat_id: fromChatId, - message_id: messageId - }; - + forwardMessage(chatId, fromChatId, messageId, form = {}) { + form.chat_id = chatId; + form.from_chat_id = fromChatId; + form.message_id = messageId; return this._request('forwardMessage', { form }); } @@ -636,17 +654,23 @@ class TelegramBot extends EventEmitter { * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object. * * @param {Number|String} userId Unique identifier of the target user - * @param {Number} [offset] Sequential number of the first photo to be returned. By default, all photos are returned. - * @param {Number} [limit] Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. + * @param {Object} [options] Additional Telegram query options * @return {Promise} * @see https://core.telegram.org/bots/api#getuserprofilephotos */ - getUserProfilePhotos(userId, offset, limit) { - const form = { - user_id: userId, - offset, - limit - }; + getUserProfilePhotos(userId, form = {}) { + /* The older method signature was getUserProfilePhotos(userId, offset, limit). + * We need to ensure backwards-compatibility while maintaining + * consistency of the method signatures throughout the library */ + if (typeof form !== 'object') { + /* eslint-disable no-param-reassign, prefer-rest-params */ + form = { + offset: arguments[1], + limit: arguments[2], + }; + /* eslint-enable no-param-reassign, prefer-rest-params */ + } + form.user_id = userId; return this._request('getUserProfilePhotos', { form }); }