From bb6a0bb3ff2841c0f844050db7a6125a311a58fd Mon Sep 17 00:00:00 2001 From: Yago Date: Sun, 27 Sep 2015 13:05:46 +0200 Subject: [PATCH] setWebHook allow sending certificate as param. WebHook Documentation --- README.hbs | 10 ++++++++++ README.md | 21 ++++++++++++++++----- src/telegram.js | 24 +++++++++++++++++------- test/index.js | 10 ++++++++++ 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/README.hbs b/README.hbs index eaae887..8a9e61d 100644 --- a/README.hbs +++ b/README.hbs @@ -26,6 +26,16 @@ There are some other examples on [examples](https://github.com/yagop/node-telegr Every time TelegramBot receives a message, it emits a `message`. Depending on which [message](https://core.telegram.org/bots/api#message) was received, emits an event from this ones: `text`, `audio`, `document`, `photo`, `sticker`, `video`, `voice`, `contact`, `location`, `new_chat_participant`, `left_chat_participant`, `new_chat_title`, `new_chat_photo`, `delete_chat_photo`, `group_chat_created`. Its much better to listen a specific event rather than a `message` in order to stay safe from the content. * * * +### WebHooks + +Telegram only supports HTTPS connections to WebHooks, in order to set a WebHook a private key file and public certificate must be used. Since August 29, 2015 Telegram supports self signed ones, to generate them: +```bash +# Our private cert will be key.pem, keep in private this file. +openssl genrsa -out key.pem 2048 +# Our public certificate will be crt.pem +openssl req -new -sha256 -key key.pem -out crt.pem +``` +Once they are generated, the `crt.pem` can be provided to `telegramBot.setWebHook(url, crt)` as `crt`. ## API Reference {{#class name="TelegramBot"~}} diff --git a/README.md b/README.md index 6b176e5..706456f 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,16 @@ There are some other examples on [examples](https://github.com/yagop/node-telegr Every time TelegramBot receives a message, it emits a `message`. Depending on which [message](https://core.telegram.org/bots/api#message) was received, emits an event from this ones: `text`, `audio`, `document`, `photo`, `sticker`, `video`, `voice`, `contact`, `location`, `new_chat_participant`, `left_chat_participant`, `new_chat_title`, `new_chat_photo`, `delete_chat_photo`, `group_chat_created`. Its much better to listen a specific event rather than a `message` in order to stay safe from the content. * * * +### WebHooks + +Telegram only supports HTTPS connections to WebHooks, in order to set a WebHook a private key file and public certificate must be used. Since August 29, 2015 Telegram supports self signed ones, to generate them: +```bash +# Our private cert will be key.pem, keep in private this file. +openssl genrsa -out key.pem 2048 +# Our public certificate will be crt.pem +openssl req -new -sha256 -key key.pem -out crt.pem +``` +Once they are generated, the `crt.pem` can be provided to `telegramBot.setWebHook(url, crt)` as `crt`. ## API Reference @@ -38,7 +48,7 @@ TelegramBot * [TelegramBot](#TelegramBot) * [new TelegramBot(token, [options])](#new_TelegramBot_new) * [.getMe()](#TelegramBot+getMe) ⇒ Promise - * [.setWebHook(url)](#TelegramBot+setWebHook) + * [.setWebHook(url, [cert])](#TelegramBot+setWebHook) * [.getUpdates([timeout], [limit], [offset])](#TelegramBot+getUpdates) ⇒ Promise * [.sendMessage(chatId, text, [options])](#TelegramBot+sendMessage) ⇒ Promise * [.forwardMessage(chatId, fromChatId, messageId)](#TelegramBot+forwardMessage) ⇒ Promise @@ -58,7 +68,7 @@ TelegramBot ### new TelegramBot(token, [options]) Both request method to obtain messages are implemented. To use standard polling, set `polling: true` -on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a valid (not self signed) SSL certificate. +on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a SSL certificate. Emits `message` when a message arrives. @@ -70,8 +80,8 @@ Emits `message` when a message arrives. | [options.polling.timeout] | String | Number | 4 | Polling time | | [options.polling.interval] | String | Number | 2000 | Interval between requests in miliseconds | | [options.webHook] | Boolean | Object | false | Set true to enable WebHook or set options | -| [options.webHook.key] | String | | PEM private key to webHook server | -| [options.webHook.cert] | String | | PEM certificate key to webHook server | +| [options.webHook.key] | String | | PEM private key to webHook server. | +| [options.webHook.cert] | String | | PEM certificate (public) to webHook server. | ### telegramBot.getMe() ⇒ Promise @@ -80,7 +90,7 @@ Returns basic information about the bot in form of a `User` object. **Kind**: instance method of [TelegramBot](#TelegramBot) **See**: https://core.telegram.org/bots/api#getme -### telegramBot.setWebHook(url) +### telegramBot.setWebHook(url, [cert]) Specify an url to receive incoming updates via an outgoing webHook. **Kind**: instance method of [TelegramBot](#TelegramBot) @@ -89,6 +99,7 @@ Specify an url to receive incoming updates via an outgoing webHook. | Param | Type | Description | | --- | --- | --- | | url | String | URL where Telegram will make HTTP Post. Leave empty to delete webHook. | +| [cert] | String | stream.Stream | PEM certificate key (public). | ### telegramBot.getUpdates([timeout], [limit], [offset]) ⇒ Promise diff --git a/src/telegram.js b/src/telegram.js index 19b1e60..63b6711 100644 --- a/src/telegram.js +++ b/src/telegram.js @@ -17,7 +17,7 @@ var requestPromise = Promise.promisify(request); /** * Both request method to obtain messages are implemented. To use standard polling, set `polling: true` - * on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a valid (not self signed) SSL certificate. + * on `options`. Notice that [webHook](https://core.telegram.org/bots/api#setwebhook) will need a SSL certificate. * Emits `message` when a message arrives. * * @class TelegramBot @@ -28,8 +28,8 @@ var requestPromise = Promise.promisify(request); * @param {String|Number} [options.polling.timeout=4] Polling time * @param {String|Number} [options.polling.interval=2000] Interval between requests in miliseconds * @param {Boolean|Object} [options.webHook=false] Set true to enable WebHook or set options - * @param {String} [options.webHook.key] PEM private key to webHook server - * @param {String} [options.webHook.cert] PEM certificate key to webHook server + * @param {String} [options.webHook.key] PEM private key to webHook server. + * @param {String} [options.webHook.cert] PEM certificate (public) to webHook server. * @see https://core.telegram.org/bots/api */ var TelegramBot = function (token, options) { @@ -108,7 +108,7 @@ TelegramBot.prototype._request = function (path, options) { * @see https://core.telegram.org/bots/api#making-requests */ TelegramBot.prototype._buildURL = function(path) { - return URL.format({ + return URL.format({ protocol: 'https', host: 'api.telegram.org', pathname: '/bot' + this.token + '/' + path @@ -129,12 +129,22 @@ TelegramBot.prototype.getMe = function () { * Specify an url to receive incoming updates via an outgoing webHook. * @param {String} url URL where Telegram will make HTTP Post. Leave empty to * delete webHook. + * @param {String|stream.Stream} [cert] PEM certificate key (public). * @see https://core.telegram.org/bots/api#setwebhook */ -TelegramBot.prototype.setWebHook = function (url) { +TelegramBot.prototype.setWebHook = function (url, cert) { var path = 'setWebHook'; - var form = {url: url}; - return this._request(path, {form: form}) + var opts = { + qs: {url: url} + }; + + if (cert) { + var content = this._formatSendData('certificate', cert); + opts.formData = content[0]; + opts.qs.certificate = content[1]; + } + + return this._request(path, opts) .then(function (resp) { if (!resp) { throw new Error(resp); diff --git a/test/index.js b/test/index.js index cef66f7..e10628b 100644 --- a/test/index.js +++ b/test/index.js @@ -19,12 +19,22 @@ describe('Telegram', function () { describe('#setWebHook', function () { it('should set a webHook', function (done) { var bot = new Telegram(TOKEN); + // Google IP ¯\_(ツ)_/¯ bot.setWebHook('216.58.210.174').then(function (resp) { resp.should.be.exactly(true); done(); }); }); + it('should set a webHook with certificate', function (done) { + var bot = new Telegram(TOKEN); + var cert = __dirname+'/../examples/crt.pem'; + bot.setWebHook('216.58.210.174', cert).then(function (resp) { + resp.should.be.exactly(true); + done(); + }); + }); + it('should delete the webHook', function (done) { var bot = new Telegram(TOKEN); bot.setWebHook('').then(function (resp) {