mirror of
https://github.com/yagop/node-telegram-bot-api
synced 2025-08-31 14:25:57 +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)
|
||||
* [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>
|
||||
* [.isPolling()](#TelegramBot+isPolling) ⇒ <code>Boolean</code>
|
||||
* [.openWebHook()](#TelegramBot+openWebHook)
|
||||
* [.openWebHook()](#TelegramBot+openWebHook) ⇒ <code>Promise</code>
|
||||
* [.closeWebHook()](#TelegramBot+closeWebHook) ⇒ <code>Promise</code>
|
||||
* [.hasOpenWebHook()](#TelegramBot+hasOpenWebHook) ⇒ <code>Boolean</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.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()
|
||||
Start polling
|
||||
### telegramBot.startPolling([options]) ⇒ <code>Promise</code>
|
||||
Start polling.
|
||||
|
||||
**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>
|
||||
|
||||
### 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>
|
||||
**Returns**: <code>Promise</code> - promise Promise, of last polling request
|
||||
<a name="TelegramBot+isPolling"></a>
|
||||
|
||||
### telegramBot.isPolling() ⇒ <code>Boolean</code>
|
||||
@@ -165,14 +186,16 @@ Return true if polling. Otherwise, false.
|
||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||
<a name="TelegramBot+openWebHook"></a>
|
||||
|
||||
### telegramBot.openWebHook()
|
||||
Open webhook
|
||||
### telegramBot.openWebHook() ⇒ <code>Promise</code>
|
||||
Open webhook.
|
||||
Multiple invocations do nothing if webhook is already open.
|
||||
|
||||
**Kind**: instance method of <code>[TelegramBot](#TelegramBot)</code>
|
||||
<a name="TelegramBot+closeWebHook"></a>
|
||||
|
||||
### 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>
|
||||
**Returns**: <code>Promise</code> - promise
|
||||
|
@@ -72,11 +72,13 @@ class TelegramBot extends EventEmitter {
|
||||
this.options.baseApiUrl = options.baseApiUrl || 'https://api.telegram.org';
|
||||
this._textRegexpCallbacks = [];
|
||||
this._onReplyToMessages = [];
|
||||
this._polling = null;
|
||||
this._webHook = null;
|
||||
|
||||
if (options.polling) {
|
||||
const autoStart = options.polling.autoStart;
|
||||
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() {
|
||||
if (this._polling) {
|
||||
this._polling.stopPolling({
|
||||
cancel: true,
|
||||
reason: 'Polling restart',
|
||||
});
|
||||
startPolling(options = {}) {
|
||||
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));
|
||||
}
|
||||
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
|
||||
* @return {Promise} promise Promise, of last polling request
|
||||
* Alias of `TelegramBot#startPolling()`. This is **deprecated**.
|
||||
* @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() {
|
||||
if (!this._polling) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const polling = this._polling;
|
||||
delete this._polling;
|
||||
return polling.stopPolling();
|
||||
return this._polling.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,30 +267,31 @@ class TelegramBot extends EventEmitter {
|
||||
* @return {Boolean}
|
||||
*/
|
||||
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() {
|
||||
if (this._webHook) {
|
||||
return;
|
||||
if (!this._webHook) {
|
||||
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
|
||||
*/
|
||||
closeWebHook() {
|
||||
if (!this._webHook) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const webHook = this._webHook;
|
||||
delete this._webHook;
|
||||
return webHook.close();
|
||||
return this._webHook.close();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,7 +300,7 @@ class TelegramBot extends EventEmitter {
|
||||
* @return {Boolean}
|
||||
*/
|
||||
hasOpenWebHook() {
|
||||
return !!this._webHook;
|
||||
return this._webHook ? this._webHook.isOpen() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -33,7 +33,27 @@ class TelegramBotPolling {
|
||||
this._lastRequest = null;
|
||||
this._abort = false;
|
||||
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 {Boolean} [options.cancel] Cancel current request
|
||||
* @param {String} [options.reason] Reason for stopping polling
|
||||
* @return {Promise}
|
||||
*/
|
||||
stopPolling(options = {}) {
|
||||
this._abort = true;
|
||||
stop(options = {}) {
|
||||
if (!this._lastRequest) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const lastRequest = this._lastRequest;
|
||||
this._lastRequest = null;
|
||||
clearTimeout(this._pollingTimeout);
|
||||
if (options.cancel) {
|
||||
const reason = options.reason || 'Polling stop';
|
||||
return this._lastRequest.cancel(reason);
|
||||
lastRequest.cancel(reason);
|
||||
return Promise.resolve();
|
||||
}
|
||||
// wait until the last request is fulfilled
|
||||
return this._lastRequest;
|
||||
this._abort = true;
|
||||
return lastRequest.finally(() => {
|
||||
this._abort = false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return `true` if is polling. Otherwise, `false`.
|
||||
*/
|
||||
isPolling() {
|
||||
return !!this._lastRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes polling (with recursion!)
|
||||
* @return {Promise} promise of the current request
|
||||
* @private
|
||||
*/
|
||||
_polling() {
|
||||
@@ -81,6 +117,7 @@ class TelegramBotPolling {
|
||||
this._pollingTimeout = setTimeout(() => this._polling(), this.options.interval);
|
||||
}
|
||||
});
|
||||
return this._lastRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -47,12 +47,47 @@ class TelegramBotWebHook {
|
||||
debug('HTTP WebHook enabled');
|
||||
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
|
||||
_safeParse(json) {
|
||||
try {
|
||||
@@ -106,20 +141,6 @@ class TelegramBotWebHook {
|
||||
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;
|
||||
|
@@ -178,10 +178,11 @@ describe('TelegramBot', function telegramSuite() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#initPolling', function initPollingSuite() {
|
||||
describe('#startPolling', function initPollingSuite() {
|
||||
it('initiates polling', function test() {
|
||||
testbot.initPolling();
|
||||
return utils.isPollingMockServer(pollingPort);
|
||||
return testbot.startPolling().then(() => {
|
||||
return utils.isPollingMockServer(pollingPort);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -213,8 +214,9 @@ describe('TelegramBot', function telegramSuite() {
|
||||
|
||||
describe('#openWebHook', function openWebHookSuite() {
|
||||
it('opens webhook', function test() {
|
||||
testbot.openWebHook();
|
||||
return utils.hasOpenWebHook(webHookPort);
|
||||
return testbot.openWebHook().then(() => {
|
||||
return utils.hasOpenWebHook(webHookPort);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user