Skip to content

Commit

Permalink
fixed #303 port already in use
Browse files Browse the repository at this point in the history
  • Loading branch information
windka committed Apr 29, 2023
1 parent b2fe0c1 commit 079ca48
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion telegrambot/99-telegrambot.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@
<input type="checkbox" id="node-config-input-sslterminated" style="display: inline-block; width: auto; vertical-align: top;">
</div>

<div class="form-tips" style="width: auto"><b>Tip:</b> 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.</div>
<div class="form-tips" style="width: auto"><b>Tip:</b> 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.</div>
</div>
</div>

Expand Down
59 changes: 56 additions & 3 deletions telegrambot/99-telegrambot.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}) {
Expand All @@ -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 = {};
Expand All @@ -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;
Expand Down Expand Up @@ -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.');
}
}

Expand All @@ -220,7 +259,7 @@ module.exports = function (RED) {
let newTelegramBot;

let webHook = {
autoOpen: true,
autoOpen: false,
port: this.localBotPort,
};
if (!this.sslTerminated) {
Expand All @@ -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');

Expand Down Expand Up @@ -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.');
Expand Down

1 comment on commit 079ca48

@cowchimp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this @windkh! I had node-red crash on me in the past because of this so this is really helpful 🙏

Please sign in to comment.