diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3450e4c..90c28fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
# Changelog
All notable changes to this project will be documented in this file.
+# [15.1.1] - 2023-04-29
+### fixed port conflict in webhook mode - [#303](https://github.com/windkh/node-red-contrib-telegrambot/issues/303)
+
# [15.1.0] - 2023-04-15
### fixed sendInvoice: startParameter removed - [#302](https://github.com/windkh/node-red-contrib-telegrambot/issues/302)
diff --git a/package.json b/package.json
index dad39d5..2d10807 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "node-red-contrib-telegrambot",
- "version": "15.1.0",
+ "version": "15.1.1",
"description": "Telegram bot nodes for Node-RED",
"dependencies": {
"bluebird": "^3.7.2",
diff --git a/telegrambot/99-telegrambot.html b/telegrambot/99-telegrambot.html
index 2f17ed8..ee83937 100644
--- a/telegrambot/99-telegrambot.html
+++ b/telegrambot/99-telegrambot.html
@@ -182,7 +182,7 @@
-
Tip: Webhook mode requires a HTTPS certificate. The certificate can also be a self-signed (=custom) one. If any of the host, key, certificate properties is left blank the bot will default to polling mode. If SSL termination is already handled by reverse proxy, key and certificate is not required.
+
Tip: Webhook mode requires a HTTPS certificate. The certificate can also be a self-signed (=custom) one. If any of the host, key, certificate properties is left blank the bot will default to send only mode. If SSL termination is already handled by reverse proxy, key and certificate is not required.
diff --git a/telegrambot/99-telegrambot.js b/telegrambot/99-telegrambot.js
index 0007a20..38e9258 100644
--- a/telegrambot/99-telegrambot.js
+++ b/telegrambot/99-telegrambot.js
@@ -17,8 +17,34 @@ module.exports = function (RED) {
});
let telegramBot = require('node-telegram-bot-api');
+ let telegramBotWebHook = require('node-telegram-bot-api/src/telegramWebHook');
+
let { SocksProxyAgent } = require('socks-proxy-agent');
+ // Orginal class is extended to be able to emit an event when getUpdates is called.
+ class telegramBotWebHookEx extends telegramBotWebHook {
+ constructor(bot) {
+ super(bot);
+ }
+
+ open() {
+ if (this.isOpen()) {
+ return Promise.resolve();
+ }
+ return new Promise((resolve, reject) => {
+ this._webServer.listen(this.options.port, this.options.host, () => {
+ // debug('WebHook listening on port %s', this.options.port);
+ this._open = true;
+ return resolve();
+ });
+
+ this._webServer.once('error', (err) => {
+ reject(err);
+ });
+ });
+ }
+ }
+
// Orginal class is extended to be able to emit an event when getUpdates is called.
class telegramBotEx extends telegramBot {
constructor(token, options = {}) {
@@ -39,6 +65,18 @@ module.exports = function (RED) {
return result;
}
+
+ openWebHook() {
+ if (this.isPolling()) {
+ return Promise.reject('WebHook and Polling are mutually exclusive');
+ }
+
+ if (!this._webHook) {
+ this._webHook = new telegramBotWebHookEx(this);
+ }
+
+ return this._webHook.open();
+ }
}
let botsByToken = {};
@@ -64,6 +102,7 @@ module.exports = function (RED) {
// first of all check if the token is used twice: in this case we abort
if (this.credentials !== undefined && this.credentials.token !== undefined) {
this.token = this.credentials.token;
+
let configNodeId = botsByToken[this.token];
if (configNodeId === undefined) {
botsByToken[self.token] = n.id;
@@ -207,7 +246,7 @@ module.exports = function (RED) {
if (this.botHost && (this.sslTerminated || (this.privateKey && this.certificate))) {
this.useWebhook = true;
} else {
- self.error('Configuration data for webhook is not complete. Defaulting to polling mode.');
+ self.error('Configuration data for webhook is not complete. Defaulting to send only mode.');
}
}
@@ -220,7 +259,7 @@ module.exports = function (RED) {
let newTelegramBot;
let webHook = {
- autoOpen: true,
+ autoOpen: false,
port: this.localBotPort,
};
if (!this.sslTerminated) {
@@ -232,8 +271,22 @@ module.exports = function (RED) {
baseApiUrl: this.baseApiUrl,
request: this.socksRequest,
};
+
newTelegramBot = new telegramBotEx(this.token, options);
+ newTelegramBot
+ .openWebHook()
+ .then(function () {
+ // web hook listening on port, everything ok.
+ })
+ .catch(function (err) {
+ self.warn('Opening webhook failed: ' + err);
+
+ self.abortBot('Failed to listen on configured port', function () {
+ self.error('Bot stopped: failed to open web hook.');
+ });
+ });
+
newTelegramBot.on('webhook_error', function (error) {
self.setStatus('error', 'webhook error');
@@ -267,7 +320,7 @@ module.exports = function (RED) {
}
if (success) {
- self.status = 'connected';
+ self.status = 'connected'; // TODO: check if this must be SetStatus
} else {
self.abortBot('Failed to set webhook ' + botUrl, function () {
self.error('Bot stopped: Webhook not set.');