Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-telegram-bot-api

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-telegram-bot-api - npm Package Compare versions

Comparing version 0.25.0 to 0.26.0

CHANGELOG.md

55

CONTRIBUTING.md

@@ -1,14 +0,49 @@

If you are willing to contribute, first you should know I will love you and the Telegram Bot comunity too.
# Contributing
Other considerations:
> If you are willing to contribute, first you should know that
> I will love you and so will the Telegram Bot community.
- `README.md` is generated by the inline jsdoc with `npm run gen-doc`.
- Provide tests for your methods. For running tests you need to set some environment variables:
Before proceeding any further, read the following documents:
1. [code of conduct][coc]
1. [software license][license]
[coc]:https://github.com/yagop/node-telegram-bot-api/blob/master/CODE_OF_CONDUCT.md
[license]:https://github.com/yagop/node-telegram-bot-api/blob/master/LICENSE.md
### General Information
**Updating API Reference i.e. generating `doc/api.md`:**
Run:
```bash
export TEST_TELEGRAM_TOKEN="123456:AAGoASDFJKnlj6uSQLIhjhBgOUY" # Your bot token
export TEST_USER_ID="66368736" # User wich the bot will send the messages (can be yours ID)
export TEST_GROUP_ID="-163889657" # A Telegram group which the bot have access
npm run test
$ npm run gen-doc
```
- The code is transpilled with babel on Git Hook prepublish
- E=mc²
---
**Running tests:**
Please read `test/README.md` for more information.
---
**Transpiling ES6 for older Node.js versions:**
We use babel to transpile the code:
```bash
$ npm run build
```
---
> E=mc²

@@ -1,1 +0,13 @@

module.exports = require('./src/telegram');
/**
* If running on Nodejs 0.12, we load the transpiled code.
* Otherwise, we use the ES6 code.
* We are deprecating support for Node.js v0.x
*/
const majorVersion = process.versions.node.split('.')[0];
if (majorVersion === '0') {
const deprecate = require('depd')('node-telegram-bot-api');
deprecate('Node.js v0.12 and below will no longer be supported in the future');
module.exports = require('./lib/telegram');
} else {
module.exports = require('./src/telegram');
}

749

lib/telegram.js
'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

