mirror of
https://github.com/yagop/node-telegram-bot-api
synced 2025-09-02 07:15:34 +00:00
[webhook,polling] Improve starting, stopping of webhook, polling
Feature: The different mechanisms of fetching updates, i.e. polling and webhook, have had their implementations improved: * the TelegramBot instance needs to create the polling and webhook instances once, and when necessary * returning promises from TelegramBot#openWebHook() and TelegramBot#startPolling() allows more precise control Also, * TelegramBot#initPolling() is being deprecated in favor of TelegramBot#startPolling() to ensure consistency (as the opposite action of TelegramBot#stopPolling())
This commit is contained in:
43
README.md
43
README.md
@@ -71,10 +71,11 @@ TelegramBot
|
|||||||
|
|
||||||
* [TelegramBot](#TelegramBot)
|
* [TelegramBot](#TelegramBot)
|
||||||
* [new TelegramBot(token, [options])](#new_TelegramBot_new)
|
* [new TelegramBot(token, [options])](#new_TelegramBot_new)
|
||||||
* [.initPolling()](#TelegramBot+initPolling)
|
* [.startPolling([options])](#TelegramBot+startPolling) ⇒ <code>Promise</code>
|
||||||
|
* ~~[.initPolling([options])](#TelegramBot+initPolling) ⇒ <code>Promise</code>~~
|
||||||
* [.stopPolling()](#TelegramBot+stopPolling) ⇒ <code>Promise</code>
|
* [.stopPolling()](#TelegramBot+stopPolling) ⇒ <code>Promise</code>
|
||||||
* [.isPolling()](#TelegramBot+isPolling) ⇒ <code>Boolean</code>
|
* [.isPolling()](#TelegramBot+isPolling) ⇒ <code>Boolean</code>
|
||||||
* [.openWebHook()](#TelegramBot+openWebHook)
|
* [.openWebHook()](#TelegramBot+openWebHook) ⇒ <code>Promise</code>
|
||||||
* [.closeWebHook()](#TelegramBot+closeWebHook) ⇒ <code>Promise</code>
|
* [.closeWebHook()](#TelegramBot+closeWebHook) ⇒ <code>Promise</code>
|
||||||
* [.hasOpenWebHook()](#TelegramBot+hasOpenWebHook) ⇒ <code>Boolean</code>
|
* [.hasOpenWebHook()](#TelegramBot+hasOpenWebHook) ⇒ <code>Boolean</code>
|
||||||
* [.getMe()](#TelegramBot+getMe) ⇒ <code>Promise</code>
|
* [.getMe()](#TelegramBot+getMe) ⇒ <code>Promise</code>
|
||||||
@@ -144,19 +145,39 @@ Emits `message` when a message arrives.
|
|||||||
| [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. |
|
| [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. |
|
||||||
| [options.baseApiUrl] | <code>String</code> | <code>https://api.telegram.org</code> | API Base URl; useful for proxying and testing |
|
| [options.baseApiUrl] | <code>String</code> | <code>https://api.telegram.org</code> | API Base URl; useful for proxying and testing |
|
||||||
|
|
||||||
<a name="TelegramBot+initPolling"></a>
|
<a name="TelegramBot+startPolling"></a>
|
||||||
|
|
||||||
### telegramBot.initPolling()
|
### telegramBot.startPolling([options]) ⇒ <code>Promise</code>
|
||||||
Start polling
|
Start polling.
|
||||||
|
|
||||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
|
|
||||||
|
| Param | Type | Default | Description |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| [options] | <code>Object</code> | | |
|
||||||
|
| [options.restart] | <code>Boolean</code> | <code>true</code> | Consecutive calls to this method causes polling to be restarted |
|
||||||
|
|
||||||
|
<a name="TelegramBot+initPolling"></a>
|
||||||
|
|
||||||
|
### ~~telegramBot.initPolling([options]) ⇒ <code>Promise</code>~~
|
||||||
|
***Deprecated***
|
||||||
|
|
||||||
|
Alias of `TelegramBot#startPolling()`. This is **deprecated**.
|
||||||
|
|
||||||
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
|
|
||||||
|
| Param | Type |
|
||||||
|
| --- | --- |
|
||||||
|
| [options] | <code>Object</code> |
|
||||||
|
|
||||||
<a name="TelegramBot+stopPolling"></a>
|
<a name="TelegramBot+stopPolling"></a>
|
||||||
|
|
||||||
### telegramBot.stopPolling() ⇒ <code>Promise</code>
|
### telegramBot.stopPolling() ⇒ <code>Promise</code>
|
||||||
Stops polling after the last polling request resolves
|
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**.
|
||||||
|
|
||||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
**Returns**: <code>Promise</code> - promise Promise, of last polling request
|
|
||||||
<a name="TelegramBot+isPolling"></a>
|
<a name="TelegramBot+isPolling"></a>
|
||||||
|
|
||||||
### telegramBot.isPolling() ⇒ <code>Boolean</code>
|
### telegramBot.isPolling() ⇒ <code>Boolean</code>
|
||||||
@@ -165,14 +186,16 @@ Return true if polling. Otherwise, false.
|
|||||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
<a name="TelegramBot+openWebHook"></a>
|
<a name="TelegramBot+openWebHook"></a>
|
||||||
|
|
||||||
### telegramBot.openWebHook()
|
### telegramBot.openWebHook() ⇒ <code>Promise</code>
|
||||||
Open webhook
|
Open webhook.
|
||||||
|
Multiple invocations do nothing if webhook is already open.
|
||||||
|
|
||||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
<a name="TelegramBot+closeWebHook"></a>
|
<a name="TelegramBot+closeWebHook"></a>
|
||||||
|
|
||||||
### telegramBot.closeWebHook() ⇒ <code>Promise</code>
|
### telegramBot.closeWebHook() ⇒ <code>Promise</code>
|
||||||
Close webhook after closing all current connections
|
Close webhook after closing all current connections.
|
||||||
|
Multiple invocations do nothing if webhook is already closed.
|
||||||
|
|
||||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||||
**Returns**: <code>Promise</code> - promise
|
**Returns**: <code>Promise</code> - promise
|
||||||
|
@@ -72,11 +72,13 @@ class TelegramBot extends EventEmitter {
|
|||||||
this.options.baseApiUrl = options.baseApiUrl || 'https://api.telegram.org';
|
this.options.baseApiUrl = options.baseApiUrl || 'https://api.telegram.org';
|
||||||
this._textRegexpCallbacks = [];
|
this._textRegexpCallbacks = [];
|
||||||
this._onReplyToMessages = [];
|
this._onReplyToMessages = [];
|
||||||
|
this._polling = null;
|
||||||
|
this._webHook = null;
|
||||||
|
|
||||||
if (options.polling) {
|
if (options.polling) {
|
||||||
const autoStart = options.polling.autoStart;
|
const autoStart = options.polling.autoStart;
|
||||||
if (typeof autoStart === 'undefined' || autoStart === true) {
|
if (typeof autoStart === 'undefined' || autoStart === true) {
|
||||||
this.initPolling();
|
this.startPolling();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,29 +225,41 @@ class TelegramBot extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start polling
|
* Start polling.
|
||||||
|
* @param {Object} [options]
|
||||||
|
* @param {Boolean} [options.restart=true] Consecutive calls to this method causes polling to be restarted
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
initPolling() {
|
startPolling(options = {}) {
|
||||||
if (this._polling) {
|
options.restart = typeof options.restart === 'undefined' ? true : options.restart;
|
||||||
this._polling.stopPolling({
|
if (!this._polling) {
|
||||||
cancel: true,
|
this._polling = new TelegramBotPolling(this._request.bind(this), this.options.polling, this.processUpdate.bind(this));
|
||||||
reason: 'Polling restart',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this._polling = new TelegramBotPolling(this._request.bind(this), this.options.polling, this.processUpdate.bind(this));
|
return this._polling.start(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops polling after the last polling request resolves
|
* Alias of `TelegramBot#startPolling()`. This is **deprecated**.
|
||||||
* @return {Promise} promise Promise, of last polling request
|
* @param {Object} [options]
|
||||||
|
* @return {Promise}
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
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}
|
||||||
*/
|
*/
|
||||||
stopPolling() {
|
stopPolling() {
|
||||||
if (!this._polling) {
|
if (!this._polling) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
const polling = this._polling;
|
return this._polling.stop();
|
||||||
delete this._polling;
|
|
||||||
return polling.stopPolling();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -253,30 +267,31 @@ class TelegramBot extends EventEmitter {
|
|||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
isPolling() {
|
isPolling() {
|
||||||
return !!this._polling;
|
return this._polling ? this._polling.isPolling() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open webhook
|
* Open webhook.
|
||||||
|
* Multiple invocations do nothing if webhook is already open.
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
openWebHook() {
|
openWebHook() {
|
||||||
if (this._webHook) {
|
if (!this._webHook) {
|
||||||
return;
|
this._webHook = new TelegramBotWebHook(this.token, this.options.webHook, this.processUpdate.bind(this));
|
||||||
}
|
}
|
||||||
this._webHook = new TelegramBotWebHook(this.token, this.options.webHook, this.processUpdate.bind(this));
|
return this._webHook.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close webhook after closing all current connections
|
* Close webhook after closing all current connections.
|
||||||
|
* Multiple invocations do nothing if webhook is already closed.
|
||||||
* @return {Promise} promise
|
* @return {Promise} promise
|
||||||
*/
|
*/
|
||||||
closeWebHook() {
|
closeWebHook() {
|
||||||
if (!this._webHook) {
|
if (!this._webHook) {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
const webHook = this._webHook;
|
return this._webHook.close();
|
||||||
delete this._webHook;
|
|
||||||
return webHook.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -285,7 +300,7 @@ class TelegramBot extends EventEmitter {
|
|||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
hasOpenWebHook() {
|
hasOpenWebHook() {
|
||||||
return !!this._webHook;
|
return this._webHook ? this._webHook.isOpen() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -33,7 +33,27 @@ class TelegramBotPolling {
|
|||||||
this._lastRequest = null;
|
this._lastRequest = null;
|
||||||
this._abort = false;
|
this._abort = false;
|
||||||
this._pollingTimeout = null;
|
this._pollingTimeout = null;
|
||||||
this._polling();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start polling
|
||||||
|
* @param {Object} [options]
|
||||||
|
* @param {Object} [options.restart]
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
start(options = {}) {
|
||||||
|
if (this._lastRequest) {
|
||||||
|
if (!options.restart) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return this.stop({
|
||||||
|
cancel: true,
|
||||||
|
reason: 'Polling restart',
|
||||||
|
}).then(() => {
|
||||||
|
return this._polling();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this._polling();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,20 +61,36 @@ class TelegramBotPolling {
|
|||||||
* @param {Object} [options]
|
* @param {Object} [options]
|
||||||
* @param {Boolean} [options.cancel] Cancel current request
|
* @param {Boolean} [options.cancel] Cancel current request
|
||||||
* @param {String} [options.reason] Reason for stopping polling
|
* @param {String} [options.reason] Reason for stopping polling
|
||||||
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
stopPolling(options = {}) {
|
stop(options = {}) {
|
||||||
this._abort = true;
|
if (!this._lastRequest) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
const lastRequest = this._lastRequest;
|
||||||
|
this._lastRequest = null;
|
||||||
clearTimeout(this._pollingTimeout);
|
clearTimeout(this._pollingTimeout);
|
||||||
if (options.cancel) {
|
if (options.cancel) {
|
||||||
const reason = options.reason || 'Polling stop';
|
const reason = options.reason || 'Polling stop';
|
||||||
return this._lastRequest.cancel(reason);
|
lastRequest.cancel(reason);
|
||||||
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
// wait until the last request is fulfilled
|
this._abort = true;
|
||||||
return this._lastRequest;
|
return lastRequest.finally(() => {
|
||||||
|
this._abort = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return `true` if is polling. Otherwise, `false`.
|
||||||
|
*/
|
||||||
|
isPolling() {
|
||||||
|
return !!this._lastRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes polling (with recursion!)
|
* Invokes polling (with recursion!)
|
||||||
|
* @return {Promise} promise of the current request
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_polling() {
|
_polling() {
|
||||||
@@ -81,6 +117,7 @@ class TelegramBotPolling {
|
|||||||
this._pollingTimeout = setTimeout(() => this._polling(), this.options.interval);
|
this._pollingTimeout = setTimeout(() => this._polling(), this.options.interval);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return this._lastRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -47,12 +47,47 @@ class TelegramBotWebHook {
|
|||||||
debug('HTTP WebHook enabled');
|
debug('HTTP WebHook enabled');
|
||||||
this._webServer = http.createServer(this._requestListener);
|
this._webServer = http.createServer(this._requestListener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this._webServer.listen(this.options.port, this.options.host, () => {
|
/**
|
||||||
debug('WebHook listening on port %s', this.options.port);
|
* Open WebHook by listening on the port
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
open() {
|
||||||
|
if (this._webServer.listening) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this._webServer.listen(this.options.port, this.options.host, () => {
|
||||||
|
debug('WebHook listening on port %s', this.options.port);
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the webHook
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
if (!this._webServer.listening) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this._webServer.close(error => {
|
||||||
|
if (error) return reject(error);
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return `true` if server is listening. Otherwise, `false`.
|
||||||
|
*/
|
||||||
|
isOpen() {
|
||||||
|
return this._webServer.listening;
|
||||||
|
}
|
||||||
|
|
||||||
// used so that other funcs are not non-optimizable
|
// used so that other funcs are not non-optimizable
|
||||||
_safeParse(json) {
|
_safeParse(json) {
|
||||||
try {
|
try {
|
||||||
@@ -106,20 +141,6 @@ class TelegramBotWebHook {
|
|||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the webHook
|
|
||||||
* @return {Promise}
|
|
||||||
*/
|
|
||||||
close() {
|
|
||||||
const self = this;
|
|
||||||
return new Promise(function closePromise(resolve, reject) {
|
|
||||||
self._webServer.close(function closeCb(error) {
|
|
||||||
if (error) return reject(error);
|
|
||||||
return resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TelegramBotWebHook;
|
module.exports = TelegramBotWebHook;
|
||||||
|
@@ -178,10 +178,11 @@ describe('TelegramBot', function telegramSuite() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#initPolling', function initPollingSuite() {
|
describe('#startPolling', function initPollingSuite() {
|
||||||
it('initiates polling', function test() {
|
it('initiates polling', function test() {
|
||||||
testbot.initPolling();
|
return testbot.startPolling().then(() => {
|
||||||
return utils.isPollingMockServer(pollingPort);
|
return utils.isPollingMockServer(pollingPort);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -213,8 +214,9 @@ describe('TelegramBot', function telegramSuite() {
|
|||||||
|
|
||||||
describe('#openWebHook', function openWebHookSuite() {
|
describe('#openWebHook', function openWebHookSuite() {
|
||||||
it('opens webhook', function test() {
|
it('opens webhook', function test() {
|
||||||
testbot.openWebHook();
|
return testbot.openWebHook().then(() => {
|
||||||
return utils.hasOpenWebHook(webHookPort);
|
return utils.hasOpenWebHook(webHookPort);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user