dockerized_openAger/nodered/rootfs/data/node_modules/node-telegram-bot-api/lib/telegramWebHook.js
2020-10-17 18:42:50 +02:00

189 lines
6.1 KiB
JavaScript

'use strict';
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var errors = require('./errors');
var debug = require('debug')('node-telegram-bot-api');
var https = require('https');
var http = require('http');
var fs = require('fs');
var bl = require('bl');
var Promise = require('bluebird');
var TelegramBotWebHook = function () {
/**
* Sets up a webhook to receive updates
* @param {TelegramBot} bot
* @see https://core.telegram.org/bots/api#getting-updates
*/
function TelegramBotWebHook(bot) {
_classCallCheck(this, TelegramBotWebHook);
this.bot = bot;
this.options = typeof bot.options.webHook === 'boolean' ? {} : bot.options.webHook;
this.options.host = this.options.host || '0.0.0.0';
this.options.port = this.options.port || 8443;
this.options.https = this.options.https || {};
this.options.healthEndpoint = this.options.healthEndpoint || '/healthz';
this._healthRegex = new RegExp(this.options.healthEndpoint);
this._webServer = null;
this._open = false;
this._requestListener = this._requestListener.bind(this);
this._parseBody = this._parseBody.bind(this);
if (this.options.key && this.options.cert) {
debug('HTTPS WebHook enabled (by key/cert)');
this.options.https.key = fs.readFileSync(this.options.key);
this.options.https.cert = fs.readFileSync(this.options.cert);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (this.options.pfx) {
debug('HTTPS WebHook enabled (by pfx)');
this.options.https.pfx = fs.readFileSync(this.options.pfx);
this._webServer = https.createServer(this.options.https, this._requestListener);
} else if (Object.keys(this.options.https).length) {
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);
}
}
/**
* Open WebHook by listening on the port
* @return {Promise}
*/
_createClass(TelegramBotWebHook, [{
key: 'open',
value: function open() {
var _this = this;
if (this.isOpen()) {
return Promise.resolve();
}
return new Promise(function (resolve) {
_this._webServer.listen(_this.options.port, _this.options.host, function () {
debug('WebHook listening on port %s', _this.options.port);
_this._open = true;
return resolve();
});
});
}
/**
* Close the webHook
* @return {Promise}
*/
}, {
key: 'close',
value: function close() {
var _this2 = this;
if (!this.isOpen()) {
return Promise.resolve();
}
return new Promise(function (resolve, reject) {
_this2._webServer.close(function (error) {
if (error) return reject(error);
_this2._open = false;
return resolve();
});
});
}
/**
* Return `true` if server is listening. Otherwise, `false`.
*/
}, {
key: 'isOpen',
value: function isOpen() {
// NOTE: Since `http.Server.listening` was added in v5.7.0
// and we still need to support Node v4,
// we are going to fallback to 'this._open'.
// The following LOC would suffice for newer versions of Node.js
// return this._webServer.listening;
return this._open;
}
/**
* Handle error thrown during processing of webhook request.
* @private
* @param {Error} error
*/
}, {
key: '_error',
value: function _error(error) {
if (!this.bot.listeners('webhook_error').length) {
return console.error('error: [webhook_error] %j', error); // eslint-disable-line no-console
}
return this.bot.emit('webhook_error', error);
}
/**
* Handle request body by passing it to 'callback'
* @private
*/
}, {
key: '_parseBody',
value: function _parseBody(error, body) {
if (error) {
return this._error(new errors.FatalError(error));
}
var data = void 0;
try {
data = JSON.parse(body.toString());
} catch (parseError) {
return this._error(new errors.ParseError(parseError.message));
}
return this.bot.processUpdate(data);
}
/**
* Listener for 'request' event on server
* @private
* @see https://nodejs.org/docs/latest/api/http.html#http_http_createserver_requestlistener
* @see https://nodejs.org/docs/latest/api/https.html#https_https_createserver_options_requestlistener
*/
}, {
key: '_requestListener',
value: function _requestListener(req, res) {
debug('WebHook request URL: %s', req.url);
debug('WebHook request headers: %j', req.headers);
if (req.url.indexOf(this.bot.token) !== -1) {
if (req.method !== 'POST') {
debug('WebHook request isn\'t a POST');
res.statusCode = 418; // I'm a teabot!
res.end();
} else {
req.pipe(bl(this._parseBody)).on('finish', function () {
return res.end('OK');
});
}
} else if (this._healthRegex.test(req.url)) {
debug('WebHook health check passed');
res.statusCode = 200;
res.end('OK');
} else {
debug('WebHook request unauthorized');
res.statusCode = 401;
res.end();
}
}
}]);
return TelegramBotWebHook;
}();
module.exports = TelegramBotWebHook;