@@ -28,5 +28,11 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var pump = require('pump');
var deprecate = require('depd')('node-telegram-bot-api');
var _messageTypes = ['text', 'audio', 'document', 'photo', 'sticker', 'video', 'voice', 'contact', 'location', 'new_chat_participant', 'left_chat_participant', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created'];
// enable cancellation
Promise.config({
cancellation: true
});
var TelegramBot = function (_EventEmitter) {

@@ -50,11 +56,27 @@ _inherits(TelegramBot, _EventEmitter);

* @param {Object} [options]
* @param {Boolean|Object} [options.polling=false] Set true to enable polling or set options
* @param {String|Number} [options.polling.timeout=10] Polling time in seconds
* @param {String|Number} [options.polling.interval=2000] Interval between requests in miliseconds
* @param {Boolean|Object} [options.polling=false] Set true to enable polling or set options.
* If a WebHook has been set, it will be deleted automatically.
* @param {String|Number} [options.polling.timeout=10] Timeout in seconds for long polling
* @param {String|Number} [options.polling.interval=300] Interval between requests in miliseconds
* @param {Boolean} [options.polling.autoStart=true] Start polling immediately
* @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook or set options
* @param {String} [options.webHook.key] PEM private key to webHook server.
* @param {String} [options.webHook.cert] PEM certificate (public) to webHook server.
* @param {Number} [options.webHook.port=8443] Port to bind to
* @param {String} [options.webHook.key] Path to file with PEM private key for webHook server.
* The file is read **synchronously**!
* @param {String} [options.webHook.cert] Path to file with PEM certificate (public) for webHook server.
* The file is read **synchronously**!
* @param {String} [options.webHook.pfx] Path to file with PFX private key and certificate chain for webHook server.
* The file is read **synchronously**!
* @param {Boolean} [options.webHook.autoOpen=true] Open webHook immediately
* @param {Object} [options.webHook.https] Options to be passed to `https.createServer()`.
* Note that `options.webHook.key`, `options.webHook.cert` and `options.webHook.pfx`, if provided, will be
* used to override `key`, `cert` and `pfx` in this object, respectively.
* See https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener for more information.
* @param {Boolean} [options.onlyFirstMatch=false] Set to true to stop after first match. Otherwise, all regexps are executed
* @param {Object} [options.request] Options which will be added for all requests to telegram api.
* See https://github.com/request/request#requestoptions-callback for more information.
* @param {String} [options.baseApiUrl=https://api.telegram.org] API Base URl; useful for proxying and testing
* @param {Boolean} [options.filepath=true] Allow passing file-paths as arguments when sending files,
* such as photos using `TelegramBot#sendPhoto()`. See [usage information][usage-sending-files-performance]
* for more information on this option and its consequences.
* @see https://core.telegram.org/bots/api

@@ -72,13 +94,25 @@ */

_this.token = token;
_this.options = options;
_this.token = token;
_this.textRegexpCallbacks = [];
_this.onReplyToMessages = [];
_this.options.polling = typeof options.polling === 'undefined' ? false : options.polling;
_this.options.webHook = typeof options.webHook === 'undefined' ? false : options.webHook;
_this.options.baseApiUrl = options.baseApiUrl || 'https://api.telegram.org';
_this.options.filepath = typeof options.filepath === 'undefined' ? true : options.filepath;
_this._textRegexpCallbacks = [];
_this._onReplyToMessages = [];
_this._polling = null;
_this._webHook = null;
if (options.polling) {
_this.initPolling();
var autoStart = options.polling.autoStart;
if (typeof autoStart === 'undefined' || autoStart === true) {
_this.startPolling();
}
}
if (options.webHook) {
_this._WebHook = new TelegramBotWebHook(token, options.webHook, _this.processUpdate.bind(_this));
var autoOpen = options.webHook.autoOpen;
if (typeof autoOpen === 'undefined' || autoOpen === true) {
_this.openWebHook();
}
}

@@ -88,121 +122,26 @@ return _this;

/**
* Generates url with bot token and provided path/method you want to be got/executed by bot
* @param {String} path
* @return {String} url
* @private
* @see https://core.telegram.org/bots/api#making-requests
*/
_createClass(TelegramBot, [{
key: 'initPolling',
value: function initPolling() {
if (this._polling) {
this._polling.abort = true;
this._polling.lastRequest.cancel('Polling restart');
}
this._polling = new TelegramBotPolling(this.token, this.options.polling, this.processUpdate.bind(this));
key: '_buildURL',
value: function _buildURL(_path) {
return this.options.baseApiUrl + '/bot' + this.token + '/' + _path;
}
/**
* Stops polling after the last polling request resolves
*
* @return {Promise} promise Promise, of last polling request
* Fix 'reply_markup' parameter by making it JSON-serialized, as
* required by the Telegram Bot API
* @param {Object} obj Object; either 'form' or 'qs'
* @private
* @see https://core.telegram.org/bots/api#sendmessage
*/
}, {
key: 'stopPolling',
value: function stopPolling() {
if (this._polling) {
return this._polling.stopPolling();
}
return Promise.resolve();
}
}, {
key: 'processUpdate',
value: function processUpdate(update) {
var _this2 = this;
debug('Process Update %j', update);
var message = update.message;
var editedMessage = update.edited_message;
var channelPost = update.channel_post;
var editedChannelPost = update.edited_channel_post;
var inlineQuery = update.inline_query;
var chosenInlineResult = update.chosen_inline_result;
var callbackQuery = update.callback_query;
if (message) {
debug('Process Update message %j', message);
this.emit('message', message);
var processMessageType = function processMessageType(messageType) {
if (message[messageType]) {
debug('Emtting %s: %j', messageType, message);
_this2.emit(messageType, message);
}
};
TelegramBot.messageTypes.forEach(processMessageType);
if (message.text) {
debug('Text message');
this.textRegexpCallbacks.some(function (reg) {
debug('Matching %s with %s', message.text, reg.regexp);
var result = reg.regexp.exec(message.text);
if (result) {
debug('Matches %s', reg.regexp);
reg.callback(message, result);
// returning truthy value exits .some
return _this2.options.onlyFirstMatch;
}
});
}
if (message.reply_to_message) {
// Only callbacks waiting for this message
this.onReplyToMessages.forEach(function (reply) {
// Message from the same chat
if (reply.chatId === message.chat.id) {
// Responding to that message
if (reply.messageId === message.reply_to_message.message_id) {
// Resolve the promise
reply.callback(message);
}
}
});
}
} else if (editedMessage) {
debug('Process Update edited_message %j', editedMessage);
this.emit('edited_message', editedMessage);
if (editedMessage.text) {
this.emit('edited_message_text', editedMessage);
}
if (editedMessage.caption) {
this.emit('edited_message_caption', editedMessage);
}
} else if (channelPost) {
debug('Process Update channel_post %j', channelPost);
this.emit('channel_post', channelPost);
} else if (editedChannelPost) {
debug('Process Update edited_channel_post %j', editedChannelPost);
this.emit('edited_channel_post', editedChannelPost);
if (editedChannelPost.text) {
this.emit('edited_channel_post_text', editedChannelPost);
}
if (editedChannelPost.caption) {
this.emit('edited_channel_post_caption', editedChannelPost);
}
} else if (inlineQuery) {
debug('Process Update inline_query %j', inlineQuery);
this.emit('inline_query', inlineQuery);
} else if (chosenInlineResult) {
debug('Process Update chosen_inline_result %j', chosenInlineResult);
this.emit('chosen_inline_result', chosenInlineResult);
} else if (callbackQuery) {
debug('Process Update callback_query %j', callbackQuery);
this.emit('callback_query', callbackQuery);
}
}
// used so that other funcs are not non-optimizable
}, {
key: '_safeParse',
value: function _safeParse(json) {
try {
return JSON.parse(json);
} catch (err) {
throw new Error('Error parsing Telegram response: ' + String(json));
}
}
}, {
key: '_fixReplyMarkup',

@@ -212,3 +151,2 @@ value: function _fixReplyMarkup(obj) {

if (replyMarkup && typeof replyMarkup !== 'string') {
// reply_markup must be passed as JSON stringified to Telegram
obj.reply_markup = JSON.stringify(replyMarkup);

@@ -218,3 +156,9 @@ }

// request-promise
/**
* Make request against the API
* @param {String} _path API endpoint
* @param {Object} [options]
* @private
* @return {Promise}
*/

@@ -224,4 +168,2 @@ }, {

value: function _request(_path) {
var _this3 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -243,2 +185,4 @@

}
options.method = 'POST';
options.url = this._buildURL(_path);

@@ -251,6 +195,17 @@ options.simple = false;

if (resp.statusCode !== 200) {
throw new Error(resp.statusCode + ' ' + resp.body);
var _error = new Error(resp.statusCode + ' ' + resp.body);
_error.response = resp;
throw _error;
}
var data = _this3._safeParse(resp.body);
var data = void 0;
try {
data = JSON.parse(resp.body);
} catch (err) {
var _error2 = new Error('Error parsing Telegram response: ' + resp.body);
_error2.response = resp;
throw _error2;
}
if (data.ok) {

@@ -260,3 +215,6 @@ return data.result;

throw new Error(data.error_code + ' ' + data.description);
var error = new Error(data.error_code + ' ' + data.description);
error.response = resp;
error.response.body = data;
throw error;
});

@@ -266,20 +224,175 @@ }

/**
* Generates url with bot token and provided path/method you want to be got/executed by bot
* @return {String} url
* @param {String} path
* Format data to be uploaded; handles file paths, streams and buffers
* @param {String} type
* @param {String|stream.Stream|Buffer} data
* @return {Array} formatted
* @return {Object} formatted[0] formData
* @return {String} formatted[1] fileId
* @throws Error if Buffer file type is not supported.
* @see https://npmjs.com/package/file-type
* @private
* @see https://core.telegram.org/bots/api#making-requests
*/
}, {
key: '_buildURL',
value: function _buildURL(_path) {
return URL.format({
protocol: 'https',
host: 'api.telegram.org',
pathname: '/bot' + this.token + '/' + _path
});
key: '_formatSendData',
value: function _formatSendData(type, data) {
var formData = void 0;
var fileName = void 0;
var fileId = void 0;
if (data instanceof stream.Stream) {
fileName = URL.parse(path.basename(data.path.toString())).pathname;
formData = {};
formData[type] = {
value: data,
options: {
filename: qs.unescape(fileName),
contentType: mime.lookup(fileName)
}
};
} else if (Buffer.isBuffer(data)) {
var filetype = fileType(data);
if (!filetype) {
throw new Error('Unsupported Buffer file type');
}
formData = {};
formData[type] = {
value: data,
options: {
filename: 'data.' + filetype.ext,
contentType: filetype.mime
}
};
} else if (!this.options.filepath) {
/**
* When the constructor option 'filepath' is set to
* 'false', we do not support passing file-paths.
*/
fileId = data;
} else if (fs.existsSync(data)) {
fileName = path.basename(data);
formData = {};
formData[type] = {
value: fs.createReadStream(data),
options: {
filename: fileName,
contentType: mime.lookup(fileName)
}
};
} else {
fileId = data;
}
return [formData, fileId];
}
/**
* Start polling.
* Rejects returned promise if a WebHook is being used by this instance.
* @param {Object} [options]
* @param {Boolean} [options.restart=true] Consecutive calls to this method causes polling to be restarted
* @return {Promise}
*/
}, {
key: 'startPolling',
value: function startPolling() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this.hasOpenWebHook()) {
return Promise.reject(new Error('Polling and WebHook are mutually exclusive'));
}
options.restart = typeof options.restart === 'undefined' ? true : options.restart;
if (!this._polling) {
this._polling = new TelegramBotPolling(this._request.bind(this), this.options.polling, this.processUpdate.bind(this));
}
return this._polling.start(options);
}
/**
* Alias of `TelegramBot#startPolling()`. This is **deprecated**.
* @param {Object} [options]
* @return {Promise}
* @deprecated
*/
}, {
key: 'initPolling',
value: function initPolling() {
deprecate('TelegramBot#initPolling() is deprecated');
return this.startPolling();
}
/**
* Stops polling after the last polling request resolves.
* Multiple invocations do nothing if polling is already stopped.
* Returning the promise of the last polling request is **deprecated**.
* @return {Promise}
*/
}, {
key: 'stopPolling',
value: function stopPolling() {
if (!this._polling) {
return Promise.resolve();
}
return this._polling.stop();
}
/**
* Return true if polling. Otherwise, false.
* @return {Boolean}
*/
}, {
key: 'isPolling',
value: function isPolling() {
return this._polling ? this._polling.isPolling() : false;
}
/**
* Open webhook.
* Multiple invocations do nothing if webhook is already open.
* Rejects returned promise if Polling is being used by this instance.
* @return {Promise}
*/
}, {
key: 'openWebHook',
value: function openWebHook() {
if (this.isPolling()) {
return Promise.reject(new Error('WebHook and Polling are mutually exclusive'));
}
if (!this._webHook) {
this._webHook = new TelegramBotWebHook(this.token, this.options.webHook, this.processUpdate.bind(this));
}
return this._webHook.open();
}
/**
* Close webhook after closing all current connections.
* Multiple invocations do nothing if webhook is already closed.
* @return {Promise} promise
*/
}, {
key: 'closeWebHook',
value: function closeWebHook() {
if (!this._webHook) {
return Promise.resolve();
}
return this._webHook.close();
}
/**
* Return true if using webhook and it is open i.e. accepts connections.
* Otherwise, false.
* @return {Boolean}
*/
}, {
key: 'hasOpenWebHook',
value: function hasOpenWebHook() {
return this._webHook ? this._webHook.isOpen() : false;
}
/**
* Returns basic information about the bot in form of a `User` object.

@@ -299,5 +412,10 @@ * @return {Promise}

* Specify an url to receive incoming updates via an outgoing webHook.
* @param {String} url URL where Telegram will make HTTP Post. Leave empty to
* 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 {String|stream.Stream} [cert] PEM certificate key (public).
* @param {Object} [options] Additional Telegram query options
* @param {String|stream.Stream} [options.certificate] PEM certificate key (public).
* @return {Promise}
* @see https://core.telegram.org/bots/api#setwebhook

@@ -308,17 +426,34 @@ */

key: 'setWebHook',
value: function setWebHook(url, cert) {
var _path = 'setWebHook';
var opts = { qs: { url: url } };
value: function setWebHook(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
/* The older method signature was setWebHook(url, cert).
* We need to ensure backwards-compatibility while maintaining
* consistency of the method signatures throughout the library */
var cert = void 0;
// Note: 'options' could be an object, if a stream was provided (in place of 'cert')
if ((typeof options === 'undefined' ? 'undefined' : _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;
}
var opts = {
qs: options
};
opts.qs.url = url;
if (cert) {
var _formatSendData2 = this._formatSendData('certificate', cert),
_formatSendData3 = _slicedToArray(_formatSendData2, 2),
formData = _formatSendData3[0],
certificate = _formatSendData3[1];
opts.formData = formData;
opts.qs.certificate = certificate;
try {
var sendData = this._formatSendData('certificate', cert);
opts.formData = sendData[0];
opts.qs.certificate = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
}
return this._request(_path, opts).then(function (resp) {
return this._request('setWebHook', opts).then(function (resp) {
if (!resp) {

@@ -333,7 +468,36 @@ throw new Error(resp);

/**
* Use this method to receive incoming updates using long polling
* @param {Number|String} [timeout] Timeout in seconds for long polling.
* @param {Number|String} [limit] Limits the number of updates to be retrieved.
* @param {Number|String} [offset] Identifier of the first update to be returned.
* @return {Promise} Updates
* Use this method to remove webhook integration if you decide to
* switch back to getUpdates. Returns True on success.
* @return {Promise}
* @see https://core.telegram.org/bots/api#deletewebhook
*/
}, {
key: 'deleteWebHook',
value: function deleteWebHook() {
return this._request('deleteWebhook');
}
/**
* 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.
* @return {Promise}
* @see https://core.telegram.org/bots/api#getwebhookinfo
*/
}, {
key: 'getWebHookInfo',
value: function getWebHookInfo() {
return this._request('getWebhookInfo');
}
/**
* 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

@@ -344,9 +508,19 @@ */

key: 'getUpdates',
value: function getUpdates(timeout, limit, offset) {
var form = {
offset: offset,
limit: limit,
timeout: timeout
};
value: function getUpdates() {
var form = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
/* 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 === 'undefined' ? 'undefined' : _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: form });

@@ -356,2 +530,94 @@ }

/**
* 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
*/
}, {
key: 'processUpdate',
value: function processUpdate(update) {
var _this2 = this;
debug('Process Update %j', update);
var message = update.message;
var editedMessage = update.edited_message;
var channelPost = update.channel_post;
var editedChannelPost = update.edited_channel_post;
var inlineQuery = update.inline_query;
var chosenInlineResult = update.chosen_inline_result;
var callbackQuery = update.callback_query;
if (message) {
debug('Process Update message %j', message);
this.emit('message', message);
var processMessageType = function processMessageType(messageType) {
if (message[messageType]) {
debug('Emitting %s: %j', messageType, message);
_this2.emit(messageType, message);
}
};
TelegramBot.messageTypes.forEach(processMessageType);
if (message.text) {
debug('Text message');
this._textRegexpCallbacks.some(function (reg) {
debug('Matching %s with %s', message.text, reg.regexp);
var result = reg.regexp.exec(message.text);
if (!result) {
return false;
}
debug('Matches %s', reg.regexp);
reg.callback(message, result);
// returning truthy value exits .some
return _this2.options.onlyFirstMatch;
});
}
if (message.reply_to_message) {
// Only callbacks waiting for this message
this._onReplyToMessages.forEach(function (reply) {
// Message from the same chat
if (reply.chatId === message.chat.id) {
// Responding to that message
if (reply.messageId === message.reply_to_message.message_id) {
// Resolve the promise
reply.callback(message);
}
}
});
}
} else if (editedMessage) {
debug('Process Update edited_message %j', editedMessage);
this.emit('edited_message', editedMessage);
if (editedMessage.text) {
this.emit('edited_message_text', editedMessage);
}
if (editedMessage.caption) {
this.emit('edited_message_caption', editedMessage);
}
} else if (channelPost) {
debug('Process Update channel_post %j', channelPost);
this.emit('channel_post', channelPost);
} else if (editedChannelPost) {
debug('Process Update edited_channel_post %j', editedChannelPost);
this.emit('edited_channel_post', editedChannelPost);
if (editedChannelPost.text) {
this.emit('edited_channel_post_text', editedChannelPost);
}
if (editedChannelPost.caption) {
this.emit('edited_channel_post_caption', editedChannelPost);
}
} else if (inlineQuery) {
debug('Process Update inline_query %j', inlineQuery);
this.emit('inline_query', inlineQuery);
} else if (chosenInlineResult) {
debug('Process Update chosen_inline_result %j', chosenInlineResult);
this.emit('chosen_inline_result', chosenInlineResult);
} else if (callbackQuery) {
debug('Process Update callback_query %j', callbackQuery);
this.emit('callback_query', callbackQuery);
}
}
/**
* Send text message.

@@ -400,2 +666,3 @@ * @param {Number|String} chatId Unique identifier for the message recipient

* @param {Number|String} messageId Unique message identifier
* @param {Object} [options] Additional Telegram query options
* @return {Promise}

@@ -407,54 +674,9 @@ */

value: function forwardMessage(chatId, fromChatId, messageId) {
var form = {
chat_id: chatId,
from_chat_id: fromChatId,
message_id: messageId
};
var form = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
form.chat_id = chatId;
form.from_chat_id = fromChatId;
form.message_id = messageId;
return this._request('forwardMessage', { form: form });
}
}, {
key: '_formatSendData',
value: function _formatSendData(type, data) {
var formData = void 0;
var fileName = void 0;
var fileId = void 0;
if (data instanceof stream.Stream) {
fileName = URL.parse(path.basename(data.path.toString())).pathname;
formData = {};
formData[type] = {
value: data,
options: {
filename: qs.unescape(fileName),
contentType: mime.lookup(fileName)
}
};
} else if (Buffer.isBuffer(data)) {
var filetype = fileType(data);
if (!filetype) {
throw new Error('Unsupported Buffer file type');
}
formData = {};
formData[type] = {
value: data,
options: {
filename: 'data.' + filetype.ext,
contentType: filetype.mime
}
};
} else if (fs.existsSync(data)) {
fileName = path.basename(data);
formData = {};
formData[type] = {
value: fs.createReadStream(data),
options: {
filename: fileName,
contentType: mime.lookup(fileName)
}
};
} else {
fileId = data;
}
return [formData, fileId];
}

@@ -480,5 +702,9 @@ /**

opts.qs.chat_id = chatId;
var content = this._formatSendData('photo', photo);
opts.formData = content[0];
opts.qs.photo = content[1];
try {
var sendData = this._formatSendData('photo', photo);
opts.formData = sendData[0];
opts.qs.photo = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendPhoto', opts);

@@ -506,5 +732,9 @@ }

opts.qs.chat_id = chatId;
var content = this._formatSendData('audio', audio);
opts.formData = content[0];
opts.qs.audio = content[1];
try {
var sendData = this._formatSendData('audio', audio);
opts.formData = sendData[0];
opts.qs.audio = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendAudio', opts);

@@ -534,5 +764,9 @@ }

opts.qs.chat_id = chatId;
var content = this._formatSendData('document', doc);
opts.formData = content[0];
opts.qs.document = content[1];
try {
var sendData = this._formatSendData('document', doc);
opts.formData = sendData[0];
opts.qs.document = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
if (opts.formData && Object.keys(fileOpts).length) {

@@ -563,5 +797,9 @@ opts.formData.document.options = fileOpts;

opts.qs.chat_id = chatId;
var content = this._formatSendData('sticker', sticker);
opts.formData = content[0];
opts.qs.sticker = content[1];
try {
var sendData = this._formatSendData('sticker', sticker);
opts.formData = sendData[0];
opts.qs.sticker = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendSticker', opts);

@@ -589,5 +827,9 @@ }

opts.qs.chat_id = chatId;
var content = this._formatSendData('video', video);
opts.formData = content[0];
opts.qs.video = content[1];
try {
var sendData = this._formatSendData('video', video);
opts.formData = sendData[0];
opts.qs.video = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendVideo', opts);

@@ -615,5 +857,9 @@ }

opts.qs.chat_id = chatId;
var content = this._formatSendData('voice', voice);
opts.formData = content[0];
opts.qs.voice = content[1];
try {
var sendData = this._formatSendData('voice', voice);
opts.formData = sendData[0];
opts.qs.voice = sendData[1];
} catch (ex) {
return Promise.reject(ex);
}
return this._request('sendVoice', opts);

@@ -787,6 +1033,7 @@ }

* 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} userId Unique identifier of the target user
* @param {Number} [offset] Sequential number of the first photo to be returned. By default, all photos are returned.
* @param {Number} [limit] Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100.
* @param {Object} [options] Additional Telegram query options
* @return {Promise}

@@ -798,8 +1045,18 @@ * @see https://core.telegram.org/bots/api#getuserprofilephotos

key: 'getUserProfilePhotos',
value: function getUserProfilePhotos(userId, offset, limit) {
var form = {
user_id: userId,
offset: offset,
limit: limit
};
value: function getUserProfilePhotos(userId) {
var form = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
/* 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 === 'undefined' ? 'undefined' : _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: form });

@@ -914,10 +1171,6 @@ }

value: function getFileLink(fileId) {
var _this4 = this;
var _this3 = this;
return this.getFile(fileId).then(function (resp) {
return URL.format({
protocol: 'https',
host: 'api.telegram.org',
pathname: '/file/bot' + _this4.token + '/' + resp.file_path
});
return _this3.options.baseApiUrl + '/file/bot' + _this3.token + '/' + resp.file_path;
});

@@ -960,3 +1213,3 @@ }

value: function onText(regexp, callback) {
this.textRegexpCallbacks.push({ regexp: regexp, callback: callback });
this._textRegexpCallbacks.push({ regexp: regexp, callback: callback });
}

@@ -975,3 +1228,3 @@

value: function onReplyToMessage(chatId, messageId, callback) {
this.onReplyToMessages.push({
this._onReplyToMessages.push({
chatId: chatId,

@@ -978,0 +1231,0 @@ messageId: messageId,

@@ -7,10 +7,17 @@ 'use strict';

var Promise = require('bluebird');
var debug = require('debug')('node-telegram-bot-api');
var request = require('request-promise');
var URL = require('url');
var ANOTHER_WEB_HOOK_USED = 409;
var TelegramBotPolling = function () {
function TelegramBotPolling(token) {
/**
* Handles polling against the Telegram servers.
*
* @param {Function} request Function used to make HTTP requests
* @param {Boolean|Object} options Polling options
* @param {Number} [options.timeout=10] Timeout in seconds for long polling
* @param {Number} [options.interval=300] Interval between requests in milliseconds
* @param {Function} callback Function for processing a new update
* @see https://core.telegram.org/bots/api#getupdates
*/
function TelegramBotPolling(request) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -21,42 +28,112 @@ var callback = arguments[2];

// enable cancellation
Promise.config({
cancellation: true
});
/* eslint-disable no-param-reassign */
if (typeof options === 'function') {
callback = options; // eslint-disable-line no-param-reassign
options = {}; // eslint-disable-line no-param-reassign
callback = options;
options = {};
} else if (typeof options === 'boolean') {
options = {};
}
/* eslint-enable no-param-reassign */
this.offset = 0;
this.token = token;
this.request = request;
this.options = options;
this.options.timeout = typeof options.timeout === 'number' ? options.timeout : 10;
this.options.interval = typeof options.interval === 'number' ? options.interval : 300;
this.callback = callback;
this.timeout = options.timeout || 10;
this.interval = typeof options.interval === 'number' ? options.interval : 300;
this.lastUpdate = 0;
this.lastRequest = null;
this.abort = false;
this._polling();
this._offset = 0;
this._lastUpdate = 0;
this._lastRequest = null;
this._abort = false;
this._pollingTimeout = null;
}
/**
* Start polling
* @param {Object} [options]
* @param {Object} [options.restart]
* @return {Promise}
*/
_createClass(TelegramBotPolling, [{
key: 'stopPolling',
value: function stopPolling() {
this.abort = true;
// wait until the last request is fulfilled
return this.lastRequest;
key: 'start',
value: function start() {
var _this = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this._lastRequest) {
if (!options.restart) {
return Promise.resolve();
}
return this.stop({
cancel: true,
reason: 'Polling restart'
}).then(function () {
return _this._polling();
});
}
return this._polling();
}
/**
* Stop polling
* @param {Object} [options]
* @param {Boolean} [options.cancel] Cancel current request
* @param {String} [options.reason] Reason for stopping polling
* @return {Promise}
*/
}, {
key: 'stop',
value: function stop() {
var _this2 = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!this._lastRequest) {
return Promise.resolve();
}
var lastRequest = this._lastRequest;
this._lastRequest = null;
clearTimeout(this._pollingTimeout);
if (options.cancel) {
var reason = options.reason || 'Polling stop';
lastRequest.cancel(reason);
return Promise.resolve();
}
this._abort = true;
return lastRequest.finally(function () {
_this2._abort = false;
});
}
/**
* Return `true` if is polling. Otherwise, `false`.
*/
}, {
key: 'isPolling',
value: function isPolling() {
return !!this._lastRequest;
}
/**
* Invokes polling (with recursion!)
* @return {Promise} promise of the current request
* @private
*/
}, {
key: '_polling',
value: function _polling() {
var _this = this;
var _this3 = this;
this.lastRequest = this._getUpdates().then(function (updates) {
_this.lastUpdate = Date.now();
this._lastRequest = this._getUpdates().then(function (updates) {
_this3._lastUpdate = Date.now();
debug('polling data %j', updates);
updates.forEach(function (update) {
_this.offset = update.update_id;
debug('updated offset: %s', _this.offset);
_this.callback(update);
_this3._offset = update.update_id;
debug('updated offset: %s', _this3._offset);
_this3.callback(update);
});

@@ -67,80 +144,50 @@ }).catch(function (err) {

}).finally(function () {
if (_this.abort) {
if (_this3._abort) {
debug('Polling is aborted!');
} else {
debug('setTimeout for %s miliseconds', _this.interval);
setTimeout(function () {
return _this._polling();
}, _this.interval);
debug('setTimeout for %s miliseconds', _this3.options.interval);
_this3._pollingTimeout = setTimeout(function () {
return _this3._polling();
}, _this3.options.interval);
}
});
return this._lastRequest;
}
// used so that other funcs are not non-optimizable
/**
* Unset current webhook. Used when we detect that a webhook has been set
* and we are trying to poll. Polling and WebHook are mutually exclusive.
* @see https://core.telegram.org/bots/api#getting-updates
* @private
*/
}, {
key: '_safeParse',
value: function _safeParse(json) {
try {
return JSON.parse(json);
} catch (err) {
throw new Error('Error parsing Telegram response: ' + String(json));
}
}
}, {
key: '_unsetWebHook',
value: function _unsetWebHook() {
return request({
url: URL.format({
protocol: 'https',
host: 'api.telegram.org',
pathname: '/bot' + this.token + '/setWebHook'
}),
simple: false,
resolveWithFullResponse: true
}).promise().then(function (resp) {
if (!resp) {
throw new Error(resp);
}
return [];
});
return this.request('setWebHook');
}
/**
* Retrieve updates
*/
}, {
key: '_getUpdates',
value: function _getUpdates() {
var _this2 = this;
var _this4 = this;
var opts = {
qs: {
offset: this.offset + 1,
limit: this.limit,
timeout: this.timeout
},
url: URL.format({
protocol: 'https',
host: 'api.telegram.org',
pathname: '/bot' + this.token + '/getUpdates'
}),
simple: false,
resolveWithFullResponse: true,
forever: true
offset: this._offset + 1,
limit: this.options.limit,
timeout: this.options.timeout
}
};
debug('polling with options: %j', opts);
return request(opts).promise().timeout((10 + this.timeout) * 1000).then(function (resp) {
if (resp.statusCode === ANOTHER_WEB_HOOK_USED) {
return _this2._unsetWebHook();
return this.request('getUpdates', opts).catch(function (err) {
if (err.response.statusCode === ANOTHER_WEB_HOOK_USED) {
return _this4._unsetWebHook();
}
if (resp.statusCode !== 200) {
throw new Error(resp.statusCode + ' ' + resp.body);
}
var data = _this2._safeParse(resp.body);
if (data.ok) {
return data.result;
}
throw new Error(data.error_code + ' ' + data.description);
throw err;
});

@@ -147,0 +194,0 @@ }

@@ -12,47 +12,16 @@ 'use strict';

var bl = require('bl');
var Promise = require('bluebird');
var TelegramBotWebHook = function () {
/**
* Sets up a webhook to receive updates
*
* @param {String} token Telegram API token
* @param {Boolean|Object} options WebHook options
* @param {Number} [options.port=8443] Port to bind to
* @param {Function} callback Function for process a new update
*/
function TelegramBotWebHook(token, options, callback) {
var _this = this;
_classCallCheck(this, TelegramBotWebHook);
this._parseBody = function (err, body) {
if (err) {
return debug(err);
}
var data = _this._safeParse(body);
if (data) {
return _this.callback(data);
}
return null;
};
this._requestListener = function (req, res) {
debug('WebHook request URL: %s', req.url);
debug('WebHook request headers: %j', req.headers);
// If there isn't token on URL
if (!_this.regex.test(req.url)) {
debug('WebHook request unauthorized');
res.statusCode = 401;
res.end();
} else if (req.method === 'POST') {
req.pipe(bl(_this._parseBody)).on('finish', function () {
return res.end('OK');
});
} else {
// Authorized but not a POST
debug('WebHook request isn\'t a POST');
res.statusCode = 418; // I'm a teabot!
res.end();
}
};
this.token = token;
this.callback = callback;
this.regex = new RegExp(this.token);
// define opts

@@ -62,12 +31,26 @@ if (typeof options === 'boolean') {

}
options.port = options.port || 8443;
if (options.key && options.cert) {
// HTTPS Server
debug('HTTPS WebHook enabled');
var opts = {
key: fs.readFileSync(options.key),
cert: fs.readFileSync(options.cert)
};
this._webServer = https.createServer(opts, this._requestListener);
this.token = token;
this.options = options;
this.options.port = options.port || 8443;
this.options.https = options.https || {};
this.callback = callback;
this._regex = new RegExp(this.token);
this._webServer = null;
this._open = false;
this._requestListener = this._requestListener.bind(this);
this._parseBody = this._parseBody.bind(this);
if (this.options.key && this.options.cert) {
debug('HTTPS WebHook enabled (by key/cert)');
this.options.https.key = fs.readFileSync(this.options.key);
this.options.https.cert = fs.readFileSync(this.options.cert);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (this.options.pfx) {
debug('HTTPS WebHook enabled (by pfx)');
this.options.https.pfx = fs.readFileSync(this.options.pfx);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (Object.keys(this.options.https).length) {
debug('HTTPS WebHook enabled by (https)');
this._webServer = https.createServer(this.options.https, this._requestListener);
} else {

@@ -77,12 +60,67 @@ debug('HTTP WebHook enabled');

}
this._webServer.listen(options.port, options.host, function () {
debug('WebHook listening on port %s', options.port);
});
}
// used so that other funcs are not non-optimizable
/**
* Open WebHook by listening on the port
* @return {Promise}
*/
_createClass(TelegramBotWebHook, [{
key: 'open',
value: function open() {
var _this = this;
if (this.isOpen()) {
return Promise.resolve();
}
return new Promise(function (resolve) {
_this._webServer.listen(_this.options.port, _this.options.host, function () {
debug('WebHook listening on port %s', _this.options.port);
_this._open = true;
return resolve();
});
});
}
/**
* Close the webHook
* @return {Promise}
*/
}, {
key: 'close',
value: function close() {
var _this2 = this;
if (!this.isOpen()) {
return Promise.resolve();
}
return new Promise(function (resolve, reject) {
_this2._webServer.close(function (error) {
if (error) return reject(error);
_this2._open = false;
return resolve();
});
});
}
/**
* Return `true` if server is listening. Otherwise, `false`.
*/
}, {
key: 'isOpen',
value: function isOpen() {
// NOTE: Since `http.Server.listening` was added in v5.7.0
// and we still need to support Node v4,
// we are going to fallback to 'this._open'.
// The following LOC would suffice for newer versions of Node.js
// return this._webServer.listening;
return this._open;
}
// used so that other funcs are not non-optimizable
}, {
key: '_safeParse',

@@ -98,7 +136,51 @@ value: function _safeParse(json) {

// pipe+parse body
/**
* Handle request body by passing it to 'callback'
* @private
*/
}, {
key: '_parseBody',
value: function _parseBody(err, body) {
if (err) {
return debug(err);
}
// bound req listener
var data = this._safeParse(body);
if (data) {
return this.callback(data);
}
return null;
}
/**
* Listener for 'request' event on server
* @private
* @see https://nodejs.org/docs/latest/api/http.html#http_http_createserver_requestlistener
* @see https://nodejs.org/docs/latest/api/https.html#https_https_createserver_options_requestlistener
*/
}, {
key: '_requestListener',
value: function _requestListener(req, res) {
debug('WebHook request URL: %s', req.url);
debug('WebHook request headers: %j', req.headers);
// If there isn't token on URL
if (!this._regex.test(req.url)) {
debug('WebHook request unauthorized');
res.statusCode = 401;
res.end();
} else if (req.method === 'POST') {
req.pipe(bl(this._parseBody)).on('finish', function () {
return res.end('OK');
});
} else {
// Authorized but not a POST
debug('WebHook request isn\'t a POST');
res.statusCode = 418; // I'm a teabot!
res.end();
}
}
}]);

@@ -105,0 +187,0 @@

{
"name": "node-telegram-bot-api",
"version": "0.25.0",
"version": "0.26.0",
"description": "Telegram Bot API",
"main": "./lib/telegram.js",
"main": "./index.js",
"directories": {

@@ -17,10 +17,15 @@ "example": "examples",

"scripts": {
"prepublish": "babel -d ./lib src",
"test": "istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec --timeout 10000",
"prepublish:test": "npm run prepublish && npm run test",
"gen-doc": "jsdoc2md --src src/telegram.js -t README.hbs > README.md",
"eslint": "eslint ./src"
"gen-doc": "jsdoc2md --files src/telegram.js --template doc/api.hbs > doc/api.md",
"build": "babel -d ./lib src",
"prepublish": "npm run build && npm run gen-doc",
"eslint": "eslint ./src ./test ./examples",
"mocha": "mocha",
"pretest": "npm run build",
"test": "npm run eslint && istanbul cover ./node_modules/mocha/bin/_mocha"
},
"author": "Yago Pérez <yagoperezs@gmail.com>",
"license": "MIT",
"engines": {
"node" : ">=0.12"
},
"dependencies": {

@@ -30,4 +35,5 @@ "bl": "^1.1.2",

"debug": "^2.2.0",
"eventemitter3": "^1.2.0",
"file-type": "^3.8.0",
"depd": "^1.1.0",
"eventemitter3": "^2.0.2",
"file-type": "^3.9.0",
"mime": "^1.3.4",

@@ -40,3 +46,3 @@ "pump": "^1.0.1",

"babel-cli": "^6.6.5",
"babel-eslint": "^6.0.4",
"babel-eslint": "^6.1.2",
"babel-plugin-transform-class-properties": "^6.6.0",

@@ -52,10 +58,11 @@ "babel-plugin-transform-es2015-destructuring": "^6.6.5",

"contributor": "^0.1.25",
"eslint": "^2.11.1",
"eslint-config-airbnb": "^6.1.0",
"eslint-plugin-mocha": "^2.0.0",
"eslint": "^2.13.1",
"eslint-config-airbnb": "^6.2.0",
"eslint-plugin-mocha": "^4.8.0",
"is": "^3.1.0",
"istanbul": "^1.1.0-alpha.1",
"jsdoc-to-markdown": "^1.3.3",
"mocha": "^2.4.5",
"mocha-lcov-reporter": "^1.2.0"
"jsdoc-to-markdown": "^2.0.1",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.2.0",
"node-static": "^0.7.9"
},

@@ -72,7 +79,43 @@ "repository": {

{
"name": "Sebastian Troć",
"email": "sebastian.troc@gucman.pl",
"url": "https://github.com/SebastianTroc",
"name": "Mohammed Sohail",
"email": "sohailsameja@gmail.com",
"url": "https://github.com/kamikazechaser",
"contributions": 1,
"additions": 18,
"deletions": 4,
"hireable": true
},
{
"name": "Alexander Tarmolov",
"email": "tarmolov@gmail.com",
"url": "https://github.com/tarmolov",
"contributions": 1,
"additions": 5,
"deletions": 0,
"hireable": null
},
{
"name": "Plusb Preco",
"email": "plusb21@gmail.com",
"url": "https://github.com/preco21",
"contributions": 1,
"additions": 1,
"deletions": 0,
"hireable": null
},
{
"name": null,
"email": null,
"url": "https://github.com/GingerPlusPlus",
"contributions": 1,
"additions": 6,
"deletions": 2,
"hireable": null
},
{
"name": "Sergey Bogdanov",
"email": "sergey.bogdanov@gmail.com",
"url": "https://github.com/desunit",
"contributions": 1,
"additions": 1,
"deletions": 1,

@@ -82,7 +125,25 @@ "hireable": null

{
"name": "Cristian Baldi",
"email": "bld.cris.96@gmail.com",
"url": "https://github.com/crisbal",
"contributions": 2,
"additions": 26,
"name": "Mikhail Burshteyn",
"email": null,
"url": "https://github.com/m-burst",
"contributions": 1,
"additions": 12,
"deletions": 5,
"hireable": null
},
{
"name": "Ola Flisbäck",
"email": null,
"url": "https://github.com/oflisback",
"contributions": 1,
"additions": 3,
"deletions": 3,
"hireable": true
},
{
"name": "Horus Lugo",
"email": "horusgoul@gmail.com",
"url": "https://github.com/HorusGoul",
"contributions": 1,
"additions": 108,
"deletions": 1,

@@ -92,2 +153,38 @@ "hireable": true

{
"name": "Serhii Dmytruk",
"email": "dmitruksergey@gmail.com",
"url": "https://github.com/serhiidmytruk",
"contributions": 1,
"additions": 35,
"deletions": 1,
"hireable": null
},
{
"name": "Conor Fennell",
"email": null,
"url": "https://github.com/conorfennell",
"contributions": 1,
"additions": 50,
"deletions": 1,
"hireable": null
},
{
"name": "Matthew Brandly",
"email": "matt@brandly.me",
"url": "https://github.com/brandly",
"contributions": 1,
"additions": 1,
"deletions": 1,
"hireable": null
},
{
"name": "Anton",
"email": null,
"url": "https://github.com/Feverqwe",
"contributions": 1,
"additions": 23,
"deletions": 5,
"hireable": null
},
{
"name": "Patricio López Juri",

@@ -102,8 +199,8 @@ "email": "patricio@lopezjuri.com",

{
"name": "Anton",
"email": null,
"url": "https://github.com/Feverqwe",
"name": "Aleksandr L.",
"email": "w.siteee@gmail.com",
"url": "https://github.com/w-site",
"contributions": 1,
"additions": 23,
"deletions": 5,
"additions": 24,
"deletions": 0,
"hireable": null

@@ -121,5 +218,5 @@ },

{
"name": "Matthew Brandly",
"email": "matt@brandly.me",
"url": "https://github.com/brandly",
"name": "Sebastian Troć",
"email": "sebastian.troc@gucman.pl",
"url": "https://github.com/SebastianTroc",
"contributions": 1,

@@ -131,20 +228,65 @@ "additions": 1,

{
"name": "Vítor Augusto da Silva Vasconcellos",
"email": "vasvas10@gmail.com",
"url": "https://github.com/HeavenVolkoff",
"name": "Jérémy Gotteland",
"email": null,
"url": "https://github.com/Tketa",
"contributions": 2,
"additions": 12,
"deletions": 0,
"additions": 81,
"deletions": 3,
"hireable": null
},
{
"name": "Rafael Kr",
"name": "Alex Godko",
"email": "koloboid@gmail.com",
"url": "https://github.com/koloboid",
"contributions": 2,
"additions": 2,
"deletions": 2,
"hireable": true
},
{
"name": "Iiro Jäppinen",
"email": null,
"url": "https://github.com/RafaelKr",
"contributions": 3,
"additions": 3,
"deletions": 2,
"url": "https://github.com/iiroj",
"contributions": 2,
"additions": 40,
"deletions": 0,
"hireable": null
},
{
"name": "Dardan Neziri",
"email": "dard.ne@gmail.com",
"url": "https://github.com/knock-in",
"contributions": 2,
"additions": 22,
"deletions": 16,
"hireable": true
},
{
"name": "Jishnu Mohan",
"email": "jishnu7@gmail.com",
"url": "https://github.com/jishnu7",
"contributions": 2,
"additions": 84,
"deletions": 0,
"hireable": true
},
{
"name": "TJ Horner",
"email": "me@tjhorner.com",
"url": "https://github.com/tjhorner",
"contributions": 2,
"additions": 223,
"deletions": 1,
"hireable": null
},
{
"name": null,
"email": "plo.cav@gmail.com",
"url": "https://github.com/evolun",
"contributions": 2,
"additions": 7,
"deletions": 3,
"hireable": null
},
{
"name": "Vitaly Aminev",

@@ -159,2 +301,11 @@ "email": null,

{
"name": "Vítor Augusto da Silva Vasconcellos",
"email": "vasvas10@gmail.com",
"url": "https://github.com/HeavenVolkoff",
"contributions": 2,
"additions": 12,
"deletions": 0,
"hireable": true
},
{
"name": "Rey",

@@ -169,2 +320,11 @@ "email": null,

{
"name": "Rafael Kr",
"email": null,
"url": "https://github.com/RafaelKr",
"contributions": 3,
"additions": 3,
"deletions": 2,
"hireable": null
},
{
"name": "Ivan Skorokhodov",

@@ -179,8 +339,8 @@ "email": "iskorokhodov@gmail.com",

{
"name": "Ilias Ismanalijev",
"email": "hello@illyism.com",
"url": "https://github.com/Illyism",
"contributions": 7,
"additions": 140,
"deletions": 10,
"name": "Riddler",
"email": null,
"url": "https://github.com/Waterloo",
"contributions": 3,
"additions": 64,
"deletions": 2,
"hireable": true

@@ -198,17 +358,44 @@ },

{
"name": "Riddler",
"name": "Chris54721",
"email": null,
"url": "https://github.com/Waterloo",
"contributions": 3,
"additions": 64,
"deletions": 2,
"url": "https://github.com/chris54721",
"contributions": 5,
"additions": 22,
"deletions": 6,
"hireable": null
},
{
"name": "Ilias Ismanalijev",
"email": "hello@illyism.com",
"url": "https://github.com/Illyism",
"contributions": 7,
"additions": 140,
"deletions": 10,
"hireable": true
},
{
"name": "Gocho Mugo",
"email": "mugo@forfuture.co.ke",
"url": "https://github.com/GochoMugo",
"contributions": 56,
"additions": 3779,
"deletions": 2167,
"hireable": true
},
{
"name": "Cristian Baldi",
"email": "bld.cris.96@gmail.com",
"url": "https://github.com/crisbal",
"contributions": 2,
"additions": 26,
"deletions": 1,
"hireable": true
},
{
"name": "Yago",
"email": "yago@yago.me",
"url": "https://github.com/yagop",
"contributions": 169,
"additions": 2676,
"deletions": 1091,
"contributions": 194,
"additions": 3014,
"deletions": 1173,
"hireable": true

@@ -215,0 +402,0 @@ }

@@ -1,5 +0,12 @@

[![Build Status](https://travis-ci.org/yagop/node-telegram-bot-api.svg?branch=master)](https://travis-ci.org/yagop/node-telegram-bot-api) [![Build status](https://ci.appveyor.com/api/projects/status/ujko6bsum3g5msjh/branch/master?svg=true)](https://ci.appveyor.com/project/yagop/node-telegram-bot-api/branch/master) [![Coverage Status](https://coveralls.io/repos/yagop/node-telegram-bot-api/badge.svg?branch=master)](https://coveralls.io/r/yagop/node-telegram-bot-api?branch=master) [![bitHound Score](https://www.bithound.io/github/yagop/node-telegram-bot-api/badges/score.svg)](https://www.bithound.io/github/yagop/node-telegram-bot-api) [![https://telegram.me/node_telegram_bot_api](https://img.shields.io/badge/💬 Telegram-node__telegram__bot__api-blue.svg)](https://telegram.me/node_telegram_bot_api) [![https://telegram.me/Yago_Perez](https://img.shields.io/badge/💬 Telegram-Yago__Perez-blue.svg)](https://telegram.me/Yago_Perez)
[![Build Status](https://travis-ci.org/yagop/node-telegram-bot-api.svg?branch=master)](https://travis-ci.org/yagop/node-telegram-bot-api)
[![Build status](https://ci.appveyor.com/api/projects/status/ujko6bsum3g5msjh/branch/master?svg=true)](https://ci.appveyor.com/project/yagop/node-telegram-bot-api/branch/master)
[![Coverage Status](https://coveralls.io/repos/yagop/node-telegram-bot-api/badge.svg?branch=master)](https://coveralls.io/r/yagop/node-telegram-bot-api?branch=master)
[![bitHound Score](https://www.bithound.io/github/yagop/node-telegram-bot-api/badges/score.svg)](https://www.bithound.io/github/yagop/node-telegram-bot-api)
[![https://telegram.me/node_telegram_bot_api](https://img.shields.io/badge/💬 Telegram-node__telegram__bot__api-blue.svg)](https://telegram.me/node_telegram_bot_api)
[![https://telegram.me/Yago_Perez](https://img.shields.io/badge/💬 Telegram-Yago__Perez-blue.svg)](https://telegram.me/Yago_Perez)
Node.js module to interact with official [Telegram Bot API](https://core.telegram.org/bots/api). A bot token is needed, to obtain one, talk to [@botfather](https://telegram.me/BotFather) and create a new bot.
**Installation:**
```sh

@@ -9,2 +16,4 @@ npm install node-telegram-bot-api

**Sample Usage:**
```js

@@ -42,624 +51,54 @@ var TelegramBot = require('node-telegram-bot-api');

There are some other examples on [examples](https://github.com/yagop/node-telegram-bot-api/tree/master/examples).
### Events
Every time TelegramBot receives a message, it emits a `message`. Depending on which [message](https://core.telegram.org/bots/api#message) was received, emits an event from this ones: `text`, `audio`, `document`, `photo`, `sticker`, `video`, `voice`, `contact`, `location`, `new_chat_participant`, `left_chat_participant`, `new_chat_title`, `new_chat_photo`, `delete_chat_photo`, `group_chat_created`. Its much better to listen a specific event rather than a `message` in order to stay safe from the content.
TelegramBot emits `callback_query` when receives a [Callback Query](https://core.telegram.org/bots/api#callbackquery).
TelegramBot emits `inline_query` when receives an [Inline Query](https://core.telegram.org/bots/api#inlinequery) and `chosen_inline_result` when receives a [ChosenInlineResult](https://core.telegram.org/bots/api#choseninlineresult). Bot must be enabled on [inline mode](https://core.telegram.org/bots/api#inline-mode).
TelegramBot emits `channel_post` on a new incoming channel post of any kind.
TelegramBot emits `edited_message` when a message is edited, and also `edited_message_text` or `edited_message_caption` depending on which type of message was edited.
TelegramBot emits `edited_channel_post` when a channel post is edited, and also `edited_channel_post_text` or `edited_channel_post_caption` depending on which type of channel post was edited.
* * *
### WebHooks
Telegram only supports HTTPS connections to WebHooks, in order to set a WebHook a private key file and public certificate must be used. Since August 29, 2015 Telegram supports self signed ones, to generate them:
```bash
# Our private cert will be key.pem, keep in private this file.
openssl genrsa -out key.pem 2048
# Our public certificate will be crt.pem
openssl req -new -sha256 -key key.pem -out crt.pem
```
Once they are generated, the `crt.pem` can be provided to `telegramBot.setWebHook(url, crt)` as `crt`.
## Documentation
## API Reference
<a name="TelegramBot"></a>
* Usage ([release][usage-release] / [development][usage-dev])
* Examples ([release][examples-release] / [development][examples-dev])
* Help Information ([release][help-release] / [development][help-dev])
* API Reference ([release][api-release] / [development][api-dev])
* [Contributing to the Project][contributing]
## TelegramBot
TelegramBot
_**Note**: Development is done against the **master** branch. Code for the latest release
resides on the **release** branch._
**Kind**: global class
**See**: https://core.telegram.org/bots/api
[usage-release]:https://github.com/yagop/node-telegram-bot-api/tree/release/doc/usage.md
[examples-release]:https://github.com/yagop/node-telegram-bot-api/tree/release/doc/help.md
[help-release]:https://github.com/yagop/node-telegram-bot-api/tree/release/examples
[api-release]:https://github.com/yagop/node-telegram-bot-api/tree/release/doc/api.md
* [TelegramBot](#TelegramBot)
* [new TelegramBot(token, [options])](#new_TelegramBot_new)
* [.stopPolling()](#TelegramBot+stopPolling) ⇒ <code>Promise</code>
* [.getMe()](#TelegramBot+getMe) ⇒ <code>Promise</code>
* [.setWebHook(url, [cert])](#TelegramBot+setWebHook)
* [.getUpdates([timeout], [limit], [offset])](#TelegramBot+getUpdates) ⇒ <code>Promise</code>
* [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ <code>Promise</code>
* [.answerInlineQuery(inlineQueryId, results, [options])](#TelegramBot+answerInlineQuery) ⇒ <code>Promise</code>
* [.forwardMessage(chatId, fromChatId, messageId)](#TelegramBot+forwardMessage) ⇒ <code>Promise</code>
* [.sendPhoto(chatId, photo, [options])](#TelegramBot+sendPhoto) ⇒ <code>Promise</code>
* [.sendAudio(chatId, audio, [options])](#TelegramBot+sendAudio) ⇒ <code>Promise</code>
* [.sendDocument(chatId, doc, [options], [fileOpts])](#TelegramBot+sendDocument) ⇒ <code>Promise</code>
* [.sendSticker(chatId, sticker, [options])](#TelegramBot+sendSticker) ⇒ <code>Promise</code>
* [.sendVideo(chatId, video, [options])](#TelegramBot+sendVideo) ⇒ <code>Promise</code>
* [.sendVoice(chatId, voice, [options])](#TelegramBot+sendVoice) ⇒ <code>Promise</code>
* [.sendChatAction(chatId, action)](#TelegramBot+sendChatAction) ⇒ <code>Promise</code>
* [.kickChatMember(chatId, userId)](#TelegramBot+kickChatMember) ⇒ <code>Promise</code>
* [.unbanChatMember(chatId, userId)](#TelegramBot+unbanChatMember) ⇒ <code>Promise</code>
* [.answerCallbackQuery(callbackQueryId, text, showAlert, [options])](#TelegramBot+answerCallbackQuery) ⇒ <code>Promise</code>
* [.editMessageText(text, [options])](#TelegramBot+editMessageText) ⇒ <code>Promise</code>
* [.editMessageCaption(caption, [options])](#TelegramBot+editMessageCaption) ⇒ <code>Promise</code>
* [.editMessageReplyMarkup(replyMarkup, [options])](#TelegramBot+editMessageReplyMarkup) ⇒ <code>Promise</code>
* [.getUserProfilePhotos(userId, [offset], [limit])](#TelegramBot+getUserProfilePhotos) ⇒ <code>Promise</code>
* [.sendLocation(chatId, latitude, longitude, [options])](#TelegramBot+sendLocation) ⇒ <code>Promise</code>
* [.sendVenue(chatId, latitude, longitude, title, address, [options])](#TelegramBot+sendVenue) ⇒ <code>Promise</code>
* [.sendContact(chatId, phoneNumber, firstName, [options])](#TelegramBot+sendContact) ⇒ <code>Promise</code>
* [.getFile(fileId)](#TelegramBot+getFile) ⇒ <code>Promise</code>
* [.getFileLink(fileId)](#TelegramBot+getFileLink) ⇒ <code>Promise</code>
* [.downloadFile(fileId, downloadDir)](#TelegramBot+downloadFile) ⇒ <code>Promise</code>
* [.onText(regexp, callback)](#TelegramBot+onText)
* [.onReplyToMessage(chatId, messageId, callback)](#TelegramBot+onReplyToMessage)
* [.getChat(chatId)](#TelegramBot+getChat) ⇒ <code>Promise</code>
* [.getChatAdministrators(chatId)](#TelegramBot+getChatAdministrators) ⇒ <code>Promise</code>
* [.getChatMembersCount(chatId)](#TelegramBot+getChatMembersCount) ⇒ <code>Promise</code>
* [.getChatMember(chatId, userId)](#TelegramBot+getChatMember) ⇒ <code>Promise</code>
* [.leaveChat(chatId)](#TelegramBot+leaveChat) ⇒ <code>Promise</code>
* [.sendGame(chatId, gameShortName, [options])](#TelegramBot+sendGame) ⇒ <code>Promise</code>
* [.setGameScore(userId, score, [options])](#TelegramBot+setGameScore) ⇒ <code>Promise</code>
* [.getGameHighScores(userId, [options])](#TelegramBot+getGameHighScores) ⇒ <code>Promise</code>
[usage-dev]:https://github.com/yagop/node-telegram-bot-api/tree/master/doc/usage.md
[examples-dev]:https://github.com/yagop/node-telegram-bot-api/tree/master/doc/help.md
[help-dev]:https://github.com/yagop/node-telegram-bot-api/tree/master/examples
[api-dev]:https://github.com/yagop/node-telegram-bot-api/tree/master/doc/api.md
[contributing]:https://github.com/yagop/node-telegram-bot-api/tree/master/CONTRIBUTING.md
<a name="new_TelegramBot_new"></a>
### new TelegramBot(token, [options])
Both request method to obtain messages are implemented. To use standard polling, set `polling: true`
on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a SSL certificate.
Emits `message` when a message arrives.
* * *
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| token | <code>String</code> | | Bot Token |
| [options] | <code>Object</code> | | |
| [options.polling] | <code>Boolean</code> &#124; <code>Object</code> | <code>false</code> | Set true to enable polling or set options |
| [options.polling.timeout] | <code>String</code> &#124; <code>Number</code> | <code>10</code> | Polling time in seconds |
| [options.polling.interval] | <code>String</code> &#124; <code>Number</code> | <code>2000</code> | Interval between requests in miliseconds |
| [options.webHook] | <code>Boolean</code> &#124; <code>Object</code> | <code>false</code> | Set true to enable WebHook or set options |
| [options.webHook.key] | <code>String</code> | | PEM private key to webHook server. |
| [options.webHook.cert] | <code>String</code> | | PEM certificate (public) to webHook server. |
| [options.onlyFirstMatch] | <code>Boolean</code> | <code>false</code> | Set to true to stop after first match. Otherwise, all regexps are executed |
| [options.request] | <code>Object</code> | | Options which will be added for all requests to telegram api. See https://github.com/request/request#requestoptions-callback for more information. |
## Our Community
<a name="TelegramBot+stopPolling"></a>
We have a [Telegram channel][tg-channel] where we post updates on
the Project. Head over and subscribe!
### telegramBot.stopPolling() ⇒ <code>Promise</code>
Stops polling after the last polling request resolves
Some things built using this library, and might interest you:
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**Returns**: <code>Promise</code> - promise Promise, of last polling request
<a name="TelegramBot+getMe"></a>
* [tgfancy](https://github.com/GochoMugo/tgfancy): A Fancy, Higher-Level Wrapper for Telegram Bot API
* [node-telegram-bot-api-middleware](https://github.com/idchlife/node-telegram-bot-api-middleware): Middleware for node-telegram-bot-api
* [teleirc](https://github.com/FruitieX/teleirc): A simple Telegram ↔ IRC gateway
### telegramBot.getMe() ⇒ <code>Promise</code>
Returns basic information about the bot in form of a `User` object.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getme
<a name="TelegramBot+setWebHook"></a>
* * *
### telegramBot.setWebHook(url, [cert])
Specify an url to receive incoming updates via an outgoing webHook.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#setwebhook
## License Information
| Param | Type | Description |
| --- | --- | --- |
| url | <code>String</code> | URL where Telegram will make HTTP Post. Leave empty to delete webHook. |
| [cert] | <code>String</code> &#124; <code>stream.Stream</code> | PEM certificate key (public). |
**The MIT License (MIT)**
<a name="TelegramBot+getUpdates"></a>
Copyright (c) 2015 Yago
### telegramBot.getUpdates([timeout], [limit], [offset]) ⇒ <code>Promise</code>
Use this method to receive incoming updates using long polling
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**Returns**: <code>Promise</code> - Updates
**See**: https://core.telegram.org/bots/api#getupdates
| Param | Type | Description |
| --- | --- | --- |
| [timeout] | <code>Number</code> &#124; <code>String</code> | Timeout in seconds for long polling. |
| [limit] | <code>Number</code> &#124; <code>String</code> | Limits the number of updates to be retrieved. |
| [offset] | <code>Number</code> &#124; <code>String</code> | Identifier of the first update to be returned. |
<a name="TelegramBot+sendMessage"></a>
### telegramBot.sendMessage(chatId, text, [options]) ⇒ <code>Promise</code>
Send text message.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendmessage
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| text | <code>String</code> | Text of the message to be sent |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+answerInlineQuery"></a>
### telegramBot.answerInlineQuery(inlineQueryId, results, [options]) ⇒ <code>Promise</code>
Send answers to an inline query.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#answerinlinequery
| Param | Type | Description |
| --- | --- | --- |
| inlineQueryId | <code>String</code> | Unique identifier of the query |
| results | <code>Array.&lt;InlineQueryResult&gt;</code> | An array of results for the inline query |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+forwardMessage"></a>
### telegramBot.forwardMessage(chatId, fromChatId, messageId) ⇒ <code>Promise</code>
Forward messages of any kind.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| fromChatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the chat where the original message was sent |
| messageId | <code>Number</code> &#124; <code>String</code> | Unique message identifier |
<a name="TelegramBot+sendPhoto"></a>
### telegramBot.sendPhoto(chatId, photo, [options]) ⇒ <code>Promise</code>
Send photo
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendphoto
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| photo | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or a Stream. Can also be a `file_id` previously uploaded |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendAudio"></a>
### telegramBot.sendAudio(chatId, audio, [options]) ⇒ <code>Promise</code>
Send audio
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendaudio
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| audio | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendDocument"></a>
### telegramBot.sendDocument(chatId, doc, [options], [fileOpts]) ⇒ <code>Promise</code>
Send Document
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendDocument
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| doc | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options |
| [fileOpts] | <code>Object</code> | Optional file related meta-data |
<a name="TelegramBot+sendSticker"></a>
### telegramBot.sendSticker(chatId, sticker, [options]) ⇒ <code>Promise</code>
Send .webp stickers.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendsticker
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| sticker | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. Stickers are WebP format files. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendVideo"></a>
### telegramBot.sendVideo(chatId, video, [options]) ⇒ <code>Promise</code>
Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as Document).
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendvideo
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| video | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path or Stream. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendVoice"></a>
### telegramBot.sendVoice(chatId, voice, [options]) ⇒ <code>Promise</code>
Send voice
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendvoice
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| voice | <code>String</code> &#124; <code>stream.Stream</code> &#124; <code>Buffer</code> | A file path, Stream or Buffer. Can also be a `file_id` previously uploaded. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendChatAction"></a>
### telegramBot.sendChatAction(chatId, action) ⇒ <code>Promise</code>
Send chat action.
`typing` for text messages,
`upload_photo` for photos, `record_video` or `upload_video` for videos,
`record_audio` or `upload_audio` for audio files, `upload_document` for general files,
`find_location` for location data.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendchataction
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| action | <code>String</code> | Type of action to broadcast. |
<a name="TelegramBot+kickChatMember"></a>
### telegramBot.kickChatMember(chatId, userId) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#kickchatmember
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup |
| userId | <code>String</code> | Unique identifier of the target user |
<a name="TelegramBot+unbanChatMember"></a>
### telegramBot.unbanChatMember(chatId, userId) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#unbanchatmember
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup |
| userId | <code>String</code> | Unique identifier of the target user |
<a name="TelegramBot+answerCallbackQuery"></a>
### telegramBot.answerCallbackQuery(callbackQueryId, text, showAlert, [options]) ⇒ <code>Promise</code>
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.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#answercallbackquery
| Param | Type | Description |
| --- | --- | --- |
| callbackQueryId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the query to be answered |
| text | <code>String</code> | Text of the notification. If not specified, nothing will be shown to the user |
| showAlert | <code>Boolean</code> | Whether to show an alert or a notification at the top of the screen |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+editMessageText"></a>
### telegramBot.editMessageText(text, [options]) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#editmessagetext
| Param | Type | Description |
| --- | --- | --- |
| text | <code>String</code> | New text of the message |
| [options] | <code>Object</code> | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) |
<a name="TelegramBot+editMessageCaption"></a>
### telegramBot.editMessageCaption(caption, [options]) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#editmessagecaption
| Param | Type | Description |
| --- | --- | --- |
| caption | <code>String</code> | New caption of the message |
| [options] | <code>Object</code> | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) |
<a name="TelegramBot+editMessageReplyMarkup"></a>
### telegramBot.editMessageReplyMarkup(replyMarkup, [options]) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#editmessagetext
| Param | Type | Description |
| --- | --- | --- |
| replyMarkup | <code>Object</code> | A JSON-serialized object for an inline keyboard. |
| [options] | <code>Object</code> | Additional Telegram query options (provide either one of chat_id, message_id, or inline_message_id here) |
<a name="TelegramBot+getUserProfilePhotos"></a>
### telegramBot.getUserProfilePhotos(userId, [offset], [limit]) ⇒ <code>Promise</code>
Use this method to get a list of profile pictures for a user.
Returns a [UserProfilePhotos](https://core.telegram.org/bots/api#userprofilephotos) object.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getuserprofilephotos
| Param | Type | Description |
| --- | --- | --- |
| userId | <code>Number</code> &#124; <code>String</code> | Unique identifier of the target user |
| [offset] | <code>Number</code> | Sequential number of the first photo to be returned. By default, all photos are returned. |
| [limit] | <code>Number</code> | Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100. |
<a name="TelegramBot+sendLocation"></a>
### telegramBot.sendLocation(chatId, latitude, longitude, [options]) ⇒ <code>Promise</code>
Send location.
Use this method to send point on the map.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendlocation
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| latitude | <code>Float</code> | Latitude of location |
| longitude | <code>Float</code> | Longitude of location |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendVenue"></a>
### telegramBot.sendVenue(chatId, latitude, longitude, title, address, [options]) ⇒ <code>Promise</code>
Send venue.
Use this method to send information about a venue.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendvenue
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| latitude | <code>Float</code> | Latitude of location |
| longitude | <code>Float</code> | Longitude of location |
| title | <code>String</code> | Name of the venue |
| address | <code>String</code> | Address of the venue |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+sendContact"></a>
### telegramBot.sendContact(chatId, phoneNumber, firstName, [options]) ⇒ <code>Promise</code>
Send contact.
Use this method to send phone contacts.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendcontact
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| phoneNumber | <code>String</code> | Contact's phone number |
| firstName | <code>String</code> | Contact's first name |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+getFile"></a>
### telegramBot.getFile(fileId) ⇒ <code>Promise</code>
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.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getfile
| Param | Type | Description |
| --- | --- | --- |
| fileId | <code>String</code> | File identifier to get info about |
<a name="TelegramBot+getFileLink"></a>
### telegramBot.getFileLink(fileId) ⇒ <code>Promise</code>
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 <code>[TelegramBot](#TelegramBot)</code>
**Returns**: <code>Promise</code> - promise Promise which will have *fileURI* in resolve callback
**See**: https://core.telegram.org/bots/api#getfile
| Param | Type | Description |
| --- | --- | --- |
| fileId | <code>String</code> | File identifier to get info about |
<a name="TelegramBot+downloadFile"></a>
### telegramBot.downloadFile(fileId, downloadDir) ⇒ <code>Promise</code>
Downloads file in the specified folder.
This is just a sugar for (getFile)[#getfilefiled] method
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**Returns**: <code>Promise</code> - promise Promise, which will have *filePath* of downloaded file in resolve callback
| Param | Type | Description |
| --- | --- | --- |
| fileId | <code>String</code> | File identifier to get info about |
| downloadDir | <code>String</code> | Absolute path to the folder in which file will be saved |
<a name="TelegramBot+onText"></a>
### telegramBot.onText(regexp, callback)
Register a RegExp to test against an incomming text message.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
| Param | Type | Description |
| --- | --- | --- |
| regexp | <code>RegExp</code> | RegExp to be executed with `exec`. |
| callback | <code>function</code> | Callback will be called with 2 parameters, the `msg` and the result of executing `regexp.exec` on message text. |
<a name="TelegramBot+onReplyToMessage"></a>
### telegramBot.onReplyToMessage(chatId, messageId, callback)
Register a reply to wait for a message response.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | The chat id where the message cames from. |
| messageId | <code>Number</code> &#124; <code>String</code> | The message id to be replied. |
| callback | <code>function</code> | Callback will be called with the reply message. |
<a name="TelegramBot+getChat"></a>
### telegramBot.getChat(chatId) ⇒ <code>Promise</code>
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.).
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getchat
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target chat or username of the target supergroup or channel |
<a name="TelegramBot+getChatAdministrators"></a>
### telegramBot.getChatAdministrators(chatId) ⇒ <code>Promise</code>
Returns the administrators in a chat in form of an Array of `ChatMember` objects.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getchatadministrators
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup |
<a name="TelegramBot+getChatMembersCount"></a>
### telegramBot.getChatMembersCount(chatId) ⇒ <code>Promise</code>
Use this method to get the number of members in a chat.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getchatmemberscount
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup |
<a name="TelegramBot+getChatMember"></a>
### telegramBot.getChatMember(chatId, userId) ⇒ <code>Promise</code>
Use this method to get information about a member of a chat.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getchatmember
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup |
| userId | <code>String</code> | Unique identifier of the target user |
<a name="TelegramBot+leaveChat"></a>
### telegramBot.leaveChat(chatId) ⇒ <code>Promise</code>
Leave a group, supergroup or channel.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#leavechat
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the target group or username of the target supergroup (in the format @supergroupusername) |
<a name="TelegramBot+sendGame"></a>
### telegramBot.sendGame(chatId, gameShortName, [options]) ⇒ <code>Promise</code>
Use this method to send a game.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#sendgame
| Param | Type | Description |
| --- | --- | --- |
| chatId | <code>Number</code> &#124; <code>String</code> | Unique identifier for the message recipient |
| gameShortName | <code>String</code> | name of the game to be sent. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+setGameScore"></a>
### telegramBot.setGameScore(userId, score, [options]) ⇒ <code>Promise</code>
Use this method to set the score of the specified user in a game.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#setgamescore
| Param | Type | Description |
| --- | --- | --- |
| userId | <code>String</code> | Unique identifier of the target user |
| score | <code>Number</code> | New score value. |
| [options] | <code>Object</code> | Additional Telegram query options |
<a name="TelegramBot+getGameHighScores"></a>
### telegramBot.getGameHighScores(userId, [options]) ⇒ <code>Promise</code>
Use this method to get data for high score table.
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
**See**: https://core.telegram.org/bots/api#getgamehighscores
| Param | Type | Description |
| --- | --- | --- |
| userId | <code>String</code> | Unique identifier of the target user |
| [options] | <code>Object</code> | Additional Telegram query options |
* * *
[tg-channel]:https://telegram.me/node_telegram_bot_api

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc