alicezetion 1.7.6 → 1.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -1
  2. package/.cache/replit/nix/env.json +1 -1
  3. package/.travis.yml +6 -0
  4. package/index.js +120 -655
  5. package/package.json +25 -37
  6. package/replit.nix +4 -3
  7. package/src/addExternalModule.js +5 -13
  8. package/src/addUserToGroup.js +12 -36
  9. package/src/changeAdminStatus.js +37 -85
  10. package/src/changeArchivedStatus.js +9 -15
  11. package/src/changeBio.js +8 -13
  12. package/src/changeBlockedStatus.js +8 -14
  13. package/src/changeGroupImage.js +13 -28
  14. package/src/changeNickname.js +11 -22
  15. package/src/changeThreadColor.js +10 -16
  16. package/src/changeThreadEmoji.js +9 -18
  17. package/src/chat.js +280 -401
  18. package/src/createNewGroup.js +10 -18
  19. package/src/createPoll.js +11 -17
  20. package/src/deleteMessage.js +10 -17
  21. package/src/deleteThread.js +10 -17
  22. package/src/forwardAttachment.js +9 -15
  23. package/src/forwardMessage.js +0 -0
  24. package/src/getCurrentUserID.js +1 -1
  25. package/src/getEmojiUrl.js +2 -3
  26. package/src/getFriendsList.js +10 -18
  27. package/src/getThreadHistory.js +59 -156
  28. package/src/getThreadHistoryDeprecated.js +15 -26
  29. package/src/getThreadInfo.js +42 -68
  30. package/src/getThreadInfoDeprecated.js +13 -25
  31. package/src/getThreadList.js +53 -112
  32. package/src/getThreadListDeprecated.js +12 -30
  33. package/src/getThreadPictures.js +13 -25
  34. package/src/getUserID.js +7 -9
  35. package/src/getUserInfo.js +10 -12
  36. package/src/handleFriendRequest.js +35 -36
  37. package/src/handleMessageRequest.js +10 -18
  38. package/src/httpGet.js +13 -20
  39. package/src/httpPost.js +13 -19
  40. package/src/listen.js +553 -0
  41. package/src/listenMqtt-Test.js +687 -0
  42. package/src/listenMqtt.js +621 -1224
  43. package/src/logout.js +13 -18
  44. package/src/markAsDelivered.js +10 -17
  45. package/src/markAsRead.js +24 -36
  46. package/src/{seen.js → markAsReadAll.js} +10 -17
  47. package/src/markAsSeen.js +12 -22
  48. package/src/muteThread.js +9 -15
  49. package/src/removeUserFromGroup.js +11 -38
  50. package/src/resolvePhotoUrl.js +6 -9
  51. package/src/searchForThread.js +8 -14
  52. package/src/sendMessage.js +315 -0
  53. package/src/sendTypingIndicator.js +19 -44
  54. package/src/{react.js → setMessageReaction.js} +9 -20
  55. package/src/setPostReaction.js +22 -63
  56. package/src/setTitle.js +12 -22
  57. package/src/threadColors.js +19 -17
  58. package/src/unfriend.js +9 -15
  59. package/src/{unsend.js → unsendMessage.js} +8 -9
  60. package/test/data/shareAttach.js +146 -0
  61. package/test/data/something.mov +0 -0
  62. package/test/data/test.png +0 -0
  63. package/test/data/test.txt +7 -0
  64. package/test/example-config.json +18 -0
  65. package/test/test-page.js +140 -0
  66. package/test/test.js +385 -0
  67. package/utils.js +27 -120
  68. package/Extra/Database/index.js +0 -399
  69. package/Extra/Database/methods.js +0 -286
  70. package/Extra/ExtraAddons.js +0 -213
  71. package/Extra/ExtraGetThread.js +0 -1
  72. package/Extra/ExtraUptimeRobot.js +0 -59
  73. package/Extra/PM2/ecosystem.config.js +0 -23
  74. package/Extra/Src/Last-Run.js +0 -48
  75. package/Language/index.json +0 -151
  76. package/StateCrypt.js +0 -22
  77. package/broadcast.js +0 -42
  78. package/logger.js +0 -21
  79. package/src/changeAvt.js +0 -91
  80. package/src/getAccessToken.js +0 -32
  81. package/src/getMessage.js +0 -84
  82. package/src/getUserInfoV2.js +0 -35
  83. package/src/httpPostFormData.js +0 -46
package/src/httpGet.js CHANGED
@@ -3,52 +3,45 @@
3
3
  var utils = require("../utils");
4
4
  var log = require("npmlog");
5
5
 
6
- module.exports = function(defaultFuncs, api, ctx) {
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
7
  return function httpGet(url, form, callback, notAPI) {
8
- var resolveFunc = function() {};
9
- var rejectFunc = function() {};
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
10
 
11
- var returnPromise = new Promise(function(resolve, reject) {
11
+ var returnPromise = new Promise(function (resolve, reject) {
12
12
  resolveFunc = resolve;
13
13
  rejectFunc = reject;
14
14
  });
15
15
 
16
- if (
17
- !callback &&
18
- (utils.getType(form) == "Function" ||
19
- utils.getType(form) == "AsyncFunction")
20
- ) {
16
+ if (!callback && (utils.getType(form) == "Function" || utils.getType(form) == "AsyncFunction")) {
21
17
  callback = form;
22
18
  form = {};
23
19
  }
24
-
25
20
  form = form || {};
26
21
 
27
- callback =
28
- callback ||
29
- function(err, data) {
30
- if (err) return rejectFunc(err);
31
- resolveFunc(data);
32
- };
22
+ callback = callback || function (err, data) {
23
+ if (err) return rejectFunc(err);
24
+ resolveFunc(data);
25
+ };
33
26
 
34
27
  if (notAPI) {
35
28
  utils
36
29
  .get(url, ctx.jar, form, ctx.globalOptions)
37
30
  .then(resData => callback(null, resData.body.toString()))
38
- .catch(function(err) {
31
+ .catch(function (err) {
39
32
  log.error("httpGet", err);
40
33
  return callback(err);
41
34
  });
42
- } else {
35
+ }
36
+ else {
43
37
  defaultFuncs
44
38
  .get(url, ctx.jar, form)
45
39
  .then(resData => callback(null, resData.body.toString()))
46
- .catch(function(err) {
40
+ .catch(function (err) {
47
41
  log.error("httpGet", err);
48
42
  return callback(err);
49
43
  });
50
44
  }
51
-
52
45
  return returnPromise;
53
46
  };
54
47
  };
package/src/httpPost.js CHANGED
@@ -3,47 +3,41 @@
3
3
  var utils = require("../utils");
4
4
  var log = require("npmlog");
5
5
 
6
- module.exports = function(defaultFuncs, api, ctx) {
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
7
  return function httpGet(url, form, callback, notAPI) {
8
- var resolveFunc = function() {};
9
- var rejectFunc = function() {};
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
10
 
11
- var returnPromise = new Promise(function(resolve, reject) {
11
+ var returnPromise = new Promise(function (resolve, reject) {
12
12
  resolveFunc = resolve;
13
13
  rejectFunc = reject;
14
14
  });
15
15
 
16
- if (
17
- !callback &&
18
- (utils.getType(form) == "Function" ||
19
- utils.getType(form) == "AsyncFunction")
20
- ) {
16
+ if (!callback && (utils.getType(form) == "Function" || utils.getType(form) == "AsyncFunction")) {
21
17
  callback = form;
22
18
  form = {};
23
19
  }
24
-
25
20
  form = form || {};
26
21
 
27
- callback =
28
- callback ||
29
- function(err, data) {
30
- if (err) return rejectFunc(err);
31
- resolveFunc(data);
32
- };
22
+ callback = callback || function (err, data) {
23
+ if (err) return rejectFunc(err);
24
+ resolveFunc(data);
25
+ };
33
26
 
34
27
  if (notAPI) {
35
28
  utils
36
29
  .post(url, ctx.jar, form, ctx.globalOptions)
37
30
  .then(resData => callback(null, resData.body.toString()))
38
- .catch(function(err) {
31
+ .catch(function (err) {
39
32
  log.error("httpPost", err);
40
33
  return callback(err);
41
34
  });
42
- } else {
35
+ }
36
+ else {
43
37
  defaultFuncs
44
38
  .post(url, ctx.jar, form, {})
45
39
  .then(resData => callback(null, resData.body.toString()))
46
- .catch(function(err) {
40
+ .catch(function (err) {
47
41
  log.error("httpPost", err);
48
42
  return callback(err);
49
43
  });
package/src/listen.js ADDED
@@ -0,0 +1,553 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ var msgsRecv = 0;
7
+ var identity = function() {};
8
+
9
+ module.exports = function(defaultFuncs, api, ctx) {
10
+ var currentlyRunning = null;
11
+ var globalCallback = identity;
12
+
13
+ var stopListening = function() {
14
+ globalCallback = identity;
15
+ if (currentlyRunning) {
16
+ clearTimeout(currentlyRunning);
17
+ currentlyRunning = null;
18
+ }
19
+ };
20
+
21
+ var prev = Date.now();
22
+ var tmpPrev = Date.now();
23
+ var lastSync = Date.now();
24
+
25
+ var form = {
26
+ channel: "p_" + ctx.userID,
27
+ seq: "0",
28
+ partition: "-2",
29
+ clientid: ctx.clientID,
30
+ viewer_uid: ctx.userID,
31
+ uid: ctx.userID,
32
+ state: "active",
33
+ idle: 0,
34
+ cap: "8",
35
+ msgs_recv: msgsRecv,
36
+ qp: "y",
37
+ pws: "fresh"
38
+ };
39
+
40
+ if (ctx.globalOptions.pageID) {
41
+ form.aiq = ctx.globalOptions.pageID + ",0";
42
+ }
43
+
44
+ /**
45
+ * Get an object maybe representing an event. Handles events it wants to handle
46
+ * and returns true if it did handle an event (and called the globalCallback).
47
+ * Returns false otherwise.
48
+ */
49
+ function handleMessagingEvents(event) {
50
+ switch (event.event) {
51
+ // "read_receipt" event triggers when other people read the user's messages.
52
+ case "read_receipt":
53
+ var fmtMsg;
54
+ try {
55
+ fmtMsg = utils.formatReadReceipt(event);
56
+ } catch (err) {
57
+ globalCallback({
58
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
59
+ detail: err,
60
+ res: event,
61
+ type: "parse_error"
62
+ });
63
+ return true;
64
+ }
65
+ globalCallback(null, fmtMsg);
66
+ return true;
67
+ // "read event" triggers when the user read other people's messages.
68
+ case "read":
69
+ var fmtMsg;
70
+ try {
71
+ fmtMsg = utils.formatRead(event);
72
+ } catch (err) {
73
+ globalCallback({
74
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
75
+ detail: err,
76
+ res: event,
77
+ type: "parse_error"
78
+ });
79
+ return true;
80
+ }
81
+ globalCallback(null, fmtMsg);
82
+ return true;
83
+ default:
84
+ return false;
85
+ }
86
+ }
87
+
88
+ var serverNumber = "0";
89
+
90
+ function listen(servern) {
91
+ if (currentlyRunning == null || !ctx.loggedIn) {
92
+ return;
93
+ }
94
+
95
+ form.idle = ~~(Date.now() / 1000) - prev;
96
+ prev = ~~(Date.now() / 1000);
97
+ var presence = utils.generatePresence(ctx.userID);
98
+ ctx.jar.setCookie(
99
+ "presence=" + presence + "; path=/; domain=.facebook.com; secure",
100
+ "https://www.facebook.com"
101
+ );
102
+ defaultFuncs
103
+ .get(
104
+ "https://" + serverNumber + "-edge-chat.facebook.com/pull",
105
+ ctx.jar,
106
+ form
107
+ )
108
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
109
+ .then(function(resData) {
110
+ var now = Date.now();
111
+ log.info("listen", "Got answer in " + (now - tmpPrev));
112
+ tmpPrev = now;
113
+ if (resData && resData.t === "lb") {
114
+ form.sticky_token = resData.lb_info.sticky;
115
+ form.sticky_pool = resData.lb_info.pool;
116
+ }
117
+
118
+ if (resData && resData.t === "fullReload") {
119
+ form.seq = resData.seq;
120
+ delete form.sticky_pool;
121
+ delete form.sticky_token;
122
+ var form4 = {
123
+ lastSync: ~~(lastSync / 1000)
124
+ };
125
+ defaultFuncs
126
+ .get("https://www.facebook.com/notifications/sync/", ctx.jar, form4)
127
+ .then(utils.saveCookies(ctx.jar))
128
+ .then(function() {
129
+ lastSync = Date.now();
130
+ var form = {
131
+ client: "mercury",
132
+ "folders[0]": "inbox",
133
+ last_action_timestamp: ~~(Date.now() - 60)
134
+ };
135
+ defaultFuncs
136
+ .post(
137
+ "https://www.facebook.com/ajax/mercury/thread_sync.php",
138
+ ctx.jar,
139
+ form
140
+ )
141
+ .then(function() {
142
+ currentlyRunning = setTimeout(listen, 1000);
143
+ });
144
+ });
145
+ return;
146
+ }
147
+
148
+ if (resData.ms) {
149
+ msgsRecv += resData.ms.length;
150
+ var atLeastOne = false;
151
+ resData.ms
152
+ .sort(function(a, b) {
153
+ return a.timestamp - b.timestamp;
154
+ })
155
+ .forEach(function parsePackets(v) {
156
+ switch (v.type) {
157
+ // TODO: 'ttyp' was used before. It changed to 'typ'. We're keeping
158
+ // both for now but we should remove 'ttyp' at some point.
159
+ case "ttyp":
160
+ case "typ":
161
+ if (
162
+ !ctx.globalOptions.listenEvents ||
163
+ (!ctx.globalOptions.selfListen &&
164
+ v.from.toString() === ctx.userID)
165
+ ) {
166
+ return;
167
+ }
168
+ var fmtMsg;
169
+ try {
170
+ fmtMsg = utils.formatTyp(v);
171
+ } catch (err) {
172
+ return globalCallback({
173
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
174
+ detail: err,
175
+ res: v,
176
+ type: "parse_error"
177
+ });
178
+ }
179
+ return globalCallback(null, fmtMsg);
180
+ case "chatproxy-presence":
181
+ // TODO: what happens when you're logged in as a page?
182
+ if (!ctx.globalOptions.updatePresence) {
183
+ return;
184
+ }
185
+
186
+ if (ctx.loggedIn) {
187
+ for (var userID in v.buddyList) {
188
+ var formattedPresence;
189
+ try {
190
+ formattedPresence = utils.formatProxyPresence(
191
+ v.buddyList[userID],
192
+ userID
193
+ );
194
+ } catch (err) {
195
+ return globalCallback({
196
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
197
+ detail: err,
198
+ res: v.buddyList[userID],
199
+ type: "parse_error"
200
+ });
201
+ }
202
+
203
+ if (formattedPresence != null) {
204
+ globalCallback(null, formattedPresence);
205
+ }
206
+ }
207
+ return;
208
+ }
209
+
210
+ break;
211
+ case "buddylist_overlay":
212
+ // TODO: what happens when you're logged in as a page?
213
+ if (!ctx.globalOptions.updatePresence) {
214
+ return;
215
+ }
216
+ // There should be only one key inside overlay
217
+ Object.keys(v.overlay).map(function(userID) {
218
+ var formattedPresence;
219
+ try {
220
+ formattedPresence = utils.formatPresence(
221
+ v.overlay[userID],
222
+ userID
223
+ );
224
+ } catch (err) {
225
+ return globalCallback({
226
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
227
+ detail: err,
228
+ res: v.overlay[userID],
229
+ type: "parse_error"
230
+ });
231
+ }
232
+ if (ctx.loggedIn) {
233
+ return globalCallback(null, formattedPresence);
234
+ }
235
+ });
236
+ break;
237
+ case "delta":
238
+ if (v.delta.class == "NewMessage") {
239
+ if (ctx.globalOptions.pageID &&
240
+ ctx.globalOptions.pageID != v.queue
241
+ )
242
+ return;
243
+
244
+ (function resolveAttachmentUrl(i) {
245
+ if (i == v.delta.attachments.length) {
246
+ var fmtMsg;
247
+ try {
248
+ fmtMsg = utils.formatDeltaMessage(v);
249
+ } catch (err) {
250
+ return globalCallback({
251
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
252
+ detail: err,
253
+ res: v,
254
+ type: "parse_error"
255
+ });
256
+ }
257
+ return !ctx.globalOptions.selfListen &&
258
+ fmtMsg.senderID === ctx.userID ?
259
+ undefined :
260
+ globalCallback(null, fmtMsg);
261
+ } else {
262
+ if (
263
+ v.delta.attachments[i].mercury.attach_type == "photo"
264
+ ) {
265
+ api.resolvePhotoUrl(
266
+ v.delta.attachments[i].fbid,
267
+ (err, url) => {
268
+ if (!err)
269
+ v.delta.attachments[
270
+ i
271
+ ].mercury.metadata.url = url;
272
+ return resolveAttachmentUrl(i + 1);
273
+ }
274
+ );
275
+ } else {
276
+ return resolveAttachmentUrl(i + 1);
277
+ }
278
+ }
279
+ })(0);
280
+ break;
281
+ }
282
+
283
+ if (v.delta.class == "ClientPayload") {
284
+ var clientPayload = utils.decodeClientPayload(
285
+ v.delta.payload
286
+ );
287
+ if (clientPayload && clientPayload.deltas) {
288
+ for (var i in clientPayload.deltas) {
289
+ var delta = clientPayload.deltas[i];
290
+ if (delta.deltaMessageReaction && !!ctx.globalOptions.listenEvents) {
291
+ globalCallback(null, {
292
+ type: "message_reaction",
293
+ threadID: delta.deltaMessageReaction.threadKey
294
+ .threadFbId ?
295
+ delta.deltaMessageReaction.threadKey.threadFbId : delta.deltaMessageReaction.threadKey
296
+ .otherUserFbId,
297
+ messageID: delta.deltaMessageReaction.messageId,
298
+ reaction: delta.deltaMessageReaction.reaction,
299
+ senderID: delta.deltaMessageReaction.senderId,
300
+ userID: delta.deltaMessageReaction.userId,
301
+ timestamp: v.ofd_ts
302
+ });
303
+ } else if (delta.deltaRecallMessageData && !!ctx.globalOptions.listenEvents) {
304
+ globalCallback(null, {
305
+ type: "message_unsend",
306
+ threadID: delta.deltaRecallMessageData.threadKey.threadFbId ?
307
+ delta.deltaRecallMessageData.threadKey.threadFbId : delta.deltaRecallMessageData.threadKey
308
+ .otherUserFbId,
309
+ messageID: delta.deltaRecallMessageData.messageID,
310
+ senderID: delta.deltaRecallMessageData.senderID,
311
+ deletionTimestamp: delta.deltaRecallMessageData.deletionTimestamp,
312
+ timestamp: v.ofd_ts
313
+ });
314
+ } else if (delta.deltaMessageReply) {
315
+ //Mention block - #1
316
+ var mdata =
317
+ delta.deltaMessageReply.message.data === undefined ? [] :
318
+ delta.deltaMessageReply.message.data.prng === undefined ? [] :
319
+ JSON.parse(delta.deltaMessageReply.message.data.prng);
320
+ var m_id = mdata.map(u => u.i);
321
+ var m_offset = mdata.map(u => u.o);
322
+ var m_length = mdata.map(u => u.l);
323
+
324
+ var mentions = {};
325
+
326
+ for (var i = 0; i < m_id.length; i++) {
327
+ mentions[m_id[i]] = delta.deltaMessageReply.message.body.substring(
328
+ m_offset[i],
329
+ m_offset[i] + m_length[i]
330
+ );
331
+ }
332
+ //Mention block - 1#
333
+ //Mention block - #2
334
+ var mdata =
335
+ delta.deltaMessageReply.repliedToMessage.data === undefined ? [] :
336
+ delta.deltaMessageReply.repliedToMessage.data.prng === undefined ? [] :
337
+ JSON.parse(delta.deltaMessageReply.repliedToMessage.data.prng);
338
+ var m_id = mdata.map(u => u.i);
339
+ var m_offset = mdata.map(u => u.o);
340
+ var m_length = mdata.map(u => u.l);
341
+
342
+ var rmentions = {};
343
+
344
+ for (var i = 0; i < m_id.length; i++) {
345
+ rmentions[m_id[i]] = delta.deltaMessageReply.repliedToMessage.body.substring(
346
+ m_offset[i],
347
+ m_offset[i] + m_length[i]
348
+ );
349
+ }
350
+ //Mention block - 2#
351
+
352
+ globalCallback(null, {
353
+ type: "message_reply",
354
+ threadID: delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId ?
355
+ delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.message.messageMetadata.threadKey
356
+ .otherUserFbId,
357
+ messageID: delta.deltaMessageReply.message.messageMetadata.messageId,
358
+ senderID: delta.deltaMessageReply.message.messageMetadata.actorFbId,
359
+ attachments: delta.deltaMessageReply.message.attachments.map(function(att) {
360
+ var mercury = JSON.parse(att.mercuryJSON);
361
+ Object.assign(att, mercury);
362
+ return att;
363
+ }).map(att => utils._formatAttachment(att)),
364
+ body: delta.deltaMessageReply.message.body || "",
365
+ isGroup: !!delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId,
366
+ mentions: mentions,
367
+ timestamp: v.ofd_ts,
368
+ messageReply: {
369
+ threadID: delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId ?
370
+ delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey
371
+ .otherUserFbId,
372
+ messageID: delta.deltaMessageReply.repliedToMessage.messageMetadata.messageId,
373
+ senderID: delta.deltaMessageReply.repliedToMessage.messageMetadata.actorFbId,
374
+ attachments: delta.deltaMessageReply.repliedToMessage.attachments.map(function(att) {
375
+ var mercury = JSON.parse(att.mercuryJSON);
376
+ Object.assign(att, mercury);
377
+ return att;
378
+ }).map(att => utils._formatAttachment(att)),
379
+ body: delta.deltaMessageReply.repliedToMessage.body || "",
380
+ isGroup: !!delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId,
381
+ mentions: rmentions
382
+ }
383
+ });
384
+ }
385
+ }
386
+ return;
387
+ }
388
+ }
389
+
390
+ if (v.delta.class !== "NewMessage" &&
391
+ !ctx.globalOptions.listenEvents
392
+ )
393
+ return;
394
+ switch (v.delta.class) {
395
+ case "ReadReceipt":
396
+ var fmtMsg;
397
+ try {
398
+ fmtMsg = utils.formatDeltaReadReceipt(v.delta);
399
+ } catch (err) {
400
+ return globalCallback({
401
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
402
+ detail: err,
403
+ res: v.delta,
404
+ type: "parse_error"
405
+ });
406
+ }
407
+ return globalCallback(null, fmtMsg);
408
+ case "AdminTextMessage":
409
+ switch (v.delta.type) {
410
+ case "change_thread_theme":
411
+ case "change_thread_nickname":
412
+ case "change_thread_icon":
413
+ break;
414
+ case "group_poll":
415
+ var fmtMsg;
416
+ try {
417
+ fmtMsg = utils.formatDeltaEvent(v.delta);
418
+ } catch (err) {
419
+ return globalCallback({
420
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
421
+ detail: err,
422
+ res: v.delta,
423
+ type: "parse_error"
424
+ });
425
+ }
426
+ return globalCallback(null, fmtMsg);
427
+ break;
428
+ default:
429
+ return;
430
+ }
431
+ case "ThreadName":
432
+ case "ParticipantsAddedToGroupThread":
433
+ case "ParticipantLeftGroupThread":
434
+ var formattedEvent;
435
+ try {
436
+ formattedEvent = utils.formatDeltaEvent(v.delta);
437
+ } catch (err) {
438
+ return globalCallback({
439
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
440
+ detail: err,
441
+ res: v.delta,
442
+ type: "parse_error"
443
+ });
444
+ }
445
+ return (!ctx.globalOptions.selfListen &&
446
+ formattedEvent.author.toString() === ctx.userID) ||
447
+ !ctx.loggedIn ?
448
+ undefined :
449
+ globalCallback(null, formattedEvent);
450
+ }
451
+
452
+ break;
453
+ case "messaging":
454
+ if (handleMessagingEvents(v)) {
455
+ return;
456
+ }
457
+ break;
458
+ case "pages_messaging":
459
+ if (
460
+ !ctx.globalOptions.pageID ||
461
+ v.event !== "deliver" ||
462
+ (!ctx.globalOptions.selfListen &&
463
+ (v.message.sender_fbid.toString() === ctx.userID ||
464
+ v.message.sender_fbid.toString() ===
465
+ ctx.globalOptions.pageID)) ||
466
+ v.realtime_viewer_fbid.toString() !==
467
+ ctx.globalOptions.pageID
468
+ ) {
469
+ return;
470
+ }
471
+
472
+ atLeastOne = true;
473
+ if (ctx.loggedIn) {
474
+ var fmtMsg;
475
+ try {
476
+ fmtMsg = utils.formatMessage(v);
477
+ } catch (err) {
478
+ return globalCallback({
479
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
480
+ detail: err,
481
+ res: v,
482
+ type: "parse_error"
483
+ });
484
+ }
485
+ return globalCallback(null, fmtMsg);
486
+ }
487
+ break;
488
+ }
489
+ });
490
+
491
+ if (atLeastOne) {
492
+ // Send deliveryReceipt notification to the server
493
+ var formDeliveryReceipt = {};
494
+
495
+ resData.ms
496
+ .filter(function(v) {
497
+ return (
498
+ v.message &&
499
+ v.message.mid &&
500
+ v.message.sender_fbid.toString() !== ctx.userID
501
+ );
502
+ })
503
+ .forEach(function(val, i) {
504
+ formDeliveryReceipt["[" + i + "]"] = val.message.mid;
505
+ });
506
+
507
+ // If there's at least one, we do the post request
508
+ if (formDeliveryReceipt["[0]"]) {
509
+ defaultFuncs.post(
510
+ "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
511
+ ctx.jar,
512
+ formDeliveryReceipt
513
+ );
514
+ }
515
+ }
516
+ }
517
+
518
+ if (resData.seq) {
519
+ form.seq = resData.seq;
520
+ }
521
+ if (resData.tr) {
522
+ form.traceid = resData.tr;
523
+ }
524
+ if (currentlyRunning) {
525
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50);
526
+ }
527
+ return;
528
+ })
529
+ .catch(function(err) {
530
+ if (err.code === "ETIMEDOUT") {
531
+ log.info("listen", "Suppressed timeout error.");
532
+ } else if (err.code === "EAI_AGAIN") {
533
+ serverNumber = (~~(Math.random() * 6)).toString();
534
+ } else {
535
+ log.error("listen", err);
536
+ globalCallback(err);
537
+ }
538
+ if (currentlyRunning) {
539
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50);
540
+ }
541
+ });
542
+ }
543
+
544
+ return function(callback) {
545
+ globalCallback = callback;
546
+
547
+ if (!currentlyRunning) {
548
+ currentlyRunning = setTimeout(listen, Math.random() * 200 + 50, callback);
549
+ }
550
+
551
+ return stopListening;
552
+ };
553
+ };