2016-03-17 02:44:34 +03:00
|
|
|
const debug = require('debug')('node-telegram-bot-api');
|
|
|
|
const https = require('https');
|
|
|
|
const http = require('http');
|
|
|
|
const fs = require('fs');
|
|
|
|
const bl = require('bl');
|
2015-09-27 11:18:25 +02:00
|
|
|
|
2015-07-13 00:24:49 +02:00
|
|
|
|
2017-01-02 13:04:44 +03:00
|
|
|
class TelegramBotWebHook {
|
|
|
|
/**
|
|
|
|
* Sets up a webhook to receive updates
|
|
|
|
*
|
|
|
|
* @param {String} token Telegram API token
|
|
|
|
* @param {Boolean|Object} options WebHook options
|
|
|
|
* @param {Number} [options.port=8443] Port to bind to
|
|
|
|
* @param {Function} callback Function for process a new update
|
|
|
|
*/
|
2016-03-17 02:44:34 +03:00
|
|
|
constructor(token, options, callback) {
|
|
|
|
// define opts
|
|
|
|
if (typeof options === 'boolean') {
|
|
|
|
options = {}; // eslint-disable-line no-param-reassign
|
|
|
|
}
|
2017-01-02 13:04:44 +03:00
|
|
|
|
|
|
|
this.token = token;
|
|
|
|
this.options = options;
|
|
|
|
this.options.port = options.port || 8443;
|
|
|
|
this.callback = callback;
|
|
|
|
this._regex = new RegExp(this.token);
|
|
|
|
this._webServer = null;
|
2016-03-17 02:44:34 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
} else {
|
|
|
|
debug('HTTP WebHook enabled');
|
|
|
|
this._webServer = http.createServer(this._requestListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._webServer.listen(options.port, options.host, () => {
|
|
|
|
debug('WebHook listening on port %s', options.port);
|
|
|
|
});
|
2015-07-13 00:24:49 +02:00
|
|
|
}
|
|
|
|
|
2016-03-17 02:44:34 +03:00
|
|
|
// used so that other funcs are not non-optimizable
|
|
|
|
_safeParse(json) {
|
|
|
|
try {
|
|
|
|
return JSON.parse(json);
|
|
|
|
} catch (err) {
|
|
|
|
debug(err);
|
|
|
|
return null;
|
|
|
|
}
|
2015-07-13 00:24:49 +02:00
|
|
|
}
|
|
|
|
|
2017-01-02 13:04:44 +03:00
|
|
|
/**
|
|
|
|
* Handle request body by passing it to 'callback'
|
|
|
|
* @private
|
|
|
|
*/
|
2016-03-17 02:44:34 +03:00
|
|
|
_parseBody = (err, body) => {
|
|
|
|
if (err) {
|
|
|
|
return debug(err);
|
|
|
|
}
|
2015-07-13 00:24:49 +02:00
|
|
|
|
2016-03-17 02:44:34 +03:00
|
|
|
const data = this._safeParse(body);
|
|
|
|
if (data) {
|
|
|
|
return this.callback(data);
|
|
|
|
}
|
2015-07-13 00:24:49 +02:00
|
|
|
|
2016-03-17 02:44:34 +03:00
|
|
|
return null;
|
2015-07-13 00:24:49 +02:00
|
|
|
}
|
2016-03-17 02:44:34 +03:00
|
|
|
|
2017-01-02 13:04:44 +03:00
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*/
|
2016-03-17 02:44:34 +03:00
|
|
|
_requestListener = (req, res) => {
|
2016-07-13 19:52:50 +02:00
|
|
|
debug('WebHook request URL: %s', req.url);
|
2016-03-17 02:44:34 +03:00
|
|
|
debug('WebHook request headers: %j', req.headers);
|
|
|
|
|
|
|
|
// If there isn't token on URL
|
2017-01-02 13:04:44 +03:00
|
|
|
if (!this._regex.test(req.url)) {
|
2016-03-17 02:44:34 +03:00
|
|
|
debug('WebHook request unauthorized');
|
|
|
|
res.statusCode = 401;
|
|
|
|
res.end();
|
|
|
|
} else if (req.method === 'POST') {
|
|
|
|
req
|
|
|
|
.pipe(bl(this._parseBody))
|
2016-04-25 16:03:36 +09:00
|
|
|
.on('finish', () => res.end('OK'));
|
2016-03-17 02:44:34 +03:00
|
|
|
} else {
|
|
|
|
// Authorized but not a POST
|
|
|
|
debug('WebHook request isn\'t a POST');
|
|
|
|
res.statusCode = 418; // I'm a teabot!
|
|
|
|
res.end();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2015-07-13 00:24:49 +02:00
|
|
|
|
|
|
|
module.exports = TelegramBotWebHook;
|