2
0
mirror of https://github.com/yagop/node-telegram-bot-api synced 2025-08-22 09:57:10 +00:00

[webhook] Allow passing options to HTTPS server

Feature:

  We shall allow passing more options to the HTTP server,
  in `https.createServer()`.

  We are using a new property, `https`, to avoid any namespace
  collisions with our own options.

  `options.key`, `options.cert` and `options.pfx` are convenient
  options, in that they allow the user to provide paths to the
  corresponding files, which are read automatically,
  though synchronously!

Implementation:

  * completely backwards-compatible
  * all changes are being tested, except `options.pfx`

References:

  * Pass `ca` prop to https.createServer(): https://github.com/yagop/node-telegram-bot-api/pull/17
This commit is contained in:
GochoMugo 2017-01-07 17:58:01 +03:00
parent f8667dc548
commit 31a2376a1f
No known key found for this signature in database
GPG Key ID: 7B6A01CB57AA39E4
5 changed files with 71 additions and 24 deletions

View File

@ -135,9 +135,11 @@ Emits `message` when a message arrives.
| [options.polling.autoStart] | <code>Boolean</code> | <code>true</code> | Start polling immediately |
| [options.webHook] | <code>Boolean</code> &#124; <code>Object</code> | <code>false</code> | Set true to enable WebHook or set options |
| [options.webHook.port] | <code>Number</code> | <code>8443</code> | Port to bind to |
| [options.webHook.key] | <code>String</code> | | Path to file with PEM private key for webHook server. (Read synchronously!) |
| [options.webHook.cert] | <code>String</code> | | Path to file with PEM certificate (public) for webHook server. (Read synchronously!) |
| [options.webHook.key] | <code>String</code> | | Path to file with PEM private key for webHook server. The file is read **synchronously**! |
| [options.webHook.cert] | <code>String</code> | | Path to file with PEM certificate (public) for webHook server. The file is read **synchronously**! |
| [options.webHook.pfx] | <code>String</code> | | Path to file with PFX private key and certificate chain for webHook server. The file is read **synchronously**! |
| [options.webHook.autoOpen] | <code>Boolean</code> | <code>true</code> | Open webHook immediately |
| [options.webHook.https] | <code>Object</code> | | 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. |
| [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. |
| [options.baseApiUrl] | <code>String</code> | <code>https://api.telegram.org</code> | API Base URl; useful for proxying and testing |

View File

@ -47,9 +47,17 @@ class TelegramBot extends EventEmitter {
* @param {Boolean} [options.polling.autoStart=true] Start polling immediately
* @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook or set options
* @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. (Read synchronously!)
* @param {String} [options.webHook.cert] Path to file with PEM certificate (public) for webHook server. (Read synchronously!)
* @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.

View File

@ -24,19 +24,25 @@ class TelegramBotWebHook {
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._requestListener = this._requestListener.bind(this);
this._parseBody = this._parseBody.bind(this);
if (options.key && options.cert) { // HTTPS Server
debug('HTTPS WebHook enabled');
const opts = {
key: fs.readFileSync(options.key),
cert: fs.readFileSync(options.cert)
};
this._webServer = https.createServer(opts, this._requestListener);
if (options.key && options.cert) {
debug('HTTPS WebHook enabled (by key/cert)');
this.options.https.key = fs.readFileSync(options.key);
this.options.https.cert = fs.readFileSync(options.cert);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (options.pfx) {
debug('HTTPS WebHook enabled (by pfx)');
this.options.https.pfx = fs.readFileSync(options.pfx);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (options.https) {
debug('HTTPS WebHook enabled by (https)');
this._webServer = https.createServer(this.options.https, this._requestListener);
} else {
debug('HTTP WebHook enabled');
this._webServer = http.createServer(this._requestListener);

View File

@ -1,4 +1,4 @@
const Telegram = require('../lib/telegram');
const TelegramBot = require('../lib/telegram');
const Promise = require('bluebird');
const request = require('request-promise');
const assert = require('assert');
@ -8,7 +8,9 @@ const path = require('path');
const is = require('is');
const utils = require('./utils');
// Allows self-signed certificates to be used in our tests
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
const TOKEN = process.env.TEST_TELEGRAM_TOKEN;
if (!TOKEN) {
throw new Error('Bot token not provided');
@ -19,12 +21,15 @@ const USERID = process.env.TEST_USER_ID || 777000;
const GROUPID = process.env.TEST_GROUP_ID || -1001075450562;
const GAME_SHORT_NAME = process.env.TEST_GAME_SHORT_NAME || 'medusalab_test';
const timeout = 60 * 1000;
const staticPort = 8091;
const pollingPort = 8092;
const webHookPort = 8093;
const pollingPort2 = 8094;
const webHookPort2 = 8095;
let portindex = 8091;
const staticPort = portindex++;
const pollingPort = portindex++;
const webHookPort = portindex++;
const pollingPort2 = portindex++;
const webHookPort2 = portindex++;
const staticUrl = `http://127.0.0.1:${staticPort}`;
const key = `${__dirname}/../examples/key.pem`;
const cert = `${__dirname}/../examples/crt.pem`;
let FILE_ID;
let GAME_CHAT_ID;
let GAME_MSG_ID;
@ -37,7 +42,7 @@ before(function beforeAll() {
});
});
describe('Telegram', function telegramSuite() {
describe('TelegramBot', function telegramSuite() {
let bot;
let testbot;
let botPolling;
@ -45,8 +50,8 @@ describe('Telegram', function telegramSuite() {
before(function beforeAll() {
this.timeout(timeout);
bot = new Telegram(TOKEN);
testbot = new Telegram(TOKEN, {
bot = new TelegramBot(TOKEN);
testbot = new TelegramBot(TOKEN, {
baseApiUrl: `http://127.0.0.1:${pollingPort}`,
polling: {
autoStart: false,
@ -56,11 +61,11 @@ describe('Telegram', function telegramSuite() {
port: webHookPort,
},
});
botPolling = new Telegram(TOKEN, {
botPolling = new TelegramBot(TOKEN, {
baseApiUrl: `http://127.0.0.1:${pollingPort2}`,
polling: true,
});
botWebHook = new Telegram(TOKEN, {
botWebHook = new TelegramBot(TOKEN, {
webHook: {
port: webHookPort2,
},
@ -136,6 +141,31 @@ describe('Telegram', function telegramSuite() {
});
});
describe('WebHook HTTPS', function webHookHTTPSSuite() {
const port = portindex++;
let httpsbot;
afterEach(function afterEach() {
return httpsbot.closeWebHook();
});
it('is enabled, through options.key and options.cert', function test() {
httpsbot = new TelegramBot(TOKEN, { webHook: { port, key, cert } });
return utils.sendWebHookMessage(port, TOKEN, { https: true });
});
it('is enabled, through options.pfx');
it('is enabled, through options.https', function test() {
httpsbot = new TelegramBot(TOKEN, {
webHook: {
port,
https: {
key: fs.readFileSync(key),
cert: fs.readFileSync(cert),
},
},
});
return utils.sendWebHookMessage(port, TOKEN, { https: true });
});
});
describe('#initPolling', function initPollingSuite() {
it('initiates polling', function test() {
testbot.initPolling();
@ -215,7 +245,6 @@ describe('Telegram', function telegramSuite() {
describe('#setWebHook', function setWebHookSuite() {
const ip = '216.58.210.174';
const cert = `${__dirname}/../examples/crt.pem`;
before(function before() {
utils.handleRatelimit(bot, 'setWebHook', this);
});

View File

@ -37,6 +37,7 @@ exports = module.exports = {
* @param {Object} [options]
* @param {String} [options.method=POST] Method to use
* @param {Object} [options.message] Message to send. Default to a generic text message
* @param {Boolean} [options.https=false] Use https
* @return {Promise}
*/
sendWebHookMessage,
@ -136,7 +137,8 @@ function hasOpenWebHook(port, reverse) {
function sendWebHookMessage(port, token, options = {}) {
assert.ok(port);
assert.ok(token);
const url = `http://127.0.0.1:${port}/bot${token}`;
const protocol = options.https ? 'https' : 'http';
const url = `${protocol}://127.0.0.1:${port}/bot${token}`;
return request({
url,
method: options.method || 'POST',