From f50cf982c78022f496397211ad860b68115a2a9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=C3=A9rez=20Fern=C3=A1ndez?= Date: Tue, 19 Jul 2022 12:43:39 +0200 Subject: [PATCH] Hotfix: tests + modify order src/telegram + docs (#988) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: stopPoll * test: setChatStickerSet and deleteChatStickerSet * refactor: src/telegram.js * Remove legacy methods: - getChatMembersCount - getChatMembersCount - kickChatMember * Remove mandatory param “start_parameter” from sendInvoice, because actually is a optional param * docs: Update docs API * docs: Update * fix: addStickerToSet * fix: stringify * refactor: And add deleteStickerFromSet + setStickerPositionInSet * fix: eslint * docs: Update changelog --- .eslintrc | 3 +- CHANGELOG.md | 25 + doc/api.md | 2129 ++++++++++++++++++++++--------------------- package.json | 4 +- src/telegram.js | 2276 +++++++++++++++++++++++----------------------- test/telegram.js | 1588 +++++++++++++++++--------------- 6 files changed, 3138 insertions(+), 2887 deletions(-) diff --git a/.eslintrc b/.eslintrc index 6c4d62f..89f049b 100644 --- a/.eslintrc +++ b/.eslintrc @@ -7,7 +7,8 @@ "no-param-reassign": [2,{"props":false}], "max-len": [2, 200], "arrow-body-style": 0, - "comma-dangle": 0 + "comma-dangle": 0, + "indent": ["error", 2] }, "plugins": [ "mocha" diff --git a/CHANGELOG.md b/CHANGELOG.md index d26a338..cc10f64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,31 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [0.59.0][0.59.0] - 2022-07-19 + +1. Remove dependencies: (@danielperez9430) + * Remove *bluebird* => Use NodeJS Native Promises + * Remove *depd* => Use node native deprecate util for warnings + * Remove contributor dev dependency and add list of contributors in the readme + +2. Remove legacy methods: (@danielperez9430) + * getChatMembersCount + * kickChatMember + +3. Docs: (@danielperez9430) + * Update the docs of functions + * Order functions follow the Telegram bot API docs in src/telegram.js + +4. Fix: (@danielperez9430) + * addStickerToSet() -> Allow to send tgs_sticker + webm_sticker + * Remove mandatory param “start_parameter” from sendInvoice, because in the docs is a optional param + * Fix some tests + +5. New Test: (@danielperez9430) + * deleteStickerFromSet + * setStickerPositionInSet + + ## [0.58.0][0.58.0] - 2022-06-22 1. Support Bot API v6.1: (@danielperez9430) diff --git a/doc/api.md b/doc/api.md index 7b3f00d..e1e309c 100644 --- a/doc/api.md +++ b/doc/api.md @@ -17,47 +17,62 @@ TelegramBot * [.startPolling([options])](#TelegramBot+startPolling) ⇒ Promise * ~~[.initPolling([options])](#TelegramBot+initPolling) ⇒ Promise~~ * [.stopPolling([options])](#TelegramBot+stopPolling) ⇒ Promise + * [.getFileLink(fileId, [options])](#TelegramBot+getFileLink) ⇒ Promise + * [.getFileStream(fileId, [options])](#TelegramBot+getFileStream) ⇒ stream.Readable + * [.downloadFile(fileId, downloadDir, [options])](#TelegramBot+downloadFile) ⇒ Promise + * [.onText(regexpRexecuted, callback)](#TelegramBot+onText) + * [.removeTextListener(regexp)](#TelegramBot+removeTextListener) ⇒ Object + * [.clearTextListeners()](#TelegramBot+clearTextListeners) + * [.onReplyToMessage(chatId, messageId, callback)](#TelegramBot+onReplyToMessage) ⇒ Number + * [.removeReplyListener(replyListenerId)](#TelegramBot+removeReplyListener) ⇒ Object + * [.clearReplyListeners()](#TelegramBot+clearReplyListeners) ⇒ Array * [.isPolling()](#TelegramBot+isPolling) ⇒ Boolean * [.openWebHook()](#TelegramBot+openWebHook) ⇒ Promise * [.closeWebHook()](#TelegramBot+closeWebHook) ⇒ Promise * [.hasOpenWebHook()](#TelegramBot+hasOpenWebHook) ⇒ Boolean - * [.getMe([options])](#TelegramBot+getMe) ⇒ Promise - * [.logOut([options])](#TelegramBot+logOut) ⇒ Promise - * [.close([options])](#TelegramBot+close) ⇒ Promise + * [.processUpdate(update)](#TelegramBot+processUpdate) + * [.getUpdates([options])](#TelegramBot+getUpdates) ⇒ Promise * [.setWebHook(url, [options], [fileOptions])](#TelegramBot+setWebHook) ⇒ Promise * [.deleteWebHook([options])](#TelegramBot+deleteWebHook) ⇒ Promise * [.getWebHookInfo([options])](#TelegramBot+getWebHookInfo) ⇒ Promise - * [.getUpdates([options])](#TelegramBot+getUpdates) ⇒ Promise - * [.processUpdate(update)](#TelegramBot+processUpdate) + * [.getMe([options])](#TelegramBot+getMe) ⇒ Promise + * [.logOut([options])](#TelegramBot+logOut) ⇒ Promise + * [.close([options])](#TelegramBot+close) ⇒ Promise * [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ Promise - * [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ Promise * [.forwardMessage(chatId, fromChatId, messageId, [options])](#TelegramBot+forwardMessage) ⇒ Promise * [.copyMessage(chatId, fromChatId, messageId, [options])](#TelegramBot+copyMessage) ⇒ Promise * [.sendPhoto(chatId, photo, [options], [fileOptions])](#TelegramBot+sendPhoto) ⇒ Promise * [.sendAudio(chatId, audio, [options], [fileOptions])](#TelegramBot+sendAudio) ⇒ Promise - * [.sendDice(chatId, [options])](#TelegramBot+sendDice) ⇒ Promise * [.sendDocument(chatId, doc, [options], [fileOptions])](#TelegramBot+sendDocument) ⇒ Promise - * [.sendSticker(chatId, sticker, [options], [fileOptions])](#TelegramBot+sendSticker) ⇒ Promise * [.sendVideo(chatId, video, [options], [fileOptions])](#TelegramBot+sendVideo) ⇒ Promise * [.sendAnimation(chatId, animation, [options], [fileOptions])](#TelegramBot+sendAnimation) ⇒ Promise - * [.sendVideoNote(chatId, videoNote, [options], [fileOptions])](#TelegramBot+sendVideoNote) ⇒ Promise * [.sendVoice(chatId, voice, [options], [fileOptions])](#TelegramBot+sendVoice) ⇒ Promise + * [.sendVideoNote(chatId, videoNote, [options], [fileOptions])](#TelegramBot+sendVideoNote) ⇒ Promise + * [.sendMediaGroup(chatId, media, [options])](#TelegramBot+sendMediaGroup) ⇒ Promise + * [.sendLocation(chatId, latitude, longitude, [options])](#TelegramBot+sendLocation) ⇒ Promise + * [.editMessageLiveLocation(latitude, longitude, [options])](#TelegramBot+editMessageLiveLocation) ⇒ Promise + * [.stopMessageLiveLocation([options])](#TelegramBot+stopMessageLiveLocation) ⇒ Promise + * [.sendVenue(chatId, latitude, longitude, title, address, [options])](#TelegramBot+sendVenue) ⇒ Promise + * [.sendContact(chatId, phoneNumber, firstName, [options])](#TelegramBot+sendContact) ⇒ Promise + * [.sendPoll(chatId, question, pollOptions, [options])](#TelegramBot+sendPoll) ⇒ Promise + * [.sendDice(chatId, [options])](#TelegramBot+sendDice) ⇒ Promise * [.sendChatAction(chatId, action, [options])](#TelegramBot+sendChatAction) ⇒ Promise - * ~~[.kickChatMember(chatId, userId, [options])](#TelegramBot+kickChatMember) ⇒ Promise~~ + * [.getUserProfilePhotos(userId, [options])](#TelegramBot+getUserProfilePhotos) ⇒ Promise + * [.getFile(fileId, [options])](#TelegramBot+getFile) ⇒ Promise * [.banChatMember(chatId, userId, [options])](#TelegramBot+banChatMember) ⇒ Promise * [.unbanChatMember(chatId, userId, [options])](#TelegramBot+unbanChatMember) ⇒ Promise * [.restrictChatMember(chatId, userId, [options])](#TelegramBot+restrictChatMember) ⇒ Promise * [.promoteChatMember(chatId, userId, [options])](#TelegramBot+promoteChatMember) ⇒ Promise * [.setChatAdministratorCustomTitle(chatId, userId, customTitle, [options])](#TelegramBot+setChatAdministratorCustomTitle) ⇒ Promise - * [.banChatSenderChat(chatId, senderChatId, [options])](#TelegramBot+banChatSenderChat) ⇒ Boolean - * [.unbanChatSenderChat(chatId, senderChatId, [options])](#TelegramBot+unbanChatSenderChat) ⇒ Boolean + * [.banChatSenderChat(chatId, senderChatId, [options])](#TelegramBot+banChatSenderChat) ⇒ Promise + * [.unbanChatSenderChat(chatId, senderChatId, [options])](#TelegramBot+unbanChatSenderChat) ⇒ Promise * [.setChatPermissions(chatId, chatPermissions, [options])](#TelegramBot+setChatPermissions) ⇒ Promise * [.exportChatInviteLink(chatId, [options])](#TelegramBot+exportChatInviteLink) ⇒ Promise * [.createChatInviteLink(chatId, [options])](#TelegramBot+createChatInviteLink) ⇒ Object - * [.editChatInviteLink(chatId, inviteLink, [options])](#TelegramBot+editChatInviteLink) ⇒ Object - * [.revokeChatInviteLink(chatId, [options])](#TelegramBot+revokeChatInviteLink) ⇒ Object - * [.approveChatJoinRequest(chatId, userId, [options])](#TelegramBot+approveChatJoinRequest) ⇒ Boolean - * [.declineChatJoinRequest(chatId, userId, [options])](#TelegramBot+declineChatJoinRequest) ⇒ Boolean + * [.editChatInviteLink(chatId, inviteLink, [options])](#TelegramBot+editChatInviteLink) ⇒ Promise + * [.revokeChatInviteLink(chatId, [options])](#TelegramBot+revokeChatInviteLink) ⇒ Promise + * [.approveChatJoinRequest(chatId, userId, [options])](#TelegramBot+approveChatJoinRequest) ⇒ Promise + * [.declineChatJoinRequest(chatId, userId, [options])](#TelegramBot+declineChatJoinRequest) ⇒ Promise * [.setChatPhoto(chatId, photo, [options], [fileOptions])](#TelegramBot+setChatPhoto) ⇒ Promise * [.deleteChatPhoto(chatId, [options])](#TelegramBot+deleteChatPhoto) ⇒ Promise * [.setChatTitle(chatId, title, [options])](#TelegramBot+setChatTitle) ⇒ Promise @@ -65,61 +80,44 @@ TelegramBot * [.pinChatMessage(chatId, messageId, [options])](#TelegramBot+pinChatMessage) ⇒ Promise * [.unpinChatMessage(chatId, [options])](#TelegramBot+unpinChatMessage) ⇒ Promise * [.unpinAllChatMessages(chatId, [options])](#TelegramBot+unpinAllChatMessages) ⇒ Promise + * [.leaveChat(chatId, [options])](#TelegramBot+leaveChat) ⇒ Promise + * [.getChat(chatId, [options])](#TelegramBot+getChat) ⇒ Promise + * [.getChatAdministrators(chatId, [options])](#TelegramBot+getChatAdministrators) ⇒ Promise + * [.getChatMemberCount(chatId, [options])](#TelegramBot+getChatMemberCount) ⇒ Promise + * [.getChatMember(chatId, userId, [options])](#TelegramBot+getChatMember) ⇒ Promise + * [.setChatStickerSet(chatId, stickerSetName, [options])](#TelegramBot+setChatStickerSet) ⇒ Promise + * [.deleteChatStickerSet(chatId, [options])](#TelegramBot+deleteChatStickerSet) ⇒ Promise * [.answerCallbackQuery(callbackQueryId, [options])](#TelegramBot+answerCallbackQuery) ⇒ Promise - * [.answerWebAppQuery(webAppQueryId, result, [options])](#TelegramBot+answerWebAppQuery) ⇒ Promise * [.setMyCommands(commands, [options])](#TelegramBot+setMyCommands) ⇒ Promise + * [.deleteMyCommands([options])](#TelegramBot+deleteMyCommands) ⇒ Promise * [.getMyCommands([options])](#TelegramBot+getMyCommands) ⇒ Promise * [.setChatMenuButton([options])](#TelegramBot+setChatMenuButton) ⇒ Promise * [.getChatMenuButton([options])](#TelegramBot+getChatMenuButton) ⇒ Promise * [.setMyDefaultAdministratorRights([options])](#TelegramBot+setMyDefaultAdministratorRights) ⇒ Promise * [.getMyDefaultAdministratorRights([options])](#TelegramBot+getMyDefaultAdministratorRights) ⇒ Promise - * [.deleteMyCommands([options])](#TelegramBot+deleteMyCommands) ⇒ Promise * [.editMessageText(text, [options])](#TelegramBot+editMessageText) ⇒ Promise * [.editMessageCaption(caption, [options])](#TelegramBot+editMessageCaption) ⇒ Promise * [.editMessageMedia(media, [options])](#TelegramBot+editMessageMedia) ⇒ Promise * [.editMessageReplyMarkup(replyMarkup, [options])](#TelegramBot+editMessageReplyMarkup) ⇒ Promise - * [.getUserProfilePhotos(userId, [options])](#TelegramBot+getUserProfilePhotos) ⇒ Promise - * [.sendLocation(chatId, latitude, longitude, [options])](#TelegramBot+sendLocation) ⇒ Promise - * [.editMessageLiveLocation(latitude, longitude, [options])](#TelegramBot+editMessageLiveLocation) ⇒ Promise - * [.stopMessageLiveLocation([options])](#TelegramBot+stopMessageLiveLocation) ⇒ Promise - * [.sendVenue(chatId, latitude, longitude, title, address, [options])](#TelegramBot+sendVenue) ⇒ Promise - * [.sendContact(chatId, phoneNumber, firstName, [options])](#TelegramBot+sendContact) ⇒ Promise - * [.sendPoll(chatId, question, pollOptions, [options])](#TelegramBot+sendPoll) ⇒ Promise * [.stopPoll(chatId, pollId, [options])](#TelegramBot+stopPoll) ⇒ Promise - * [.getFile(fileId, [options])](#TelegramBot+getFile) ⇒ Promise - * [.getFileLink(fileId, [options])](#TelegramBot+getFileLink) ⇒ Promise - * [.getFileStream(fileId, [options])](#TelegramBot+getFileStream) ⇒ stream.Readable - * [.downloadFile(fileId, downloadDir, [options])](#TelegramBot+downloadFile) ⇒ Promise - * [.onText(regexp, callback)](#TelegramBot+onText) - * [.removeTextListener(regexp)](#TelegramBot+removeTextListener) ⇒ Object - * [.clearTextListeners()](#TelegramBot+clearTextListeners) - * [.onReplyToMessage(chatId, messageId, callback)](#TelegramBot+onReplyToMessage) ⇒ Number - * [.removeReplyListener(replyListenerId)](#TelegramBot+removeReplyListener) ⇒ Object - * [.clearReplyListeners()](#TelegramBot+clearReplyListeners) - * [.getChat(chatId, [options])](#TelegramBot+getChat) ⇒ Promise - * [.getChatAdministrators(chatId, [options])](#TelegramBot+getChatAdministrators) ⇒ Promise - * ~~[.getChatMembersCount(chatId, [options])](#TelegramBot+getChatMembersCount) ⇒ Promise~~ - * [.getChatMemberCount(chatId, [options])](#TelegramBot+getChatMemberCount) ⇒ Promise - * [.getChatMember(chatId, userId, [options])](#TelegramBot+getChatMember) ⇒ Promise - * [.leaveChat(chatId, [options])](#TelegramBot+leaveChat) ⇒ Promise - * [.setChatStickerSet(chatId, stickerSetName, [options])](#TelegramBot+setChatStickerSet) ⇒ Promise - * [.deleteChatStickerSet(chatId, [options])](#TelegramBot+deleteChatStickerSet) ⇒ Promise - * [.sendGame(chatId, gameShortName, [options])](#TelegramBot+sendGame) ⇒ Promise - * [.setGameScore(userId, score, [options])](#TelegramBot+setGameScore) ⇒ Promise - * [.getGameHighScores(userId, [options])](#TelegramBot+getGameHighScores) ⇒ Promise * [.deleteMessage(chatId, messageId, [options])](#TelegramBot+deleteMessage) ⇒ Promise - * [.sendInvoice(chatId, title, description, payload, providerToken, startParameter, currency, prices, [options])](#TelegramBot+sendInvoice) ⇒ Promise - * [.createInvoiceLink(title, description, payload, providerToken, currency, prices, [options])](#TelegramBot+createInvoiceLink) ⇒ String - * [.answerShippingQuery(shippingQueryId, ok, [options])](#TelegramBot+answerShippingQuery) ⇒ Promise - * [.answerPreCheckoutQuery(preCheckoutQueryId, ok, [options])](#TelegramBot+answerPreCheckoutQuery) ⇒ Promise + * [.sendSticker(chatId, sticker, [options], [fileOptions])](#TelegramBot+sendSticker) ⇒ Promise * [.getStickerSet(name, [options])](#TelegramBot+getStickerSet) ⇒ Promise * [.uploadStickerFile(userId, pngSticker, [options], [fileOptions])](#TelegramBot+uploadStickerFile) ⇒ Promise * [.createNewStickerSet(userId, name, title, pngSticker, emojis, [options], [fileOptions])](#TelegramBot+createNewStickerSet) ⇒ Promise - * [.addStickerToSet(userId, name, pngSticker, emojis, [options], [fileOptions])](#TelegramBot+addStickerToSet) ⇒ Promise - * [.setStickerSetThumb(userId, name, pngThumb, [options], [fileOptions])](#TelegramBot+setStickerSetThumb) ⇒ Promise + * [.addStickerToSet(userId, name, sticker, emojis, stickerType, [options], [fileOptions])](#TelegramBot+addStickerToSet) ⇒ Promise * [.setStickerPositionInSet(sticker, position, [options])](#TelegramBot+setStickerPositionInSet) ⇒ Promise * [.deleteStickerFromSet(sticker, [options])](#TelegramBot+deleteStickerFromSet) ⇒ Promise - * [.sendMediaGroup(chatId, media, [options])](#TelegramBot+sendMediaGroup) ⇒ Promise + * [.setStickerSetThumb(userId, name, pngThumb, [options], [fileOptions])](#TelegramBot+setStickerSetThumb) ⇒ Promise + * [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ Promise + * [.answerWebAppQuery(webAppQueryId, result, [options])](#TelegramBot+answerWebAppQuery) ⇒ Promise + * [.sendInvoice(chatId, title, description, payload, providerToken, currency, prices, [options])](#TelegramBot+sendInvoice) ⇒ Promise + * [.createInvoiceLink(title, description, payload, providerToken, currency, prices, [options])](#TelegramBot+createInvoiceLink) ⇒ Promise + * [.answerShippingQuery(shippingQueryId, ok, [options])](#TelegramBot+answerShippingQuery) ⇒ Promise + * [.answerPreCheckoutQuery(preCheckoutQueryId, ok, [options])](#TelegramBot+answerPreCheckoutQuery) ⇒ Promise + * [.sendGame(chatId, gameShortName, [options])](#TelegramBot+sendGame) ⇒ Promise + * [.setGameScore(userId, score, [options])](#TelegramBot+setGameScore) ⇒ Promise + * [.getGameHighScores(userId, [options])](#TelegramBot+getGameHighScores) ⇒ Promise * _static_ * [.errors](#TelegramBot.errors) : Object * [.messageTypes](#TelegramBot.messageTypes) : [ 'Array' ].<String> @@ -216,6 +214,130 @@ Returning the promise of the last polling request is **deprecated**. | [options.cancel] | Boolean | Cancel current request | | [options.reason] | String | Reason for stopping polling | + + +### telegramBot.getFileLink(fileId, [options]) ⇒ Promise +Get link for file. +Use this method to get link for file for subsequent use. +Attention: link will be valid for 1 hour. + +This method is a sugar extension of the (getFile)[#getfilefileid] method, +which returns just path to file on remote server (you will have to manually build full uri after that). + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Promise which will have *fileURI* in resolve callback +**See**: https://core.telegram.org/bots/api#getfile + +| Param | Type | Description | +| --- | --- | --- | +| fileId | String | File identifier to get info about | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.getFileStream(fileId, [options]) ⇒ stream.Readable +Return a readable stream for file. + +`fileStream.path` is the specified file ID i.e. `fileId`. +`fileStream` emits event `info` passing a single argument i.e. +`info` with the interface `{ uri }` where `uri` is the URI of the +file on Telegram servers. + +This method is a sugar extension of the [getFileLink](#TelegramBot+getFileLink) method, +which returns the full URI to the file on remote server. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: stream.Readable - fileStream + +| Param | Type | Description | +| --- | --- | --- | +| fileId | String | File identifier to get info about | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.downloadFile(fileId, downloadDir, [options]) ⇒ Promise +Downloads file in the specified folder. + +This method is a sugar extension of the [getFileStream](#TelegramBot+getFileStream) method, +which returns a readable file stream. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Promise, which will have *filePath* of downloaded file in resolve callback + +| Param | Type | Description | +| --- | --- | --- | +| fileId | String | File identifier to get info about | +| downloadDir | String | Absolute path to the folder in which file will be saved | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.onText(regexpRexecuted, callback) +Register a RegExp to test against an incomming text message. + +**Kind**: instance method of [TelegramBot](#TelegramBot) + +| Param | Type | Description | +| --- | --- | --- | +| regexpRexecuted | RegExp | with `exec`. | +| callback | function | Callback will be called with 2 parameters, the `msg` and the result of executing `regexp.exec` on message text. | + + + +### telegramBot.removeTextListener(regexp) ⇒ Object +Remove a listener registered with `onText()`. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Object - deletedListener The removed reply listener if + found. This object has `regexp` and `callback` + properties. If not found, returns `null`. + +| Param | Type | Description | +| --- | --- | --- | +| regexp | RegExp | RegExp used previously in `onText()` | + + + +### telegramBot.clearTextListeners() +Remove all listeners registered with `onText()`. + +**Kind**: instance method of [TelegramBot](#TelegramBot) + + +### telegramBot.onReplyToMessage(chatId, messageId, callback) ⇒ Number +Register a reply to wait for a message response. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Number - id The ID of the inserted reply listener. + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | The chat id where the message cames from. | +| messageId | Number \| String | The message id to be replied. | +| callback | function | Callback will be called with the reply message. | + + + +### telegramBot.removeReplyListener(replyListenerId) ⇒ Object +Removes a reply that has been prev. registered for a message response. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Object - deletedListener The removed reply listener if + found. This object has `id`, `chatId`, `messageId` and `callback` + properties. If not found, returns `null`. + +| Param | Type | Description | +| --- | --- | --- | +| replyListenerId | Number | The ID of the reply listener. | + + + +### telegramBot.clearReplyListeners() ⇒ Array +Removes all replies that have been prev. registered for a message response. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Array - deletedListeners An array of removed listeners. ### telegramBot.isPolling() ⇒ Boolean @@ -237,7 +359,7 @@ Close webhook after closing all current connections. Multiple invocations do nothing if webhook is already closed. **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Promise - promise +**Returns**: Promise - Promise ### telegramBot.hasOpenWebHook() ⇒ Boolean @@ -245,42 +367,29 @@ Return true if using webhook and it is open i.e. accepts connections. Otherwise, false. **Kind**: instance method of [TelegramBot](#TelegramBot) - + -### telegramBot.getMe([options]) ⇒ Promise -Returns basic information about the bot in form of a `User` object. +### telegramBot.processUpdate(update) +Process an update; emitting the proper events and executing regexp +callbacks. This method is useful should you be using a different +way to fetch updates, other than those provided by TelegramBot. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getme +**See**: https://core.telegram.org/bots/api#update -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | +| Param | Type | +| --- | --- | +| update | Object | - + -### telegramBot.logOut([options]) ⇒ Promise -This method log out your bot from the cloud Bot API server before launching the bot locally. -You must log out the bot before running it locally, otherwise there is no guarantee that the bot will receive updates. -After a successful call, you will not be able to log in again using the same token for 10 minutes. -Returns True on success. +### telegramBot.getUpdates([options]) ⇒ Promise +Use this method to receive incoming updates using long polling. +This method has an [older, compatible signature][getUpdates-v0.25.0] +that is being deprecated. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#logout - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.close([options]) ⇒ Promise -This method close the bot instance before moving it from one local server to another. -This method will return error 429 in the first 10 minutes after the bot is launched. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#close +**See**: https://core.telegram.org/bots/api#getupdates | Param | Type | Description | | --- | --- | --- | @@ -335,33 +444,47 @@ url field empty. | --- | --- | --- | | [options] | Object | Additional Telegram query options | - + -### telegramBot.getUpdates([options]) ⇒ Promise -Use this method to receive incoming updates using long polling. -This method has an [older, compatible signature][getUpdates-v0.25.0] -that is being deprecated. +### telegramBot.getMe([options]) ⇒ Promise +A simple method for testing your bot's authentication token. Requires no parameters. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getupdates +**Returns**: Promise - basic information about the bot in form of a [User](https://core.telegram.org/bots/api#user) object. +**See**: https://core.telegram.org/bots/api#getme | Param | Type | Description | | --- | --- | --- | | [options] | Object | Additional Telegram query options | - + -### telegramBot.processUpdate(update) -Process an update; emitting the proper events and executing regexp -callbacks. This method is useful should you be using a different -way to fetch updates, other than those provided by TelegramBot. +### telegramBot.logOut([options]) ⇒ Promise +This method log out your bot from the cloud Bot API server before launching the bot locally. +You must log out the bot before running it locally, otherwise there is no guarantee that the bot will receive updates. +After a successful call, you will not be able to log in again using the same token for 10 minutes. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#update +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#logout -| Param | Type | -| --- | --- | -| update | Object | +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.close([options]) ⇒ Promise +This method close the bot instance before moving it from one local server to another. +This method will return error 429 in the first 10 minutes after the bot is launched. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#close + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | @@ -369,28 +492,15 @@ way to fetch updates, other than those provided by TelegramBot. Send text message. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See**: https://core.telegram.org/bots/api#sendmessage | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | text | String | Text of the message to be sent | | [options] | Object | Additional Telegram query options | - - -### telegramBot.answerInlineQuery(inlineQueryId, results, [options]) ⇒ Promise -Send answers to an inline query. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#answerinlinequery - -| Param | Type | Description | -| --- | --- | --- | -| inlineQueryId | String | Unique identifier of the query | -| results | [ 'Array' ].<InlineQueryResult> | An array of results for the inline query | -| [options] | Object | Additional Telegram query options | - ### telegramBot.forwardMessage(chatId, fromChatId, messageId, [options]) ⇒ Promise @@ -401,25 +511,26 @@ Forward messages of any kind. | Param | Type | Description | | --- | --- | --- | -| 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 | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) or username of the target channel (in the format `@channelusername`) | +| fromChatId | Number \| String | Unique identifier for the chat where the original message was sent (or channel username in the format `@channelusername`) | +| messageId | Number \| String | Unique message identifier in the chat specified in fromChatId | | [options] | Object | Additional Telegram query options | ### telegramBot.copyMessage(chatId, fromChatId, messageId, [options]) ⇒ Promise -Copy messages of any kind. +Copy messages of any kind. **Service messages and invoice messages can't be copied.** The method is analogous to the method forwardMessages, but the copied message doesn't have a link to the original message. Returns the MessageId of the sent message on success. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - The [MessageId](https://core.telegram.org/bots/api#messageid) of the sent message on success **See**: https://core.telegram.org/bots/api#copymessage | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | 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 | @@ -430,6 +541,7 @@ Returns the MessageId of the sent message on success. Send photo **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See** - https://core.telegram.org/bots/api#sendphoto @@ -438,7 +550,7 @@ Send photo | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | photo | String \| stream.Stream \| Buffer | A file path or a Stream. Can also be a `file_id` previously uploaded | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | @@ -448,7 +560,10 @@ Send photo ### telegramBot.sendAudio(chatId, audio, [options], [fileOptions]) ⇒ Promise Send audio +**Your audio must be in the .MP3 or .M4A format.** + **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See** - https://core.telegram.org/bots/api#sendaudio @@ -457,31 +572,18 @@ Send audio | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | audio | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | - - -### telegramBot.sendDice(chatId, [options]) ⇒ Promise -Send Dice -Use this method to send a dice. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#senddice - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| [options] | Object | Additional Telegram query options | - ### telegramBot.sendDocument(chatId, doc, [options], [fileOptions]) ⇒ Promise Send Document **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See** - https://core.telegram.org/bots/api#sendDocument @@ -490,32 +592,18 @@ Send Document | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | doc | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | - - -### telegramBot.sendSticker(chatId, sticker, [options], [fileOptions]) ⇒ Promise -Send .webp stickers. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#sendsticker - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| sticker | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. Stickers are WebP format files. | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - ### telegramBot.sendVideo(chatId, video, [options], [fileOptions]) ⇒ Promise -Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). +Use this method to send video files, **Telegram clients support mp4 videos** (other formats may be sent as Document). **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See** - https://core.telegram.org/bots/api#sendvideo @@ -524,7 +612,7 @@ Use this method to send video files, Telegram clients support mp4 videos (other | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | video | String \| stream.Stream \| Buffer | A file path or Stream. Can also be a `file_id` previously uploaded. | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | @@ -535,6 +623,7 @@ Use this method to send video files, Telegram clients support mp4 videos (other Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See** - https://core.telegram.org/bots/api#sendanimation @@ -543,17 +632,41 @@ Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without s | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | animation | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | + + +### telegramBot.sendVoice(chatId, voice, [options], [fileOptions]) ⇒ Promise +Send voice + +**Your audio must be in an .OGG file encoded with OPUS** (other formats may be sent as Audio or Document) + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned +**See** + +- https://core.telegram.org/bots/api#sendvoice +- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| voice | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + ### telegramBot.sendVideoNote(chatId, videoNote, [options], [fileOptions]) ⇒ Promise -Use this method to send rounded square videos of upto 1 minute long. +Use this method to send video messages +Telegram clients support **rounded square MPEG4 videos** of up to 1 minute long. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **Info**: The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed. **See** @@ -563,629 +676,34 @@ Use this method to send rounded square videos of upto 1 minute long. | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | videoNote | String \| stream.Stream \| Buffer | A file path or Stream. Can also be a `file_id` previously uploaded. | | [options] | Object | Additional Telegram query options | | [fileOptions] | Object | Optional file related meta-data | - + -### telegramBot.sendVoice(chatId, voice, [options], [fileOptions]) ⇒ Promise -Send voice +### telegramBot.sendMediaGroup(chatId, media, [options]) ⇒ Promise +Use this method to send a group of photos or videos as an album. + +**Documents and audio files can be only grouped in an album with messages of the same type** + +If you wish to [specify file options](https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files), +add a `fileOptions` property to the target input in `media`. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, an array of the sent [Messages](https://core.telegram.org/bots/api#message) +is returned. **See** -- https://core.telegram.org/bots/api#sendvoice +- https://core.telegram.org/bots/api#sendmediagroup - https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| voice | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.sendChatAction(chatId, action, [options]) ⇒ Promise -Send chat action. -`typing` for text messages, -`upload_photo` for photos, `record_video` or `upload_video` for videos, -`record_voice` or `upload_voice` for audio files, `upload_document` for general files, -`choose_sticker` for stickers, `find_location` for location data, -`record_video_note` or `upload_video_note` for video notes. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#sendchataction - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| action | String | Type of action to broadcast. | -| [options] | Object | Additional Telegram query options | - - - -### ~~telegramBot.kickChatMember(chatId, userId, [options]) ⇒ Promise~~ -***Deprecated*** - -Use this method to kick a user from a group or a supergroup. -In the case of supergroups, the user will not be able to return -to the group on their own using invite links, etc., unless unbanned -first. The bot must be an administrator in the group for this to work. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#kickchatmember - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.banChatMember(chatId, userId, [options]) ⇒ Promise -Use this method to ban a user in a group, a supergroup or a channel. -In the case of supergroups and channels, the user will not be able to -return to the chat on their own using invite links, etc., unless unbanned first.. -The bot must be an administrator in the group for this to work. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#banchatmember - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.unbanChatMember(chatId, userId, [options]) ⇒ Promise -Use this method to unban a previously kicked user in a supergroup. -The user will not return to the group automatically, but will be -able to join via link, etc. The bot must be an administrator in -the group for this to work. Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#unbanchatmember - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.restrictChatMember(chatId, userId, [options]) ⇒ Promise -Use this method to restrict a user in a supergroup. -The bot must be an administrator in the supergroup for this to work -and must have the appropriate admin rights. Pass True for all boolean parameters -to lift restrictions from a user. Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#restrictchatmember - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.promoteChatMember(chatId, userId, [options]) ⇒ Promise -Use this method to promote or demote a user in a supergroup or a channel. -The bot must be an administrator in the chat for this to work -and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#promotechatmember - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| userId | Number | | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatAdministratorCustomTitle(chatId, userId, customTitle, [options]) ⇒ Promise -Use this method to set a custom title for an administrator in a supergroup promoted by the bot. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchatadministratorcustomtitle - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| userId | Number | Unique identifier of the target user | -| customTitle | String | New custom title for the administrator; 0-16 characters, emoji are not allowed | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.banChatSenderChat(chatId, senderChatId, [options]) ⇒ Boolean -Use this method to ban a channel chat in a supergroup or a channel. -The owner of the chat will not be able to send messages and join live streams -on behalf of the chat, unless it is unbanned first. -The bot must be an administrator in the supergroup or channel for this to work -and must have the appropriate administrator rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#banchatsenderchat - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| senderChatId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.unbanChatSenderChat(chatId, senderChatId, [options]) ⇒ Boolean -Use this method to unban a previously banned channel chat in a supergroup or channel. -The bot must be an administrator for this to work and must have the appropriate administrator rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#unbanchatsenderchat - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| senderChatId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatPermissions(chatId, chatPermissions, [options]) ⇒ Promise -Use this method to set default chat permissions for all members. -The bot must be an administrator in the group or a supergroup for this to -work and must have the can_restrict_members admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchatpermissions - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| chatPermissions | Array | New default chat permissions | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.exportChatInviteLink(chatId, [options]) ⇒ Promise -Use this method to export an invite link to a supergroup or a channel. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns exported invite link as String on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#exportchatinvitelink - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.createChatInviteLink(chatId, [options]) ⇒ Object -Use this method to create an additional invite link for a chat. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns the new invite link as ChatInviteLink object. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Object - ChatInviteLink -**See**: https://core.telegram.org/bots/api#createchatinvitelink - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.editChatInviteLink(chatId, inviteLink, [options]) ⇒ Object -Use this method to edit a non-primary invite link created by the bot. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns the edited invite link as a ChatInviteLink object. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Object - ChatInviteLink -**See**: https://core.telegram.org/bots/api#editchatinvitelink - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| inviteLink | String | Text with the invite link to edit | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.revokeChatInviteLink(chatId, [options]) ⇒ Object -Use this method to revoke an invite link created by the bot. -Note: If the primary link is revoked, a new link is automatically generated -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns the revoked invite link as ChatInviteLink object. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Object - ChatInviteLink -**See**: https://core.telegram.org/bots/api#revokechatinvitelink - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.approveChatJoinRequest(chatId, userId, [options]) ⇒ Boolean -Use this method to approve a chat join request. -The bot must be an administrator in the chat for this to work and must have the can_invite_users administrator right. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Boolean - True on success -**See**: https://core.telegram.org/bots/api#approvechatjoinrequest - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.declineChatJoinRequest(chatId, userId, [options]) ⇒ Boolean -Use this method to decline a chat join request. -The bot must be an administrator in the chat for this to work and must have the can_invite_users administrator right. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Boolean - True on success -**See**: https://core.telegram.org/bots/api#declinechatjoinrequest - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup | -| userId | Number | Unique identifier of the target user | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatPhoto(chatId, photo, [options], [fileOptions]) ⇒ Promise -Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchatphoto - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| photo | stream.Stream \| Buffer | A file path or a Stream. | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.deleteChatPhoto(chatId, [options]) ⇒ Promise -Use this method to delete a chat photo. Photos can't be changed for private chats. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#deletechatphoto - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatTitle(chatId, title, [options]) ⇒ Promise -Use this method to change the title of a chat. Titles can't be changed for private chats. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchattitle - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| title | String | New chat title, 1-255 characters | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatDescription(chatId, description, [options]) ⇒ Promise -Use this method to change the description of a supergroup or a channel. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchatdescription - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| description | String | New chat title, 1-255 characters | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.pinChatMessage(chatId, messageId, [options]) ⇒ Promise -Use this method to pin a message in a supergroup. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#pinchatmessage - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| messageId | Number | Identifier of a message to pin | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.unpinChatMessage(chatId, [options]) ⇒ Promise -Use this method to unpin a message in a supergroup chat. -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#unpinchatmessage - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.unpinAllChatMessages(chatId, [options]) ⇒ Promise -Use this method to clear the list of pinned messages in a chat -The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#unpinallchatmessages - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.answerCallbackQuery(callbackQueryId, [options]) ⇒ Promise -Use this method to send answers to callback queries sent from -inline keyboards. The answer will be displayed to the user as -a notification at the top of the chat screen or as an alert. -On success, True is returned. - -This method has **older, compatible signatures ([1][answerCallbackQuery-v0.27.1])([2][answerCallbackQuery-v0.29.0])** -that are being deprecated. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#answercallbackquery - -| Param | Type | Description | -| --- | --- | --- | -| callbackQueryId | String | Unique identifier for the query to be answered | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.answerWebAppQuery(webAppQueryId, result, [options]) ⇒ Promise -Use this method to set the result of an interaction with a Web App and send a corresponding message on behalf of the user to the chat from which the query originated. -On success, a SentWebAppMessage object is returned. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#answercallbackquery - -| Param | Type | Description | -| --- | --- | --- | -| webAppQueryId | String | Unique identifier for the query to be answered | -| result | InlineQueryResult | object that represents one result of an inline query | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setMyCommands(commands, [options]) ⇒ Promise -Use this method to change the list of the bot's commands. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setmycommands - -| Param | Type | Description | -| --- | --- | --- | -| commands | Array | Poll options, between 2-10 options | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.getMyCommands([options]) ⇒ Promise -Use this method to get the current list of the bot's commands for the given scope and user language. -Returns Array of BotCommand on success. If commands aren't set, an empty list is returned. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getmycommands - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setChatMenuButton([options]) ⇒ Promise -Use this method to change the bot's menu button in a private chat, or the default menu button. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setchatmenubutton - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.getChatMenuButton([options]) ⇒ Promise -Use this method to get the current value of the bot's menu button in a private chat, or the default menu button. -Returns MenuButton on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getchatmenubutton - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.setMyDefaultAdministratorRights([options]) ⇒ Promise -Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels. -These rights will be suggested to users, but they are are free to modify the list before adding the bot. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getchatmenubutton - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.getMyDefaultAdministratorRights([options]) ⇒ Promise -Use this method to get the current default administrator rights of the bot. -Returns ChatAdministratorRights on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getmydefaultadministratorrights - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.deleteMyCommands([options]) ⇒ Promise -Returns True on success. -Use this method to delete the list of the bot's commands for the given scope and user language. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#deletemycommands - -| Param | Type | Description | -| --- | --- | --- | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.editMessageText(text, [options]) ⇒ Promise -Use this method to edit text messages sent by the bot or via -the bot (for inline bots). On success, the edited Message is -returned. - -Note that you must provide one of chat_id, message_id, or -inline_message_id in your request. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#editmessagetext - -| Param | Type | Description | -| --- | --- | --- | -| text | String | New text of the message | -| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | - - - -### telegramBot.editMessageCaption(caption, [options]) ⇒ Promise -Use this method to edit captions of messages sent by the -bot or via the bot (for inline bots). On success, the -edited Message is returned. - -Note that you must provide one of chat_id, message_id, or -inline_message_id in your request. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#editmessagecaption - -| Param | Type | Description | -| --- | --- | --- | -| caption | String | New caption of the message | -| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | - - - -### telegramBot.editMessageMedia(media, [options]) ⇒ Promise -Use this method to edit audio, document, photo, or video messages. -If a message is a part of a message album, then it can be edited only to a photo or a video. -Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. -Use previously uploaded file via its file_id or specify a URL. -On success, the edited Message is returned. - -Note that you must provide one of chat_id, message_id, or inline_message_id in your request. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#editmessagemedia - -| Param | Type | Description | -| --- | --- | --- | -| media | Object | A JSON-serialized object for a new media content of the message | -| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | - - - -### telegramBot.editMessageReplyMarkup(replyMarkup, [options]) ⇒ Promise -Use this method to edit only the reply markup of messages -sent by the bot or via the bot (for inline bots). -On success, the edited Message is returned. - -Note that you must provide one of chat_id, message_id, or -inline_message_id in your request. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#editmessagetext - -| Param | Type | Description | -| --- | --- | --- | -| replyMarkup | Object | A JSON-serialized object for an inline keyboard. | -| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | - - - -### 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. -This method has an [older, compatible signature][getUserProfilePhotos-v0.25.0] -that is being deprecated. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getuserprofilephotos - -| Param | Type | Description | -| --- | --- | --- | -| userId | Number | Unique identifier of the target user | +| chatId | String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| media | Array | A JSON-serialized array describing photos and videos to be sent, must include 2–10 items | | [options] | Object | Additional Telegram query options | @@ -1195,11 +713,12 @@ Send location. Use this method to send point on the map. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See**: https://core.telegram.org/bots/api#sendlocation | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | latitude | Float | Latitude of location | | longitude | Float | Longitude of location | | [options] | Object | Additional Telegram query options | @@ -1210,10 +729,13 @@ Use this method to send point on the map. Use this method to edit live location messages sent by the bot or via the bot (for inline bots). + A location **can be edited until its live_period expires or editing is explicitly disabled by a call to [stopMessageLiveLocation](https://core.telegram.org/bots/api#stopmessagelivelocation)** + Note that you must provide one of chat_id, message_id, or inline_message_id in your request. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned. **See**: https://core.telegram.org/bots/api#editmessagelivelocation | Param | Type | Description | @@ -1232,6 +754,7 @@ Note that you must provide one of chat_id, message_id, or inline_message_id in your request. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned. **See**: https://core.telegram.org/bots/api#stopmessagelivelocation | Param | Type | Description | @@ -1245,11 +768,12 @@ Send venue. Use this method to send information about a venue. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned. **See**: https://core.telegram.org/bots/api#sendvenue | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | latitude | Float | Latitude of location | | longitude | Float | Longitude of location | | title | String | Name of the venue | @@ -1263,11 +787,12 @@ Send contact. Use this method to send phone contacts. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See**: https://core.telegram.org/bots/api#sendcontact | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | | phoneNumber | String | Contact's phone number | | firstName | String | Contact's first name | | [options] | Object | Additional Telegram query options | @@ -1279,28 +804,70 @@ Send poll. Use this method to send a native poll. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned **See**: https://core.telegram.org/bots/api#sendpoll | Param | Type | Description | | --- | --- | --- | | chatId | Number \| String | Unique identifier for the group/channel | -| question | String | Poll question, 255 char limit | -| pollOptions | Array | Poll options, between 2-10 options | +| question | String | Poll question, 1-300 characters | +| pollOptions | Array | Poll options, between 2-10 options (only 1-100 characters each) | | [options] | Object | Additional Telegram query options | - + -### telegramBot.stopPoll(chatId, pollId, [options]) ⇒ Promise -Stop poll. -Use this method to stop a native poll. +### telegramBot.sendDice(chatId, [options]) ⇒ Promise +Send Dice +Use this method to send an animated emoji that will display a random value. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#stoppoll +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned +**See**: https://core.telegram.org/bots/api#senddice | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the group/channel | -| pollId | Number | Identifier of the original message with the poll | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.sendChatAction(chatId, action, [options]) ⇒ Promise +Send chat action. + +Use this method when you need to tell the user that something is happening on the bot's side. +**The status is set for 5 seconds or less** (when a message arrives from your bot, Telegram clients clear its typing status). + + Action `typing` for [text messages](https://core.telegram.org/bots/api#sendmessage), +`upload_photo` for [photos](https://core.telegram.org/bots/api#sendphoto), `record_video` or `upload_video` for [videos](https://core.telegram.org/bots/api#sendvideo), +`record_voice` or `upload_voice` for [voice notes](https://core.telegram.org/bots/api#sendvoice), `upload_document` for [general files](https://core.telegram.org/bots/api#senddocument), +`choose_sticker` for [stickers](https://core.telegram.org/bots/api#sendsticker), `find_location` for [location data](https://core.telegram.org/bots/api#sendlocation), +`record_video_note` or `upload_video_note` for [video notes](https://core.telegram.org/bots/api#sendvideonote). + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#sendchataction + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| action | String | Type of action to broadcast. | +| [options] | Object | Additional Telegram query options | + + + +### 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. +This method has an [older, compatible signature][getUserProfilePhotos-v0.25.0] +that is being deprecated. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object +**See**: https://core.telegram.org/bots/api#getuserprofilephotos + +| Param | Type | Description | +| --- | --- | --- | +| userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | @@ -1308,9 +875,11 @@ Use this method to stop a native poll. ### telegramBot.getFile(fileId, [options]) ⇒ Promise Get file. Use this method to get basic info about a file and prepare it for downloading. -Attention: link will be valid for 1 hour. + +Attention: **link will be valid for 1 hour.** **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, a [File](https://core.telegram.org/bots/api#file) object is returned **See**: https://core.telegram.org/bots/api#getfile | Param | Type | Description | @@ -1318,129 +887,387 @@ Attention: link will be valid for 1 hour. | fileId | String | File identifier to get info about | | [options] | Object | Additional Telegram query options | - + -### telegramBot.getFileLink(fileId, [options]) ⇒ Promise -Get link for file. -Use this method to get link for file for subsequent use. -Attention: link will be valid for 1 hour. +### telegramBot.banChatMember(chatId, userId, [options]) ⇒ Promise +Use this method to ban a user in a group, a supergroup or a channel. +In the case of supergroups and channels, the user will not be able to +return to the chat on their own using invite links, etc., unless unbanned first.. -This method is a sugar extension of the (getFile)[#getfilefileid] method, -which returns just path to file on remote server (you will have to manually build full uri after that). +The **bot must be an administrator in the group, supergroup or a channel** for this to work. **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Promise - promise Promise which will have *fileURI* in resolve callback -**See**: https://core.telegram.org/bots/api#getfile +**Returns**: Promise - True on success. +**See**: https://core.telegram.org/bots/api#banchatmember | Param | Type | Description | | --- | --- | --- | -| fileId | String | File identifier to get info about | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | - + -### telegramBot.getFileStream(fileId, [options]) ⇒ stream.Readable -Return a readable stream for file. +### telegramBot.unbanChatMember(chatId, userId, [options]) ⇒ Promise +Use this method to unban a previously kicked user in a supergroup. +The user will not return to the group automatically, but will be +able to join via link, etc. -`fileStream.path` is the specified file ID i.e. `fileId`. -`fileStream` emits event `info` passing a single argument i.e. -`info` with the interface `{ uri }` where `uri` is the URI of the -file on Telegram servers. +The **bot must be an administrator** in the supergroup or channel for this to work. -This method is a sugar extension of the [getFileLink](#TelegramBot+getFileLink) method, -which returns the full URI to the file on remote server. +**By default**, this method guarantees that after the call the user is not a member of the chat, but will be able to join it. +So **if the user is a member of the chat they will also be removed from the chat**. If you don't want this, use the parameter *only_if_banned* **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: stream.Readable - fileStream +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#unbanchatmember | Param | Type | Description | | --- | --- | --- | -| fileId | String | File identifier to get info about | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | - + -### telegramBot.downloadFile(fileId, downloadDir, [options]) ⇒ Promise -Downloads file in the specified folder. - -This method is a sugar extension of the [getFileStream](#TelegramBot+getFileStream) method, -which returns a readable file stream. +### telegramBot.restrictChatMember(chatId, userId, [options]) ⇒ Promise +Use this method to restrict a user in a supergroup. +The bot **must be an administrator in the supergroup** for this to work +and must have the appropriate admin rights. Pass True for all boolean parameters +to lift restrictions from a user. Returns True on success. **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Promise - promise Promise, which will have *filePath* of downloaded file in resolve callback +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#restrictchatmember | Param | Type | Description | | --- | --- | --- | -| fileId | String | File identifier to get info about | -| downloadDir | String | Absolute path to the folder in which file will be saved | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | - + -### telegramBot.onText(regexp, callback) -Register a RegExp to test against an incomming text message. +### telegramBot.promoteChatMember(chatId, userId, [options]) ⇒ Promise +Use this method to promote or demote a user in a supergroup or a channel. +The bot **must be an administrator** in the chat for this to work +and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success. +**See**: https://core.telegram.org/bots/api#promotechatmember | Param | Type | Description | | --- | --- | --- | -| regexp | RegExp | RegExp to be executed with `exec`. | -| callback | function | Callback will be called with 2 parameters, the `msg` and the result of executing `regexp.exec` on message text. | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | | +| [options] | Object | Additional Telegram query options | - + -### telegramBot.removeTextListener(regexp) ⇒ Object -Remove a listener registered with `onText()`. +### telegramBot.setChatAdministratorCustomTitle(chatId, userId, customTitle, [options]) ⇒ Promise +Use this method to set a custom title for an administrator in a supergroup promoted by the bot. **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Object - deletedListener The removed reply listener if - found. This object has `regexp` and `callback` - properties. If not found, returns `null`. +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchatadministratorcustomtitle | Param | Type | Description | | --- | --- | --- | -| regexp | RegExp | RegExp used previously in `onText()` | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | +| customTitle | String | New custom title for the administrator; 0-16 characters, emoji are not allowed | +| [options] | Object | Additional Telegram query options | - + -### telegramBot.clearTextListeners() -Remove all listeners registered with `onText()`. +### telegramBot.banChatSenderChat(chatId, senderChatId, [options]) ⇒ Promise +Use this method to ban a channel chat in a supergroup or a channel. + +Until the chat is [unbanned](https://core.telegram.org/bots/api#unbanchatsenderchat), the owner of the banned chat won't be able to send messages on behalf of any of their channels. +The bot **must be an administrator in the supergroup or channel** for this to work and must have the appropriate administrator rights **Kind**: instance method of [TelegramBot](#TelegramBot) - - -### telegramBot.onReplyToMessage(chatId, messageId, callback) ⇒ Number -Register a reply to wait for a message response. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Number - id The ID of the inserted reply listener. +**Returns**: Promise - True on success. +**See**: https://core.telegram.org/bots/api#banchatsenderchat | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | The chat id where the message cames from. | -| messageId | Number \| String | The message id to be replied. | -| callback | function | Callback will be called with the reply message. | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| senderChatId | Number | Unique identifier of the target user | +| [options] | Object | Additional Telegram query options | - + -### telegramBot.removeReplyListener(replyListenerId) ⇒ Object -Removes a reply that has been prev. registered for a message response. +### telegramBot.unbanChatSenderChat(chatId, senderChatId, [options]) ⇒ Promise +Use this method to unban a previously banned channel chat in a supergroup or channel. + +The bot **must be an administrator** for this to work and must have the appropriate administrator rights. **Kind**: instance method of [TelegramBot](#TelegramBot) -**Returns**: Object - deletedListener The removed reply listener if - found. This object has `id`, `chatId`, `messageId` and `callback` - properties. If not found, returns `null`. +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#unbanchatsenderchat | Param | Type | Description | | --- | --- | --- | -| replyListenerId | Number | The ID of the reply listener. | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| senderChatId | Number | Unique identifier of the target user | +| [options] | Object | Additional Telegram query options | - + -### telegramBot.clearReplyListeners() -Removes all replies that have been prev. registered for a message response. +### telegramBot.setChatPermissions(chatId, chatPermissions, [options]) ⇒ Promise +Use this method to set default chat permissions for all members. + +The bot **must be an administrator in the group or a supergroup** for this to +work and **must have the `can_restrict_members` admin rights.** **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchatpermissions + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| chatPermissions | Array | New default chat permissions | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.exportChatInviteLink(chatId, [options]) ⇒ Promise +Use this method to generate a new primary invite link for a chat. **Any previously generated primary link is revoked**. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Exported invite link as String on success. +**See**: https://core.telegram.org/bots/api#exportchatinvitelink + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.createChatInviteLink(chatId, [options]) ⇒ Object +Use this method to create an additional invite link for a chat. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +The link generated with this method can be revoked using the method [revokeChatInviteLink](https://core.telegram.org/bots/api#revokechatinvitelink) + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Object - The new invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object +**See**: https://core.telegram.org/bots/api#createchatinvitelink + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.editChatInviteLink(chatId, inviteLink, [options]) ⇒ Promise +Use this method to edit a non-primary invite link created by the bot. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - The edited invite link as a [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object +**See**: https://core.telegram.org/bots/api#editchatinvitelink + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| inviteLink | String | Text with the invite link to edit | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.revokeChatInviteLink(chatId, [options]) ⇒ Promise +Use this method to revoke an invite link created by the bot. +Note: If the primary link is revoked, a new link is automatically generated + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - The revoked invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object +**See**: https://core.telegram.org/bots/api#revokechatinvitelink + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.approveChatJoinRequest(chatId, userId, [options]) ⇒ Promise +Use this method to approve a chat join request. + +The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right.** + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#approvechatjoinrequest + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.declineChatJoinRequest(chatId, userId, [options]) ⇒ Promise +Use this method to decline a chat join request. + +The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right**. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#declinechatjoinrequest + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| userId | Number | Unique identifier of the target user | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setChatPhoto(chatId, photo, [options], [fileOptions]) ⇒ Promise +Use this method to set a new profile photo for the chat. **Photos can't be changed for private chats**. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchatphoto + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| photo | stream.Stream \| Buffer | A file path or a Stream. | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + + + +### telegramBot.deleteChatPhoto(chatId, [options]) ⇒ Promise +Use this method to delete a chat photo. **Photos can't be changed for private chats**. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#deletechatphoto + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setChatTitle(chatId, title, [options]) ⇒ Promise +Use this method to change the title of a chat. **Titles can't be changed for private chats**. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchattitle + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| title | String | New chat title, 1-255 characters | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setChatDescription(chatId, description, [options]) ⇒ Promise +Use this method to change the description of a group, a supergroup or a channel. + +The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchatdescription + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| description | String | New chat title, 0-255 characters | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.pinChatMessage(chatId, messageId, [options]) ⇒ Promise +Use this method to pin a message in a supergroup. + +If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator +right in a supergroup or `can_edit_messages` administrator right in a channel. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#pinchatmessage + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| messageId | Number | Identifier of a message to pin | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.unpinChatMessage(chatId, [options]) ⇒ Promise +Use this method to remove a message from the list of pinned messages in a chat + +If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator +right in a supergroup or `can_edit_messages` administrator right in a channel. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#unpinchatmessage + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.unpinAllChatMessages(chatId, [options]) ⇒ Promise +Use this method to clear the list of pinned messages in a chat. + +If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator +right in a supergroup or `can_edit_messages` administrator right in a channel. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#unpinallchatmessages + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.leaveChat(chatId, [options]) ⇒ Promise +Use this method for your bot to leave a group, supergroup or channel + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#leavechat + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| [options] | Object | Additional Telegram query options | + ### telegramBot.getChat(chatId, [options]) ⇒ Promise @@ -1449,19 +1276,22 @@ Use this method to get up to date information about the chat username of a user, group or channel, etc.). **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - [Chat](https://core.telegram.org/bots/api#chat) object on success **See**: https://core.telegram.org/bots/api#getchat | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target chat or username of the target supergroup or channel | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) or channel | | [options] | Object | Additional Telegram query options | ### telegramBot.getChatAdministrators(chatId, [options]) ⇒ Promise -Returns the administrators in a chat in form of an Array of `ChatMember` objects. +Use this method to get a list of administrators in a chat **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, returns an Array of [ChatMember](https://core.telegram.org/bots/api#chatmember) objects that contains information about all chat administrators except other bots. +If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned **See**: https://core.telegram.org/bots/api#getchatadministrators | Param | Type | Description | @@ -1469,29 +1299,13 @@ Returns the administrators in a chat in form of an Array of `ChatMember` objects | chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | | [options] | Object | Additional Telegram query options | - - -### ~~telegramBot.getChatMembersCount(chatId, [options]) ⇒ Promise~~ -***Deprecated*** - -Use this method to get the number of members in a chat. -Returns Int on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getchatmemberscount - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup | -| [options] | Object | Additional Telegram query options | - ### telegramBot.getChatMemberCount(chatId, [options]) ⇒ Promise Use this method to get the number of members in a chat. -Returns Int on success **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Int on success **See**: https://core.telegram.org/bots/api#getchatmembercount | Param | Type | Description | @@ -1505,6 +1319,7 @@ Returns Int on success Use this method to get information about a member of a chat. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - [ChatMember](https://core.telegram.org/bots/api#chatmember) object on success **See**: https://core.telegram.org/bots/api#getchatmember | Param | Type | Description | @@ -1513,25 +1328,17 @@ Use this method to get information about a member of a chat. | userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | - - -### telegramBot.leaveChat(chatId, [options]) ⇒ Promise -Leave a group, supergroup or channel. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#leavechat - -| Param | Type | Description | -| --- | --- | --- | -| chatId | Number \| String | Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) | -| [options] | Object | Additional Telegram query options | - ### telegramBot.setChatStickerSet(chatId, stickerSetName, [options]) ⇒ Promise Use this method to set a new group sticker set for a supergroup. +The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights. + +**Note:** Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method. + **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success **See**: https://core.telegram.org/bots/api#setchatstickerset | Param | Type | Description | @@ -1545,7 +1352,10 @@ Use this method to set a new group sticker set for a supergroup. ### telegramBot.deleteChatStickerSet(chatId, [options]) ⇒ Promise Use this method to delete a group sticker set from a supergroup. +Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method. + **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success **See**: https://core.telegram.org/bots/api#deletechatstickerset | Param | Type | Description | @@ -1553,53 +1363,222 @@ Use this method to delete a group sticker set from a supergroup. | chatId | Number \| String | Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) | | [options] | Object | Additional Telegram query options | - + -### telegramBot.sendGame(chatId, gameShortName, [options]) ⇒ Promise -Use this method to send a game. +### telegramBot.answerCallbackQuery(callbackQueryId, [options]) ⇒ Promise +Use this method to send answers to callback queries sent from +[inline keyboards](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating). + +The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. + +This method has **older, compatible signatures ([1][answerCallbackQuery-v0.27.1])([2][answerCallbackQuery-v0.29.0])** +that are being deprecated. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#sendgame +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#answercallbackquery | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| gameShortName | String | name of the game to be sent. | +| callbackQueryId | String | Unique identifier for the query to be answered | | [options] | Object | Additional Telegram query options | - + -### telegramBot.setGameScore(userId, score, [options]) ⇒ Promise -Use this method to set the score of the specified user in a game. +### telegramBot.setMyCommands(commands, [options]) ⇒ Promise +Use this method to change the list of the bot's commands. + +See https://core.telegram.org/bots#commands for more details about bot commands **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setgamescore +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setmycommands | Param | Type | Description | | --- | --- | --- | -| userId | Number | Unique identifier of the target user | -| score | Number | New score value. | +| commands | Array | List of bot commands to be set as the list of the [bot's commands](https://core.telegram.org/bots/api#botcommand). At most 100 commands can be specified. | | [options] | Object | Additional Telegram query options | - + -### telegramBot.getGameHighScores(userId, [options]) ⇒ Promise -Use this method to get data for high score table. +### telegramBot.deleteMyCommands([options]) ⇒ Promise +Use this method to delete the list of the bot's commands for the given scope and user language. + + After deletion, [higher level commands](https://core.telegram.org/bots/api#determining-list-of-commands) will be shown to affected users. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getgamehighscores +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#deletemycommands | Param | Type | Description | | --- | --- | --- | -| userId | Number | Unique identifier of the target user | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.getMyCommands([options]) ⇒ Promise +Use this method to get the current list of the bot's commands for the given scope and user language. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - Array of [BotCommand](https://core.telegram.org/bots/api#botcommand) on success. If commands aren't set, an empty list is returned. +**See**: https://core.telegram.org/bots/api#getmycommands + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setChatMenuButton([options]) ⇒ Promise +Use this method to change the bot's menu button in a private chat, or the default menu button. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setchatmenubutton + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.getChatMenuButton([options]) ⇒ Promise +Use this method to get the current value of the bot's menu button in a private chat, or the default menu button. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - [MenuButton](https://core.telegram.org/bots/api#menubutton) on success +**See**: https://core.telegram.org/bots/api#getchatmenubutton + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setMyDefaultAdministratorRights([options]) ⇒ Promise +Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels. + +These rights will be suggested to users, but they are are free to modify the list before adding the bot. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#getchatmenubutton + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.getMyDefaultAdministratorRights([options]) ⇒ Promise +Use this method to get the current default administrator rights of the bot. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - [ChatAdministratorRights](https://core.telegram.org/bots/api#chatadministratorrights) on success +**See**: https://core.telegram.org/bots/api#getmydefaultadministratorrights + +| Param | Type | Description | +| --- | --- | --- | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.editMessageText(text, [options]) ⇒ Promise +Use this method to edit text or [game](https://core.telegram.org/bots/api#games) messages sent by the bot or via the bot (for inline bots). + +Note: that **you must provide one of chat_id, message_id, or inline_message_id** in your request. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned +**See**: https://core.telegram.org/bots/api#editmessagetext + +| Param | Type | Description | +| --- | --- | --- | +| text | String | New text of the message | +| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | + + + +### telegramBot.editMessageCaption(caption, [options]) ⇒ Promise +Use this method to edit captions of messages sent by the bot or via the bot (for inline bots). + +Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned +**See**: https://core.telegram.org/bots/api#editmessagecaption + +| Param | Type | Description | +| --- | --- | --- | +| caption | String | New caption of the message | +| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | + + + +### telegramBot.editMessageMedia(media, [options]) ⇒ Promise +Use this method to edit animation, audio, document, photo, or video messages. + +If a message is a part of a message album, then it can be edited only to a photo or a video. + +Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. +Use previously uploaded file via its file_id or specify a URL. + +Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned +**See**: https://core.telegram.org/bots/api#editmessagemedia + +| Param | Type | Description | +| --- | --- | --- | +| media | Object | A JSON-serialized object for a new media content of the message | +| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | + + + +### telegramBot.editMessageReplyMarkup(replyMarkup, [options]) ⇒ Promise +Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). + +Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned +**See**: https://core.telegram.org/bots/api#editmessagetext + +| Param | Type | Description | +| --- | --- | --- | +| replyMarkup | Object | A JSON-serialized object for an inline keyboard. | +| [options] | Object | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) | + + + +### telegramBot.stopPoll(chatId, pollId, [options]) ⇒ Promise +Use this method to stop a poll which was sent by the bot. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the stopped [Poll](https://core.telegram.org/bots/api#poll) is returned +**See**: https://core.telegram.org/bots/api#stoppoll + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the group/channel | +| pollId | Number | Identifier of the original message with the poll | | [options] | Object | Additional Telegram query options | ### telegramBot.deleteMessage(chatId, messageId, [options]) ⇒ Promise -Use this method to delete a message. +Use this method to delete a message, including service messages, with the following limitations: +- A message can only be deleted if it was sent less than 48 hours ago. +- A dice message can only be deleted if it was sent more than 24 hours ago. +- Bots can delete outgoing messages in groups and supergroups. +- Bots can delete incoming messages in groups, supergroups and channels. +- Bots granted `can_post_messages` permissions can delete outgoing messages in channels. +- If the bot is an administrator of a group, it can delete any message there. +- If the bot has `can_delete_messages` permission in a supergroup, it can delete any message there. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success **See**: https://core.telegram.org/bots/api#deletemessage | Param | Type | Description | @@ -1608,34 +1587,214 @@ Use this method to delete a message. | messageId | Number | Unique identifier of the target message | | [options] | Object | Additional Telegram query options | + + +### telegramBot.sendSticker(chatId, sticker, [options], [fileOptions]) ⇒ Promise +Use this method to send static .WEBP, [animated](https://telegram.org/blog/animated-stickers) .TGS, +or [video](https://telegram.org/blog/video-stickers-better-reactions) .WEBM stickers. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned +**See**: https://core.telegram.org/bots/api#sendsticker + +| Param | Type | Description | +| --- | --- | --- | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| sticker | String \| stream.Stream \| Buffer | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. Stickers are WebP format files. | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + + + +### telegramBot.getStickerSet(name, [options]) ⇒ Promise +Use this method to get a sticker set. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, a [StickerSet](https://core.telegram.org/bots/api#stickerset) object is returned +**See**: https://core.telegram.org/bots/api#getstickerset + +| Param | Type | Description | +| --- | --- | --- | +| name | String | Name of the sticker set | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.uploadStickerFile(userId, pngSticker, [options], [fileOptions]) ⇒ Promise +Use this method to upload a .png file with a sticker for later use in *createNewStickerSet* and *addStickerToSet* methods (can be used multiple +times). + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, a [File](https://core.telegram.org/bots/api#file) object is returned +**See**: https://core.telegram.org/bots/api#uploadstickerfile + +| Param | Type | Description | +| --- | --- | --- | +| userId | Number | User identifier of sticker file owner | +| pngSticker | String \| stream.Stream \| Buffer | A file path or a Stream. Can also be a `file_id` previously uploaded. **Png** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + + + +### telegramBot.createNewStickerSet(userId, name, title, pngSticker, emojis, [options], [fileOptions]) ⇒ Promise +Use this method to create new sticker set owned by a user. + +The bot will be able to edit the created sticker set. + +You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker* + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#createnewstickerset + +| Param | Type | Description | +| --- | --- | --- | +| userId | Number | User identifier of created sticker set owner | +| name | String | Short name of sticker set, to be used in `t.me/addstickers/` URLs (e.g., *"animals"*). Can contain only english letters, digits and underscores. Must begin with a letter, can't contain consecutive underscores and must end in `.` is case insensitive. 1-64 characters. | +| title | String | Sticker set title, 1-64 characters | +| pngSticker | String \| stream.Stream \| Buffer | Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. | +| emojis | String | One or more emoji corresponding to the sticker | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + + + +### telegramBot.addStickerToSet(userId, name, sticker, emojis, stickerType, [options], [fileOptions]) ⇒ Promise +Use this method to add a new sticker to a set created by the bot. + +You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker* + +Animated stickers can be added to animated sticker sets and only to them: +- Animated sticker sets can have up to 50 stickers. +- Static sticker sets can have up to 120 stickers + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#addstickertoset + +| Param | Type | Default | Description | +| --- | --- | --- | --- | +| userId | Number | | User identifier of sticker set owner | +| name | String | | Sticker set name | +| sticker | String \| stream.Stream \| Buffer | | Png image with the sticker (must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px), [TGS animation](https://core.telegram.org/stickers#animated-sticker-requirements) with the sticker or [WEBM video](https://core.telegram.org/stickers#video-sticker-requirements) with the sticker. | +| emojis | String | | One or more emoji corresponding to the sticker | +| stickerType | String | png_sticker | Allow values: `png_sticker`, `tgs_sticker`, or `webm_sticker`. | +| [options] | Object | | Additional Telegram query options | +| [fileOptions] | Object | | Optional file related meta-data | + + + +### telegramBot.setStickerPositionInSet(sticker, position, [options]) ⇒ Promise +Use this method to move a sticker in a set created by the bot to a specific position. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setstickerpositioninset + +| Param | Type | Description | +| --- | --- | --- | +| sticker | String | File identifier of the sticker | +| position | Number | New sticker position in the set, zero-based | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.deleteStickerFromSet(sticker, [options]) ⇒ Promise +Use this method to delete a sticker from a set created by the bot. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#deletestickerfromset +**Todo** + +- [ ] Add tests for this method! + + +| Param | Type | Description | +| --- | --- | --- | +| sticker | String | File identifier of the sticker | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.setStickerSetThumb(userId, name, pngThumb, [options], [fileOptions]) ⇒ Promise +Use this method to add a thumb to a set created by the bot. + +Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - True on success +**See**: https://core.telegram.org/bots/api#setstickersetthumb + +| Param | Type | Description | +| --- | --- | --- | +| userId | Number | User identifier of sticker set owner | +| name | String | Sticker set name | +| pngThumb | String \| stream.Stream \| Buffer | A PNG image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, a TGS animation with the thumbnail up to 32 kilobytes in size or a WEBM video with the thumbnail up to 32 kilobytes in size. Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one. Animated sticker set thumbnails can't be uploaded via HTTP URL. | +| [options] | Object | Additional Telegram query options | +| [fileOptions] | Object | Optional file related meta-data | + + + +### telegramBot.answerInlineQuery(inlineQueryId, results, [options]) ⇒ Promise +Send answers to an inline query. + +Note: No more than 50 results per query are allowed. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, True is returned +**See**: https://core.telegram.org/bots/api#answerinlinequery + +| Param | Type | Description | +| --- | --- | --- | +| inlineQueryId | String | Unique identifier of the query | +| results | [ 'Array' ].<InlineQueryResult> | An array of results for the inline query | +| [options] | Object | Additional Telegram query options | + + + +### telegramBot.answerWebAppQuery(webAppQueryId, result, [options]) ⇒ Promise +Use this method to set the result of an interaction with a [Web App](https://core.telegram.org/bots/webapps) +and send a corresponding message on behalf of the user to the chat from which the query originated. + +**Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, a [SentWebAppMessage](https://core.telegram.org/bots/api#sentwebappmessage) object is returned +**See**: https://core.telegram.org/bots/api#answerwebappquery + +| Param | Type | Description | +| --- | --- | --- | +| webAppQueryId | String | Unique identifier for the query to be answered | +| result | InlineQueryResult | object that represents one result of an inline query | +| [options] | Object | Additional Telegram query options | + -### telegramBot.sendInvoice(chatId, title, description, payload, providerToken, startParameter, currency, prices, [options]) ⇒ Promise -Send invoice. +### telegramBot.sendInvoice(chatId, title, description, payload, providerToken, currency, prices, [options]) ⇒ Promise Use this method to send an invoice. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned **See**: https://core.telegram.org/bots/api#sendinvoice | Param | Type | Description | | --- | --- | --- | -| chatId | Number \| String | Unique identifier for the message recipient | -| title | String | Product name | -| description | String | product description | -| payload | String | Bot defined invoice payload | -| providerToken | String | Payments provider token | -| startParameter | String | Deep-linking parameter | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| title | String | Product name, 1-32 characters | +| description | String | Product description, 1-255 characters | +| payload | String | Bot defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. | +| providerToken | String | Payments provider token, obtained via `@BotFather` | | currency | String | Three-letter ISO 4217 currency code | | prices | Array | Breakdown of prices | | [options] | Object | Additional Telegram query options | -### telegramBot.createInvoiceLink(title, description, payload, providerToken, currency, prices, [options]) ⇒ String -Create Invoice Link -Use this method to create a link for an invoice. Returns the created invoice link as String on success. +### telegramBot.createInvoiceLink(title, description, payload, providerToken, currency, prices, [options]) ⇒ Promise +Use this method to create a link for an invoice. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - The created invoice link as String on success. **See**: https://core.telegram.org/bots/api#createinvoicelink | Param | Type | Description | @@ -1651,10 +1810,13 @@ Use this method to create a link for an invoice. Returns the created invoice lin ### telegramBot.answerShippingQuery(shippingQueryId, ok, [options]) ⇒ Promise -Answer shipping query. Use this method to reply to shipping queries. +If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, +the Bot API will send an [Update](https://core.telegram.org/bots/api#update) with a shipping_query field to the bot + **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, True is returned **See**: https://core.telegram.org/bots/api#answershippingquery | Param | Type | Description | @@ -1666,10 +1828,15 @@ Use this method to reply to shipping queries. ### telegramBot.answerPreCheckoutQuery(preCheckoutQueryId, ok, [options]) ⇒ Promise -Answer pre-checkout query. -Use this method to confirm shipping of a product. +Use this method to respond to such pre-checkout queries + +Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of +an [Update](https://core.telegram.org/bots/api#update) with the field *pre_checkout_query*. + +**Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. **Kind**: instance method of [TelegramBot](#TelegramBot) +**Returns**: Promise - On success, True is returned **See**: https://core.telegram.org/bots/api#answerprecheckoutquery | Param | Type | Description | @@ -1678,160 +1845,50 @@ Use this method to confirm shipping of a product. | ok | Boolean | Specify if every order details are ok | | [options] | Object | Additional Telegram query options | - + -### telegramBot.getStickerSet(name, [options]) ⇒ Promise -Use this method to get a sticker set. On success, a [StickerSet](https://core.telegram.org/bots/api#stickerset) object is returned. +### telegramBot.sendGame(chatId, gameShortName, [options]) ⇒ Promise +Use this method to send a game. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#getstickerset +**Returns**: Promise - On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned +**See**: https://core.telegram.org/bots/api#sendgame | Param | Type | Description | | --- | --- | --- | -| name | String | Name of the sticker set | +| chatId | Number \| String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | +| gameShortName | String | name of the game to be sent. Set up your games via `@BotFather`. | | [options] | Object | Additional Telegram query options | - + -### telegramBot.uploadStickerFile(userId, pngSticker, [options], [fileOptions]) ⇒ Promise -Use this method to upload a .png file with a sticker for later use in *createNewStickerSet* and *addStickerToSet* methods (can be used multiple -times). Returns the uploaded [File](https://core.telegram.org/bots/api#file) on success. +### telegramBot.setGameScore(userId, score, [options]) ⇒ Promise +Use this method to set the score of the specified user in a game message. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#uploadstickerfile +**Returns**: Promise - On success, if the message is not an inline message, the [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned +**See**: https://core.telegram.org/bots/api#setgamescore | Param | Type | Description | | --- | --- | --- | -| userId | Number | User identifier of sticker file owner | -| pngSticker | String \| stream.Stream \| Buffer | A file path or a Stream. Can also be a `file_id` previously uploaded. **Png** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.createNewStickerSet(userId, name, title, pngSticker, emojis, [options], [fileOptions]) ⇒ Promise -Use this method to create new sticker set owned by a user. -The bot will be able to edit the created sticker set. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#createnewstickerset -**Todo** - -- [ ] Add tests for this method! - - -| Param | Type | Description | -| --- | --- | --- | -| userId | Number | User identifier of created sticker set owner | -| name | String | Short name of sticker set, to be used in `t.me/addstickers/` URLs (e.g., *animals*) | -| title | String | Sticker set title, 1-64 characters | -| pngSticker | String \| stream.Stream \| Buffer | Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. | -| emojis | String | One or more emoji corresponding to the sticker | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.addStickerToSet(userId, name, pngSticker, emojis, [options], [fileOptions]) ⇒ Promise -Use this method to add a new sticker to a set created by the bot. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#addstickertoset -**Todo** - -- [ ] Add tests for this method! - - -| Param | Type | Description | -| --- | --- | --- | -| userId | Number | User identifier of sticker set owner | -| name | String | Sticker set name | -| pngSticker | String \| stream.Stream \| Buffer | Png image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px | -| emojis | String | One or more emoji corresponding to the sticker | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.setStickerSetThumb(userId, name, pngThumb, [options], [fileOptions]) ⇒ Promise -Use this method to add a thumb to a set created by the bot. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setstickersetthumb -**Todo** - -- [ ] Add tests for this method! - - -| Param | Type | Description | -| --- | --- | --- | -| userId | Number | User identifier of sticker set owner | -| name | String | Sticker set name | -| pngThumb | String \| stream.Stream \| Buffer | A PNG image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a TGS animation with the thumbnail up to 32 kilobytes in size; | -| [options] | Object | Additional Telegram query options | -| [fileOptions] | Object | Optional file related meta-data | - - - -### telegramBot.setStickerPositionInSet(sticker, position, [options]) ⇒ Promise -Use this method to move a sticker in a set created by the bot to a specific position. -Returns True on success. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#setstickerpositioninset -**Todo** - -- [ ] Add tests for this method! - - -| Param | Type | Description | -| --- | --- | --- | -| sticker | String | File identifier of the sticker | -| position | Number | New sticker position in the set, zero-based | +| userId | Number | Unique identifier of the target user | +| score | Number | New score value, must be non-negative | | [options] | Object | Additional Telegram query options | - + -### telegramBot.deleteStickerFromSet(sticker, [options]) ⇒ Promise -Use this method to delete a sticker from a set created by the bot. -Returns True on success. +### telegramBot.getGameHighScores(userId, [options]) ⇒ Promise +Use this method to get data for high score tables. + +Will return the score of the specified user and several of their neighbors in a game. **Kind**: instance method of [TelegramBot](#TelegramBot) -**See**: https://core.telegram.org/bots/api#deletestickerfromset -**Todo** - -- [ ] Add tests for this method! - +**Returns**: Promise - On success, returns an Array of [GameHighScore](https://core.telegram.org/bots/api#gamehighscore) objects +**See**: https://core.telegram.org/bots/api#getgamehighscores | Param | Type | Description | | --- | --- | --- | -| sticker | String | File identifier of the sticker | -| [options] | Object | Additional Telegram query options | - - - -### telegramBot.sendMediaGroup(chatId, media, [options]) ⇒ Promise -Use this method to send a group of photos or videos as an album. -On success, an array of the sent [Messages](https://core.telegram.org/bots/api#message) -is returned. - -If you wish to [specify file options](https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files), -add a `fileOptions` property to the target input in `media`. - -**Kind**: instance method of [TelegramBot](#TelegramBot) -**See** - -- https://core.telegram.org/bots/api#sendmediagroup -- https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files - - -| Param | Type | Description | -| --- | --- | --- | -| chatId | String | Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) | -| media | Array | A JSON-serialized array describing photos and videos to be sent, must include 2–10 items | +| userId | Number | Unique identifier of the target user | | [options] | Object | Additional Telegram query options | diff --git a/package.json b/package.json index 130c956..3cf3fd1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-telegram-bot-api", - "version": "0.58.0", + "version": "0.59.0", "description": "Telegram Bot API", "main": "./index.js", "directories": { @@ -31,7 +31,7 @@ "dependencies": { "array.prototype.findindex": "^2.0.2", "bl": "^1.2.3", - "debug": "^3.1.0", + "debug": "^3.2.7", "eventemitter3": "^3.0.0", "file-type": "^3.9.0", "mime": "^1.6.0", diff --git a/src/telegram.js b/src/telegram.js index 03103fb..2914e98 100644 --- a/src/telegram.js +++ b/src/telegram.js @@ -388,8 +388,172 @@ class TelegramBot extends EventEmitter { return this._polling.stop(options); } + /** + * Get link for file. + * Use this method to get link for file for subsequent use. + * Attention: link will be valid for 1 hour. + * + * This method is a sugar extension of the (getFile)[#getfilefileid] method, + * which returns just path to file on remote server (you will have to manually build full uri after that). + * + * @param {String} fileId File identifier to get info about + * @param {Object} [options] Additional Telegram query options + * @return {Promise} Promise which will have *fileURI* in resolve callback + * @see https://core.telegram.org/bots/api#getfile + */ + getFileLink(fileId, form = {}) { + return this.getFile(fileId, form) + .then(resp => `${this.options.baseApiUrl}/file/bot${this.token}/${resp.file_path}`); + } + + /** + * Return a readable stream for file. + * + * `fileStream.path` is the specified file ID i.e. `fileId`. + * `fileStream` emits event `info` passing a single argument i.e. + * `info` with the interface `{ uri }` where `uri` is the URI of the + * file on Telegram servers. + * + * This method is a sugar extension of the [getFileLink](#TelegramBot+getFileLink) method, + * which returns the full URI to the file on remote server. + * + * @param {String} fileId File identifier to get info about + * @param {Object} [options] Additional Telegram query options + * @return {stream.Readable} fileStream + */ + getFileStream(fileId, form = {}) { + const fileStream = new stream.PassThrough(); + fileStream.path = fileId; + this.getFileLink(fileId, form) + .then((fileURI) => { + fileStream.emit('info', { + uri: fileURI, + }); + pump(streamedRequest(Object.assign({ uri: fileURI }, this.options.request)), fileStream); + }) + .catch((error) => { + fileStream.emit('error', error); + }); + return fileStream; + } + + /** + * Downloads file in the specified folder. + * + * This method is a sugar extension of the [getFileStream](#TelegramBot+getFileStream) method, + * which returns a readable file stream. + * + * @param {String} fileId File identifier to get info about + * @param {String} downloadDir Absolute path to the folder in which file will be saved + * @param {Object} [options] Additional Telegram query options + * @return {Promise} Promise, which will have *filePath* of downloaded file in resolve callback + */ + downloadFile(fileId, downloadDir, form = {}) { + let resolve; + let reject; + const promise = new Promise((a, b) => { + resolve = a; + reject = b; + }); + const fileStream = this.getFileStream(fileId, form); + fileStream.on('info', (info) => { + const fileName = info.uri.slice(info.uri.lastIndexOf('/') + 1); + // TODO: Ensure fileName doesn't contains slashes + const filePath = path.join(downloadDir, fileName); + pump(fileStream, fs.createWriteStream(filePath), (error) => { + if (error) { return reject(error); } + return resolve(filePath); + }); + }); + fileStream.on('error', (err) => { + reject(err); + }); + return promise; + } + + /** + * Register a RegExp to test against an incomming text message. + * @param {RegExp} regexpRexecuted with `exec`. + * @param {Function} callback Callback will be called with 2 parameters, + * the `msg` and the result of executing `regexp.exec` on message text. + */ + onText(regexp, callback) { + this._textRegexpCallbacks.push({ regexp, callback }); + } + + /** + * Remove a listener registered with `onText()`. + * @param {RegExp} regexp RegExp used previously in `onText()` + * @return {Object} deletedListener The removed reply listener if + * found. This object has `regexp` and `callback` + * properties. If not found, returns `null`. + */ + removeTextListener(regexp) { + const index = this._textRegexpCallbacks.findIndex((textListener) => { + return String(textListener.regexp) === String(regexp); + }); + if (index === -1) { + return null; + } + return this._textRegexpCallbacks.splice(index, 1)[0]; + } + + /** + * Remove all listeners registered with `onText()`. + */ + clearTextListeners() { + this._textRegexpCallbacks = []; + } + + /** + * Register a reply to wait for a message response. + * + * @param {Number|String} chatId The chat id where the message cames from. + * @param {Number|String} messageId The message id to be replied. + * @param {Function} callback Callback will be called with the reply + * message. + * @return {Number} id The ID of the inserted reply listener. + */ + onReplyToMessage(chatId, messageId, callback) { + const id = ++this._replyListenerId; + this._replyListeners.push({ + id, + chatId, + messageId, + callback + }); + return id; + } + + /** + * Removes a reply that has been prev. registered for a message response. + * @param {Number} replyListenerId The ID of the reply listener. + * @return {Object} deletedListener The removed reply listener if + * found. This object has `id`, `chatId`, `messageId` and `callback` + * properties. If not found, returns `null`. + */ + removeReplyListener(replyListenerId) { + const index = this._replyListeners.findIndex((replyListener) => { + return replyListener.id === replyListenerId; + }); + if (index === -1) { + return null; + } + return this._replyListeners.splice(index, 1)[0]; + } + + /** + * Removes all replies that have been prev. registered for a message response. + * + * @return {Array} deletedListeners An array of removed listeners. + */ + clearReplyListeners() { + this._replyListeners = []; + } + /** * Return true if polling. Otherwise, false. + * * @return {Boolean} */ isPolling() { @@ -400,6 +564,7 @@ class TelegramBot extends EventEmitter { * Open webhook. * Multiple invocations do nothing if webhook is already open. * Rejects returned promise if Polling is being used by this instance. + * * @return {Promise} */ openWebHook() { @@ -415,7 +580,8 @@ class TelegramBot extends EventEmitter { /** * Close webhook after closing all current connections. * Multiple invocations do nothing if webhook is already closed. - * @return {Promise} promise + * + * @return {Promise} Promise */ closeWebHook() { if (!this._webHook) { @@ -427,148 +593,19 @@ class TelegramBot extends EventEmitter { /** * Return true if using webhook and it is open i.e. accepts connections. * Otherwise, false. + * * @return {Boolean} */ hasOpenWebHook() { return this._webHook ? this._webHook.isOpen() : false; } - /** - * Returns basic information about the bot in form of a `User` object. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getme - */ - getMe(form = {}) { - return this._request('getMe', { form }); - } - - /** - * This method log out your bot from the cloud Bot API server before launching the bot locally. - * You must log out the bot before running it locally, otherwise there is no guarantee that the bot will receive updates. - * After a successful call, you will not be able to log in again using the same token for 10 minutes. - * Returns True on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#logout - */ - logOut(form = {}) { - return this._request('logOut', { form }); - } - - /** - * This method close the bot instance before moving it from one local server to another. - * This method will return error 429 in the first 10 minutes after the bot is launched. - * Returns True on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#close - */ - close(form = {}) { - return this._request('close', { form }); - } - - /** - * Specify an url to receive incoming updates via an outgoing webHook. - * This method has an [older, compatible signature][setWebHook-v0.25.0] - * that is being deprecated. - * - * @param {String} url URL where Telegram will make HTTP Post. Leave empty to - * delete webHook. - * @param {Object} [options] Additional Telegram query options - * @param {String|stream.Stream} [options.certificate] PEM certificate key (public). - * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} - * @see https://core.telegram.org/bots/api#setwebhook - * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files - */ - setWebHook(url, options = {}, fileOptions = {}) { - /* 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) { - deprecate('The method signature setWebHook(url, cert) has been deprecated since v0.25.0'); - cert = options; - options = {}; // eslint-disable-line no-param-reassign - } else { - cert = options.certificate; - } - - const opts = { - qs: options, - }; - opts.qs.url = url; - - if (cert) { - try { - const sendData = this._formatSendData('certificate', cert, fileOptions); - opts.formData = sendData[0]; - opts.qs.certificate = sendData[1]; - } catch (ex) { - return Promise.reject(ex); - } - } - - return this._request('setWebHook', opts); - } - - /** - * Use this method to remove webhook integration if you decide to - * switch back to getUpdates. Returns True on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#deletewebhook - */ - deleteWebHook(form = {}) { - return this._request('deleteWebhook', { form }); - } - - /** - * Use this method to get current webhook status. - * On success, returns a [WebhookInfo](https://core.telegram.org/bots/api#webhookinfo) object. - * If the bot is using getUpdates, will return an object with the - * url field empty. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getwebhookinfo - */ - getWebHookInfo(form = {}) { - return this._request('getWebhookInfo', { form }); - } - - /** - * Use this method to receive incoming updates using long polling. - * This method has an [older, compatible signature][getUpdates-v0.25.0] - * that is being deprecated. - * - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getupdates - */ - 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 */ - deprecate('The method signature getUpdates(timeout, limit, offset) has been deprecated since v0.25.0'); - form = { - timeout: arguments[0], - limit: arguments[1], - offset: arguments[2], - }; - /* eslint-enable no-param-reassign, prefer-rest-params */ - } - - return this._request('getUpdates', { form }); - } /** * Process an update; emitting the proper events and executing regexp * callbacks. This method is useful should you be using a different * way to fetch updates, other than those provided by TelegramBot. + * * @param {Object} update * @see https://core.telegram.org/bots/api#update */ @@ -683,12 +720,147 @@ class TelegramBot extends EventEmitter { } } + /** Start Telegram Bot API methods */ + /** - * Send text message. - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String} text Text of the message to be sent + * Use this method to receive incoming updates using long polling. + * This method has an [older, compatible signature][getUpdates-v0.25.0] + * that is being deprecated. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} + * @see https://core.telegram.org/bots/api#getupdates + */ + 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 */ + deprecate('The method signature getUpdates(timeout, limit, offset) has been deprecated since v0.25.0'); + form = { + timeout: arguments[0], + limit: arguments[1], + offset: arguments[2], + }; + /* eslint-enable no-param-reassign, prefer-rest-params */ + } + + return this._request('getUpdates', { form }); + } + + /** + * Specify an url to receive incoming updates via an outgoing webHook. + * This method has an [older, compatible signature][setWebHook-v0.25.0] + * that is being deprecated. + * + * @param {String} url URL where Telegram will make HTTP Post. Leave empty to + * delete webHook. + * @param {Object} [options] Additional Telegram query options + * @param {String|stream.Stream} [options.certificate] PEM certificate key (public). + * @param {Object} [fileOptions] Optional file related meta-data + * @return {Promise} + * @see https://core.telegram.org/bots/api#setwebhook + * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + */ + setWebHook(url, options = {}, fileOptions = {}) { + /* 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) { + deprecate('The method signature setWebHook(url, cert) has been deprecated since v0.25.0'); + cert = options; + options = {}; // eslint-disable-line no-param-reassign + } else { + cert = options.certificate; + } + + const opts = { + qs: options, + }; + opts.qs.url = url; + + if (cert) { + try { + const sendData = this._formatSendData('certificate', cert, fileOptions); + opts.formData = sendData[0]; + opts.qs.certificate = sendData[1]; + } catch (ex) { + return Promise.reject(ex); + } + } + + return this._request('setWebHook', opts); + } + + /** + * Use this method to remove webhook integration if you decide to + * switch back to getUpdates. Returns True on success. * @param {Object} [options] Additional Telegram query options * @return {Promise} + * @see https://core.telegram.org/bots/api#deletewebhook + */ + deleteWebHook(form = {}) { + return this._request('deleteWebhook', { form }); + } + + /** + * Use this method to get current webhook status. + * On success, returns a [WebhookInfo](https://core.telegram.org/bots/api#webhookinfo) object. + * If the bot is using getUpdates, will return an object with the + * url field empty. + * @param {Object} [options] Additional Telegram query options + * @return {Promise} + * @see https://core.telegram.org/bots/api#getwebhookinfo + */ + getWebHookInfo(form = {}) { + return this._request('getWebhookInfo', { form }); + } + + /** + * A simple method for testing your bot's authentication token. Requires no parameters. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} basic information about the bot in form of a [User](https://core.telegram.org/bots/api#user) object. + * @see https://core.telegram.org/bots/api#getme + */ + getMe(form = {}) { + return this._request('getMe', { form }); + } + + /** + * This method log out your bot from the cloud Bot API server before launching the bot locally. + * You must log out the bot before running it locally, otherwise there is no guarantee that the bot will receive updates. + * After a successful call, you will not be able to log in again using the same token for 10 minutes. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#logout + */ + logOut(form = {}) { + return this._request('logOut', { form }); + } + + /** + * This method close the bot instance before moving it from one local server to another. + * This method will return error 429 in the first 10 minutes after the bot is launched. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#close + */ + close(form = {}) { + return this._request('close', { form }); + } + + /** + * Send text message. + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String} text Text of the message to be sent + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned * @see https://core.telegram.org/bots/api#sendmessage */ sendMessage(chatId, text, form = {}) { @@ -697,26 +869,13 @@ class TelegramBot extends EventEmitter { return this._request('sendMessage', { form }); } - /** - * Send answers to an inline query. - * @param {String} inlineQueryId Unique identifier of the query - * @param {InlineQueryResult[]} results An array of results for the inline query - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#answerinlinequery - */ - answerInlineQuery(inlineQueryId, results, form = {}) { - form.inline_query_id = inlineQueryId; - form.results = stringify(results); - return this._request('answerInlineQuery', { form }); - } - /** * Forward messages of any kind. - * @param {Number|String} chatId Unique identifier for the message recipient + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * or username of the target channel (in the format `@channelusername`) * @param {Number|String} fromChatId Unique identifier for the chat where the - * original message was sent - * @param {Number|String} messageId Unique message identifier + * original message was sent (or channel username in the format `@channelusername`) + * @param {Number|String} messageId Unique message identifier in the chat specified in fromChatId * @param {Object} [options] Additional Telegram query options * @return {Promise} * @see https://core.telegram.org/bots/api#forwardmessage @@ -729,16 +888,16 @@ class TelegramBot extends EventEmitter { } /** - * Copy messages of any kind. + * Copy messages of any kind. **Service messages and invoice messages can't be copied.** * The method is analogous to the method forwardMessages, but the copied message doesn't * have a link to the original message. * Returns the MessageId of the sent message on success. - * @param {Number|String} chatId Unique identifier for the message recipient + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @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} + * @return {Promise} The [MessageId](https://core.telegram.org/bots/api#messageid) of the sent message on success * @see https://core.telegram.org/bots/api#copymessage */ copyMessage(chatId, fromChatId, messageId, form = {}) { @@ -750,12 +909,12 @@ class TelegramBot extends EventEmitter { /** * Send photo - * @param {Number|String} chatId Unique identifier for the message recipient + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String|stream.Stream|Buffer} photo A file path or a Stream. Can * also be a `file_id` previously uploaded * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned * @see https://core.telegram.org/bots/api#sendphoto * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files */ @@ -775,16 +934,19 @@ class TelegramBot extends EventEmitter { } /** - * Send audio - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String|stream.Stream|Buffer} audio A file path, Stream or Buffer. - * Can also be a `file_id` previously uploaded. - * @param {Object} [options] Additional Telegram query options - * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendaudio - * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files - */ + * Send audio + * + * **Your audio must be in the .MP3 or .M4A format.** + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String|stream.Stream|Buffer} audio A file path, Stream or Buffer. + * Can also be a `file_id` previously uploaded. + * @param {Object} [options] Additional Telegram query options + * @param {Object} [fileOptions] Optional file related meta-data + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#sendaudio + * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + */ sendAudio(chatId, audio, options = {}, fileOptions = {}) { const opts = { qs: options @@ -822,38 +984,16 @@ class TelegramBot extends EventEmitter { } /** - * Send Dice - * Use this method to send a dice. - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#senddice - */ - sendDice(chatId, options = {}) { - const opts = { - qs: options, - }; - opts.qs.chat_id = chatId; - try { - const sendData = this._formatSendData('dice'); - opts.formData = sendData[0]; - } catch (ex) { - return Promise.reject(ex); - } - return this._request('sendDice', opts); - } - - /** - * Send Document - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String|stream.Stream|Buffer} doc A file path, Stream or Buffer. - * Can also be a `file_id` previously uploaded. - * @param {Object} [options] Additional Telegram query options - * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendDocument - * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files - */ + * Send Document + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String|stream.Stream|Buffer} doc A file path, Stream or Buffer. + * Can also be a `file_id` previously uploaded. + * @param {Object} [options] Additional Telegram query options + * @param {Object} [fileOptions] Optional file related meta-data + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#sendDocument + * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + */ sendDocument(chatId, doc, options = {}, fileOptions = {}) { const opts = { qs: options @@ -870,38 +1010,14 @@ class TelegramBot extends EventEmitter { } /** - * Send .webp stickers. - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String|stream.Stream|Buffer} sticker A file path, Stream or Buffer. - * Can also be a `file_id` previously uploaded. Stickers are WebP format files. - * @param {Object} [options] Additional Telegram query options - * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendsticker - */ - sendSticker(chatId, sticker, options = {}, fileOptions = {}) { - const opts = { - qs: options - }; - opts.qs.chat_id = chatId; - try { - const sendData = this._formatSendData('sticker', sticker, fileOptions); - opts.formData = sendData[0]; - opts.qs.sticker = sendData[1]; - } catch (ex) { - return Promise.reject(ex); - } - return this._request('sendSticker', opts); - } - - /** - * Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document). - * @param {Number|String} chatId Unique identifier for the message recipient + * Use this method to send video files, **Telegram clients support mp4 videos** (other formats may be sent as Document). + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String|stream.Stream|Buffer} video A file path or Stream. * Can also be a `file_id` previously uploaded. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned * @see https://core.telegram.org/bots/api#sendvideo * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files */ @@ -922,12 +1038,12 @@ class TelegramBot extends EventEmitter { /** * Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). - * @param {Number|String} chatId Unique identifier for the message recipient + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String|stream.Stream|Buffer} animation A file path, Stream or Buffer. * Can also be a `file_id` previously uploaded. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned * @see https://core.telegram.org/bots/api#sendanimation * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files */ @@ -946,41 +1062,16 @@ class TelegramBot extends EventEmitter { return this._request('sendAnimation', opts); } - /** - * Use this method to send rounded square videos of upto 1 minute long. - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String|stream.Stream|Buffer} videoNote A file path or Stream. - * Can also be a `file_id` previously uploaded. - * @param {Object} [options] Additional Telegram query options - * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} - * @info The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed. - * @see https://core.telegram.org/bots/api#sendvideonote - * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files - */ - sendVideoNote(chatId, videoNote, options = {}, fileOptions = {}) { - const opts = { - qs: options - }; - opts.qs.chat_id = chatId; - try { - const sendData = this._formatSendData('video_note', videoNote, fileOptions); - opts.formData = sendData[0]; - opts.qs.video_note = sendData[1]; - } catch (ex) { - return Promise.reject(ex); - } - return this._request('sendVideoNote', opts); - } - /** * Send voice - * @param {Number|String} chatId Unique identifier for the message recipient + * + * **Your audio must be in an .OGG file encoded with OPUS** (other formats may be sent as Audio or Document) + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String|stream.Stream|Buffer} voice A file path, Stream or Buffer. * Can also be a `file_id` previously uploaded. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned * @see https://core.telegram.org/bots/api#sendvoice * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files */ @@ -999,19 +1090,236 @@ class TelegramBot extends EventEmitter { return this._request('sendVoice', opts); } + /** + * Use this method to send video messages + * Telegram clients support **rounded square MPEG4 videos** of up to 1 minute long. + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String|stream.Stream|Buffer} videoNote A file path or Stream. + * Can also be a `file_id` previously uploaded. + * @param {Object} [options] Additional Telegram query options + * @param {Object} [fileOptions] Optional file related meta-data + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @info The length parameter is actually optional. However, the API (at time of writing) requires you to always provide it until it is fixed. + * @see https://core.telegram.org/bots/api#sendvideonote + * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + */ + sendVideoNote(chatId, videoNote, options = {}, fileOptions = {}) { + const opts = { + qs: options + }; + opts.qs.chat_id = chatId; + try { + const sendData = this._formatSendData('video_note', videoNote, fileOptions); + opts.formData = sendData[0]; + opts.qs.video_note = sendData[1]; + } catch (ex) { + return Promise.reject(ex); + } + return this._request('sendVideoNote', opts); + } + + /** + * Use this method to send a group of photos or videos as an album. + * + * **Documents and audio files can be only grouped in an album with messages of the same type** + * + * If you wish to [specify file options](https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files), + * add a `fileOptions` property to the target input in `media`. + * + * @param {String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Array} media A JSON-serialized array describing photos and videos to be sent, must include 2–10 items + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, an array of the sent [Messages](https://core.telegram.org/bots/api#message) + * is returned. + * @see https://core.telegram.org/bots/api#sendmediagroup + * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + */ + sendMediaGroup(chatId, media, options = {}) { + const opts = { + qs: options, + }; + opts.qs.chat_id = chatId; + + opts.formData = {}; + const inputMedia = []; + let index = 0; + for (const input of media) { + const payload = Object.assign({}, input); + delete payload.media; + delete payload.fileOptions; + try { + const attachName = String(index); + const [formData, fileId] = this._formatSendData(attachName, input.media, input.fileOptions); + if (formData) { + opts.formData[attachName] = formData[attachName]; + payload.media = `attach://${attachName}`; + } else { + payload.media = fileId; + } + } catch (ex) { + return Promise.reject(ex); + } + inputMedia.push(payload); + index++; + } + opts.qs.media = stringify(inputMedia); + + return this._request('sendMediaGroup', opts); + } + + + /** + * Send location. + * Use this method to send point on the map. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Float} latitude Latitude of location + * @param {Float} longitude Longitude of location + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#sendlocation + */ + sendLocation(chatId, latitude, longitude, form = {}) { + form.chat_id = chatId; + form.latitude = latitude; + form.longitude = longitude; + return this._request('sendLocation', { form }); + } + + /** + * Use this method to edit live location messages sent by + * the bot or via the bot (for inline bots). + * + * A location **can be edited until its live_period expires or editing is explicitly disabled by a call to [stopMessageLiveLocation](https://core.telegram.org/bots/api#stopmessagelivelocation)** + * + * Note that you must provide one of chat_id, message_id, or + * inline_message_id in your request. + * + * @param {Float} latitude Latitude of location + * @param {Float} longitude Longitude of location + * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned. + * @see https://core.telegram.org/bots/api#editmessagelivelocation + */ + editMessageLiveLocation(latitude, longitude, form = {}) { + form.latitude = latitude; + form.longitude = longitude; + return this._request('editMessageLiveLocation', { form }); + } + + /** + * Use this method to stop updating a live location message sent by + * the bot or via the bot (for inline bots) before live_period expires. + * + * Note that you must provide one of chat_id, message_id, or + * inline_message_id in your request. + * + * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned. + * @see https://core.telegram.org/bots/api#stopmessagelivelocation + */ + stopMessageLiveLocation(form = {}) { + return this._request('stopMessageLiveLocation', { form }); + } + + /** + * Send venue. + * Use this method to send information about a venue. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Float} latitude Latitude of location + * @param {Float} longitude Longitude of location + * @param {String} title Name of the venue + * @param {String} address Address of the venue + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned. + * @see https://core.telegram.org/bots/api#sendvenue + */ + sendVenue(chatId, latitude, longitude, title, address, form = {}) { + form.chat_id = chatId; + form.latitude = latitude; + form.longitude = longitude; + form.title = title; + form.address = address; + return this._request('sendVenue', { form }); + } + + /** + * Send contact. + * Use this method to send phone contacts. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String} phoneNumber Contact's phone number + * @param {String} firstName Contact's first name + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#sendcontact + */ + sendContact(chatId, phoneNumber, firstName, form = {}) { + form.chat_id = chatId; + form.phone_number = phoneNumber; + form.first_name = firstName; + return this._request('sendContact', { form }); + } + + /** + * Send poll. + * Use this method to send a native poll. + * + * @param {Number|String} chatId Unique identifier for the group/channel + * @param {String} question Poll question, 1-300 characters + * @param {Array} pollOptions Poll options, between 2-10 options (only 1-100 characters each) + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#sendpoll + */ + sendPoll(chatId, question, pollOptions, form = {}) { + form.chat_id = chatId; + form.question = question; + form.options = stringify(pollOptions); + return this._request('sendPoll', { form }); + } + + /** + * Send Dice + * Use this method to send an animated emoji that will display a random value. + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) object is returned + * @see https://core.telegram.org/bots/api#senddice + */ + sendDice(chatId, options = {}) { + const opts = { + qs: options, + }; + opts.qs.chat_id = chatId; + try { + const sendData = this._formatSendData('dice'); + opts.formData = sendData[0]; + } catch (ex) { + return Promise.reject(ex); + } + return this._request('sendDice', opts); + } + /** * Send chat action. - * `typing` for text messages, - * `upload_photo` for photos, `record_video` or `upload_video` for videos, - * `record_voice` or `upload_voice` for audio files, `upload_document` for general files, - * `choose_sticker` for stickers, `find_location` for location data, - * `record_video_note` or `upload_video_note` for video notes. * - * @param {Number|String} chatId Unique identifier for the message recipient + * Use this method when you need to tell the user that something is happening on the bot's side. + * **The status is set for 5 seconds or less** (when a message arrives from your bot, Telegram clients clear its typing status). + * + * Action `typing` for [text messages](https://core.telegram.org/bots/api#sendmessage), + * `upload_photo` for [photos](https://core.telegram.org/bots/api#sendphoto), `record_video` or `upload_video` for [videos](https://core.telegram.org/bots/api#sendvideo), + * `record_voice` or `upload_voice` for [voice notes](https://core.telegram.org/bots/api#sendvoice), `upload_document` for [general files](https://core.telegram.org/bots/api#senddocument), + * `choose_sticker` for [stickers](https://core.telegram.org/bots/api#sendsticker), `find_location` for [location data](https://core.telegram.org/bots/api#sendlocation), + * `record_video_note` or `upload_video_note` for [video notes](https://core.telegram.org/bots/api#sendvideonote). + * + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String} action Type of action to broadcast. * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#sendchataction */ sendChatAction(chatId, action, form = {}) { @@ -1021,39 +1329,63 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to kick a user from a group or a supergroup. - * In the case of supergroups, the user will not be able to return - * to the group on their own using invite links, etc., unless unbanned - * first. The bot must be an administrator in the group for this to work. - * Returns True on success. + * Use this method to get a list of profile pictures for a user. + * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object. + * This method has an [older, compatible signature][getUserProfilePhotos-v0.25.0] + * that is being deprecated. * - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup * @param {Number} userId Unique identifier of the target user * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#kickchatmember - * @deprecated Deprecated since Telegram Bot API v5.3, replace with "banChatMember" + * @return {Promise} Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object + * @see https://core.telegram.org/bots/api#getuserprofilephotos */ - kickChatMember(chatId, userId, form = {}) { - deprecate('The method kickChatMembet is deprecated since Telegram Bot API v5.3, replace it with "banChatMember"'); - form.chat_id = chatId; + 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 */ + deprecate('The method signature getUserProfilePhotos(userId, offset, limit) has been deprecated since v0.25.0'); + form = { + offset: arguments[1], + limit: arguments[2], + }; + /* eslint-enable no-param-reassign, prefer-rest-params */ + } form.user_id = userId; - return this._request('kickChatMember', { form }); + return this._request('getUserProfilePhotos', { form }); } /** - * Use this method to ban a user in a group, a supergroup or a channel. - * In the case of supergroups and channels, the user will not be able to - * return to the chat on their own using invite links, etc., unless unbanned first.. - * The bot must be an administrator in the group for this to work. - * Returns True on success. - * - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#banchatmember - */ + * Get file. + * Use this method to get basic info about a file and prepare it for downloading. + * + * Attention: **link will be valid for 1 hour.** + * + * @param {String} fileId File identifier to get info about + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, a [File](https://core.telegram.org/bots/api#file) object is returned + * @see https://core.telegram.org/bots/api#getfile + */ + getFile(fileId, form = {}) { + form.file_id = fileId; + return this._request('getFile', { form }); + } + + /** + * Use this method to ban a user in a group, a supergroup or a channel. + * In the case of supergroups and channels, the user will not be able to + * return to the chat on their own using invite links, etc., unless unbanned first.. + * + * The **bot must be an administrator in the group, supergroup or a channel** for this to work. + * + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Number} userId Unique identifier of the target user + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success. + * @see https://core.telegram.org/bots/api#banchatmember + */ banChatMember(chatId, userId, form = {}) { form.chat_id = chatId; form.user_id = userId; @@ -1061,17 +1393,21 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to unban a previously kicked user in a supergroup. - * The user will not return to the group automatically, but will be - * able to join via link, etc. The bot must be an administrator in - * the group for this to work. Returns True on success. - * - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#unbanchatmember - */ + * Use this method to unban a previously kicked user in a supergroup. + * The user will not return to the group automatically, but will be + * able to join via link, etc. + * + * The **bot must be an administrator** in the supergroup or channel for this to work. + * + * **By default**, this method guarantees that after the call the user is not a member of the chat, but will be able to join it. + * So **if the user is a member of the chat they will also be removed from the chat**. If you don't want this, use the parameter *only_if_banned* + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Number} userId Unique identifier of the target user + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#unbanchatmember + */ unbanChatMember(chatId, userId, form = {}) { form.chat_id = chatId; form.user_id = userId; @@ -1079,17 +1415,17 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to restrict a user in a supergroup. - * The bot must be an administrator in the supergroup for this to work - * and must have the appropriate admin rights. Pass True for all boolean parameters - * to lift restrictions from a user. Returns True on success. - * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#restrictchatmember - */ + * Use this method to restrict a user in a supergroup. + * The bot **must be an administrator in the supergroup** for this to work + * and must have the appropriate admin rights. Pass True for all boolean parameters + * to lift restrictions from a user. Returns True on success. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Number} userId Unique identifier of the target user + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#restrictchatmember + */ restrictChatMember(chatId, userId, form = {}) { form.chat_id = chatId; form.user_id = userId; @@ -1098,14 +1434,14 @@ class TelegramBot extends EventEmitter { /** * Use this method to promote or demote a user in a supergroup or a channel. - * The bot must be an administrator in the chat for this to work + * The bot **must be an administrator** in the chat for this to work * and must have the appropriate admin rights. Pass False for all boolean parameters to demote a user. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} userId * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success. * @see https://core.telegram.org/bots/api#promotechatmember */ promoteChatMember(chatId, userId, form = {}) { @@ -1116,13 +1452,12 @@ class TelegramBot extends EventEmitter { /** * Use this method to set a custom title for an administrator in a supergroup promoted by the bot. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the message recipient + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} userId Unique identifier of the target user * @param {String} customTitle New custom title for the administrator; 0-16 characters, emoji are not allowed * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setchatadministratorcustomtitle */ setChatAdministratorCustomTitle(chatId, userId, customTitle, form = {}) { @@ -1135,16 +1470,14 @@ class TelegramBot extends EventEmitter { /** * Use this method to ban a channel chat in a supergroup or a channel. - * The owner of the chat will not be able to send messages and join live streams - * on behalf of the chat, unless it is unbanned first. - * The bot must be an administrator in the supergroup or channel for this to work - * and must have the appropriate administrator rights. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup + * Until the chat is [unbanned](https://core.telegram.org/bots/api#unbanchatsenderchat), the owner of the banned chat won't be able to send messages on behalf of any of their channels. + * The bot **must be an administrator in the supergroup or channel** for this to work and must have the appropriate administrator rights + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} senderChatId Unique identifier of the target user * @param {Object} [options] Additional Telegram query options - * @return {Boolean} + * @return {Promise} True on success. * @see https://core.telegram.org/bots/api#banchatsenderchat */ banChatSenderChat(chatId, senderChatId, form = {}) { @@ -1155,13 +1488,13 @@ class TelegramBot extends EventEmitter { /** * Use this method to unban a previously banned channel chat in a supergroup or channel. - * The bot must be an administrator for this to work and must have the appropriate administrator rights. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Number} senderChatId Unique identifier of the target user + * The bot **must be an administrator** for this to work and must have the appropriate administrator rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Number} senderChatId Unique identifier of the target user * @param {Object} [options] Additional Telegram query options - * @return {Boolean} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#unbanchatsenderchat */ unbanChatSenderChat(chatId, senderChatId, form = {}) { @@ -1172,30 +1505,30 @@ class TelegramBot extends EventEmitter { /** * Use this method to set default chat permissions for all members. - * The bot must be an administrator in the group or a supergroup for this to - * work and must have the can_restrict_members admin rights. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the message recipient + * The bot **must be an administrator in the group or a supergroup** for this to + * work and **must have the `can_restrict_members` admin rights.** + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Array} chatPermissions New default chat permissions * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setchatpermissions */ setChatPermissions(chatId, chatPermissions, form = {}) { form.chat_id = chatId; - form.permissions = JSON.stringify(chatPermissions); + form.permissions = stringify(chatPermissions); return this._request('setChatPermissions', { form }); } /** - * Use this method to export an invite link to a supergroup or a channel. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns exported invite link as String on success. + * Use this method to generate a new primary invite link for a chat. **Any previously generated primary link is revoked**. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} Exported invite link as String on success. * @see https://core.telegram.org/bots/api#exportchatinvitelink */ exportChatInviteLink(chatId, form = {}) { @@ -1205,12 +1538,14 @@ class TelegramBot extends EventEmitter { /** * Use this method to create an additional invite link for a chat. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns the new invite link as ChatInviteLink object. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * The link generated with this method can be revoked using the method [revokeChatInviteLink](https://core.telegram.org/bots/api#revokechatinvitelink) + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Object} [options] Additional Telegram query options - * @return {Object} ChatInviteLink + * @return {Object} The new invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object * @see https://core.telegram.org/bots/api#createchatinvitelink */ createChatInviteLink(chatId, form = {}) { @@ -1220,13 +1555,13 @@ class TelegramBot extends EventEmitter { /** * Use this method to edit a non-primary invite link created by the bot. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns the edited invite link as a ChatInviteLink object. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String} inviteLink Text with the invite link to edit * @param {Object} [options] Additional Telegram query options - * @return {Object} ChatInviteLink + * @return {Promise} The edited invite link as a [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object * @see https://core.telegram.org/bots/api#editchatinvitelink */ editChatInviteLink(chatId, inviteLink, form = {}) { @@ -1238,12 +1573,12 @@ class TelegramBot extends EventEmitter { /** * Use this method to revoke an invite link created by the bot. * Note: If the primary link is revoked, a new link is automatically generated - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns the revoked invite link as ChatInviteLink object. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Object} [options] Additional Telegram query options - * @return {Object} ChatInviteLink + * @return {Promise} The revoked invite link as [ChatInviteLink](https://core.telegram.org/bots/api#chatinvitelink) object * @see https://core.telegram.org/bots/api#revokechatinvitelink */ revokeChatInviteLink(chatId, inviteLink, form = {}) { @@ -1254,13 +1589,13 @@ class TelegramBot extends EventEmitter { /** * Use this method to approve a chat join request. - * The bot must be an administrator in the chat for this to work and must have the can_invite_users administrator right. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right.** + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} userId Unique identifier of the target user * @param {Object} [options] Additional Telegram query options - * @return {Boolean} True on success + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#approvechatjoinrequest */ approveChatJoinRequest(chatId, userId, form = {}) { @@ -1271,13 +1606,13 @@ class TelegramBot extends EventEmitter { /** * Use this method to decline a chat join request. - * The bot must be an administrator in the chat for this to work and must have the can_invite_users administrator right. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup + * The bot **must be an administrator in the chat** for this to work and **must have the `can_invite_users` administrator right**. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} userId Unique identifier of the target user * @param {Object} [options] Additional Telegram query options - * @return {Boolean} True on success + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#declinechatjoinrequest */ declineChatJoinRequest(chatId, userId, form = {}) { @@ -1286,17 +1621,16 @@ class TelegramBot extends EventEmitter { return this._request('declineChatJoinRequest', { form }); } - /** - * Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. + * Use this method to set a new profile photo for the chat. **Photos can't be changed for private chats**. * - * @param {Number|String} chatId Unique identifier for the message recipient + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {stream.Stream|Buffer} photo A file path or a Stream. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setchatphoto */ setChatPhoto(chatId, photo, options = {}, fileOptions = {}) { @@ -1315,29 +1649,29 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to delete a chat photo. Photos can't be changed for private chats. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. - * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#deletechatphoto - */ + * Use this method to delete a chat photo. **Photos can't be changed for private chats**. + * + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#deletechatphoto + */ deleteChatPhoto(chatId, form = {}) { form.chat_id = chatId; return this._request('deleteChatPhoto', { form }); } /** - * Use this method to change the title of a chat. Titles can't be changed for private chats. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. + * Use this method to change the title of a chat. **Titles can't be changed for private chats**. * - * @param {Number|String} chatId Unique identifier for the message recipient + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {String} title New chat title, 1-255 characters * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setchattitle */ setChatTitle(chatId, title, form = {}) { @@ -1347,14 +1681,14 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to change the description of a supergroup or a channel. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. + * Use this method to change the description of a group, a supergroup or a channel. * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String} description New chat title, 1-255 characters + * The bot **must be an administrator in the chat** for this to work and must have the appropriate admin rights. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String} description New chat title, 0-255 characters * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setchatdescription */ setChatDescription(chatId, description, form = {}) { @@ -1365,13 +1699,14 @@ class TelegramBot extends EventEmitter { /** * Use this method to pin a message in a supergroup. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. * - * @param {Number|String} chatId Unique identifier for the message recipient + * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator + * right in a supergroup or `can_edit_messages` administrator right in a channel. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Number} messageId Identifier of a message to pin * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#pinchatmessage */ pinChatMessage(chatId, messageId, form = {}) { @@ -1381,13 +1716,14 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to unpin a message in a supergroup chat. - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. + * Use this method to remove a message from the list of pinned messages in a chat * - * @param {Number|String} chatId Unique identifier for the message recipient + * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator + * right in a supergroup or `can_edit_messages` administrator right in a channel. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#unpinchatmessage */ unpinChatMessage(chatId, form = {}) { @@ -1396,13 +1732,14 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to clear the list of pinned messages in a chat - * The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. - * Returns True on success. + * Use this method to clear the list of pinned messages in a chat. * - * @param {Number|String} chatId Unique identifier for the message recipient + * If the chat is not a private chat, the **bot must be an administrator in the chat** for this to work and must have the `can_pin_messages` administrator + * right in a supergroup or `can_edit_messages` administrator right in a channel. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#unpinallchatmessages */ unpinAllChatMessages(chatId, form = {}) { @@ -1410,18 +1747,122 @@ class TelegramBot extends EventEmitter { return this._request('unpinAllChatMessages', { form }); } + /** + * Use this method for your bot to leave a group, supergroup or channel + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#leavechat + */ + leaveChat(chatId, form = {}) { + form.chat_id = chatId; + return this._request('leaveChat', { form }); + } + + /** + * Use this method to get up to date information about the chat + * (current name of the user for one-on-one conversations, current + * username of a user, group or channel, etc.). + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) or channel + * @param {Object} [options] Additional Telegram query options + * @return {Promise} [Chat](https://core.telegram.org/bots/api#chat) object on success + * @see https://core.telegram.org/bots/api#getchat + */ + getChat(chatId, form = {}) { + form.chat_id = chatId; + return this._request('getChat', { form }); + } + + /** + * Use this method to get a list of administrators in a chat + * + * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, returns an Array of [ChatMember](https://core.telegram.org/bots/api#chatmember) objects that contains information about all chat administrators except other bots. + * If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned + * @see https://core.telegram.org/bots/api#getchatadministrators + */ + getChatAdministrators(chatId, form = {}) { + form.chat_id = chatId; + return this._request('getChatAdministrators', { form }); + } + + /** + * Use this method to get the number of members in a chat. + * + * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup + * @param {Object} [options] Additional Telegram query options + * @return {Promise} Int on success + * @see https://core.telegram.org/bots/api#getchatmembercount + */ + getChatMemberCount(chatId, form = {}) { + form.chat_id = chatId; + return this._request('getChatMemberCount', { form }); + } + + /** + * Use this method to get information about a member of a chat. + * + * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup + * @param {Number} userId Unique identifier of the target user + * @param {Object} [options] Additional Telegram query options + * @return {Promise} [ChatMember](https://core.telegram.org/bots/api#chatmember) object on success + * @see https://core.telegram.org/bots/api#getchatmember + */ + getChatMember(chatId, userId, form = {}) { + form.chat_id = chatId; + form.user_id = userId; + return this._request('getChatMember', { form }); + } + + /** + * Use this method to set a new group sticker set for a supergroup. + * + * The bot **must be an administrator in the chat** for this to work and must have the appropriate administrator rights. + * + * **Note:** Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method. + * + * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) + * @param {String} stickerSetName Name of the sticker set to be set as the group sticker set + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#setchatstickerset + */ + setChatStickerSet(chatId, stickerSetName, form = {}) { + form.chat_id = chatId; + form.sticker_set_name = stickerSetName; + return this._request('setChatStickerSet', { form }); + } + + + /** + * Use this method to delete a group sticker set from a supergroup. + * + * Use the field `can_set_sticker_set` optionally returned in [getChat](https://core.telegram.org/bots/api#getchat) requests to check if the bot can use this method. + * + * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#deletechatstickerset + */ + deleteChatStickerSet(chatId, form = {}) { + form.chat_id = chatId; + return this._request('deleteChatStickerSet', { form }); + } + /** * Use this method to send answers to callback queries sent from - * inline keyboards. The answer will be displayed to the user as - * a notification at the top of the chat screen or as an alert. - * On success, True is returned. + * [inline keyboards](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating). + * + * The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. * * This method has **older, compatible signatures ([1][answerCallbackQuery-v0.27.1])([2][answerCallbackQuery-v0.29.0])** * that are being deprecated. * * @param {String} callbackQueryId Unique identifier for the query to be answered * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#answercallbackquery */ answerCallbackQuery(callbackQueryId, form = {}) { @@ -1453,113 +1894,99 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to set the result of an interaction with a Web App and send a corresponding message on behalf of the user to the chat from which the query originated. - * On success, a SentWebAppMessage object is returned. + * Use this method to change the list of the bot's commands. * - * @param {String} webAppQueryId Unique identifier for the query to be answered - * @param {InlineQueryResult} result object that represents one result of an inline query + * See https://core.telegram.org/bots#commands for more details about bot commands + * + * @param {Array} commands List of bot commands to be set as the list of the [bot's commands](https://core.telegram.org/bots/api#botcommand). At most 100 commands can be specified. * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#answercallbackquery + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#setmycommands */ - answerWebAppQuery(webAppQueryId, result, form = {}) { - form.web_app_query_id = webAppQueryId; - form.result = stringify(result); - return this._request('answerWebAppQuery', { form }); - } - - - /** - * Use this method to change the list of the bot's commands. - * Returns True on success. - * @param {Array} commands Poll options, between 2-10 options - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#setmycommands - */ setMyCommands(commands, form = {}) { form.commands = stringify(commands); return this._request('setMyCommands', { form }); } /** - * Use this method to get the current list of the bot's commands for the given scope and user language. - * Returns Array of BotCommand on success. If commands aren't set, an empty list is returned. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getmycommands - */ + * Use this method to delete the list of the bot's commands for the given scope and user language. + * + * After deletion, [higher level commands](https://core.telegram.org/bots/api#determining-list-of-commands) will be shown to affected users. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#deletemycommands + */ + deleteMyCommands(form = {}) { + return this._request('deleteMyCommands', { form }); + } + + + /** + * Use this method to get the current list of the bot's commands for the given scope and user language. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} Array of [BotCommand](https://core.telegram.org/bots/api#botcommand) on success. If commands aren't set, an empty list is returned. + * @see https://core.telegram.org/bots/api#getmycommands + */ getMyCommands(form = {}) { return this._request('getMyCommands', { form }); } /** - * Use this method to change the bot's menu button in a private chat, or the default menu button. - * Returns True on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#setchatmenubutton - */ + * Use this method to change the bot's menu button in a private chat, or the default menu button. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#setchatmenubutton + */ setChatMenuButton(form = {}) { return this._request('setChatMenuButton', { form }); } /** - * Use this method to get the current value of the bot's menu button in a private chat, or the default menu button. - * Returns MenuButton on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatmenubutton - */ + * Use this method to get the current value of the bot's menu button in a private chat, or the default menu button. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} [MenuButton](https://core.telegram.org/bots/api#menubutton) on success + * @see https://core.telegram.org/bots/api#getchatmenubutton + */ getChatMenuButton(form = {}) { return this._request('getChatMenuButton', { form }); } /** - * Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels. - * These rights will be suggested to users, but they are are free to modify the list before adding the bot. - * Returns True on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatmenubutton - */ + * Use this method to change the default administrator rights requested by the bot when it's added as an administrator to groups or channels. + * + * These rights will be suggested to users, but they are are free to modify the list before adding the bot. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#getchatmenubutton + */ setMyDefaultAdministratorRights(form = {}) { return this._request('setMyDefaultAdministratorRights', { form }); } /** - * Use this method to get the current default administrator rights of the bot. - * Returns ChatAdministratorRights on success. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getmydefaultadministratorrights - */ + * Use this method to get the current default administrator rights of the bot. + * + * @param {Object} [options] Additional Telegram query options + * @return {Promise} [ChatAdministratorRights](https://core.telegram.org/bots/api#chatadministratorrights) on success + * @see https://core.telegram.org/bots/api#getmydefaultadministratorrights + */ getMyDefaultAdministratorRights(form = {}) { return this._request('getMyDefaultAdministratorRights', { form }); } /** - * Returns True on success. - * Use this method to delete the list of the bot's commands for the given scope and user language. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#deletemycommands - */ - deleteMyCommands(form = {}) { - return this._request('deleteMyCommands', { form }); - } - - /** - * Use this method to edit text messages sent by the bot or via - * the bot (for inline bots). On success, the edited Message is - * returned. + * Use this method to edit text or [game](https://core.telegram.org/bots/api#games) messages sent by the bot or via the bot (for inline bots). * - * Note that you must provide one of chat_id, message_id, or - * inline_message_id in your request. + * Note: that **you must provide one of chat_id, message_id, or inline_message_id** in your request. * * @param {String} text New text of the message * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned * @see https://core.telegram.org/bots/api#editmessagetext */ editMessageText(text, form = {}) { @@ -1568,16 +1995,13 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to edit captions of messages sent by the - * bot or via the bot (for inline bots). On success, the - * edited Message is returned. + * Use this method to edit captions of messages sent by the bot or via the bot (for inline bots). * - * Note that you must provide one of chat_id, message_id, or - * inline_message_id in your request. + * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. * * @param {String} caption New caption of the message * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned * @see https://core.telegram.org/bots/api#editmessagecaption */ editMessageCaption(caption, form = {}) { @@ -1586,17 +2010,18 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to edit audio, document, photo, or video messages. + * Use this method to edit animation, audio, document, photo, or video messages. + * * If a message is a part of a message album, then it can be edited only to a photo or a video. + * * Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded. * Use previously uploaded file via its file_id or specify a URL. - * On success, the edited Message is returned. * - * Note that you must provide one of chat_id, message_id, or inline_message_id in your request. + * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. * * @param {Object} media A JSON-serialized object for a new media content of the message * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned * @see https://core.telegram.org/bots/api#editmessagemedia */ editMessageMedia(media, form = {}) { @@ -1630,7 +2055,7 @@ class TelegramBot extends EventEmitter { return Promise.reject(ex); } - opts.qs.media = JSON.stringify(payload); + opts.qs.media = stringify(payload); return this._request('editMessageMedia', opts); } @@ -1641,16 +2066,13 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to edit only the reply markup of messages - * sent by the bot or via the bot (for inline bots). - * On success, the edited Message is returned. + * Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). * - * Note that you must provide one of chat_id, message_id, or - * inline_message_id in your request. + * Note: You **must provide one of chat_id, message_id, or inline_message_id** in your request. * * @param {Object} replyMarkup A JSON-serialized object for an inline keyboard. * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} + * @return {Promise} On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned * @see https://core.telegram.org/bots/api#editmessagetext */ editMessageReplyMarkup(replyMarkup, form = {}) { @@ -1658,152 +2080,14 @@ class TelegramBot extends EventEmitter { return this._request('editMessageReplyMarkup', { form }); } - /** - * Use this method to get a list of profile pictures for a user. - * Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object. - * This method has an [older, compatible signature][getUserProfilePhotos-v0.25.0] - * that is being deprecated. - * - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getuserprofilephotos - */ - 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 */ - deprecate('The method signature getUserProfilePhotos(userId, offset, limit) has been deprecated since v0.25.0'); - form = { - offset: arguments[1], - limit: arguments[2], - }; - /* eslint-enable no-param-reassign, prefer-rest-params */ - } - form.user_id = userId; - return this._request('getUserProfilePhotos', { form }); - } /** - * Send location. - * Use this method to send point on the map. - * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {Float} latitude Latitude of location - * @param {Float} longitude Longitude of location - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendlocation - */ - sendLocation(chatId, latitude, longitude, form = {}) { - form.chat_id = chatId; - form.latitude = latitude; - form.longitude = longitude; - return this._request('sendLocation', { form }); - } - - /** - * Use this method to edit live location messages sent by - * the bot or via the bot (for inline bots). - * - * Note that you must provide one of chat_id, message_id, or - * inline_message_id in your request. - * - * @param {Float} latitude Latitude of location - * @param {Float} longitude Longitude of location - * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} - * @see https://core.telegram.org/bots/api#editmessagelivelocation - */ - editMessageLiveLocation(latitude, longitude, form = {}) { - form.latitude = latitude; - form.longitude = longitude; - return this._request('editMessageLiveLocation', { form }); - } - - /** - * Use this method to stop updating a live location message sent by - * the bot or via the bot (for inline bots) before live_period expires. - * - * Note that you must provide one of chat_id, message_id, or - * inline_message_id in your request. - * - * @param {Object} [options] Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) - * @return {Promise} - * @see https://core.telegram.org/bots/api#stopmessagelivelocation - */ - stopMessageLiveLocation(form = {}) { - return this._request('stopMessageLiveLocation', { form }); - } - - /** - * Send venue. - * Use this method to send information about a venue. - * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {Float} latitude Latitude of location - * @param {Float} longitude Longitude of location - * @param {String} title Name of the venue - * @param {String} address Address of the venue - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendvenue - */ - sendVenue(chatId, latitude, longitude, title, address, form = {}) { - form.chat_id = chatId; - form.latitude = latitude; - form.longitude = longitude; - form.title = title; - form.address = address; - return this._request('sendVenue', { form }); - } - - /** - * Send contact. - * Use this method to send phone contacts. - * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String} phoneNumber Contact's phone number - * @param {String} firstName Contact's first name - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendcontact - */ - sendContact(chatId, phoneNumber, firstName, form = {}) { - form.chat_id = chatId; - form.phone_number = phoneNumber; - form.first_name = firstName; - return this._request('sendContact', { form }); - } - - /** - * Send poll. - * Use this method to send a native poll. - * - * @param {Number|String} chatId Unique identifier for the group/channel - * @param {String} question Poll question, 255 char limit - * @param {Array} pollOptions Poll options, between 2-10 options - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendpoll - */ - sendPoll(chatId, question, pollOptions, form = {}) { - form.chat_id = chatId; - form.question = question; - form.options = stringify(pollOptions); - return this._request('sendPoll', { form }); - } - - /** - * Stop poll. - * Use this method to stop a native poll. + * Use this method to stop a poll which was sent by the bot. * * @param {Number|String} chatId Unique identifier for the group/channel * @param {Number} pollId Identifier of the original message with the poll * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} On success, the stopped [Poll](https://core.telegram.org/bots/api#poll) is returned * @see https://core.telegram.org/bots/api#stoppoll */ stopPoll(chatId, pollId, form = {}) { @@ -1813,333 +2097,19 @@ class TelegramBot extends EventEmitter { } /** - * Get file. - * Use this method to get basic info about a file and prepare it for downloading. - * Attention: link will be valid for 1 hour. + * Use this method to delete a message, including service messages, with the following limitations: + * - A message can only be deleted if it was sent less than 48 hours ago. + * - A dice message can only be deleted if it was sent more than 24 hours ago. + * - Bots can delete outgoing messages in groups and supergroups. + * - Bots can delete incoming messages in groups, supergroups and channels. + * - Bots granted `can_post_messages` permissions can delete outgoing messages in channels. + * - If the bot is an administrator of a group, it can delete any message there. + * - If the bot has `can_delete_messages` permission in a supergroup, it can delete any message there. * - * @param {String} fileId File identifier to get info about - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getfile - */ - getFile(fileId, form = {}) { - form.file_id = fileId; - return this._request('getFile', { form }); - } - - /** - * Get link for file. - * Use this method to get link for file for subsequent use. - * Attention: link will be valid for 1 hour. - * - * This method is a sugar extension of the (getFile)[#getfilefileid] method, - * which returns just path to file on remote server (you will have to manually build full uri after that). - * - * @param {String} fileId File identifier to get info about - * @param {Object} [options] Additional Telegram query options - * @return {Promise} promise Promise which will have *fileURI* in resolve callback - * @see https://core.telegram.org/bots/api#getfile - */ - getFileLink(fileId, form = {}) { - return this.getFile(fileId, form) - .then(resp => `${this.options.baseApiUrl}/file/bot${this.token}/${resp.file_path}`); - } - - /** - * Return a readable stream for file. - * - * `fileStream.path` is the specified file ID i.e. `fileId`. - * `fileStream` emits event `info` passing a single argument i.e. - * `info` with the interface `{ uri }` where `uri` is the URI of the - * file on Telegram servers. - * - * This method is a sugar extension of the [getFileLink](#TelegramBot+getFileLink) method, - * which returns the full URI to the file on remote server. - * - * @param {String} fileId File identifier to get info about - * @param {Object} [options] Additional Telegram query options - * @return {stream.Readable} fileStream - */ - getFileStream(fileId, form = {}) { - const fileStream = new stream.PassThrough(); - fileStream.path = fileId; - this.getFileLink(fileId, form) - .then((fileURI) => { - fileStream.emit('info', { - uri: fileURI, - }); - pump(streamedRequest(Object.assign({ uri: fileURI }, this.options.request)), fileStream); - }) - .catch((error) => { - fileStream.emit('error', error); - }); - return fileStream; - } - - /** - * Downloads file in the specified folder. - * - * This method is a sugar extension of the [getFileStream](#TelegramBot+getFileStream) method, - * which returns a readable file stream. - * - * @param {String} fileId File identifier to get info about - * @param {String} downloadDir Absolute path to the folder in which file will be saved - * @param {Object} [options] Additional Telegram query options - * @return {Promise} promise Promise, which will have *filePath* of downloaded file in resolve callback - */ - downloadFile(fileId, downloadDir, form = {}) { - let resolve; - let reject; - const promise = new Promise((a, b) => { - resolve = a; - reject = b; - }); - const fileStream = this.getFileStream(fileId, form); - fileStream.on('info', (info) => { - const fileName = info.uri.slice(info.uri.lastIndexOf('/') + 1); - // TODO: Ensure fileName doesn't contains slashes - const filePath = path.join(downloadDir, fileName); - pump(fileStream, fs.createWriteStream(filePath), (error) => { - if (error) { return reject(error); } - return resolve(filePath); - }); - }); - fileStream.on('error', (err) => { - reject(err); - }); - return promise; - } - - /** - * Register a RegExp to test against an incomming text message. - * @param {RegExp} regexp RegExp to be executed with `exec`. - * @param {Function} callback Callback will be called with 2 parameters, - * the `msg` and the result of executing `regexp.exec` on message text. - */ - onText(regexp, callback) { - this._textRegexpCallbacks.push({ regexp, callback }); - } - - /** - * Remove a listener registered with `onText()`. - * @param {RegExp} regexp RegExp used previously in `onText()` - * @return {Object} deletedListener The removed reply listener if - * found. This object has `regexp` and `callback` - * properties. If not found, returns `null`. - */ - removeTextListener(regexp) { - const index = this._textRegexpCallbacks.findIndex((textListener) => { - return String(textListener.regexp) === String(regexp); - }); - if (index === -1) { - return null; - } - return this._textRegexpCallbacks.splice(index, 1)[0]; - } - - /** - * Remove all listeners registered with `onText()`. - */ - clearTextListeners() { - this._textRegexpCallbacks = []; - } - - /** - * Register a reply to wait for a message response. - * @param {Number|String} chatId The chat id where the message cames from. - * @param {Number|String} messageId The message id to be replied. - * @param {Function} callback Callback will be called with the reply - * message. - * @return {Number} id The ID of the inserted reply listener. - */ - onReplyToMessage(chatId, messageId, callback) { - const id = ++this._replyListenerId; - this._replyListeners.push({ - id, - chatId, - messageId, - callback - }); - return id; - } - - /** - * Removes a reply that has been prev. registered for a message response. - * @param {Number} replyListenerId The ID of the reply listener. - * @return {Object} deletedListener The removed reply listener if - * found. This object has `id`, `chatId`, `messageId` and `callback` - * properties. If not found, returns `null`. - */ - removeReplyListener(replyListenerId) { - const index = this._replyListeners.findIndex((replyListener) => { - return replyListener.id === replyListenerId; - }); - if (index === -1) { - return null; - } - return this._replyListeners.splice(index, 1)[0]; - } - - /** - * Removes all replies that have been prev. registered for a message response. - */ - clearReplyListeners() { - this._replyListeners = []; - } - - /** - * Use this method to get up to date information about the chat - * (current name of the user for one-on-one conversations, current - * username of a user, group or channel, etc.). - * @param {Number|String} chatId Unique identifier for the target chat or username of the target supergroup or channel - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchat - */ - getChat(chatId, form = {}) { - form.chat_id = chatId; - return this._request('getChat', { form }); - } - - /** - * Returns the administrators in a chat in form of an Array of `ChatMember` objects. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatadministrators - */ - getChatAdministrators(chatId, form = {}) { - form.chat_id = chatId; - return this._request('getChatAdministrators', { form }); - } - - /** - * Use this method to get the number of members in a chat. - * Returns Int on success. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatmemberscount - * @deprecated Deprecated since Telegram Bot API v5.3, replace it with "getChatMembersCount" - */ - getChatMembersCount(chatId, form = {}) { - deprecate('The method "getChatMembersCount" is deprecated since Telegram Bot API v5.3, replace it with "getChatMemberCount"'); - - form.chat_id = chatId; - return this._request('getChatMembersCount', { form }); - } - - /** - * Use this method to get the number of members in a chat. - * Returns Int on success - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatmembercount - */ - getChatMemberCount(chatId, form = {}) { - form.chat_id = chatId; - return this._request('getChatMemberCount', { form }); - } - - /** - * Use this method to get information about a member of a chat. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getchatmember - */ - getChatMember(chatId, userId, form = {}) { - form.chat_id = chatId; - form.user_id = userId; - return this._request('getChatMember', { form }); - } - - /** - * Leave a group, supergroup or channel. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#leavechat - */ - leaveChat(chatId, form = {}) { - form.chat_id = chatId; - return this._request('leaveChat', { form }); - } - - /** - * Use this method to set a new group sticker set for a supergroup. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) - * @param {String} stickerSetName Name of the sticker set to be set as the group sticker set - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#setchatstickerset - */ - setChatStickerSet(chatId, stickerSetName, form = {}) { - form.chat_id = chatId; - form.sticker_set_name = stickerSetName; - return this._request('setChatStickerSet', { form }); - } - - /** - * Use this method to delete a group sticker set from a supergroup. - * @param {Number|String} chatId Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#deletechatstickerset - */ - deleteChatStickerSet(chatId, form = {}) { - form.chat_id = chatId; - return this._request('deleteChatStickerSet', { form }); - } - - /** - * Use this method to send a game. - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String} gameShortName name of the game to be sent. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendgame - */ - sendGame(chatId, gameShortName, form = {}) { - form.chat_id = chatId; - form.game_short_name = gameShortName; - return this._request('sendGame', { form }); - } - - /** - * Use this method to set the score of the specified user in a game. - * @param {Number} userId Unique identifier of the target user - * @param {Number} score New score value. - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#setgamescore - */ - setGameScore(userId, score, form = {}) { - form.user_id = userId; - form.score = score; - return this._request('setGameScore', { form }); - } - - /** - * Use this method to get data for high score table. - * @param {Number} userId Unique identifier of the target user - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#getgamehighscores - */ - getGameHighScores(userId, form = {}) { - form.user_id = userId; - return this._request('getGameHighScores', { form }); - } - - /** - * Use this method to delete a message. * @param {Number|String} chatId Unique identifier of the target chat * @param {Number} messageId Unique identifier of the target message * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#deletemessage */ deleteMessage(chatId, messageId, form = {}) { @@ -2149,97 +2119,37 @@ class TelegramBot extends EventEmitter { } /** - * Send invoice. - * Use this method to send an invoice. - * - * @param {Number|String} chatId Unique identifier for the message recipient - * @param {String} title Product name - * @param {String} description product description - * @param {String} payload Bot defined invoice payload - * @param {String} providerToken Payments provider token - * @param {String} startParameter Deep-linking parameter - * @param {String} currency Three-letter ISO 4217 currency code - * @param {Array} prices Breakdown of prices + * Use this method to send static .WEBP, [animated](https://telegram.org/blog/animated-stickers) .TGS, + * or [video](https://telegram.org/blog/video-stickers-better-reactions) .WEBM stickers. + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String|stream.Stream|Buffer} sticker A file path, Stream or Buffer. + * Can also be a `file_id` previously uploaded. Stickers are WebP format files. * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendinvoice + * @param {Object} [fileOptions] Optional file related meta-data + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned + * @see https://core.telegram.org/bots/api#sendsticker */ - sendInvoice(chatId, title, description, payload, providerToken, startParameter, currency, prices, form = {}) { - form.chat_id = chatId; - form.title = title; - form.description = description; - form.payload = payload; - form.provider_token = providerToken; - form.start_parameter = startParameter; - form.currency = currency; - form.prices = stringify(prices); - form.provider_data = stringify(form.provider_data); - return this._request('sendInvoice', { form }); + sendSticker(chatId, sticker, options = {}, fileOptions = {}) { + const opts = { + qs: options + }; + opts.qs.chat_id = chatId; + try { + const sendData = this._formatSendData('sticker', sticker, fileOptions); + opts.formData = sendData[0]; + opts.qs.sticker = sendData[1]; + } catch (ex) { + return Promise.reject(ex); + } + return this._request('sendSticker', opts); } /** - * Create Invoice Link - * Use this method to create a link for an invoice. Returns the created invoice link as String on success. - * - * @param {String} title Product name, 1-32 characters - * @param {String} description Product description, 1-255 characters - * @param {String} payload Bot defined invoice payload - * @param {String} providerToken Payment provider token - * @param {String} currency Three-letter ISO 4217 currency code - * @param {Array} prices Breakdown of prices - * @param {Object} [options] Additional Telegram query options - * @returns {String} - * @see https://core.telegram.org/bots/api#createinvoicelink - */ - createInvoiceLink(title, description, payload, providerToken, currency, prices, form = {}) { - form.title = title; - form.description = description; - form.payload = payload; - form.provider_token = providerToken; - form.currency = currency; - form.prices = stringify(prices); - return this._request('createInvoiceLink', { form }); - } - - /** - * Answer shipping query. - * Use this method to reply to shipping queries. - * - * @param {String} shippingQueryId Unique identifier for the query to be answered - * @param {Boolean} ok Specify if delivery of the product is possible - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#answershippingquery - */ - answerShippingQuery(shippingQueryId, ok, form = {}) { - form.shipping_query_id = shippingQueryId; - form.ok = ok; - form.shipping_options = stringify(form.shipping_options); - return this._request('answerShippingQuery', { form }); - } - - /** - * Answer pre-checkout query. - * Use this method to confirm shipping of a product. - * - * @param {String} preCheckoutQueryId Unique identifier for the query to be answered - * @param {Boolean} ok Specify if every order details are ok - * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#answerprecheckoutquery - */ - answerPreCheckoutQuery(preCheckoutQueryId, ok, form = {}) { - form.pre_checkout_query_id = preCheckoutQueryId; - form.ok = ok; - return this._request('answerPreCheckoutQuery', { form }); - } - - /** - * Use this method to get a sticker set. On success, a [StickerSet](https://core.telegram.org/bots/api#stickerset) object is returned. + * Use this method to get a sticker set. * * @param {String} name Name of the sticker set * @param {Object} [options] Additional Telegram query options - * @return {Promise} + * @return {Promise} On success, a [StickerSet](https://core.telegram.org/bots/api#stickerset) object is returned * @see https://core.telegram.org/bots/api#getstickerset */ getStickerSet(name, form = {}) { @@ -2248,15 +2158,15 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to upload a .png file with a sticker for later use in *createNewStickerSet* and *addStickerToSet* methods (can be used multiple - * times). Returns the uploaded [File](https://core.telegram.org/bots/api#file) on success. + * Use this method to upload a .png file with a sticker for later use in *createNewStickerSet* and *addStickerToSet* methods (can be used multiple + * times). * * @param {Number} userId User identifier of sticker file owner * @param {String|stream.Stream|Buffer} pngSticker A file path or a Stream. Can also be a `file_id` previously uploaded. **Png** image with the * sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} On success, a [File](https://core.telegram.org/bots/api#file) object is returned * @see https://core.telegram.org/bots/api#uploadstickerfile */ uploadStickerFile(userId, pngSticker, options = {}, fileOptions = {}) { @@ -2276,20 +2186,22 @@ class TelegramBot extends EventEmitter { /** * Use this method to create new sticker set owned by a user. + * * The bot will be able to edit the created sticker set. - * Returns True on success. + * + * You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker* * * @param {Number} userId User identifier of created sticker set owner - * @param {String} name Short name of sticker set, to be used in `t.me/addstickers/` URLs (e.g., *animals*) + * @param {String} name Short name of sticker set, to be used in `t.me/addstickers/` URLs (e.g., *"animals"*). Can contain only english letters, digits and underscores. + * Must begin with a letter, can't contain consecutive underscores and must end in `.` is case insensitive. 1-64 characters. * @param {String} title Sticker set title, 1-64 characters * @param {String|stream.Stream|Buffer} pngSticker Png image with the sticker, must be up to 512 kilobytes in size, * dimensions must not exceed 512px, and either width or height must be exactly 512px. * @param {String} emojis One or more emoji corresponding to the sticker * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#createnewstickerset - * @todo Add tests for this method! */ createNewStickerSet(userId, name, title, pngSticker, emojis, options = {}, fileOptions = {}) { const opts = { @@ -2312,20 +2224,26 @@ class TelegramBot extends EventEmitter { /** * Use this method to add a new sticker to a set created by the bot. - * Returns True on success. + * + * You must use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker* + * + * Animated stickers can be added to animated sticker sets and only to them: + * - Animated sticker sets can have up to 50 stickers. + * - Static sticker sets can have up to 120 stickers * * @param {Number} userId User identifier of sticker set owner * @param {String} name Sticker set name - * @param {String|stream.Stream|Buffer} pngSticker Png image with the sticker, must be up to 512 kilobytes in size, - * dimensions must not exceed 512px, and either width or height must be exactly 512px + * @param {String|stream.Stream|Buffer} sticker Png image with the sticker (must be up to 512 kilobytes in size, + * dimensions must not exceed 512px, and either width or height must be exactly 512px, [TGS animation](https://core.telegram.org/stickers#animated-sticker-requirements) + * with the sticker or [WEBM video](https://core.telegram.org/stickers#video-sticker-requirements) with the sticker. * @param {String} emojis One or more emoji corresponding to the sticker + * @param {String} stickerType Allow values: `png_sticker`, `tgs_sticker`, or `webm_sticker`. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#addstickertoset - * @todo Add tests for this method! */ - addStickerToSet(userId, name, pngSticker, emojis, options = {}, fileOptions = {}) { + addStickerToSet(userId, name, sticker, emojis, stickerType = 'png_sticker', options = {}, fileOptions = {}) { const opts = { qs: options, }; @@ -2333,30 +2251,68 @@ class TelegramBot extends EventEmitter { opts.qs.name = name; opts.qs.emojis = emojis; opts.qs.mask_position = stringify(options.mask_position); + + if (typeof stickerType !== 'string' || ['png_sticker', 'tgs_sticker', 'webm_sticker'].indexOf(stickerType) === -1) { + return Promise.reject(new Error('stickerType must be a string and the allow types is: png_sticker, tgs_sticker, webm_sticker')); + } + try { - const sendData = this._formatSendData('png_sticker', pngSticker, fileOptions); + const sendData = this._formatSendData(stickerType, sticker, fileOptions); opts.formData = sendData[0]; - opts.qs.png_sticker = sendData[1]; + opts.qs[stickerType] = sendData[1]; } catch (ex) { return Promise.reject(ex); } return this._request('addStickerToSet', opts); } + /** + * Use this method to move a sticker in a set created by the bot to a specific position. + * + * @param {String} sticker File identifier of the sticker + * @param {Number} position New sticker position in the set, zero-based + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#setstickerpositioninset + */ + setStickerPositionInSet(sticker, position, form = {}) { + form.sticker = sticker; + form.position = position; + return this._request('setStickerPositionInSet', { form }); + } + + /** + * Use this method to delete a sticker from a set created by the bot. + * + * @param {String} sticker File identifier of the sticker + * @param {Object} [options] Additional Telegram query options + * @return {Promise} True on success + * @see https://core.telegram.org/bots/api#deletestickerfromset + * @todo Add tests for this method! + */ + deleteStickerFromSet(sticker, form = {}) { + form.sticker = sticker; + return this._request('deleteStickerFromSet', { form }); + } + + /** * Use this method to add a thumb to a set created by the bot. - * Returns True on success. + * + * Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only * * @param {Number} userId User identifier of sticker set owner * @param {String} name Sticker set name * @param {String|stream.Stream|Buffer} pngThumb A PNG image with the thumbnail, * must be up to 128 kilobytes in size and have width and height exactly 100px, - * or a TGS animation with the thumbnail up to 32 kilobytes in size; + * a TGS animation with the thumbnail up to 32 kilobytes in size or a WEBM video with the thumbnail up to 32 kilobytes in size. + * + * Pass a file_id as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram + * to get a file from the Internet, or upload a new one. Animated sticker set thumbnails can't be uploaded via HTTP URL. * @param {Object} [options] Additional Telegram query options * @param {Object} [fileOptions] Optional file related meta-data - * @return {Promise} + * @return {Promise} True on success * @see https://core.telegram.org/bots/api#setstickersetthumb - * @todo Add tests for this method! */ setStickerSetThumb(userId, name, pngThumb, options = {}, fileOptions = {}) { const opts = { @@ -2376,83 +2332,169 @@ class TelegramBot extends EventEmitter { } /** - * Use this method to move a sticker in a set created by the bot to a specific position. - * Returns True on success. + * Send answers to an inline query. * - * @param {String} sticker File identifier of the sticker - * @param {Number} position New sticker position in the set, zero-based + * Note: No more than 50 results per query are allowed. + * + * @param {String} inlineQueryId Unique identifier of the query + * @param {InlineQueryResult[]} results An array of results for the inline query * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#setstickerpositioninset - * @todo Add tests for this method! + * @return {Promise} On success, True is returned + * @see https://core.telegram.org/bots/api#answerinlinequery */ - setStickerPositionInSet(sticker, position, form = {}) { - form.sticker = sticker; - form.position = position; - return this._request('setStickerPositionInSet', { form }); + answerInlineQuery(inlineQueryId, results, form = {}) { + form.inline_query_id = inlineQueryId; + form.results = stringify(results); + return this._request('answerInlineQuery', { form }); } /** - * Use this method to delete a sticker from a set created by the bot. - * Returns True on success. + * Use this method to set the result of an interaction with a [Web App](https://core.telegram.org/bots/webapps) + * and send a corresponding message on behalf of the user to the chat from which the query originated. * - * @param {String} sticker File identifier of the sticker + * @param {String} webAppQueryId Unique identifier for the query to be answered + * @param {InlineQueryResult} result object that represents one result of an inline query * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#deletestickerfromset - * @todo Add tests for this method! + * @return {Promise} On success, a [SentWebAppMessage](https://core.telegram.org/bots/api#sentwebappmessage) object is returned + * @see https://core.telegram.org/bots/api#answerwebappquery */ - deleteStickerFromSet(sticker, form = {}) { - form.sticker = sticker; - return this._request('deleteStickerFromSet', { form }); + answerWebAppQuery(webAppQueryId, result, form = {}) { + form.web_app_query_id = webAppQueryId; + form.result = stringify(result); + return this._request('answerWebAppQuery', { form }); } /** - * Use this method to send a group of photos or videos as an album. - * On success, an array of the sent [Messages](https://core.telegram.org/bots/api#message) - * is returned. + * Use this method to send an invoice. * - * If you wish to [specify file options](https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files), - * add a `fileOptions` property to the target input in `media`. - * - * @param {String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) - * @param {Array} media A JSON-serialized array describing photos and videos to be sent, must include 2–10 items + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String} title Product name, 1-32 characters + * @param {String} description Product description, 1-255 characters + * @param {String} payload Bot defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. + * @param {String} providerToken Payments provider token, obtained via `@BotFather` + * @param {String} currency Three-letter ISO 4217 currency code + * @param {Array} prices Breakdown of prices * @param {Object} [options] Additional Telegram query options - * @return {Promise} - * @see https://core.telegram.org/bots/api#sendmediagroup - * @see https://github.com/yagop/node-telegram-bot-api/blob/master/doc/usage.md#sending-files + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned + * @see https://core.telegram.org/bots/api#sendinvoice */ - sendMediaGroup(chatId, media, options = {}) { - const opts = { - qs: options, - }; - opts.qs.chat_id = chatId; + sendInvoice(chatId, title, description, payload, providerToken, currency, prices, form = {}) { + form.chat_id = chatId; + form.title = title; + form.description = description; + form.payload = payload; + form.provider_token = providerToken; + form.currency = currency; + form.prices = stringify(prices); + form.provider_data = stringify(form.provider_data); + return this._request('sendInvoice', { form }); + } - opts.formData = {}; - const inputMedia = []; - let index = 0; - for (const input of media) { - const payload = Object.assign({}, input); - delete payload.media; - delete payload.fileOptions; - try { - const attachName = String(index); - const [formData, fileId] = this._formatSendData(attachName, input.media, input.fileOptions); - if (formData) { - opts.formData[attachName] = formData[attachName]; - payload.media = `attach://${attachName}`; - } else { - payload.media = fileId; - } - } catch (ex) { - return Promise.reject(ex); - } - inputMedia.push(payload); - index++; - } - opts.qs.media = JSON.stringify(inputMedia); + /** + * Use this method to create a link for an invoice. + * + * @param {String} title Product name, 1-32 characters + * @param {String} description Product description, 1-255 characters + * @param {String} payload Bot defined invoice payload + * @param {String} providerToken Payment provider token + * @param {String} currency Three-letter ISO 4217 currency code + * @param {Array} prices Breakdown of prices + * @param {Object} [options] Additional Telegram query options + * @returns {Promise} The created invoice link as String on success. + * @see https://core.telegram.org/bots/api#createinvoicelink + */ + createInvoiceLink(title, description, payload, providerToken, currency, prices, form = {}) { + form.title = title; + form.description = description; + form.payload = payload; + form.provider_token = providerToken; + form.currency = currency; + form.prices = stringify(prices); + return this._request('createInvoiceLink', { form }); + } - return this._request('sendMediaGroup', opts); + /** + * Use this method to reply to shipping queries. + * + * If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, + * the Bot API will send an [Update](https://core.telegram.org/bots/api#update) with a shipping_query field to the bot + * + * @param {String} shippingQueryId Unique identifier for the query to be answered + * @param {Boolean} ok Specify if delivery of the product is possible + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, True is returned + * @see https://core.telegram.org/bots/api#answershippingquery + */ + answerShippingQuery(shippingQueryId, ok, form = {}) { + form.shipping_query_id = shippingQueryId; + form.ok = ok; + form.shipping_options = stringify(form.shipping_options); + return this._request('answerShippingQuery', { form }); + } + + /** + * Use this method to respond to such pre-checkout queries + * + * Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of + * an [Update](https://core.telegram.org/bots/api#update) with the field *pre_checkout_query*. + * + * **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. + * + * @param {String} preCheckoutQueryId Unique identifier for the query to be answered + * @param {Boolean} ok Specify if every order details are ok + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, True is returned + * @see https://core.telegram.org/bots/api#answerprecheckoutquery + */ + answerPreCheckoutQuery(preCheckoutQueryId, ok, form = {}) { + form.pre_checkout_query_id = preCheckoutQueryId; + form.ok = ok; + return this._request('answerPreCheckoutQuery', { form }); + } + + /** + * Use this method to send a game. + * + * @param {Number|String} chatId Unique identifier for the target chat or username of the target channel (in the format `@channelusername`) + * @param {String} gameShortName name of the game to be sent. Set up your games via `@BotFather`. + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned + * @see https://core.telegram.org/bots/api#sendgame + */ + sendGame(chatId, gameShortName, form = {}) { + form.chat_id = chatId; + form.game_short_name = gameShortName; + return this._request('sendGame', { form }); + } + + /** + * Use this method to set the score of the specified user in a game message. + * + * @param {Number} userId Unique identifier of the target user + * @param {Number} score New score value, must be non-negative + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, if the message is not an inline message, the [Message](https://core.telegram.org/bots/api#message) is returned, otherwise True is returned + * @see https://core.telegram.org/bots/api#setgamescore + */ + setGameScore(userId, score, form = {}) { + form.user_id = userId; + form.score = score; + return this._request('setGameScore', { form }); + } + + /** + * Use this method to get data for high score tables. + * + * Will return the score of the specified user and several of their neighbors in a game. + * + * @param {Number} userId Unique identifier of the target user + * @param {Object} [options] Additional Telegram query options + * @return {Promise} On success, returns an Array of [GameHighScore](https://core.telegram.org/bots/api#gamehighscore) objects + * @see https://core.telegram.org/bots/api#getgamehighscores + */ + getGameHighScores(userId, form = {}) { + form.user_id = userId; + return this._request('getGameHighScores', { form }); } } diff --git a/test/telegram.js b/test/telegram.js index 2f6b726..060ab05 100644 --- a/test/telegram.js +++ b/test/telegram.js @@ -48,6 +48,8 @@ let FILE_ID; let GAME_CHAT_ID; let GAME_MSG_ID; let BOT_USERNAME; +let CHAT_INFO; +let STICKER_FILE_ID_FROM_SET; before(function beforeAll() { utils.startStaticServer(staticPort); @@ -105,6 +107,9 @@ describe('TelegramBot', function telegramSuite() { utils.handleRatelimit(bot, 'sendPhoto', this); utils.handleRatelimit(bot, 'sendMessage', this); utils.handleRatelimit(bot, 'sendGame', this); + utils.handleRatelimit(bot, 'getMe', this); + utils.handleRatelimit(bot, 'getChat', this); + return bot.sendPhoto(USERID, FILE_PATH).then(resp => { FILE_ID = resp.photo[0].file_id; return bot.sendMessage(USERID, 'chat'); @@ -117,7 +122,10 @@ describe('TelegramBot', function telegramSuite() { return bot.getMe().then(resp => { BOT_USERNAME = resp.username; }); - }); + }).then(() => + bot.getChat(GROUPID).then(resp => { + CHAT_INFO = resp; + })); }); it('automatically starts polling', function test() { @@ -372,18 +380,6 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe('#getMe', function getMeSuite() { - before(function before() { - utils.handleRatelimit(bot, 'getMe', this); - }); - it('should return an User object', function test() { - return bot.getMe().then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.number(resp.id)); - assert.ok(is.string(resp.first_name)); - }); - }); - }); describe('#setWebHook', function setWebHookSuite() { before(function before() { @@ -419,17 +415,6 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe('#deleteWebHook', function deleteWebHookSuite() { - before(function before() { - utils.handleRatelimit(bot, 'deleteWebHook', this); - }); - it('should delete webhook', function test() { - return bot.deleteWebHook().then(resp => { - assert.strictEqual(resp, true); - }); - }); - }); - describe('#getWebHookInfo', function getWebHookInfoSuite() { before(function before() { utils.handleRatelimit(bot, 'getWebHookInfo', this); @@ -443,6 +428,17 @@ describe('TelegramBot', function telegramSuite() { }); }); + describe('#deleteWebHook', function deleteWebHookSuite() { + before(function before() { + utils.handleRatelimit(bot, 'deleteWebHook', this); + }); + it('should delete webhook', function test() { + return bot.deleteWebHook().then(resp => { + assert.strictEqual(resp, true); + }); + }); + }); + describe('#getUpdates', function getUpdatesSuite() { const opts = { timeout: 0, @@ -465,6 +461,140 @@ describe('TelegramBot', function telegramSuite() { }); }); + describe('#getMe', function getMeSuite() { + before(function before() { + utils.handleRatelimit(bot, 'getMe', this); + }); + it('should return an User object', function test() { + return bot.getMe().then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.number(resp.id)); + assert.ok(is.string(resp.first_name)); + }); + }); + }); + + describe('#getFileLink', function getFileLinkSuite() { + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'getFileLink', this); + }); + it('should get a file link', function test() { + return bot.getFileLink(FILE_ID) + .then(fileURI => { + assert.ok(is.string(fileURI)); + assert.ok(utils.isTelegramFileURI(fileURI)); + }); + }); + }); + + describe('#getFileStream', function getFileStreamSuite() { + this.timeout(timeout); + before(function before() { + // utils.handleRatelimit(bot, 'getFileStream', this); + }); + it('should get a file stream', function test(done) { + const fileStream = bot.getFileStream(FILE_ID); + assert.ok(fileStream instanceof stream.Readable); + assert.strictEqual(fileStream.path, FILE_ID); + fileStream.on('info', (info) => { + assert.ok(info); + assert.ok(utils.isTelegramFileURI(info.uri), `${info.uri} is not a file URI`); + fileStream.pipe(concat(function readFile(buffer) { + buffer.equals(fs.readFileSync(FILE_PATH)); // sync :( + return done(); + })); + }); + }); + }); + + describe('#downloadFile', function downloadFileSuite() { + const downloadPath = os.tmpdir(); + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'downloadFile', this); + }); + it('should download a file', function test() { + return bot.downloadFile(FILE_ID, downloadPath) + .then(filePath => { + assert.ok(is.string(filePath)); + assert.strictEqual(path.dirname(filePath), downloadPath); + assert.ok(fs.existsSync(filePath)); + fs.unlinkSync(filePath); // Delete file after test + }); + }); + }); + + describe('#onText', function onTextSuite() { + it('should call `onText` callback on match', function test(done) { + const regexp = /\/onText (.+)/; + botWebHook.onText(regexp, (msg, match) => { + assert.strictEqual(match[1], 'ECHO ALOHA'); + assert.ok(botWebHook.removeTextListener(regexp)); + return done(); + }); + utils.sendWebHookMessage(webHookPort2, TOKEN, { + message: { text: '/onText ECHO ALOHA' }, + }); + }); + it('should reset the global regex state with each message', function test(done) { + const regexp = /\/onText (.+)/g; + botWebHook.onText(regexp, () => { + assert.strictEqual(regexp.lastIndex, 0); + assert.ok(botWebHook.removeTextListener(regexp)); + return done(); + }); + utils.sendWebHookMessage(webHookPort2, TOKEN, { + message: { text: '/onText ECHO ALOHA' }, + }); + }); + }); + + describe('#removeTextListener', function removeTextListenerSuite() { + const regexp = /\/onText/; + const regexp2 = /\/onText/; + const callback = function noop() { }; + after(function after() { + bot.removeTextListener(regexp); + bot.removeTextListener(regexp2); + }); + it('removes the right text-listener', function test() { + bot.onText(regexp, callback); + bot.onText(regexp2, callback); + const textListener = bot.removeTextListener(regexp); + assert.strictEqual(regexp, textListener.regexp); + }); + it('returns `null` if missing', function test() { + assert.strictEqual(null, bot.removeTextListener(/404/)); + }); + }); + + describe.skip('#onReplyToMessage', function onReplyToMessageSuite() { }); + + describe('#removeReplyListener', function removeReplyListenerSuite() { + const chatId = -1234; + const messageId = 1; + const callback = function noop() { }; + it('returns the right reply-listener', function test() { + const id = bot.onReplyToMessage(chatId, messageId, callback); + const replyListener = bot.removeReplyListener(id); + assert.strictEqual(id, replyListener.id); + assert.strictEqual(chatId, replyListener.chatId); + assert.strictEqual(messageId, replyListener.messageId); + assert.strictEqual(callback, replyListener.callback); + }); + it('returns `null` if missing', function test() { + // NOTE: '0' is never a valid reply listener ID :) + assert.strictEqual(null, bot.removeReplyListener(0)); + }); + }); + + /** Telegram Bot API Methods */ + + describe.skip('#logOut', function logOutSuite() { }); + + describe.skip('#close', function closeSuite() { }); + describe('#sendMessage', function sendMessageSuite() { before(function before() { utils.handleRatelimit(bot, 'sendMessage', this); @@ -477,8 +607,6 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe.skip('#answerInlineQuery', function answerInlineQuerySuite() { }); - describe('#forwardMessage', function forwardMessageSuite() { before(function before() { utils.handleRatelimit(bot, 'sendMessage', this); @@ -658,50 +786,6 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe('#sendSticker', function sendStickerSuite() { - let stickerId; - this.timeout(timeout); - before(function before() { - utils.handleRatelimit(bot, 'sendSticker', this); - }); - it('should send a sticker from file', function test() { - const sticker = `${__dirname}/data/sticker.webp`; - return bot.sendSticker(USERID, sticker).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.sticker)); - stickerId = resp.sticker.file_id; - }); - }); - it('should send a sticker from id', function test() { - // Send the same photo as before - return bot.sendSticker(USERID, stickerId).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.sticker)); - }); - }); - it('should send a sticker from fs.readStream', function test() { - const sticker = fs.createReadStream(`${__dirname}/data/sticker.webp`); - return bot.sendSticker(USERID, sticker).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.sticker)); - }); - }); - it('should send a sticker from request Stream', function test() { - const sticker = request(`${staticUrl}/sticker.webp`); - return bot.sendSticker(USERID, sticker).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.sticker)); - }); - }); - it('should send a sticker from a Buffer', function test() { - const sticker = fs.readFileSync(`${__dirname}/data/sticker.webp`); - return bot.sendSticker(USERID, sticker).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.sticker)); - }); - }); - }); - describe('#sendVideo', function sendVideoSuite() { let videoId; this.timeout(timeout); @@ -746,40 +830,14 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe('#sendVideoNote', function sendVideoNoteSuite() { - let videoNoteId; - this.timeout(timeout); + describe('#sendAnimation', function sendAnimationSuite() { before(function before() { - utils.handleRatelimit(bot, 'sendVideoNote', this); + utils.handleRatelimit(bot, 'sendAnimation', this); }); - it('should send a video from file', function test() { - const video = `${__dirname}/data/video.mp4`; - return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { + it('should send a gif as an animation', function test() { + return bot.sendAnimation(USERID, `${__dirname}/data/photo.gif`).then(resp => { assert.ok(is.object(resp)); - assert.ok(is.object(resp.video)); - videoNoteId = resp.video.file_id; - }); - }); - it('should send a video from id', function test() { - // Send the same videonote as before - assert.ok(videoNoteId); - return bot.sendVideoNote(USERID, videoNoteId, { length: 5 }).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.video)); - }); - }); - it('should send a video from fs.readStream', function test() { - const video = fs.createReadStream(`${__dirname}/data/video.mp4`); - return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.video)); - }); - }); - it('should send a video from a Buffer', function test() { - const video = fs.readFileSync(`${__dirname}/data/video.mp4`); - return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.video)); + assert.ok(is.object(resp.document)); }); }); }); @@ -828,6 +886,204 @@ describe('TelegramBot', function telegramSuite() { }); }); + + describe('#sendVideoNote', function sendVideoNoteSuite() { + let videoNoteId; + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'sendVideoNote', this); + }); + it('should send a video from file', function test() { + const video = `${__dirname}/data/video.mp4`; + return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.video)); + videoNoteId = resp.video.file_id; + }); + }); + it('should send a video from id', function test() { + // Send the same videonote as before + assert.ok(videoNoteId); + return bot.sendVideoNote(USERID, videoNoteId, { length: 5 }).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.video)); + }); + }); + it('should send a video from fs.readStream', function test() { + const video = fs.createReadStream(`${__dirname}/data/video.mp4`); + return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.video)); + }); + }); + it('should send a video from a Buffer', function test() { + const video = fs.readFileSync(`${__dirname}/data/video.mp4`); + return bot.sendVideoNote(USERID, video, { length: 5 }).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.video)); + }); + }); + }); + + describe('#sendMediaGroup', function sendMediaGroupSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendMediaGroup', this); + }); + it('should send group of photos/videos as album', function test() { + return bot.sendMediaGroup(USERID, [ + { + type: 'photo', + media: `${__dirname}/data/photo.png`, + }, + { + type: 'video', + media: `${__dirname}/data/video.mp4`, + }, + { + type: 'photo', + media: FILE_ID, + }, + ], { + disable_notification: true, + }).then(resp => { + assert.ok(is.array(resp)); + assert.strictEqual(resp.length, 3); + }); + }); + }); + + describe('#sendLocation', function sendLocationSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendLocation', this); + }); + it('should send a location', function test() { + return bot.sendLocation(USERID, lat, long).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.location)); + assert.ok(is.number(resp.location.latitude)); + assert.ok(is.number(resp.location.longitude)); + }); + }); + }); + + describe('#editMessageLiveLocation', function editMessageLiveLocationSuite() { + let message; + before(function before() { + utils.handleRatelimit(bot, 'editMessageLiveLocation', this); + const opts = { live_period: 86400 }; + return bot.sendLocation(USERID, lat, long, opts).then(resp => { message = resp; }); + }); + it('edits live location', function test() { + const opts = { chat_id: USERID, message_id: message.message_id }; + return bot.editMessageLiveLocation(lat + 1, long + 1, opts).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.location)); + assert.ok(is.number(resp.location.latitude)); + assert.ok(is.number(resp.location.longitude)); + }); + }); + }); + + describe.skip('#stopMessageLiveLocation', function editMessageLiveLocationSuite() { + let message; + before(function before() { + utils.handleRatelimit(bot, 'stopMessageLiveLocation', this); + return bot.sendLocation(USERID, lat, long, { live_period: 86400 }) + .then((resp) => { + message = resp; + }); + }); + it('stops location updates', function test() { + const opts = { chat_id: USERID, message_id: message.message_id }; + return bot.stopMessageLiveLocation(opts).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.location)); + assert.ok(is.number(resp.location.latitude)); + assert.ok(is.number(resp.location.longitude)); + }); + }); + }); + + + describe('#sendVenue', function sendVenueSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendVenue', this); + }); + it('should send a venue', function test() { + const title = 'The Village Shopping Centre'; + const address = '430 Topsail Rd,St. John\'s, NL A1E 4N1, Canada'; + return bot.sendVenue(USERID, lat, long, title, address).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.venue)); + assert.ok(is.object(resp.venue.location)); + assert.ok(is.number(resp.venue.location.latitude)); + assert.ok(is.number(resp.venue.location.longitude)); + assert.ok(is.string(resp.venue.title)); + assert.ok(is.string(resp.venue.address)); + }); + }); + }); + + + // NOTE: We are skipping TelegramBot#sendContact() as the + // corresponding rate-limits enforced by the Telegram servers + // are too strict! During our initial tests, we were required + // to retry after ~72000 secs (1200 mins / 20 hrs). + // We surely can NOT wait for that much time during testing + // (or in most practical cases for that matter!) + describe.skip('#sendContact', function sendContactSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendContact', this); + }); + it('should send a contact', function test() { + const phoneNumber = '+1(000)000-000'; + const firstName = 'John Doe'; + return bot.sendContact(USERID, phoneNumber, firstName).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.contact)); + assert.ok(is.string(resp.contact.phone_number)); + assert.ok(is.string(resp.contact.first_name)); + }); + }); + }); + + describe('#sendPoll', function sendPollSuite() { + it('should send a Poll', function test() { + const question = '¿Are you okey?'; + const answers = ['Yes', 'No']; + const opts = { is_anonymous: true }; + return bot.sendPoll(GROUPID, question, answers, opts).then(resp => { + assert.ok(is.object(resp)); + }); + }); + it('should send a Quiz', function test() { + const question = '¿Are you okey?'; + const answers = ['Yes', 'No']; + const opts = { + is_anonymous: true, + type: 'quiz', + correct_option_id: 0 + }; + return bot.sendPoll(GROUPID, question, answers, opts).then(resp => { + assert.ok(is.object(resp)); + }); + }); + }); + + describe('#sendDice', function sendDiceSuite() { + it('should send a Dice', function test() { + return bot.sendDice(GROUPID).then(resp => { + assert.ok(is.object(resp)); + }); + }); + it('should send a Dart', function test() { + const opts = { emoji: '🎯' }; + return bot.sendDice(GROUPID, opts).then(resp => { + assert.ok(is.object(resp)); + }); + }); + }); + describe('#sendChatAction', function sendChatActionSuite() { before(function before() { utils.handleRatelimit(bot, 'sendChatAction', this); @@ -840,6 +1096,44 @@ describe('TelegramBot', function telegramSuite() { }); }); + describe('#getUserProfilePhotos', function getUserProfilePhotosSuite() { + const opts = { + offset: 0, + limit: 1, + }; + before(function before() { + utils.handleRatelimit(bot, 'getUserProfilePhotos', this); + }); + it('should get user profile photos', function test() { + return bot.getUserProfilePhotos(USERID, opts).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.number(resp.total_count)); + assert.ok(is.array(resp.photos)); + }); + }); + it('(v0.25.0 and lower) should get user profile photos', function test() { + return bot.getUserProfilePhotos(USERID, opts.offset, opts.limit).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.number(resp.total_count)); + assert.ok(is.array(resp.photos)); + }); + }); + }); + + describe('#getFile', function getFileSuite() { + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'getFile', this); + }); + it('should get a file', function test() { + return bot.getFile(FILE_ID) + .then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.string(resp.file_path)); + }); + }); + }); + describe.skip('#banChatMember', function banChatMemberSuite() { }); describe.skip('#unbanChatMember', function unbanChatMemberSuite() { }); @@ -848,102 +1142,6 @@ describe('TelegramBot', function telegramSuite() { describe.skip('#promoteChatMember', function promoteChatMemberSuite() { }); - describe.skip('#answerCallbackQuery', function answerCallbackQuerySuite() { }); - - describe('#setMyCommands', function setMyCommandsSuite() { - it('should set bot commands', function test() { - const opts = [ - { command: 'eat', description: 'Command for eat' }, - { command: 'run', description: 'Command for run' } - ]; - return bot.setMyCommands(opts).then(resp => { - assert.ok(is.boolean(resp)); - }); - }); - }); - - describe('#getMyCommands ', function getMyCommandsSuite() { - it('should get bot commands', function test() { - return bot.getMyCommands().then(resp => { - assert.ok(is.array(resp)); - }); - }); - }); - - - describe('#setChatMenuButton', function setChatMenuButtonSuite() { - it('should set chat menu button', function test() { - return bot.setChatMenuButton({ - chat_id: USERID, - menu_button: JSON.stringify({ type: 'web_app', text: 'Hello', web_app: { url: 'https://webappcontent.telegram.org/cafe' } }), - }) - .then(resp => { - assert.ok(is.boolean(resp)); - }); - }); - }); - - describe('#getChatMenuButton', function getChatMenuButtonSuite() { - it('should get chat menu button', function test() { - return bot.getChatMenuButton({ chat_id: USERID }).then(resp => { - assert.ok(is.equal(resp, { - type: 'web_app', - text: 'Hello', - web_app: { url: 'https://webappcontent.telegram.org/cafe' } - })); - }); - }); - }); - - describe('#setMyDefaultAdministratorRights', function setMyDefaultAdministratorRightsSuite() { - it('should set default administrator rights', function test() { - return bot.setMyDefaultAdministratorRights({ - rights: JSON.stringify({ - can_manage_chat: true, - can_change_info: true, - can_delete_messages: false, - can_invite_users: true, - can_restrict_members: false, - can_pin_messages: true, - can_promote_members: false, - can_manage_video_chats: false, - is_anonymous: false - }), - for_channels: false - }).then(resp => { - assert.ok(is.boolean(resp)); - }); - }); - }); - - describe('#getMyDefaultAdministratorRights ', function getMyDefaultAdministratorRightsSuite() { - it('should get my default administrator rights', function test() { - return bot.getMyDefaultAdministratorRights({ - for_channels: false - }).then(resp => { - assert.ok(is.equal(resp, { - can_manage_chat: true, - can_change_info: true, - can_delete_messages: false, - can_invite_users: true, - can_restrict_members: false, - can_pin_messages: true, - can_promote_members: false, - can_manage_video_chats: false, - is_anonymous: false - })); - }); - }); - }); - - describe('#deleteMyCommands', function deleteMyCommandsSuite() { - it('should delete bot commands', function test() { - return bot.deleteMyCommands().then(resp => { - assert.ok(is.boolean(resp)); - }); - }); - }); - describe.skip('#setChatAdministratorCustomTitle ', function setChatAdministratorCustomTitleSuite() { it('should set chat permissions', function test() { return bot.setChatAdministratorCustomTitle(GROUPID, USERID, 'Custom Name').then(resp => { @@ -1012,6 +1210,10 @@ describe('TelegramBot', function telegramSuite() { }); }); + describe.skip('#approveChatJoinRequest', function approveChatJoinRequestSuite() { }); + + describe.skip('#declineChatJoinRequest', function declineChatJoinRequestSuite() { }); + describe('#setChatPhoto', function setChatPhotoSuite() { this.timeout(timeout); before(function before() { @@ -1116,369 +1318,7 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe('#editMessageText', function editMessageTextSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendMessage', this); - utils.handleRatelimit(bot, 'editMessageText', this); - }); - it('should edit a message sent by the bot', function test() { - return bot.sendMessage(USERID, 'test').then(resp => { - assert.strictEqual(resp.text, 'test'); - const opts = { - chat_id: USERID, - message_id: resp.message_id - }; - return bot.editMessageText('edit test', opts).then(msg => { - assert.strictEqual(msg.text, 'edit test'); - }); - }); - }); - }); - - describe('#editMessageCaption', function editMessageCaptionSuite() { - this.timeout(timeout); - before(function before() { - utils.handleRatelimit(bot, 'sendPhoto', this); - utils.handleRatelimit(bot, 'editMessageCaption', this); - }); - it('should edit a caption sent by the bot', function test() { - const photo = `${__dirname}/data/photo.png`; - const options = { caption: 'test caption' }; - return bot.sendPhoto(USERID, photo, options).then(resp => { - assert.strictEqual(resp.caption, 'test caption'); - const opts = { - chat_id: USERID, - message_id: resp.message_id - }; - return bot.editMessageCaption('new test caption', opts).then(msg => { - assert.strictEqual(msg.caption, 'new test caption'); - }); - }); - }); - }); - - describe('#editMessageReplyMarkup', function editMessageReplyMarkupSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendMessage', this); - utils.handleRatelimit(bot, 'editMessageReplyMarkup', this); - }); - it('should edit previously-set reply markup', function test() { - return bot.sendMessage(USERID, 'test').then(resp => { - const replyMarkup = JSON.stringify({ - inline_keyboard: [[{ - text: 'Test button', - callback_data: 'test' - }]] - }); - const opts = { - chat_id: USERID, - message_id: resp.message_id - }; - return bot.editMessageReplyMarkup(replyMarkup, opts).then(msg => { - // Keyboard markup is not returned, do a simple object check - assert.ok(is.object(msg)); - }); - }); - }); - }); - - describe('#deleteMessage', function deleteMessageSuite() { - let messageId; - before(function before() { - utils.handleRatelimit(bot, 'deleteMessage', this); - return bot.sendMessage(USERID, 'To be deleted').then(resp => { - messageId = resp.message_id; - }); - }); - it('should delete message', function test() { - return bot.deleteMessage(USERID, messageId).then(resp => { - assert.strictEqual(resp, true); - }); - }); - }); - - describe('#getUserProfilePhotos', function getUserProfilePhotosSuite() { - const opts = { - offset: 0, - limit: 1, - }; - before(function before() { - utils.handleRatelimit(bot, 'getUserProfilePhotos', this); - }); - it('should get user profile photos', function test() { - return bot.getUserProfilePhotos(USERID, opts).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.number(resp.total_count)); - assert.ok(is.array(resp.photos)); - }); - }); - it('(v0.25.0 and lower) should get user profile photos', function test() { - return bot.getUserProfilePhotos(USERID, opts.offset, opts.limit).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.number(resp.total_count)); - assert.ok(is.array(resp.photos)); - }); - }); - }); - - describe('#sendLocation', function sendLocationSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendLocation', this); - }); - it('should send a location', function test() { - return bot.sendLocation(USERID, lat, long).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.location)); - assert.ok(is.number(resp.location.latitude)); - assert.ok(is.number(resp.location.longitude)); - }); - }); - }); - - describe('#editMessageLiveLocation', function editMessageLiveLocationSuite() { - let message; - before(function before() { - utils.handleRatelimit(bot, 'editMessageLiveLocation', this); - const opts = { live_period: 86400 }; - return bot.sendLocation(USERID, lat, long, opts).then(resp => { message = resp; }); - }); - it('edits live location', function test() { - const opts = { chat_id: USERID, message_id: message.message_id }; - return bot.editMessageLiveLocation(lat + 1, long + 1, opts).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.location)); - assert.ok(is.number(resp.location.latitude)); - assert.ok(is.number(resp.location.longitude)); - }); - }); - }); - - describe.skip('#stopMessageLiveLocation', function editMessageLiveLocationSuite() { - let message; - before(function before() { - utils.handleRatelimit(bot, 'stopMessageLiveLocation', this); - return bot.sendLocation(USERID, lat, long, { live_period: 86400 }) - .then((resp) => { - message = resp; - }); - }); - it('stops location updates', function test() { - const opts = { chat_id: USERID, message_id: message.message_id }; - return bot.stopMessageLiveLocation(opts).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.location)); - assert.ok(is.number(resp.location.latitude)); - assert.ok(is.number(resp.location.longitude)); - }); - }); - }); - - describe('#sendVenue', function sendVenueSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendVenue', this); - }); - it('should send a venue', function test() { - const title = 'The Village Shopping Centre'; - const address = '430 Topsail Rd,St. John\'s, NL A1E 4N1, Canada'; - return bot.sendVenue(USERID, lat, long, title, address).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.venue)); - assert.ok(is.object(resp.venue.location)); - assert.ok(is.number(resp.venue.location.latitude)); - assert.ok(is.number(resp.venue.location.longitude)); - assert.ok(is.string(resp.venue.title)); - assert.ok(is.string(resp.venue.address)); - }); - }); - }); - - // NOTE: We are skipping TelegramBot#sendContact() as the - // corresponding rate-limits enforced by the Telegram servers - // are too strict! During our initial tests, we were required - // to retry after ~72000 secs (1200 mins / 20 hrs). - // We surely can NOT wait for that much time during testing - // (or in most practical cases for that matter!) - describe.skip('#sendContact', function sendContactSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendContact', this); - }); - it('should send a contact', function test() { - const phoneNumber = '+1(000)000-000'; - const firstName = 'John Doe'; - return bot.sendContact(USERID, phoneNumber, firstName).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.contact)); - assert.ok(is.string(resp.contact.phone_number)); - assert.ok(is.string(resp.contact.first_name)); - }); - }); - }); - - describe('#sendPoll', function sendPollSuite() { - it('should send a Poll', function test() { - const question = '¿Are you okey?'; - const answers = ['Yes', 'No']; - const opts = { is_anonymous: true }; - return bot.sendPoll(GROUPID, question, answers, opts).then(resp => { - assert.ok(is.object(resp)); - }); - }); - it('should send a Quiz', function test() { - const question = '¿Are you okey?'; - const answers = ['Yes', 'No']; - const opts = { - is_anonymous: true, - type: 'quiz', - correct_option_id: 0 - }; - return bot.sendPoll(GROUPID, question, answers, opts).then(resp => { - assert.ok(is.object(resp)); - }); - }); - }); - - describe('#sendDice', function sendDiceSuite() { - it('should send a Dice', function test() { - return bot.sendDice(GROUPID).then(resp => { - assert.ok(is.object(resp)); - }); - }); - it('should send a Dart', function test() { - const opts = { emoji: '🎯' }; - return bot.sendDice(GROUPID, opts).then(resp => { - assert.ok(is.object(resp)); - }); - }); - }); - - describe('#getFile', function getFileSuite() { - this.timeout(timeout); - before(function before() { - utils.handleRatelimit(bot, 'getFile', this); - }); - it('should get a file', function test() { - return bot.getFile(FILE_ID) - .then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.string(resp.file_path)); - }); - }); - }); - - describe('#getFileLink', function getFileLinkSuite() { - this.timeout(timeout); - before(function before() { - utils.handleRatelimit(bot, 'getFileLink', this); - }); - it('should get a file link', function test() { - return bot.getFileLink(FILE_ID) - .then(fileURI => { - assert.ok(is.string(fileURI)); - assert.ok(utils.isTelegramFileURI(fileURI)); - }); - }); - }); - - describe('#getFileStream', function getFileStreamSuite() { - this.timeout(timeout); - before(function before() { - // utils.handleRatelimit(bot, 'getFileStream', this); - }); - it('should get a file stream', function test(done) { - const fileStream = bot.getFileStream(FILE_ID); - assert.ok(fileStream instanceof stream.Readable); - assert.strictEqual(fileStream.path, FILE_ID); - fileStream.on('info', (info) => { - assert.ok(info); - assert.ok(utils.isTelegramFileURI(info.uri), `${info.uri} is not a file URI`); - fileStream.pipe(concat(function readFile(buffer) { - buffer.equals(fs.readFileSync(FILE_PATH)); // sync :( - return done(); - })); - }); - }); - }); - - describe('#downloadFile', function downloadFileSuite() { - const downloadPath = os.tmpdir(); - this.timeout(timeout); - before(function before() { - utils.handleRatelimit(bot, 'downloadFile', this); - }); - it('should download a file', function test() { - return bot.downloadFile(FILE_ID, downloadPath) - .then(filePath => { - assert.ok(is.string(filePath)); - assert.strictEqual(path.dirname(filePath), downloadPath); - assert.ok(fs.existsSync(filePath)); - fs.unlinkSync(filePath); // Delete file after test - }); - }); - }); - - describe('#onText', function onTextSuite() { - it('should call `onText` callback on match', function test(done) { - const regexp = /\/onText (.+)/; - botWebHook.onText(regexp, (msg, match) => { - assert.strictEqual(match[1], 'ECHO ALOHA'); - assert.ok(botWebHook.removeTextListener(regexp)); - return done(); - }); - utils.sendWebHookMessage(webHookPort2, TOKEN, { - message: { text: '/onText ECHO ALOHA' }, - }); - }); - it('should reset the global regex state with each message', function test(done) { - const regexp = /\/onText (.+)/g; - botWebHook.onText(regexp, () => { - assert.strictEqual(regexp.lastIndex, 0); - assert.ok(botWebHook.removeTextListener(regexp)); - return done(); - }); - utils.sendWebHookMessage(webHookPort2, TOKEN, { - message: { text: '/onText ECHO ALOHA' }, - }); - }); - }); - - describe('#removeTextListener', function removeTextListenerSuite() { - const regexp = /\/onText/; - const regexp2 = /\/onText/; - const callback = function noop() { }; - after(function after() { - bot.removeTextListener(regexp); - bot.removeTextListener(regexp2); - }); - it('removes the right text-listener', function test() { - bot.onText(regexp, callback); - bot.onText(regexp2, callback); - const textListener = bot.removeTextListener(regexp); - assert.strictEqual(regexp, textListener.regexp); - }); - it('returns `null` if missing', function test() { - assert.strictEqual(null, bot.removeTextListener(/404/)); - }); - }); - - describe.skip('#onReplyToMessage', function onReplyToMessageSuite() { }); - - describe('#removeReplyListener', function removeReplyListenerSuite() { - const chatId = -1234; - const messageId = 1; - const callback = function noop() { }; - it('returns the right reply-listener', function test() { - const id = bot.onReplyToMessage(chatId, messageId, callback); - const replyListener = bot.removeReplyListener(id); - assert.strictEqual(id, replyListener.id); - assert.strictEqual(chatId, replyListener.chatId); - assert.strictEqual(messageId, replyListener.messageId); - assert.strictEqual(callback, replyListener.callback); - }); - it('returns `null` if missing', function test() { - // NOTE: '0' is never a valid reply listener ID :) - assert.strictEqual(null, bot.removeReplyListener(0)); - }); - }); + describe.skip('#leaveChat', function leaveChatSuite() { }); describe('#getChat', function getChatSuite() { before(function before() { @@ -1526,7 +1366,463 @@ describe('TelegramBot', function telegramSuite() { }); }); - describe.skip('#leaveChat', function leaveChatSuite() { }); + describe('#setChatStickerSet', function setChatStickerSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'setChatStickerSet', this); + // Check if the chat can set sticker sets + if (!CHAT_INFO.can_set_sticker_set) { + this.skip(); + } + }); + it('should return a Boolean', function test() { + return bot.setChatStickerSet(GROUPID, STICKER_SET_NAME).then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#deleteChatStickerSet', function deleteChatStickerSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'deleteChatStickerSet', this); + // Check if the chat can delete sticker sets + if (!CHAT_INFO.can_set_sticker_set) { + this.skip(); + } + }); + it('should return a Boolean', function test() { + return bot.deleteChatStickerSet(GROUPID).then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe.skip('#answerCallbackQuery', function answerCallbackQuerySuite() { }); + + describe('#setMyCommands', function setMyCommandsSuite() { + it('should set bot commands', function test() { + const opts = [ + { command: 'eat', description: 'Command for eat' }, + { command: 'run', description: 'Command for run' } + ]; + return bot.setMyCommands(opts).then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#deleteMyCommands', function deleteMyCommandsSuite() { + it('should delete bot commands', function test() { + return bot.deleteMyCommands().then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#getMyCommands', function getMyCommandsSuite() { + it('should get bot commands', function test() { + return bot.getMyCommands().then(resp => { + assert.ok(is.array(resp)); + }); + }); + }); + + describe('#setChatMenuButton', function setChatMenuButtonSuite() { + it('should set chat menu button', function test() { + return bot.setChatMenuButton({ + chat_id: USERID, + menu_button: JSON.stringify({ type: 'web_app', text: 'Hello', web_app: { url: 'https://webappcontent.telegram.org/cafe' } }), + }) + .then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#getChatMenuButton', function getChatMenuButtonSuite() { + it('should get chat menu button', function test() { + return bot.getChatMenuButton({ chat_id: USERID }).then(resp => { + assert.ok(is.equal(resp, { + type: 'web_app', + text: 'Hello', + web_app: { url: 'https://webappcontent.telegram.org/cafe' } + })); + }); + }); + }); + + describe('#setMyDefaultAdministratorRights', function setMyDefaultAdministratorRightsSuite() { + it('should set default administrator rights', function test() { + return bot.setMyDefaultAdministratorRights({ + rights: JSON.stringify({ + can_manage_chat: true, + can_change_info: true, + can_delete_messages: false, + can_invite_users: true, + can_restrict_members: false, + can_pin_messages: true, + can_promote_members: false, + can_manage_video_chats: false, + is_anonymous: false + }), + for_channels: false + }).then(resp => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#getMyDefaultAdministratorRights', function getMyDefaultAdministratorRightsSuite() { + it('should get my default administrator rights', function test() { + return bot.getMyDefaultAdministratorRights({ + for_channels: false + }).then(resp => { + assert.ok(is.equal(resp, { + can_manage_chat: true, + can_change_info: true, + can_delete_messages: false, + can_invite_users: true, + can_restrict_members: false, + can_pin_messages: true, + can_promote_members: false, + can_manage_video_chats: false, + is_anonymous: false + })); + }); + }); + }); + + describe('#editMessageText', function editMessageTextSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendMessage', this); + utils.handleRatelimit(bot, 'editMessageText', this); + }); + it('should edit a message sent by the bot', function test() { + return bot.sendMessage(USERID, 'test').then(resp => { + assert.strictEqual(resp.text, 'test'); + const opts = { + chat_id: USERID, + message_id: resp.message_id + }; + return bot.editMessageText('edit test', opts).then(msg => { + assert.strictEqual(msg.text, 'edit test'); + }); + }); + }); + }); + + describe('#editMessageCaption', function editMessageCaptionSuite() { + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'sendPhoto', this); + utils.handleRatelimit(bot, 'editMessageCaption', this); + }); + it('should edit a caption sent by the bot', function test() { + const photo = `${__dirname}/data/photo.png`; + const options = { caption: 'test caption' }; + return bot.sendPhoto(USERID, photo, options).then(resp => { + assert.strictEqual(resp.caption, 'test caption'); + const opts = { + chat_id: USERID, + message_id: resp.message_id + }; + return bot.editMessageCaption('new test caption', opts).then(msg => { + assert.strictEqual(msg.caption, 'new test caption'); + }); + }); + }); + }); + + describe('#editMessageMedia', function editMessageMediaSuite() { + let photoId; + let messageID; + before(function before() { + utils.handleRatelimit(bot, 'editMessageMedia', this); + const photo = `${__dirname}/data/photo.png`; + return bot.sendPhoto(USERID, photo).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.array(resp.photo)); + photoId = resp.photo[0].file_id; + messageID = resp.message_id; + }); + }); + it('should edit a media message', function nextTest() { + return bot.editMessageMedia({ type: 'photo', media: photoId, caption: 'edited' }, { chat_id: USERID, message_id: messageID }).then(editedResp => { + assert.ok(is.object(editedResp)); + assert.ok(is.string(editedResp.caption)); + }); + }); + }); + + + describe('#editMessageReplyMarkup', function editMessageReplyMarkupSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendMessage', this); + utils.handleRatelimit(bot, 'editMessageReplyMarkup', this); + }); + it('should edit previously-set reply markup', function test() { + return bot.sendMessage(USERID, 'test').then(resp => { + const replyMarkup = JSON.stringify({ + inline_keyboard: [[{ + text: 'Test button', + callback_data: 'test' + }]] + }); + const opts = { + chat_id: USERID, + message_id: resp.message_id + }; + return bot.editMessageReplyMarkup(replyMarkup, opts).then(msg => { + // Keyboard markup is not returned, do a simple object check + assert.ok(is.object(msg)); + }); + }); + }); + }); + + describe('#stopPoll', function stopPollSuite() { + let msg; + before(function before() { + utils.handleRatelimit(bot, 'stopPoll', this); + return bot.sendPoll(GROUPID, '¿Poll for stop before?', ['Yes', 'No']).then(resp => { + msg = resp; + }); + }); + it('should stop a Poll', function test() { + return bot.stopPoll(GROUPID, msg.message_id).then(resp => { + assert.ok(is.boolean(resp.is_closed) && resp.is_closed === true); + }); + } + ); + }); + + describe('#deleteMessage', function deleteMessageSuite() { + let messageId; + before(function before() { + utils.handleRatelimit(bot, 'deleteMessage', this); + return bot.sendMessage(USERID, 'To be deleted').then(resp => { + messageId = resp.message_id; + }); + }); + it('should delete message', function test() { + return bot.deleteMessage(USERID, messageId).then(resp => { + assert.strictEqual(resp, true); + }); + }); + }); + + describe('#sendSticker', function sendStickerSuite() { + let stickerId; + this.timeout(timeout); + before(function before() { + utils.handleRatelimit(bot, 'sendSticker', this); + }); + it('should send a sticker from file', function test() { + const sticker = `${__dirname}/data/sticker.webp`; + return bot.sendSticker(USERID, sticker).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.sticker)); + stickerId = resp.sticker.file_id; + }); + }); + it('should send a sticker from id', function test() { + // Send the same photo as before + return bot.sendSticker(USERID, stickerId).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.sticker)); + }); + }); + it('should send a sticker from fs.readStream', function test() { + const sticker = fs.createReadStream(`${__dirname}/data/sticker.webp`); + return bot.sendSticker(USERID, sticker).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.sticker)); + }); + }); + it('should send a sticker from request Stream', function test() { + const sticker = request(`${staticUrl}/sticker.webp`); + return bot.sendSticker(USERID, sticker).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.sticker)); + }); + }); + it('should send a sticker from a Buffer', function test() { + const sticker = fs.readFileSync(`${__dirname}/data/sticker.webp`); + return bot.sendSticker(USERID, sticker).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.sticker)); + }); + }); + }); + + describe('#uploadStickerFile', function sendPhotoSuite() { + before(function before() { + utils.handleRatelimit(bot, 'uploadStickerFile', this); + }); + it('should upload a sticker from file', function test() { + const sticker = `${__dirname}/data/sticker.png`; + + bot.uploadStickerFile(USERID, sticker).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.string(resp.file_id)); + }); + }); + // Other tests (eg. Buffer, URL) are skipped, because they rely on the same features as sendPhoto. + }); + + describe('#createNewStickerSet', function createNewStickerSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'createNewStickerSet', this); + }); + + it('should create a new sticker set', function test(done) { + const sticker = `${__dirname}/data/sticker.png`; + const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; + + bot.createNewStickerSet(USERID, stickerPackName, 'Sticker Pack Title', sticker, '😍').then((resp) => { + assert.ok(is.boolean(resp)); + }); + setTimeout(() => done(), 2000); + }); + }); + + describe('#getStickerSet', function getStickerSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'getStickerSet', this); + }); + it('should get the sticker set given the name of the set', function test() { + return bot.getStickerSet(STICKER_SET_NAME).then(resp => { + assert.ok(is.object(resp)); + assert.strictEqual(resp.name.toLowerCase(), STICKER_SET_NAME); + assert.ok(is.string(resp.title)); + assert.ok(is.boolean(resp.contains_masks)); + assert.ok(is.array(resp.stickers)); + }); + }); + // This test depends on the previous test createNewStickerSet + it('should get the recent sticker set created given the name of the set', function test() { + const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; + return bot.getStickerSet(stickerPackName).then(resp => { + STICKER_FILE_ID_FROM_SET = resp.stickers[0].file_id; + assert.ok(is.object(resp)); + assert.strictEqual(resp.name.toLowerCase(), stickerPackName.toLowerCase()); + assert.ok(is.string(resp.title)); + assert.ok(is.boolean(resp.contains_masks)); + assert.ok(is.array(resp.stickers)); + }); + }); + }); + + + describe('#addStickerToSet', function addStickerToSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'addStickerToSet', this); + }); + + it('should add a sticker to a set', function test() { + const sticker = `${__dirname}/data/sticker.png`; + const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; + + bot.addStickerToSet(USERID, stickerPackName, sticker, '😊😍🤔', 'png_sticker').then((resp) => { + assert.ok(is.boolean(resp)); + }); + }); + it('should add a sticker to a set using the file Id', function test(done) { + const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; + + bot.addStickerToSet(USERID, stickerPackName, STICKER_FILE_ID_FROM_SET, '😊🤔', 'png_sticker').then((resp) => { + assert.ok(is.boolean(resp)); + }); + setTimeout(() => done(), 2000); + }); + }); + + describe('#setStickerPositionInSet', function setStickerPositionInSet() { + before(function before() { + utils.handleRatelimit(bot, 'setStickerPositionInSet', this); + }); + it('should set the position of a sticker in a set', function test() { + bot.setStickerPositionInSet(STICKER_FILE_ID_FROM_SET, 0).then((resp) => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#deleteStickerFromSet', function deleteStickerFromSetSuite() { + before(function before() { + utils.handleRatelimit(bot, 'deleteStickerFromSet', this); + }); + it('should delete a sticker from a set', function test() { + bot.deleteStickerFromSet(STICKER_FILE_ID_FROM_SET).then((resp) => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe('#setStickerSetThumb', function setStickerSetThumbSuite() { + before(function before() { + utils.handleRatelimit(bot, 'setStickerSetThumb', this); + }); + + it('should set a sticker set thumb', function test() { + const stickerThumb = `${__dirname}/data/sticker_thumb.png`; + const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; + + bot.setStickerSetThumb(USERID, stickerPackName, stickerThumb).then((resp) => { + assert.ok(is.boolean(resp)); + }); + }); + }); + + describe.skip('#answerInlineQuery', function answerInlineQuerySuite() { }); + + describe.skip('#answerWebAppQuery', function answerCallbackQuerySuite() { }); + + describe('#sendInvoice', function sendInvoiceSuite() { + before(function before() { + utils.handleRatelimit(bot, 'sendInvoice', this); + }); + it('should send an invoice', function test() { + if (isCI) { + this.skip(); // Skip test for now + } + const title = 'Demo product'; + const description = 'our test product'; + const payload = 'sku-p001'; + const providerToken = PROVIDER_TOKEN; + const currency = 'USD'; + const prices = [{ label: 'product', amount: 11000 }, { label: 'tax', amount: 11000 }]; + return bot.sendInvoice(USERID, title, description, payload, providerToken, currency, prices).then(resp => { + assert.ok(is.object(resp)); + assert.ok(is.object(resp.invoice)); + assert.ok(is.number(resp.invoice.total_amount)); + }); + }); + }); + + describe('#createInvoiceLink', function createInvoiceLinkSuite() { + before(function before() { + utils.handleRatelimit(bot, 'createInvoiceLink', this); + }); + it('should create an invoice link', function test() { + if (isCI) { + this.skip(); // Skip test for now + } + const title = 'Invoice link product'; + const description = 'Our test invoice link product'; + const payload = 'sku-p002'; + const providerToken = PROVIDER_TOKEN; + const currency = 'EUR'; + const prices = [{ label: 'NTBA API', amount: 12000 }, { label: 'tax', amount: 10000 }]; + return bot.createInvoiceLink(title, description, payload, providerToken, currency, prices).then(resp => { + assert.ok(is.string(resp)); + }); + }); + }); + + describe.skip('#answerShippingQuery', function answerShippingQuerySuite() { }); + + + describe.skip('#answerPreCheckoutQuery', function answerPreCheckoutQuerySuite() { }); describe('#sendGame', function sendGameSuite() { before(function before() { @@ -1571,174 +1867,4 @@ describe('TelegramBot', function telegramSuite() { }); }); }); - - describe('#sendInvoice', function sendInvoiceSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendInvoice', this); - }); - it('should send an invoice', function test() { - if (isCI) { - this.skip(); // Skip test for now - } - const title = 'Demo product'; - const description = 'our test product'; - const payload = 'sku-p001'; - const providerToken = PROVIDER_TOKEN; - const startParameter = 'pay'; - const currency = 'USD'; - const prices = [{ label: 'product', amount: 11000 }, { label: 'tax', amount: 11000 }]; - return bot.sendInvoice(USERID, title, description, payload, providerToken, startParameter, currency, prices).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.invoice)); - assert.ok(is.number(resp.invoice.total_amount)); - }); - }); - }); - - describe('#createInvoiceLink', function createInvoiceLinkSuite() { - before(function before() { - utils.handleRatelimit(bot, 'createInvoiceLink', this); - }); - it('should create an invoice link', function test() { - if (isCI) { - this.skip(); // Skip test for now - } - const title = 'Invoice link product'; - const description = 'Our test invoice link product'; - const payload = 'sku-p002'; - const providerToken = PROVIDER_TOKEN; - const currency = 'EUR'; - const prices = [{ label: 'NTBA API', amount: 12000 }, { label: 'tax', amount: 10000 }]; - return bot.createInvoiceLink(title, description, payload, providerToken, currency, prices).then(resp => { - console.log(resp); - assert.ok(is.string(resp)); - }); - }); - }); - - describe.skip('#answerShippingQuery', function answerShippingQuerySuite() { }); - - describe.skip('#answerPreCheckoutQuery', function answerPreCheckoutQuerySuite() { }); - - describe('#createNewStickerSet', function createNewStickerSetSuite() { - before(function before() { - utils.handleRatelimit(bot, 'createNewStickerSet', this); - }); - - it('should create a new sticker set', function test(done) { - const sticker = `${__dirname}/data/sticker.png`; - const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; - - bot.createNewStickerSet(USERID, stickerPackName, 'Sticker Pack Title', sticker, '😍').then((resp) => { - assert.ok(is.boolean(resp)); - }); - setTimeout(() => done(), 2000); - }); - }); - - - describe('#getStickerSet', function getStickerSetSuite() { - before(function before() { - utils.handleRatelimit(bot, 'getStickerSet', this); - }); - it('should get the sticker set given the name of the set', function test() { - return bot.getStickerSet(STICKER_SET_NAME).then(resp => { - assert.ok(is.object(resp)); - assert.strictEqual(resp.name.toLowerCase(), STICKER_SET_NAME); - assert.ok(is.string(resp.title)); - assert.ok(is.boolean(resp.contains_masks)); - assert.ok(is.array(resp.stickers)); - }); - }); - it('should get the recent sticker set created given the name of the set', function test() { - const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; - return bot.getStickerSet(stickerPackName).then(resp => { - assert.ok(is.object(resp)); - assert.strictEqual(resp.name.toLowerCase(), stickerPackName.toLowerCase()); - assert.ok(is.string(resp.title)); - assert.ok(is.boolean(resp.contains_masks)); - assert.ok(is.array(resp.stickers)); - }); - }); - }); - - describe('#setStickerSetThumb', function setStickerSetThumbSuite() { - before(function before() { - utils.handleRatelimit(bot, 'setStickerSetThumb', this); - }); - - it('should set a sticker set thumb', function test() { - const stickerThumb = `${__dirname}/data/sticker_thumb.png`; - const stickerPackName = `s${CURRENT_TIMESTAMP}_by_${BOT_USERNAME}`; - - bot.setStickerSetThumb(USERID, stickerPackName, stickerThumb).then((resp) => { - assert.ok(is.boolean(resp)); - }); - }); - }); - - describe('#uploadStickerFile', function sendPhotoSuite() { - before(function before() { - utils.handleRatelimit(bot, 'uploadStickerFile', this); - }); - it('should upload a sticker from file', function test() { - const sticker = `${__dirname}/data/sticker.png`; - return bot.uploadStickerFile(USERID, sticker).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.string(resp.file_id)); - }); - }); - // Other tests (eg. Buffer, URL) are skipped, because they rely on the same features as sendPhoto. - }); - - describe('#sendMediaGroup', function sendMediaGroupSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendMediaGroup', this); - }); - it('should send group of photos/videos as album', function test() { - return bot.sendMediaGroup(USERID, [ - { - type: 'photo', - media: `${__dirname}/data/photo.png`, - }, - { - type: 'video', - media: `${__dirname}/data/video.mp4`, - }, - { - type: 'photo', - media: FILE_ID, - }, - ], { - disable_notification: true, - }).then(resp => { - assert.ok(is.array(resp)); - assert.strictEqual(resp.length, 3); - }); - }); - }); - - describe('#sendAnimation', function sendAnimationSuite() { - before(function before() { - utils.handleRatelimit(bot, 'sendAnimation', this); - }); - it('should send a gif as an animation', function test() { - return bot.sendAnimation(USERID, `${__dirname}/data/photo.gif`).then(resp => { - assert.ok(is.object(resp)); - assert.ok(is.object(resp.document)); - - describe('#editMessageMedia', function editMessageMediaSuite() { - before(function before() { - utils.handleRatelimit(bot, 'editMessageMedia', this); - }); - it('should edit a media message', function nextTest() { - return bot.editMessageMedia({ type: 'animation', media: resp.document.file_id, caption: 'edited' }, { chat_id: resp.chat.id, message_id: resp.message_id }).then(editedResp => { - assert.ok(is.object(editedResp)); - assert.ok(is.string(editedResp.caption)); - }); - }); - }); - }); - }); - }); }); // End Telegram