Skip to content

Commit aacb5a7

Browse files
committed
Webhook support
1 parent e795058 commit aacb5a7

File tree

3 files changed

+268
-81
lines changed

3 files changed

+268
-81
lines changed

index.js

Lines changed: 126 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,8 @@
11
var Duplex = require('stream').Duplex
22

3-
var inherits = require('inherits')
4-
var Telegram = require('telegram-bot-api')
5-
6-
7-
function emitError(message, data)
8-
{
9-
var error = new Error(message)
10-
error.data = data
11-
12-
this.emit('error', error)
13-
}
14-
15-
/**
16-
* Process a single received Telegram `Update` object
17-
*
18-
* @param {Object} update
19-
*
20-
* @return Boolean - more `Update` objects can be fetch
21-
*/
22-
function processUpdate(update)
23-
{
24-
var message = update.message
25-
if(message == null)
26-
return emitError.call(this, 'Inline queries are not supported', update)
27-
28-
if(message.chat.id !== this.chat_id)
29-
return emitError.call(this, 'Received message for not-listening chat', message)
30-
31-
var text = message.text
32-
if(text == null)
33-
return emitError.call(this, 'Only text messages are supported', message)
34-
35-
return this.push(message.text)
36-
}
3+
var inherits = require('inherits')
4+
var Telegram = require('telegram-bot-api')
5+
var WebhookPost = require('WebhookPost')
376

387

398
/**
@@ -59,41 +28,131 @@ function TelegramLog(token, chat_id, options)
5928
if(!token) throw 'Missing token'
6029
if(!chat_id) throw 'Missing chat_id'
6130

62-
Object.defineProperties(this,
63-
{
64-
token: {value: token},
65-
chat_id: {value: chat_id}
66-
})
67-
6831
var _updatesOffset = 0
6932

70-
var inFlight
71-
var req
72-
7333
var api = new Telegram({token: token})
7434

7535

7636
//
7737
// Private functions
7838
//
7939

40+
function emitError(message, data)
41+
{
42+
var error = new Error(message)
43+
error.data = data
44+
45+
self.emit('error', error)
46+
}
47+
8048
/**
81-
* Process a Telegram `Update` object and check if it should do more requests
49+
* Process a single received Telegram `Update` object
8250
*
83-
* @param {Boolean} fetchMoreDate
8451
* @param {Object} update
8552
*
8653
* @return Boolean - more `Update` objects can be fetch
8754
*/
88-
function processUpdate_reduce(fetchMoreDate, update)
55+
function processUpdate(update)
8956
{
9057
// Account update_id as next offset
9158
// to avoid dublicated updates
9259
var update_id = update.update_id
9360
if(update_id >= _updatesOffset)
9461
_updatesOffset = update_id + 1
9562

96-
return processUpdate.call(self, update) && fetchMoreDate
63+
var message = update.message
64+
if(message == null)
65+
return emitError('Inline queries are not supported', update)
66+
67+
if(message.chat.id !== chat_id)
68+
return emitError('Received message for not-listening chat', message)
69+
70+
var text = message.text
71+
if(text == null)
72+
return emitError('Only text messages are supported', message)
73+
74+
return self.push(message.text)
75+
}
76+
77+
var end = this.push.bind(this, null)
78+
79+
80+
//
81+
// Webhook
82+
//
83+
84+
var webhook = options.webhook
85+
if(webhook)
86+
{
87+
var certificate = options.certificate || ''
88+
89+
function closeWebhook()
90+
{
91+
if(!webhook) return
92+
93+
webhook.close()
94+
webhook = null
95+
96+
api.setWebhook({certificate: certificate}).then(end, end)
97+
}
98+
99+
// Telegram only support ports 80, 88, 443 and 8443
100+
var port
101+
if(webhook) port = webhook.port
102+
else port = webhook
103+
104+
if(!(port === 80 || port === 88 || port === 443 || port === 8443))
105+
{
106+
var error = new RangeError('Port must be one of 80, 88, 443 or 8443')
107+
error.port = webhook
108+
109+
throw error
110+
}
111+
112+
// Create webhook
113+
webhook = WebhookPost(webhook, options)
114+
.on('open', function(url)
115+
{
116+
api
117+
.setWebhook({url: url, certificate: certificate})
118+
.catch(function(error)
119+
{
120+
self.emit('error', error)
121+
122+
webhook = null
123+
end()
124+
})
125+
})
126+
.on('data', function(data)
127+
{
128+
var update = JSON.parse(data)
129+
130+
// Ignore duplicated updates
131+
if(update.update_id >= _updatesOffset) processUpdate(update)
132+
})
133+
.on('error', this.emit.bind(this, 'error'))
134+
.on('end', closeWebhook)
135+
}
136+
137+
138+
//
139+
// Polling
140+
//
141+
142+
var polling
143+
var inFlight
144+
145+
/**
146+
* Process a Telegram `Update` object and check if it should do more requests
147+
*
148+
* @param {Boolean} fetchMoreDate
149+
* @param {Object} update
150+
*
151+
* @return Boolean - more `Update` objects can be fetch
152+
*/
153+
function processUpdate_reduce(fetchMoreDate, update)
154+
{
155+
return processUpdate(update) && fetchMoreDate
97156
}
98157

99158
/**
@@ -122,7 +181,7 @@ function TelegramLog(token, chat_id, options)
122181

123182

124183
/**
125-
* Request new updates
184+
* Request new updates. This will not work when using a webhook
126185
*
127186
* @private
128187
*/
@@ -131,11 +190,13 @@ function TelegramLog(token, chat_id, options)
131190
var state = self._readableState
132191
var limit = state.highWaterMark - state.length
133192

134-
if(inFlight || state.ended || !limit) return
193+
if(inFlight || state.ended || !limit
194+
|| polling === null || webhook !== undefined)
195+
return
135196

136197
inFlight = true
137198

138-
req = api.getUpdates({
199+
polling = api.getUpdates({
139200
offset: _updatesOffset,
140201
limit: limit,
141202
timeout: 0
@@ -144,8 +205,13 @@ function TelegramLog(token, chat_id, options)
144205
.catch(onError)
145206
}
146207

208+
209+
//
210+
// Duplex API
211+
//
212+
147213
/**
148-
* Write a streamed row on the worksheet
214+
* Write a data message
149215
*
150216
* @param {Object} chunk
151217
* @param {*} _ - ignored
@@ -165,18 +231,22 @@ function TelegramLog(token, chat_id, options)
165231
.then(done.bind(null, null), done)
166232
}
167233

234+
235+
//
236+
// Public API
237+
//
238+
168239
/**
169240
* Close the connection and stop emitting more data updates
170241
*/
171242
this.close = function()
172243
{
173-
if(req)
244+
if(webhook !== undefined) return closeWebhook()
245+
if(polling)
174246
{
175-
// req.abort()
176-
req = null
247+
polling.then(end, end)
248+
polling = null
177249
}
178-
179-
this.push(null)
180250
}
181251
}
182252
inherits(TelegramLog, Duplex)

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
"jscoverage": "piranna/jscoverage",
3131
"mocha": "^2.4.5",
3232
"mocha-lcov-reporter": "^1.0.0",
33-
"nock": "^7.0.2"
33+
"nock": "^7.0.2",
34+
"partly": "^1.0.0",
35+
"webhook-post": "^0.0.0"
3436
},
3537
"dependencies": {
3638
"inherits": "^2.0.1",

0 commit comments

Comments
 (0)