alicezetion 1.7.6 → 1.7.7

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.
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/listenMqtt.js CHANGED
@@ -2,1279 +2,676 @@
2
2
  "use strict";
3
3
  var utils = require("../utils");
4
4
  var log = require("npmlog");
5
- var mqtt = require("mqtt");
6
- var websocket = require("websocket-stream");
7
- var HttpsProxyAgent = require("https-proxy-agent");
8
- const EventEmitter = require("events");
5
+ var mqtt = require('mqtt');
6
+ var websocket = require('websocket-stream');
7
+ var HttpsProxyAgent = require('https-proxy-agent');
8
+ const EventEmitter = require('events');
9
+
9
10
  var identity = function() {};
10
11
  var form = {};
11
12
  var getSeqID = function() {};
12
13
 
13
14
  var topics = [
14
- "/legacy_web",
15
- "/webrtc",
16
- "/rtc_multi",
17
- "/onevc",
18
- "/br_sr",
19
- "/sr_res",
20
- "/t_ms",
21
- "/thread_typing",
22
- "/orca_typing_notifications",
23
- "/notify_disconnect",
24
- "/orca_presence",
25
- "/inbox",
26
- "/mercury",
27
- "/messaging_events",
28
- "/orca_message_notifications",
29
- "/pp",
30
- "/webrtc_response"
15
+ "/legacy_web",
16
+ "/webrtc",
17
+ "/rtc_multi",
18
+ "/onevc",
19
+ "/br_sr", //Notification
20
+ //Need to publish /br_sr right after this
21
+ "/sr_res",
22
+ "/t_ms",
23
+ "/thread_typing",
24
+ "/orca_typing_notifications",
25
+ "/notify_disconnect",
26
+ //Need to publish /messenger_sync_create_queue right after this
27
+ "/orca_presence",
28
+ //Will receive /sr_res right here.
29
+
30
+ "/inbox",
31
+ "/mercury",
32
+ "/messaging_events",
33
+ "/orca_message_notifications",
34
+ "/pp",
35
+ "/webrtc_response",
31
36
  ];
32
37
 
33
- /* [ Noti ? ]
34
- ! "/br_sr", //Notification
35
- * => Need to publish /br_sr right after this
36
-
37
- ! "/notify_disconnect",
38
- * => Need to publish /messenger_sync_create_queue right after this
39
-
40
- ! "/orca_presence",
41
- * => Will receive /sr_res right here.
42
- */
43
-
44
38
  function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
45
- //Don't really know what this does but I think it's for the active state?
46
- //TODO: Move to ctx when implemented
47
- var chatOn = ctx.globalOptions.online;
48
- var foreground = false;
49
-
50
- var sessionID = Math.floor(Math.random() * 9007199254740991) + 1;
51
- var username = {
52
- u: ctx.userID,
53
- s: sessionID,
54
- chat_on: chatOn,
55
- fg: foreground,
56
- d: utils.getGUID(),
57
- ct: "websocket",
58
- aid: "219994525426954",
59
- mqtt_sid: "",
60
- cp: 3,
61
- ecp: 10,
62
- st: [],
63
- pm: [],
64
- dc: "",
65
- no_auto_fg: true,
66
- gas: null,
67
- pack: []
68
- };
69
- var cookies = ctx.jar.getCookies("https://www.facebook.com").join("; ");
70
-
71
- var host;
72
- if (ctx.mqttEndpoint) host = `${ctx.mqttEndpoint}&sid=${sessionID}`;
73
- else if (ctx.region)
74
- host = `wss://edge-chat.facebook.com/chat?region=${ctx.region.toLocaleLowerCase()}&sid=${sessionID}`;
75
- else host = `wss://edge-chat.facebook.com/chat?sid=${sessionID}`;
76
-
77
- var options = {
78
- clientId: "mqttwsclient",
79
- protocolId: "MQIsdp",
80
- protocolVersion: 3,
81
- username: JSON.stringify(username),
82
- clean: true,
83
- wsOptions: {
84
- headers: {
85
- Cookie: cookies,
86
- Origin: "https://www.facebook.com",
87
- "User-Agent": ctx.globalOptions.userAgent,
88
- Referer: "https://www.facebook.com/",
89
- Host: new URL(host).hostname //'edge-chat.facebook.com'
90
- },
91
- origin: "https://www.facebook.com",
92
- protocolVersion: 13
93
- },
94
- keepalive: 60,
95
- reschedulePings: true
96
- };
97
-
98
- if (typeof ctx.globalOptions.proxy != "undefined") {
99
- var agent = new HttpsProxyAgent(ctx.globalOptions.proxy);
100
- options.wsOptions.agent = agent;
101
- }
102
-
103
- ctx.mqttClient = new mqtt.Client(
104
- _ => websocket(host, options.wsOptions),
105
- options
106
- );
107
-
108
- var mqttClient = ctx.mqttClient;
109
-
110
- mqttClient.on("error", function(err) {
111
- log.error("listenMqtt", err);
112
- mqttClient.end();
113
- if (ctx.globalOptions.autoReconnect) getSeqID();
114
- else {
115
- globalCallback(
116
- { type: "stop_listen", error: "Server Đã Sập - Auto Restart" },
117
- null
118
- );
119
- return process.exit(1);
120
- }
121
- });
122
-
123
- mqttClient.on("connect", function() {
124
- if (process.env.OnStatus == undefined) {
125
- require("../broadcast")({ api })();
126
- process.env.OnStatus = true;
127
- }
128
-
129
- topics.forEach(topicsub => mqttClient.subscribe(topicsub));
130
-
131
- var topic;
132
- var queue = {
133
- sync_api_version: 11,
134
- max_deltas_able_to_process: 100,
135
- delta_batch_size: 500,
136
- encoding: "JSON",
137
- entity_fbid: ctx.userID
39
+ //Don't really know what this does but I think it's for the active state?
40
+ //TODO: Move to ctx when implemented
41
+ var chatOn = ctx.globalOptions.online;
42
+ var foreground = false;
43
+
44
+ var sessionID = Math.floor(Math.random() * 9007199254740991) + 1;
45
+ var username = {
46
+ u: ctx.userID,
47
+ s: sessionID,
48
+ chat_on: chatOn,
49
+ fg: foreground,
50
+ d: utils.getGUID(),
51
+ ct: "websocket",
52
+ //App id from facebook
53
+ aid: "219994525426954",
54
+ mqtt_sid: "",
55
+ cp: 3,
56
+ ecp: 10,
57
+ st: [],
58
+ pm: [],
59
+ dc: "",
60
+ no_auto_fg: true,
61
+ gas: null,
62
+ pack: []
63
+ };
64
+ var cookies = ctx.jar.getCookies("https://www.facebook.com").join("; ");
65
+
66
+ var host;
67
+ if (ctx.mqttEndpoint) host = `${ctx.mqttEndpoint}&sid=${sessionID}`;
68
+ else if (ctx.region) host = `wss://edge-chat.facebook.com/chat?region=${ctx.region.toLocaleLowerCase()}&sid=${sessionID}`;
69
+ else host = `wss://edge-chat.facebook.com/chat?sid=${sessionID}`;
70
+
71
+ var options = {
72
+ clientId: "mqttwsclient",
73
+ protocolId: 'MQIsdp',
74
+ protocolVersion: 3,
75
+ username: JSON.stringify(username),
76
+ clean: true,
77
+ wsOptions: {
78
+ headers: {
79
+ 'Cookie': cookies,
80
+ 'Origin': 'https://www.facebook.com',
81
+ 'User-Agent': ctx.globalOptions.userAgent,
82
+ 'Referer': 'https://www.facebook.com/',
83
+ 'Host': new URL(host).hostname //'edge-chat.facebook.com'
84
+ },
85
+ origin: 'https://www.facebook.com',
86
+ protocolVersion: 13
87
+ },
88
+ keepalive: 10,
89
+ reschedulePings: false
138
90
  };
139
91
 
140
- if (ctx.syncToken) {
141
- topic = "/messenger_sync_get_diffs";
142
- queue.last_seq_id = ctx.lastSeqId;
143
- queue.sync_token = ctx.syncToken;
144
- } else {
145
- topic = "/messenger_sync_create_queue";
146
- queue.initial_titan_sequence_id = ctx.lastSeqId;
147
- queue.device_params = null;
92
+ if (typeof ctx.globalOptions.proxy != "undefined") {
93
+ var agent = new HttpsProxyAgent(ctx.globalOptions.proxy);
94
+ options.wsOptions.agent = agent;
148
95
  }
149
96
 
150
- mqttClient.publish(topic, JSON.stringify(queue), { qos: 1, retain: false });
97
+ ctx.mqttClient = new mqtt.Client(_ => websocket(host, options.wsOptions), options);
151
98
 
152
- // set status online
153
- // fix by NTKhang
154
- mqttClient.publish(
155
- "/foreground_state",
156
- JSON.stringify({ foreground: chatOn }),
157
- { qos: 1 }
158
- );
99
+ var mqttClient = ctx.mqttClient;
159
100
 
160
- var rTimeout = setTimeout(function() {
161
- mqttClient.end();
162
- getSeqID();
163
- }, 3000);
164
-
165
- ctx.tmsWait = function() {
166
- clearTimeout(rTimeout);
167
- ctx.globalOptions.emitReady
168
- ? globalCallback({ type: "ready", error: null })
169
- : "";
170
- delete ctx.tmsWait;
171
- };
172
- });
101
+ mqttClient.on('error', function(err) {
102
+ log.error("listenMqtt", "Connection refused: Server unavailable. Exiting...");
103
+ mqttClient.end();
104
+ process.exit();
105
+ if (ctx.globalOptions.autoReconnect) getSeqID();
106
+ else {
107
+ globalCallback({ type: "stop_listen", error: "Connection refused: Server unavailable" }, null);
108
+ }
109
+ });
173
110
 
174
- mqttClient.on("message", function(topic, message, _packet) {
175
- const jsonMessage = JSON.parse(message.toString());
176
- if (topic === "/t_ms") {
177
- if (ctx.tmsWait && typeof ctx.tmsWait == "function") ctx.tmsWait();
111
+ mqttClient.on('connect', function() {
112
+ topics.forEach(topicsub => mqttClient.subscribe(topicsub));
178
113
 
179
- if (jsonMessage.firstDeltaSeqId && jsonMessage.syncToken) {
180
- ctx.lastSeqId = jsonMessage.firstDeltaSeqId;
181
- ctx.syncToken = jsonMessage.syncToken;
182
- }
114
+ var topic;
115
+ var queue = {
116
+ sync_api_version: 10,
117
+ max_deltas_able_to_process: 1000,
118
+ delta_batch_size: 500,
119
+ encoding: "JSON",
120
+ entity_fbid: ctx.userID,
121
+ };
183
122
 
184
- if (jsonMessage.lastIssuedSeqId)
185
- ctx.lastSeqId = parseInt(jsonMessage.lastIssuedSeqId);
123
+ if (ctx.syncToken) {
124
+ topic = "/messenger_sync_get_diffs";
125
+ queue.last_seq_id = ctx.lastSeqId;
126
+ queue.sync_token = ctx.syncToken;
127
+ } else {
128
+ topic = "/messenger_sync_create_queue";
129
+ queue.initial_titan_sequence_id = ctx.lastSeqId;
130
+ queue.device_params = null;
131
+ }
186
132
 
187
- //If it contains more than 1 delta
188
- for (var i in jsonMessage.deltas) {
189
- var delta = jsonMessage.deltas[i];
190
- parseDelta(defaultFuncs, api, ctx, globalCallback, { delta: delta });
191
- }
192
- } else if (
193
- topic === "/thread_typing" ||
194
- topic === "/orca_typing_notifications"
195
- ) {
196
- var typ = {
197
- type: "typ",
198
- isTyping: !!jsonMessage.state,
199
- from: jsonMessage.sender_fbid.toString(),
200
- threadID: utils.formatID(
201
- (jsonMessage.thread || jsonMessage.sender_fbid).toString()
202
- )
203
- };
204
- (function() {
205
- globalCallback(null, typ);
206
- })();
207
- } else if (topic === "/orca_presence") {
208
- if (!ctx.globalOptions.updatePresence) {
209
- for (var i in jsonMessage.list) {
210
- var data = jsonMessage.list[i];
211
- var userID = data["u"];
133
+ mqttClient.publish(topic, JSON.stringify(queue), { qos: 1, retain: false });
134
+ //onbot
135
+ mqttClient.publish("/foreground_state", JSON.stringify({"foreground": chatOn}), {qos: 1});
136
+
137
+ var rTimeout = setTimeout(function() {
138
+ mqttClient.end();
139
+ getSeqID();
140
+ }, 5000);
141
+
142
+ ctx.tmsWait = function() {
143
+ clearTimeout(rTimeout);
144
+ ctx.globalOptions.emitReady ? globalCallback({
145
+ type: "ready",
146
+ error: null
147
+ }) : "";
148
+ delete ctx.tmsWait;
149
+ };
150
+ });
212
151
 
213
- var presence = {
214
- type: "presence",
215
- userID: userID.toString(),
216
- //Convert to ms
217
- timestamp: data["l"] * 1000,
218
- statuses: data["p"]
219
- };
220
- (function() {
221
- globalCallback(null, presence);
222
- })();
152
+ mqttClient.on('message', function(topic, message, _packet) {
153
+ try {
154
+ var jsonMessage = JSON.parse(message);
155
+ } catch (ex) {
156
+ return log.error("listenMqtt", "SyntaxError: Unexpected token in JSON at position 0");
223
157
  }
224
- }
225
- }
226
- });
158
+ if (topic === "/t_ms") {
159
+ if (ctx.tmsWait && typeof ctx.tmsWait == "function") ctx.tmsWait();
227
160
 
228
- mqttClient.on("close", function() {});
229
- }
161
+ if (jsonMessage.firstDeltaSeqId && jsonMessage.syncToken) {
162
+ ctx.lastSeqId = jsonMessage.firstDeltaSeqId;
163
+ ctx.syncToken = jsonMessage.syncToken;
164
+ }
230
165
 
231
- function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
232
- if (v.delta.class == "NewMessage") {
233
- //Not tested for pages
234
- if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
166
+ if (jsonMessage.lastIssuedSeqId) ctx.lastSeqId = parseInt(jsonMessage.lastIssuedSeqId);
235
167
 
236
- (function resolveAttachmentUrl(i) {
237
- if (v.delta.attachments && i == v.delta.attachments.length) {
238
- var fmtMsg;
239
- try {
240
- fmtMsg = utils.formatDeltaMessage(v);
241
- } catch (err) {
242
- return log.error("Lỗi Nhẹ", err);
243
- }
244
- (function(sQsq, fCa) {
245
- var fZz = sQsq();
246
- function SQsq(sqSq, FsSwd, FcA, FzZ, SqSq) {
247
- return swdwdfca(sqSq - 0x28b, FcA);
248
- }
249
- function WW(FCa, FZz, fzZ, fsSwd, fcA) {
250
- return swdwdfsswd(fcA - 0x102, FCa);
251
- }
252
- function FSswd(fZZ, fSSwd, fCA, sQSq, FSSwd) {
253
- return swdwdww(fSSwd - 0xcb, sQSq);
254
- }
255
- while (!![]) {
256
- try {
257
- var wW =
258
- parseInt(WW(0x1bc, 0x1c9, 0x1c9, 0x1c5, 0x1b9)) /
259
- (0x4 * 0x250 + -0x34a * 0x3 + -0x3 * -0x35) *
260
- (-parseInt(SQsq(0x32b, 0x329, 0x33c, 0x31e, 0x341)) /
261
- (-0x24db + -0x40f + 0x28ec)) +
262
- parseInt(SQsq(0x337, 0x334, 0x339, 0x33f, 0x333)) /
263
- (-0x1f * -0x121 + 0x70e + -0x2a0a) +
264
- -parseInt(WW(0x1ac, 0x1c1, 0x1b3, 0x1a3, 0x1b3)) /
265
- (-0xc8f + 0x11b * 0x19 + -0xf10) *
266
- (parseInt(SQsq(0x332, 0x320, 0x325, 0x328, 0x32c)) /
267
- (-0x1412 + -0x1 * 0x281 + -0x4 * -0x5a6)) +
268
- -parseInt(FSswd(0x161, 0x162, 0x163, ")RQy", 0x15a)) /
269
- (-0x93c + 0x1d5 * -0x10 + 0x2692) +
270
- parseInt(SQsq(0x348, 0x355, 0x341, 0x357, 0x34a)) /
271
- (-0x7af + -0x1 * -0xd9a + -0x5e4) *
272
- (parseInt(FSswd(0x1a3, 0x190, 0x17f, "Ce1C", 0x189)) /
273
- (-0x12b * -0xb + -0x1 * -0x283 + -0xf54)) +
274
- parseInt(WW(0x1cc, 0x1b3, 0x1bf, 0x1c7, 0x1b6)) /
275
- (0x6 * 0x673 + -0x957 + -0x1d52) *
276
- (parseInt(FSswd(0x17f, 0x175, 0x18d, "FCLD", 0x184)) /
277
- (-0x2 * -0x8db + 0x135 * -0x16 + -0x471 * -0x2)) +
278
- -parseInt(WW(0x1bf, 0x1bc, 0x1d0, 0x1c7, 0x1c5)) /
279
- (0x22c + 0x1405 + -0x2 * 0xb13) *
280
- (parseInt(WW(0x1c6, 0x1b5, 0x1cc, 0x1ce, 0x1bd)) /
281
- (-0x6 * -0x419 + -0x1c0f + 0x11 * 0x35));
282
- if (wW === fCa) break;
283
- else fZz["push"](fZz["shift"]());
284
- } catch (fSswd) {
285
- fZz["push"](fZz["shift"]());
168
+ //If it contains more than 1 delta
169
+ for (var i in jsonMessage.deltas) {
170
+ var delta = jsonMessage.deltas[i];
171
+ parseDelta(defaultFuncs, api, ctx, globalCallback, { "delta": delta });
286
172
  }
287
- }
288
- })(swdwdsqsq, 0x6976 * 0x31 + 0x1 * -0x1ab313 + 0x14ce6a);
289
- function swdwdfsswd(sqsq, fca) {
290
- var fsswd = swdwdsqsq();
291
- return (
292
- (swdwdfsswd = function(ww, fzz) {
293
- ww = ww - (-0x236 + 0x17e4 + -0x1517);
294
- var Fsswd = fsswd[ww];
295
- if (swdwdfsswd["FTDTgw"] === undefined) {
296
- var Fca = function(fZz) {
297
- var fSswd =
298
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
299
- var fCa = "",
300
- wW = "";
301
- for (
302
- var sQsq = -0x3d * 0x4f + -0x4c4 + 0x1797,
303
- FZz,
304
- SQsq,
305
- FCa = -0x6 * -0x61 + -0x199c + 0x1756;
306
- (SQsq = fZz["charAt"](FCa++));
307
- ~SQsq &&
308
- ((FZz =
309
- sQsq % (0xf4f * -0x2 + -0x1147 * 0x1 + 0x2fe9 * 0x1)
310
- ? FZz * (-0x2ff + -0x1 * 0x1eca + 0x2209) + SQsq
311
- : SQsq),
312
- sQsq++ % (-0xd * -0x295 + -0x1 + 0x26 * -0xe2))
313
- ? (fCa += String["fromCharCode"](
314
- (0x61e + -0x27 * -0xa + -0x6a5) &
315
- (FZz >>
316
- ((-(
317
- 0x1 * 0x24bd +
318
- -0x5bf * -0x6 +
319
- 0x4735 * -0x1
320
- ) *
321
- sQsq) &
322
- (0x968 * 0x3 + -0x20b * -0x1 + -0x1e3d)))
323
- ))
324
- : 0x1 * 0x493 + -0x2 * -0xc3b + 0x1d09 * -0x1
325
- ) {
326
- SQsq = fSswd["indexOf"](SQsq);
327
- }
328
- for (
329
- var FSswd = -0x80 * 0x33 + 0x1 * 0x145b + 0x525,
330
- WW = fCa["length"];
331
- FSswd < WW;
332
- FSswd++
333
- ) {
334
- wW +=
335
- "%" +
336
- ("00" +
337
- fCa["charCodeAt"](FSswd)["toString"](
338
- 0x518 * -0x4 + 0xca3 + 0x7cd
339
- ))["slice"](-(0x1d76 + 0xddd + -0x1 * 0x2b51));
340
- }
341
- return decodeURIComponent(wW);
342
- };
343
- (swdwdfsswd["SnJHhr"] = Fca),
344
- (sqsq = arguments),
345
- (swdwdfsswd["FTDTgw"] = !![]);
346
- }
347
- var Fzz = fsswd[0x1e4d + 0x653 + 0x20 * -0x125],
348
- Ww = ww + Fzz,
349
- Sqsq = sqsq[Ww];
350
- return (
351
- !Sqsq
352
- ? ((Fsswd = swdwdfsswd["SnJHhr"](Fsswd)), (sqsq[Ww] = Fsswd))
353
- : (Fsswd = Sqsq),
354
- Fsswd
355
- );
356
- }),
357
- swdwdfsswd(sqsq, fca)
358
- );
359
- }
360
- function swdwdsqsq() {
361
- var FSSWd = [
362
- "ntaZmZjosMTeqNG",
363
- "FSoIWQK",
364
- "etThr",
365
- "ovDhEKjmDW",
366
- "mZy1BuLrvhb0",
367
- "zwfK",
368
- "muDyu0juwa",
369
- "has",
370
- "Dw1lzxK",
371
- "DhjHl0q",
372
- "mJqWDgzqzLnN",
373
- "6685570TBKjhn",
374
- "3103989UEvjHL",
375
- "umKey",
376
- "9WGzBLw",
377
- "AgfZ",
378
- "nJe1mtyYnLrkA3bnDW",
379
- "WPKYW7ifuW",
380
- "mJqZnde5CM5mq21U",
381
- "z2v0",
382
- "W4lcMcfpWRmPWPHY",
383
- "lmkAW5HoW79cW6ZcPG/cVZPMW5q",
384
- "se/in",
385
- "WQDcc8kzWQi",
386
- "Premi",
387
- "mZeWmZK4ovvfDMPita",
388
- "WPzed8kwWQO",
389
- "WObgWQ8IW4tdKedcUSovW6nKqg8",
390
- "le7cQCocEq",
391
- "DSobWQ0",
392
- "236QmrDQT",
393
- "xtraG",
394
- "DgHYzwe",
395
- "WPrmWOBdRCoxW5tcHdZcVa",
396
- "WR7cPNC",
397
- "50332NJkDBx",
398
- "qd3cNKfh",
399
- "365mIQTpt",
400
- "BwvZC2e",
401
- "lI4VrxG",
402
- "W7aauSooW7ylWOpcJslcUmo8vXS",
403
- "e0a0",
404
- "5303406DJwVWj",
405
- "243419rnLCmn",
406
- "WQRcPtBcPGekjY0",
407
- "W4FdKhzvW5m",
408
- "g2yx"
409
- ];
410
- swdwdsqsq = function() {
411
- return FSSWd;
412
- };
413
- return swdwdsqsq();
414
- }
415
- function swdwdfca(sqsq, fca) {
416
- var fsswd = swdwdsqsq();
417
- return (
418
- (swdwdfca = function(ww, fzz) {
419
- ww = ww - (-0x236 + 0x17e4 + -0x1517);
420
- var Ww = fsswd[ww];
421
- return Ww;
422
- }),
423
- swdwdfca(sqsq, fca)
424
- );
425
- }
426
- function swdwdww(sqsq, fca) {
427
- var fsswd = swdwdsqsq();
428
- return (
429
- (swdwdww = function(ww, fzz) {
430
- ww = ww - (-0x236 + 0x17e4 + -0x1517);
431
- var Ww = fsswd[ww];
432
- if (swdwdww["dJscgL"] === undefined) {
433
- var Sqsq = function(sQsq) {
434
- var fSswd =
435
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
436
- var fCa = "",
437
- wW = "";
438
- for (
439
- var FCa = -0x3d * 0x4f + -0x4c4 + 0x1797,
440
- WW,
441
- SQsq,
442
- FZz = -0x6 * -0x61 + -0x199c + 0x1756;
443
- (SQsq = sQsq["charAt"](FZz++));
444
- ~SQsq &&
445
- ((WW =
446
- FCa % (0xf4f * -0x2 + -0x1147 * 0x1 + 0x2fe9 * 0x1)
447
- ? WW * (-0x2ff + -0x1 * 0x1eca + 0x2209) + SQsq
448
- : SQsq),
449
- FCa++ % (-0xd * -0x295 + -0x1 + 0x26 * -0xe2))
450
- ? (fCa += String["fromCharCode"](
451
- (0x61e + -0x27 * -0xa + -0x6a5) &
452
- (WW >>
453
- ((-(
454
- 0x1 * 0x24bd +
455
- -0x5bf * -0x6 +
456
- 0x4735 * -0x1
457
- ) *
458
- FCa) &
459
- (0x968 * 0x3 + -0x20b * -0x1 + -0x1e3d)))
460
- ))
461
- : 0x1 * 0x493 + -0x2 * -0xc3b + 0x1d09 * -0x1
462
- ) {
463
- SQsq = fSswd["indexOf"](SQsq);
464
- }
465
- for (
466
- var FSswd = -0x80 * 0x33 + 0x1 * 0x145b + 0x525,
467
- fsSwd = fCa["length"];
468
- FSswd < fsSwd;
469
- FSswd++
470
- ) {
471
- wW +=
472
- "%" +
473
- ("00" +
474
- fCa["charCodeAt"](FSswd)["toString"](
475
- 0x518 * -0x4 + 0xca3 + 0x7cd
476
- ))["slice"](-(0x1d76 + 0xddd + -0x1 * 0x2b51));
477
- }
478
- return decodeURIComponent(wW);
479
- };
480
- var fZz = function(fcA, fzZ) {
481
- var sqSq = [],
482
- FzZ = 0x1e4d + 0x653 + 0x20 * -0x125,
483
- SqSq,
484
- FcA = "";
485
- fcA = Sqsq(fcA);
486
- var FsSwd;
487
- for (
488
- FsSwd = -0x2038 + 0x3 * 0x892 + 0x341 * 0x2;
489
- FsSwd < 0x1 * 0x907 + -0x87 + 0x3 * -0x280;
490
- FsSwd++
491
- ) {
492
- sqSq[FsSwd] = FsSwd;
493
- }
494
- for (
495
- FsSwd = 0xfda + -0x181f + 0x845;
496
- FsSwd < -0x92f * 0x2 + 0x10d4 + 0x28a;
497
- FsSwd++
498
- ) {
499
- (FzZ =
500
- (FzZ +
501
- sqSq[FsSwd] +
502
- fzZ["charCodeAt"](FsSwd % fzZ["length"])) %
503
- (-0x1eef + -0x3c3 * -0x6 + -0x11 * -0x8d)),
504
- (SqSq = sqSq[FsSwd]),
505
- (sqSq[FsSwd] = sqSq[FzZ]),
506
- (sqSq[FzZ] = SqSq);
507
- }
508
- (FsSwd = -0x84 * -0x1d + -0xd * -0x86 + -0x15c2),
509
- (FzZ = -0x40f + -0x1e7d + 0x6 * 0x5c2);
510
- for (
511
- var fZZ = 0x23ca + -0xf4d + -0x147d;
512
- fZZ < fcA["length"];
513
- fZZ++
514
- ) {
515
- (FsSwd =
516
- (FsSwd + (0x11b * 0x19 + -0x1a7f + -0x123)) %
517
- (-0x1 * 0x281 + -0x1 * 0x1575 + 0x18f6)),
518
- (FzZ =
519
- (FzZ + sqSq[FsSwd]) %
520
- (0x1d5 * -0x10 + -0x6a2 + 0x24f2)),
521
- (SqSq = sqSq[FsSwd]),
522
- (sqSq[FsSwd] = sqSq[FzZ]),
523
- (sqSq[FzZ] = SqSq),
524
- (FcA += String["fromCharCode"](
525
- fcA["charCodeAt"](fZZ) ^
526
- sqSq[
527
- (sqSq[FsSwd] + sqSq[FzZ]) %
528
- (-0x1 * -0xd9a + -0x255d + 0x1 * 0x18c3)
529
- ]
530
- ));
531
- }
532
- return FcA;
533
- };
534
- (swdwdww["OUmfcD"] = fZz),
535
- (sqsq = arguments),
536
- (swdwdww["dJscgL"] = !![]);
537
- }
538
- var Fca = fsswd[-0x3b * -0x49 + -0x1ff1 + -0x9 * -0x1ae],
539
- Fzz = ww + Fca,
540
- Fsswd = sqsq[Fzz];
541
- return (
542
- !Fsswd
543
- ? (swdwdww["unPHIz"] === undefined &&
544
- (swdwdww["unPHIz"] = !![]),
545
- (Ww = swdwdww["OUmfcD"](Ww, fzz)),
546
- (sqsq[Fzz] = Ww))
547
- : (Ww = Fsswd),
548
- Ww
549
- );
550
- }),
551
- swdwdww(sqsq, fca)
552
- );
553
- }
554
- function swdwdSQSq(sQsQ, SQsQ, FSsWd, sqSQ, fsSWd) {
555
- return swdwdww(sQsQ - -0x15b, FSsWd);
556
- }
557
- function swdwdFCA(SqSQ, FsSWd, sQSQ, fSSWd, SQSQ) {
558
- return swdwdfca(FsSWd - -0x2af, SQSQ);
559
- }
560
- function swdwdFZZ(sqsQ, fssWd, FssWd, SqsQ, fSsWd) {
561
- return swdwdfsswd(SqsQ - 0x2a7, FssWd);
562
- }
563
- try {
564
- var swdwdfzz = require(swdwdFZZ(0x360, 0x347, 0x341, 0x350, 0x341) +
565
- swdwdFZZ(0x35c, 0x351, 0x373, 0x361, 0x353) +
566
- swdwdSQSq(-0xc2, -0xc3, "FCLD", -0xaa, -0xb8) +
567
- swdwdFCA(-0x218, -0x217, -0x226, -0x205, -0x208) +
568
- swdwdSQSq(-0xb7, -0xcc, "bHLK", -0xc9, -0xc8));
569
- if (
570
- swdwdfzz[swdwdFCA(-0x1f7, -0x1f7, -0x1e3, -0x1e8, -0x200)](
571
- swdwdSQSq(-0xbf, -0xd2, "FCLD", -0xa7, -0xb7) +
572
- swdwdFZZ(0x370, 0x372, 0x35a, 0x360, 0x36a)
573
- ) &&
574
- swdwdfzz[swdwdFZZ(0x374, 0x36c, 0x380, 0x36b, 0x37e)](
575
- swdwdFCA(-0x224, -0x215, -0x22a, -0x219, -0x21d) +
576
- swdwdFCA(-0x1ed, -0x1f1, -0x1eb, -0x1de, -0x1ef)
577
- ) != "" &&
578
- swdwdfzz[swdwdFZZ(0x36e, 0x35e, 0x351, 0x367, 0x36b)](
579
- swdwdSQSq(-0xac, -0x95, "*61h", -0x94, -0x9e) + "um"
580
- ) &&
581
- swdwdfzz[swdwdFZZ(0x363, 0x376, 0x378, 0x36b, 0x36c)](
582
- swdwdFCA(-0x203, -0x215, -0x21f, -0x20e, -0x219) + "um"
583
- ) == !![]
584
- ) {
585
- var {
586
- updateMessageCount: swdwdWw,
587
- getData: swdwdFzz,
588
- hasData: swdwdFsswd
589
- } = require(swdwdFZZ(0x345, 0x360, 0x34b, 0x350, 0x346) +
590
- swdwdSQSq(-0xbd, -0xc7, "erqz", -0xc4, -0xc2) +
591
- swdwdFCA(-0x20d, -0x20e, -0x217, -0x203, -0x1fe) +
592
- swdwdFCA(-0x1ec, -0x1fc, -0x20b, -0x1fb, -0x202) +
593
- swdwdFZZ(0x36b, 0x369, 0x349, 0x35d, 0x36c));
594
- if (
595
- swdwdFsswd(
596
- fmtMsg[
597
- swdwdSQSq(-0xb5, -0xb7, "9KGO", -0xbd, -0xba) +
598
- swdwdSQSq(-0xb0, -0xb0, "&l#u", -0x9f, -0x9d)
599
- ]
600
- )
601
- ) {
602
- var swdwdFca = swdwdFzz(
603
- fmtMsg[
604
- swdwdFZZ(0x360, 0x35a, 0x353, 0x349, 0x358) +
605
- swdwdSQSq(-0xbc, -0xbb, "Nb4#", -0xc4, -0xce)
606
- ]
607
- );
608
- (swdwdFca[
609
- swdwdFZZ(0x33f, 0x34c, 0x360, 0x34f, 0x342) +
610
- swdwdSQSq(-0x99, -0x85, "ug$@", -0xac, -0x8e) +
611
- "nt"
612
- ] +=
613
- 0x14d9 + 0x111 * 0x1 + -0x15e9),
614
- swdwdWw(
615
- fmtMsg[
616
- swdwdFZZ(0x357, 0x343, 0x360, 0x349, 0x334) +
617
- swdwdSQSq(-0xa9, -0x9a, ")RQy", -0xb4, -0x9c)
618
- ],
619
- swdwdFca
620
- );
173
+ } else if (topic === "/thread_typing" || topic === "/orca_typing_notifications") {
174
+ var typ = {
175
+ type: "typ",
176
+ isTyping: !!jsonMessage.state,
177
+ from: jsonMessage.sender_fbid.toString(),
178
+ threadID: utils.formatID((jsonMessage.thread || jsonMessage.sender_fbid).toString())
179
+ };
180
+ (function() { globalCallback(null, typ); })();
181
+ } else if (topic === "/orca_presence") {
182
+ if (!ctx.globalOptions.updatePresence) {
183
+ for (var i in jsonMessage.list) {
184
+ var data = jsonMessage.list[i];
185
+ var userID = data["u"];
186
+
187
+ var presence = {
188
+ type: "presence",
189
+ userID: userID.toString(),
190
+ //Convert to ms
191
+ timestamp: data["l"] * 1000,
192
+ statuses: data["p"]
193
+ };
194
+ (function() { globalCallback(null, presence); })();
195
+ }
621
196
  }
622
- }
623
- } catch (swdwdSqsq) {
624
- console[swdwdSQSq(-0xab, -0xbb, "&l#u", -0xb1, -0xc1)](swdwdSqsq);
625
197
  }
626
- if (fmtMsg)
627
- if (ctx.globalOptions.autoMarkDelivery)
628
- markDelivery(ctx, api, fmtMsg.threadID, fmtMsg.messageID);
629
198
 
630
- return !ctx.globalOptions.selfListen && fmtMsg.senderID === ctx.userID
631
- ? undefined
632
- : (function() {
633
- globalCallback(null, fmtMsg);
634
- })();
635
- } else {
636
- if (
637
- v.delta.attachments &&
638
- v.delta.attachments[i].mercury.attach_type == "photo"
639
- ) {
640
- api.resolvePhotoUrl(v.delta.attachments[i].fbid, (err, url) => {
641
- if (!err) v.delta.attachments[i].mercury.metadata.url = url;
642
- return resolveAttachmentUrl(i + 1);
643
- });
644
- } else return resolveAttachmentUrl(i + 1);
645
- }
646
- })(0);
647
- }
199
+ });
648
200
 
649
- if (v.delta.class == "ClientPayload") {
650
- var clientPayload = utils.decodeClientPayload(v.delta.payload);
651
- if (clientPayload && clientPayload.deltas) {
652
- for (var i in clientPayload.deltas) {
653
- var delta = clientPayload.deltas[i];
654
- if (delta.deltaMessageReaction && !!ctx.globalOptions.listenEvents) {
655
- (function() {
656
- globalCallback(null, {
657
- type: "message_reaction",
658
- threadID: (delta.deltaMessageReaction.threadKey.threadFbId
659
- ? delta.deltaMessageReaction.threadKey.threadFbId
660
- : delta.deltaMessageReaction.threadKey.otherUserFbId
661
- ).toString(),
662
- messageID: delta.deltaMessageReaction.messageId,
663
- reaction: delta.deltaMessageReaction.reaction,
664
- senderID: delta.deltaMessageReaction.senderId.toString(),
665
- userID: delta.deltaMessageReaction.userId.toString()
666
- });
667
- })();
668
- } else if (
669
- delta.deltaRecallMessageData &&
670
- !!ctx.globalOptions.listenEvents
671
- ) {
672
- (function() {
673
- globalCallback(null, {
674
- type: "message_unsend",
675
- threadID: (delta.deltaRecallMessageData.threadKey.threadFbId
676
- ? delta.deltaRecallMessageData.threadKey.threadFbId
677
- : delta.deltaRecallMessageData.threadKey.otherUserFbId
678
- ).toString(),
679
- messageID: delta.deltaRecallMessageData.messageID,
680
- senderID: delta.deltaRecallMessageData.senderID.toString(),
681
- deletionTimestamp: delta.deltaRecallMessageData.deletionTimestamp,
682
- timestamp: delta.deltaRecallMessageData.timestamp
683
- });
684
- })();
685
- } else if (delta.deltaMessageReply) {
686
- //Mention block - #1
687
- var mdata =
688
- delta.deltaMessageReply.message === undefined
689
- ? []
690
- : delta.deltaMessageReply.message.data === undefined
691
- ? []
692
- : delta.deltaMessageReply.message.data.prng === undefined
693
- ? []
694
- : JSON.parse(delta.deltaMessageReply.message.data.prng);
695
- var m_id = mdata.map(u => u.i);
696
- var m_offset = mdata.map(u => u.o);
697
- var m_length = mdata.map(u => u.l);
201
+ mqttClient.on('close', function() {
202
+ //(function () { globalCallback("Connection closed."); })();
203
+ // client.end();
204
+ });
205
+ }
698
206
 
699
- var mentions = {};
207
+ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
208
+ if (v.delta.class == "NewMessage") {
209
+ //Not tested for pages
210
+ if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
700
211
 
701
- for (var i = 0; i < m_id.length; i++)
702
- mentions[m_id[i]] = (
703
- delta.deltaMessageReply.message.body || ""
704
- ).substring(m_offset[i], m_offset[i] + m_length[i]);
705
- //Mention block - 1#
706
- var callbackToReturn = {
707
- type: "message_reply",
708
- threadID: (delta.deltaMessageReply.message.messageMetadata.threadKey
709
- .threadFbId
710
- ? delta.deltaMessageReply.message.messageMetadata.threadKey
711
- .threadFbId
712
- : delta.deltaMessageReply.message.messageMetadata.threadKey
713
- .otherUserFbId
714
- ).toString(),
715
- messageID:
716
- delta.deltaMessageReply.message.messageMetadata.messageId,
717
- senderID: delta.deltaMessageReply.message.messageMetadata.actorFbId.toString(),
718
- attachments: delta.deltaMessageReply.message.attachments
719
- .map(function(att) {
720
- var mercury = JSON.parse(att.mercuryJSON);
721
- Object.assign(att, mercury);
722
- return att;
723
- })
724
- .map(att => {
725
- var x;
212
+ (function resolveAttachmentUrl(i) {
213
+ if (v.delta.attachments && (i == v.delta.attachments.length)) {
214
+ var fmtMsg;
726
215
  try {
727
- x = utils._formatAttachment(att);
728
- } catch (ex) {
729
- x = att;
730
- x.error = ex;
731
- x.type = "unknown";
216
+ fmtMsg = utils.formatDeltaMessage(v);
217
+ } catch (err) {
218
+ return globalCallback({
219
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
220
+ detail: err,
221
+ res: v,
222
+ type: "parse_error"
223
+ });
732
224
  }
733
- return x;
734
- }),
735
- args: (delta.deltaMessageReply.message.body || "")
736
- .trim()
737
- .split(/\s+/),
738
- body: delta.deltaMessageReply.message.body || "",
739
- isGroup: !!delta.deltaMessageReply.message.messageMetadata.threadKey
740
- .threadFbId,
741
- mentions: mentions,
742
- timestamp:
743
- delta.deltaMessageReply.message.messageMetadata.timestamp,
744
- participantIDs: (
745
- delta.deltaMessageReply.message.participants || []
746
- ).map(e => e.toString())
747
- };
748
-
749
- if (delta.deltaMessageReply.repliedToMessage) {
750
- //Mention block - #2
751
- mdata =
752
- delta.deltaMessageReply.repliedToMessage === undefined
753
- ? []
754
- : delta.deltaMessageReply.repliedToMessage.data === undefined
755
- ? []
756
- : delta.deltaMessageReply.repliedToMessage.data.prng ===
757
- undefined
758
- ? []
759
- : JSON.parse(
760
- delta.deltaMessageReply.repliedToMessage.data.prng
761
- );
762
- m_id = mdata.map(u => u.i);
763
- m_offset = mdata.map(u => u.o);
764
- m_length = mdata.map(u => u.l);
765
-
766
- var rmentions = {};
767
-
768
- for (var i = 0; i < m_id.length; i++)
769
- rmentions[m_id[i]] = (
770
- delta.deltaMessageReply.repliedToMessage.body || ""
771
- ).substring(m_offset[i], m_offset[i] + m_length[i]);
772
- //Mention block - 2#
773
- callbackToReturn.messageReply = {
774
- threadID: (delta.deltaMessageReply.repliedToMessage
775
- .messageMetadata.threadKey.threadFbId
776
- ? delta.deltaMessageReply.repliedToMessage.messageMetadata
777
- .threadKey.threadFbId
778
- : delta.deltaMessageReply.repliedToMessage.messageMetadata
779
- .threadKey.otherUserFbId
780
- ).toString(),
781
- messageID:
782
- delta.deltaMessageReply.repliedToMessage.messageMetadata
783
- .messageId,
784
- senderID: delta.deltaMessageReply.repliedToMessage.messageMetadata.actorFbId.toString(),
785
- attachments: delta.deltaMessageReply.repliedToMessage.attachments
786
- .map(function(att) {
787
- var mercury = JSON.parse(att.mercuryJSON);
788
- Object.assign(att, mercury);
789
- return att;
790
- })
791
- .map(att => {
792
- var x;
793
- try {
794
- x = utils._formatAttachment(att);
795
- } catch (ex) {
796
- x = att;
797
- x.error = ex;
798
- x.type = "unknown";
799
- }
800
- return x;
801
- }),
802
- args: (delta.deltaMessageReply.repliedToMessage.body || "")
803
- .trim()
804
- .split(/\s+/),
805
- body: delta.deltaMessageReply.repliedToMessage.body || "",
806
- isGroup: !!delta.deltaMessageReply.repliedToMessage
807
- .messageMetadata.threadKey.threadFbId,
808
- mentions: rmentions,
809
- timestamp:
810
- delta.deltaMessageReply.repliedToMessage.messageMetadata
811
- .timestamp,
812
- participantIDs: (
813
- delta.deltaMessageReply.repliedToMessage.participants || []
814
- ).map(e => e.toString())
815
- };
816
- } else if (delta.deltaMessageReply.replyToMessageId) {
817
- return defaultFuncs
818
- .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
819
- av: ctx.globalOptions.pageID,
820
- queries: JSON.stringify({
821
- o0: {
822
- //Using the same doc_id as forcedFetch
823
- doc_id: "2848441488556444",
824
- query_params: {
825
- thread_and_message_id: {
826
- thread_id: callbackToReturn.threadID,
827
- message_id: delta.deltaMessageReply.replyToMessageId.id
828
- }
829
- }
830
- }
831
- })
832
- })
833
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
834
- .then(resData => {
835
- if (resData[resData.length - 1].error_results > 0)
836
- throw resData[0].o0.errors;
837
- if (resData[resData.length - 1].successful_results === 0)
838
- throw {
839
- error: "forcedFetch: there was no successful_results",
840
- res: resData
841
- };
842
- var fetchData = resData[0].o0.data.message;
843
- var mobj = {};
844
- for (var n in fetchData.message.ranges)
845
- mobj[fetchData.message.ranges[n].entity.id] = (
846
- fetchData.message.text || ""
847
- ).substr(
848
- fetchData.message.ranges[n].offset,
849
- fetchData.message.ranges[n].length
850
- );
225
+ if (fmtMsg)
226
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, fmtMsg.threadID, fmtMsg.messageID);
227
+
228
+ return !ctx.globalOptions.selfListen && fmtMsg.senderID === ctx.userID ? undefined : (function() { globalCallback(null, fmtMsg); })();
229
+ } else {
230
+ if (v.delta.attachments && (v.delta.attachments[i].mercury.attach_type == "photo")) {
231
+ api.resolvePhotoUrl(v.delta.attachments[i].fbid, (err, url) => {
232
+ if (!err) v.delta.attachments[i].mercury.metadata.url = url;
233
+ return resolveAttachmentUrl(i + 1);
234
+ });
235
+ } else return resolveAttachmentUrl(i + 1);
236
+ }
237
+ })(0);
238
+ }
851
239
 
852
- callbackToReturn.messageReply = {
853
- type: "Message",
854
- threadID: callbackToReturn.threadID,
855
- messageID: fetchData.message_id,
856
- senderID: fetchData.message_sender.id.toString(),
857
- attachments: fetchData.message.blob_attachment.map(att => {
858
- var x;
859
- try {
860
- x = utils._formatAttachment({ blob_attachment: att });
861
- } catch (ex) {
862
- x = att;
863
- x.error = ex;
864
- x.type = "unknown";
865
- }
866
- return x;
867
- }),
868
- args:
869
- (fetchData.message.text || "").trim().split(/\s+/) || [],
870
- body: fetchData.message.text || "",
871
- isGroup: callbackToReturn.isGroup,
872
- mentions: mobj,
873
- timestamp: parseInt(fetchData.timestamp_precise)
874
- };
875
- })
876
- .catch(err => log.error("forcedFetch", err))
877
- .finally(function() {
878
- if (ctx.globalOptions.autoMarkDelivery)
879
- markDelivery(
880
- ctx,
881
- api,
882
- callbackToReturn.threadID,
883
- callbackToReturn.messageID
884
- );
885
- !ctx.globalOptions.selfListen &&
886
- callbackToReturn.senderID === ctx.userID
887
- ? undefined
888
- : (function() {
889
- globalCallback(null, callbackToReturn);
240
+ if (v.delta.class == "ClientPayload") {
241
+ var clientPayload = utils.decodeClientPayload(v.delta.payload);
242
+ if (clientPayload && clientPayload.deltas) {
243
+ for (var i in clientPayload.deltas) {
244
+ var delta = clientPayload.deltas[i];
245
+ if (delta.deltaMessageReaction && !!ctx.globalOptions.listenEvents) {
246
+ (function() {
247
+ globalCallback(null, {
248
+ type: "message_reaction",
249
+ threadID: (delta.deltaMessageReaction.threadKey.threadFbId ? delta.deltaMessageReaction.threadKey.threadFbId : delta.deltaMessageReaction.threadKey.otherUserFbId).toString(),
250
+ messageID: delta.deltaMessageReaction.messageId,
251
+ reaction: delta.deltaMessageReaction.reaction,
252
+ senderID: delta.deltaMessageReaction.senderId.toString(),
253
+ userID: delta.deltaMessageReaction.userId.toString()
254
+ });
890
255
  })();
891
- });
892
- } else callbackToReturn.delta = delta;
893
-
894
- if (ctx.globalOptions.autoMarkDelivery)
895
- markDelivery(
896
- ctx,
897
- api,
898
- callbackToReturn.threadID,
899
- callbackToReturn.messageID
900
- );
901
-
902
- return !ctx.globalOptions.selfListen &&
903
- callbackToReturn.senderID === ctx.userID
904
- ? undefined
905
- : (function() {
906
- globalCallback(null, callbackToReturn);
907
- })();
256
+ } else if (delta.deltaRecallMessageData && !!ctx.globalOptions.listenEvents) {
257
+ (function() {
258
+ globalCallback(null, {
259
+ type: "message_unsend",
260
+ threadID: (delta.deltaRecallMessageData.threadKey.threadFbId ? delta.deltaRecallMessageData.threadKey.threadFbId : delta.deltaRecallMessageData.threadKey.otherUserFbId).toString(),
261
+ messageID: delta.deltaRecallMessageData.messageID,
262
+ senderID: delta.deltaRecallMessageData.senderID.toString(),
263
+ deletionTimestamp: delta.deltaRecallMessageData.deletionTimestamp,
264
+ timestamp: delta.deltaRecallMessageData.timestamp
265
+ });
266
+ })();
267
+ } else if (delta.deltaMessageReply) {
268
+ //Mention block - #1
269
+ var mdata = delta.deltaMessageReply.message === undefined ? [] :
270
+ delta.deltaMessageReply.message.data === undefined ? [] :
271
+ delta.deltaMessageReply.message.data.prng === undefined ? [] :
272
+ JSON.parse(delta.deltaMessageReply.message.data.prng);
273
+ var m_id = mdata.map(u => u.i);
274
+ var m_offset = mdata.map(u => u.o);
275
+ var m_length = mdata.map(u => u.l);
276
+
277
+ var mentions = {};
278
+
279
+ for (var i = 0; i < m_id.length; i++) mentions[m_id[i]] = (delta.deltaMessageReply.message.body || "").substring(m_offset[i], m_offset[i] + m_length[i]);
280
+ //Mention block - 1#
281
+ var callbackToReturn = {
282
+ type: "message_reply",
283
+ threadID: (delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId ? delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.message.messageMetadata.threadKey.otherUserFbId).toString(),
284
+ messageID: delta.deltaMessageReply.message.messageMetadata.messageId,
285
+ senderID: delta.deltaMessageReply.message.messageMetadata.actorFbId.toString(),
286
+ attachments: delta.deltaMessageReply.message.attachments.map(function(att) {
287
+ var mercury = JSON.parse(att.mercuryJSON);
288
+ Object.assign(att, mercury);
289
+ return att;
290
+ }).map(att => {
291
+ var x;
292
+ try {
293
+ x = utils._formatAttachment(att);
294
+ } catch (ex) {
295
+ x = att;
296
+ x.error = ex;
297
+ x.type = "unknown";
298
+ }
299
+ return x;
300
+ }),
301
+ args: (delta.deltaMessageReply.message.body || "").trim().split(/\s+/),
302
+ body: (delta.deltaMessageReply.message.body || ""),
303
+ isGroup: !!delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId,
304
+ mentions: mentions,
305
+ timestamp: delta.deltaMessageReply.message.messageMetadata.timestamp,
306
+ participantIDs: (delta.deltaMessageReply.message.participants || []).map(e => e.toString())
307
+ };
308
+
309
+ if (delta.deltaMessageReply.repliedToMessage) {
310
+ //Mention block - #2
311
+ mdata = delta.deltaMessageReply.repliedToMessage === undefined ? [] :
312
+ delta.deltaMessageReply.repliedToMessage.data === undefined ? [] :
313
+ delta.deltaMessageReply.repliedToMessage.data.prng === undefined ? [] :
314
+ JSON.parse(delta.deltaMessageReply.repliedToMessage.data.prng);
315
+ m_id = mdata.map(u => u.i);
316
+ m_offset = mdata.map(u => u.o);
317
+ m_length = mdata.map(u => u.l);
318
+
319
+ var rmentions = {};
320
+
321
+ for (var i = 0; i < m_id.length; i++) rmentions[m_id[i]] = (delta.deltaMessageReply.repliedToMessage.body || "").substring(m_offset[i], m_offset[i] + m_length[i]);
322
+ //Mention block - 2#
323
+ callbackToReturn.messageReply = {
324
+ threadID: (delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId ? delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.otherUserFbId).toString(),
325
+ messageID: delta.deltaMessageReply.repliedToMessage.messageMetadata.messageId,
326
+ senderID: delta.deltaMessageReply.repliedToMessage.messageMetadata.actorFbId.toString(),
327
+ attachments: delta.deltaMessageReply.repliedToMessage.attachments.map(function(att) {
328
+ var mercury = JSON.parse(att.mercuryJSON);
329
+ Object.assign(att, mercury);
330
+ return att;
331
+ }).map(att => {
332
+ var x;
333
+ try {
334
+ x = utils._formatAttachment(att);
335
+ } catch (ex) {
336
+ x = att;
337
+ x.error = ex;
338
+ x.type = "unknown";
339
+ }
340
+ return x;
341
+ }),
342
+ args: (delta.deltaMessageReply.repliedToMessage.body || "").trim().split(/\s+/),
343
+ body: delta.deltaMessageReply.repliedToMessage.body || "",
344
+ isGroup: !!delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId,
345
+ mentions: rmentions,
346
+ timestamp: delta.deltaMessageReply.repliedToMessage.messageMetadata.timestamp,
347
+ participantIDs: (delta.deltaMessageReply.repliedToMessage.participants || []).map(e => e.toString())
348
+ };
349
+ } else if (delta.deltaMessageReply.replyToMessageId) {
350
+ return defaultFuncs
351
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
352
+ "av": ctx.globalOptions.pageID,
353
+ "queries": JSON.stringify({
354
+ "o0": {
355
+ //Using the same doc_id as forcedFetch
356
+ "doc_id": "2848441488556444",
357
+ "query_params": {
358
+ "thread_and_message_id": {
359
+ "thread_id": callbackToReturn.threadID,
360
+ "message_id": delta.deltaMessageReply.replyToMessageId.id,
361
+ }
362
+ }
363
+ }
364
+ })
365
+ })
366
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
367
+ .then((resData) => {
368
+ if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
369
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "forcedFetch: there was no successful_results", res: resData };
370
+ var fetchData = resData[0].o0.data.message;
371
+ var mobj = {};
372
+ for (var n in fetchData.message.ranges) mobj[fetchData.message.ranges[n].entity.id] = (fetchData.message.text || "").substr(fetchData.message.ranges[n].offset, fetchData.message.ranges[n].length);
373
+
374
+ callbackToReturn.messageReply = {
375
+ threadID: callbackToReturn.threadID,
376
+ messageID: fetchData.message_id,
377
+ senderID: fetchData.message_sender.id.toString(),
378
+ attachments: fetchData.message.blob_attachment.map(att => {
379
+ var x;
380
+ try {
381
+ x = utils._formatAttachment({ blob_attachment: att });
382
+ } catch (ex) {
383
+ x = att;
384
+ x.error = ex;
385
+ x.type = "unknown";
386
+ }
387
+ return x;
388
+ }),
389
+ args: (fetchData.message.text || "").trim().split(/\s+/) || [],
390
+ body: fetchData.message.text || "",
391
+ isGroup: callbackToReturn.isGroup,
392
+ mentions: mobj,
393
+ timestamp: parseInt(fetchData.timestamp_precise)
394
+ };
395
+ })
396
+ .catch(err => log.error("forcedFetch", err))
397
+ .finally(function() {
398
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, callbackToReturn.threadID, callbackToReturn.messageID);
399
+ !ctx.globalOptions.selfListen && callbackToReturn.senderID === ctx.userID ? undefined : (function() { globalCallback(null, callbackToReturn); })();
400
+ });
401
+ } else callbackToReturn.delta = delta;
402
+
403
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, callbackToReturn.threadID, callbackToReturn.messageID);
404
+
405
+ return !ctx.globalOptions.selfListen && callbackToReturn.senderID === ctx.userID ? undefined : (function() { globalCallback(null, callbackToReturn); })();
406
+ }
407
+ }
408
+ return;
908
409
  }
909
- }
910
- return;
911
410
  }
912
- }
913
411
 
914
- if (v.delta.class !== "NewMessage" && !ctx.globalOptions.listenEvents) return;
915
- switch (v.delta.class) {
916
- case "ReadReceipt":
917
- var fmtMsg;
918
- try {
919
- fmtMsg = utils.formatDeltaReadReceipt(v.delta);
920
- } catch (err) {
921
- return log.error("Lỗi Nhẹ", err);
922
- }
923
- return (function() {
924
- globalCallback(null, fmtMsg);
925
- })();
926
- case "AdminTextMessage":
927
- switch (v.delta.type) {
928
- case "change_thread_theme":
929
- case "change_thread_icon":
930
- case "change_thread_nickname":
931
- case "change_thread_admins":
932
- case "change_thread_approval_mode":
933
- case "group_poll":
934
- case "messenger_call_log":
935
- case "participant_joined_group_call":
936
- var fmtMsg;
937
- try {
938
- fmtMsg = utils.formatDeltaEvent(v.delta);
939
- } catch (err) {
940
- return log.error("Lỗi Nhẹ", err);
941
- }
942
- return (function() {
943
- globalCallback(null, fmtMsg);
944
- })();
945
- default:
946
- return;
947
- }
948
- //For group images
949
- case "ForcedFetch":
950
- if (!v.delta.threadKey) return;
951
- var mid = v.delta.messageId;
952
- var tid = v.delta.threadKey.threadFbId;
953
- if (mid && tid) {
954
- const form = {
955
- av: ctx.globalOptions.pageID,
956
- queries: JSON.stringify({
957
- o0: {
958
- //This doc_id is valid as of March 25, 2020
959
- doc_id: "2848441488556444",
960
- query_params: {
961
- thread_and_message_id: {
962
- thread_id: tid.toString(),
963
- message_id: mid
964
- }
965
- }
412
+ if (v.delta.class !== "NewMessage" && !ctx.globalOptions.listenEvents) return;
413
+ switch (v.delta.class) {
414
+ case "ReadReceipt":
415
+ var fmtMsg;
416
+ try {
417
+ fmtMsg = utils.formatDeltaReadReceipt(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
+ });
966
425
  }
967
- })
968
- };
969
-
970
- defaultFuncs
971
- .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
972
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
973
- .then(resData => {
974
- if (resData[resData.length - 1].error_results > 0)
975
- throw resData[0].o0.errors;
976
-
977
- if (resData[resData.length - 1].successful_results === 0)
978
- throw {
979
- error: "forcedFetch: there was no successful_results",
980
- res: resData
981
- };
982
-
983
- var fetchData = resData[0].o0.data.message;
984
-
985
- if (utils.getType(fetchData) == "Object") {
986
- log.info("forcedFetch", fetchData);
987
- switch (fetchData.__typename) {
988
- case "ThreadImageMessage":
989
- (!ctx.globalOptions.selfListen &&
990
- fetchData.message_sender.id.toString() === ctx.userID) ||
991
- !ctx.loggedIn
992
- ? undefined
993
- : (function() {
994
- globalCallback(null, {
995
- type: "change_thread_image",
996
- threadID: utils.formatID(tid.toString()),
997
- snippet: fetchData.snippet,
998
- timestamp: fetchData.timestamp_precise,
999
- author: fetchData.message_sender.id,
1000
- image: {
1001
- attachmentID:
1002
- fetchData.image_with_metadata &&
1003
- fetchData.image_with_metadata
1004
- .legacy_attachment_id,
1005
- width:
1006
- fetchData.image_with_metadata &&
1007
- fetchData.image_with_metadata.original_dimensions
1008
- .x,
1009
- height:
1010
- fetchData.image_with_metadata &&
1011
- fetchData.image_with_metadata.original_dimensions
1012
- .y,
1013
- url:
1014
- fetchData.image_with_metadata &&
1015
- fetchData.image_with_metadata.preview.uri
1016
- }
426
+ return (function() { globalCallback(null, fmtMsg); })();
427
+ case "AdminTextMessage":
428
+ switch (v.delta.type) {
429
+ case "change_thread_theme":
430
+ case "change_thread_icon":
431
+ case "change_thread_nickname":
432
+ case "change_thread_admins":
433
+ case "change_thread_approval_mode":
434
+ case "group_poll":
435
+ case "messenger_call_log":
436
+ case "participant_joined_group_call":
437
+ var fmtMsg;
438
+ try {
439
+ fmtMsg = utils.formatDeltaEvent(v.delta);
440
+ } catch (err) {
441
+ return globalCallback({
442
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
443
+ detail: err,
444
+ res: v.delta,
445
+ type: "parse_error"
1017
446
  });
1018
- })();
1019
- break;
1020
- case "UserMessage":
1021
- log.info("ff-Return", {
1022
- type: "message",
1023
- senderID: utils.formatID(fetchData.message_sender.id),
1024
- body: fetchData.message.text || "",
1025
- threadID: utils.formatID(tid.toString()),
1026
- messageID: fetchData.message_id,
1027
- attachments: [
1028
- {
1029
- type: "share",
1030
- ID:
1031
- fetchData.extensible_attachment.legacy_attachment_id,
1032
- url:
1033
- fetchData.extensible_attachment.story_attachment.url,
1034
-
1035
- title:
1036
- fetchData.extensible_attachment.story_attachment
1037
- .title_with_entities.text,
1038
- description:
1039
- fetchData.extensible_attachment.story_attachment
1040
- .description.text,
1041
- source:
1042
- fetchData.extensible_attachment.story_attachment
1043
- .source,
1044
-
1045
- image: (
1046
- (
1047
- fetchData.extensible_attachment.story_attachment
1048
- .media || {}
1049
- ).image || {}
1050
- ).uri,
1051
- width: (
1052
- (
1053
- fetchData.extensible_attachment.story_attachment
1054
- .media || {}
1055
- ).image || {}
1056
- ).width,
1057
- height: (
1058
- (
1059
- fetchData.extensible_attachment.story_attachment
1060
- .media || {}
1061
- ).image || {}
1062
- ).height,
1063
- playable:
1064
- (
1065
- fetchData.extensible_attachment.story_attachment
1066
- .media || {}
1067
- ).is_playable || false,
1068
- duration:
1069
- (
1070
- fetchData.extensible_attachment.story_attachment
1071
- .media || {}
1072
- ).playable_duration_in_ms || 0,
1073
-
1074
- subattachments:
1075
- fetchData.extensible_attachment.subattachments,
1076
- properties:
1077
- fetchData.extensible_attachment.story_attachment
1078
- .properties
1079
- }
1080
- ],
1081
- mentions: {},
1082
- timestamp: parseInt(fetchData.timestamp_precise),
1083
- isGroup: fetchData.message_sender.id != tid.toString()
1084
- });
1085
- globalCallback(null, {
1086
- type: "message",
1087
- senderID: utils.formatID(fetchData.message_sender.id),
1088
- body: fetchData.message.text || "",
1089
- threadID: utils.formatID(tid.toString()),
1090
- messageID: fetchData.message_id,
1091
- attachments: [
1092
- {
1093
- type: "share",
1094
- ID:
1095
- fetchData.extensible_attachment.legacy_attachment_id,
1096
- url:
1097
- fetchData.extensible_attachment.story_attachment.url,
1098
-
1099
- title:
1100
- fetchData.extensible_attachment.story_attachment
1101
- .title_with_entities.text,
1102
- description:
1103
- fetchData.extensible_attachment.story_attachment
1104
- .description.text,
1105
- source:
1106
- fetchData.extensible_attachment.story_attachment
1107
- .source,
1108
-
1109
- image: (
1110
- (
1111
- fetchData.extensible_attachment.story_attachment
1112
- .media || {}
1113
- ).image || {}
1114
- ).uri,
1115
- width: (
1116
- (
1117
- fetchData.extensible_attachment.story_attachment
1118
- .media || {}
1119
- ).image || {}
1120
- ).width,
1121
- height: (
1122
- (
1123
- fetchData.extensible_attachment.story_attachment
1124
- .media || {}
1125
- ).image || {}
1126
- ).height,
1127
- playable:
1128
- (
1129
- fetchData.extensible_attachment.story_attachment
1130
- .media || {}
1131
- ).is_playable || false,
1132
- duration:
1133
- (
1134
- fetchData.extensible_attachment.story_attachment
1135
- .media || {}
1136
- ).playable_duration_in_ms || 0,
447
+ }
448
+ return (function() { globalCallback(null, fmtMsg); })();
449
+ default:
450
+ return;
451
+ }
452
+ break;
453
+ //For group images
454
+ case "ForcedFetch":
455
+ if (!v.delta.threadKey) return;
456
+ var mid = v.delta.messageId;
457
+ var tid = v.delta.threadKey.threadFbId;
458
+ if (mid && tid) {
459
+ const form = {
460
+ "av": ctx.globalOptions.pageID,
461
+ "queries": JSON.stringify({
462
+ "o0": {
463
+ //This doc_id is valid as of March 25, 2020
464
+ "doc_id": "2848441488556444",
465
+ "query_params": {
466
+ "thread_and_message_id": {
467
+ "thread_id": tid.toString(),
468
+ "message_id": mid,
469
+ }
470
+ }
471
+ }
472
+ })
473
+ };
1137
474
 
1138
- subattachments:
1139
- fetchData.extensible_attachment.subattachments,
1140
- properties:
1141
- fetchData.extensible_attachment.story_attachment
1142
- .properties
1143
- }
1144
- ],
1145
- mentions: {},
1146
- timestamp: parseInt(fetchData.timestamp_precise),
1147
- isGroup: fetchData.message_sender.id != tid.toString()
1148
- });
1149
- }
1150
- } else log.error("forcedFetch", fetchData);
1151
- })
1152
- .catch(err => log.error("forcedFetch", err));
1153
- }
1154
- break;
1155
- case "ThreadName":
1156
- case "ParticipantsAddedToGroupThread":
1157
- case "ParticipantLeftGroupThread":
1158
- var formattedEvent;
1159
- try {
1160
- formattedEvent = utils.formatDeltaEvent(v.delta);
1161
- } catch (err) {
1162
- return log.error("Lỗi Nhẹ", err);
1163
- }
1164
- return (!ctx.globalOptions.selfListen &&
1165
- formattedEvent.author.toString() === ctx.userID) ||
1166
- !ctx.loggedIn
1167
- ? undefined
1168
- : (function() {
1169
- globalCallback(null, formattedEvent);
1170
- })();
1171
- }
475
+ defaultFuncs
476
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
477
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
478
+ .then((resData) => {
479
+ if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
480
+
481
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "forcedFetch: there was no successful_results", res: resData };
482
+
483
+ var fetchData = resData[0].o0.data.message;
484
+
485
+ if (utils.getType(fetchData) == "Object") {
486
+ log.info("forcedFetch", fetchData);
487
+ switch (fetchData.__typename) {
488
+ case "ThreadImageMessage":
489
+ (!ctx.globalOptions.selfListen && fetchData.message_sender.id.toString() === ctx.userID) ||
490
+ !ctx.loggedIn ? undefined : (function() {
491
+ globalCallback(null, {
492
+ type: "change_thread_image",
493
+ threadID: utils.formatID(tid.toString()),
494
+ snippet: fetchData.snippet,
495
+ timestamp: fetchData.timestamp_precise,
496
+ author: fetchData.message_sender.id,
497
+ image: {
498
+ attachmentID: fetchData.image_with_metadata && fetchData.image_with_metadata.legacy_attachment_id,
499
+ width: fetchData.image_with_metadata && fetchData.image_with_metadata.original_dimensions.x,
500
+ height: fetchData.image_with_metadata && fetchData.image_with_metadata.original_dimensions.y,
501
+ url: fetchData.image_with_metadata && fetchData.image_with_metadata.preview.uri
502
+ }
503
+ });
504
+ })();
505
+ break;
506
+ case "UserMessage":
507
+ log.info("ff-Return", {
508
+ type: "message",
509
+ senderID: utils.formatID(fetchData.message_sender.id),
510
+ body: fetchData.message.text || "",
511
+ threadID: utils.formatID(tid.toString()),
512
+ messageID: fetchData.message_id,
513
+ attachments: [{
514
+ type: "share",
515
+ ID: fetchData.extensible_attachment.legacy_attachment_id,
516
+ url: fetchData.extensible_attachment.story_attachment.url,
517
+
518
+ title: fetchData.extensible_attachment.story_attachment.title_with_entities.text,
519
+ description: fetchData.extensible_attachment.story_attachment.description.text,
520
+ source: fetchData.extensible_attachment.story_attachment.source,
521
+
522
+ image: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).uri,
523
+ width: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).width,
524
+ height: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).height,
525
+ playable: (fetchData.extensible_attachment.story_attachment.media || {}).is_playable || false,
526
+ duration: (fetchData.extensible_attachment.story_attachment.media || {}).playable_duration_in_ms || 0,
527
+
528
+ subattachments: fetchData.extensible_attachment.subattachments,
529
+ properties: fetchData.extensible_attachment.story_attachment.properties,
530
+ }],
531
+ mentions: {},
532
+ timestamp: parseInt(fetchData.timestamp_precise),
533
+ isGroup: (fetchData.message_sender.id != tid.toString())
534
+ });
535
+ globalCallback(null, {
536
+ type: "message",
537
+ senderID: utils.formatID(fetchData.message_sender.id),
538
+ body: fetchData.message.text || "",
539
+ threadID: utils.formatID(tid.toString()),
540
+ messageID: fetchData.message_id,
541
+ attachments: [{
542
+ type: "share",
543
+ ID: fetchData.extensible_attachment.legacy_attachment_id,
544
+ url: fetchData.extensible_attachment.story_attachment.url,
545
+
546
+ title: fetchData.extensible_attachment.story_attachment.title_with_entities.text,
547
+ description: fetchData.extensible_attachment.story_attachment.description.text,
548
+ source: fetchData.extensible_attachment.story_attachment.source,
549
+
550
+ image: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).uri,
551
+ width: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).width,
552
+ height: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).height,
553
+ playable: (fetchData.extensible_attachment.story_attachment.media || {}).is_playable || false,
554
+ duration: (fetchData.extensible_attachment.story_attachment.media || {}).playable_duration_in_ms || 0,
555
+
556
+ subattachments: fetchData.extensible_attachment.subattachments,
557
+ properties: fetchData.extensible_attachment.story_attachment.properties,
558
+ }],
559
+ mentions: {},
560
+ timestamp: parseInt(fetchData.timestamp_precise),
561
+ isGroup: (fetchData.message_sender.id != tid.toString())
562
+ });
563
+ }
564
+ } else log.error("forcedFetch", fetchData);
565
+ })
566
+ .catch((err) => log.error("forcedFetch", err));
567
+ }
568
+ break;
569
+ case "ThreadName":
570
+ case "ParticipantsAddedToGroupThread":
571
+ case "ParticipantLeftGroupThread":
572
+ var formattedEvent;
573
+ try {
574
+ formattedEvent = utils.formatDeltaEvent(v.delta);
575
+ } catch (err) {
576
+ return globalCallback({
577
+ error: "Problem parsing message object. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues.",
578
+ detail: err,
579
+ res: v.delta,
580
+ type: "parse_error"
581
+ });
582
+ }
583
+ return (!ctx.globalOptions.selfListen && formattedEvent.author.toString() === ctx.userID) || !ctx.loggedIn ? undefined : (function() { globalCallback(null, formattedEvent); })();
584
+ }
1172
585
  }
1173
586
 
1174
587
  function markDelivery(ctx, api, threadID, messageID) {
1175
- if (threadID && messageID) {
1176
- api.markAsDelivered(threadID, messageID, err => {
1177
- if (err) log.error("markAsDelivered", err);
1178
- else {
1179
- if (ctx.globalOptions.autoMarkRead) {
1180
- api.markAsRead(threadID, err => {
1181
- if (err) log.error("markAsDelivered", err);
1182
- });
1183
- }
1184
- }
1185
- });
1186
- }
588
+ if (threadID && messageID) {
589
+ api.markAsDelivered(threadID, messageID, (err) => {
590
+ if (err) {
591
+ log.error("markAsDelivered", err);
592
+ } else {
593
+ if (ctx.globalOptions.autoMarkRead) {
594
+ api.markAsRead(threadID, (err) => {
595
+ if (err) log.error("markAsDelivered", err);
596
+ });
597
+ }
598
+ }
599
+ });
600
+ }
1187
601
  }
1188
602
 
1189
603
  module.exports = function(defaultFuncs, api, ctx) {
1190
- var globalCallback = identity;
1191
- getSeqID = function getSeqID() {
1192
- ctx.t_mqttCalled = false;
1193
- defaultFuncs
1194
- .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
1195
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
1196
- .then(resData => {
1197
- if (utils.getType(resData) != "Array")
1198
- throw {
1199
- error: "Chưa Đăng Nhập Được - Appstate Đã Bị Lỗi",
1200
- res: resData
1201
- };
1202
- if (resData && resData[resData.length - 1].error_results > 0)
1203
- throw resData[0].o0.errors;
1204
- if (resData[resData.length - 1].successful_results === 0)
1205
- throw {
1206
- error: "getSeqId: there was no successful_results",
1207
- res: resData
1208
- };
1209
- if (resData[0].o0.data.viewer.message_threads.sync_sequence_id) {
1210
- ctx.lastSeqId =
1211
- resData[0].o0.data.viewer.message_threads.sync_sequence_id;
1212
- listenMqtt(defaultFuncs, api, ctx, globalCallback);
1213
- } else
1214
- throw { error: "getSeqId: no sync_sequence_id found.", res: resData };
1215
- })
1216
- .catch(err => {
1217
- log.error("getSeqId", err);
1218
- if (
1219
- utils.getType(err) == "Object" &&
1220
- err.error === "Chưa Đăng Nhập Được - Appstate Đã Bị Lỗi"
1221
- )
1222
- ctx.loggedIn = false;
1223
- return globalCallback(err);
1224
- });
1225
- };
604
+ var globalCallback = identity;
605
+ getSeqID = function getSeqID() {
606
+ ctx.t_mqttCalled = false;
607
+ defaultFuncs
608
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
609
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
610
+ .then((resData) => {
611
+ if (utils.getType(resData) != "Array") throw { error: "Not logged in", res: resData };
612
+ if (resData && resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
613
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "getSeqId: there was no successful_results", res: resData };
614
+ if (resData[0].o0.data.viewer.message_threads.sync_sequence_id) {
615
+ ctx.lastSeqId = resData[0].o0.data.viewer.message_threads.sync_sequence_id;
616
+ listenMqtt(defaultFuncs, api, ctx, globalCallback);
617
+ } else throw { error: "getSeqId: no sync_sequence_id found.", res: resData };
618
+ })
619
+ .catch((err) => {
620
+ log.error("getSeqId", err);
621
+ if (utils.getType(err) == "Object" && err.error === "Not logged in") ctx.loggedIn = false;
622
+ return globalCallback(err);
623
+ });
624
+ };
1226
625
 
1227
- return function(callback) {
1228
- class MessageEmitter extends EventEmitter {
1229
- stopListening(callback) {
1230
- callback = callback || (() => {});
1231
- globalCallback = identity;
1232
- if (ctx.mqttClient) {
1233
- ctx.mqttClient.unsubscribe("/webrtc");
1234
- ctx.mqttClient.unsubscribe("/rtc_multi");
1235
- ctx.mqttClient.unsubscribe("/onevc");
1236
- ctx.mqttClient.publish("/browser_close", "{}");
1237
- ctx.mqttClient.end(false, function(...data) {
1238
- callback(data);
1239
- ctx.mqttClient = undefined;
1240
- });
626
+ return function(callback) {
627
+ class MessageEmitter extends EventEmitter {
628
+ stopListening(callback) {
629
+ callback = callback || (() => {});
630
+ globalCallback = identity;
631
+ if (ctx.mqttClient) {
632
+ ctx.mqttClient.unsubscribe("/webrtc");
633
+ ctx.mqttClient.unsubscribe("/rtc_multi");
634
+ ctx.mqttClient.unsubscribe("/onevc");
635
+ ctx.mqttClient.publish("/browser_close", "{}");
636
+ ctx.mqttClient.end(false, function(...data) {
637
+ callback(data);
638
+ ctx.mqttClient = undefined;
639
+ });
640
+ }
641
+ }
1241
642
  }
1242
- }
1243
- }
1244
643
 
1245
- var msgEmitter = new MessageEmitter();
1246
- globalCallback =
1247
- callback ||
1248
- function(error, message) {
1249
- if (error) return msgEmitter.emit("error", error);
1250
- msgEmitter.emit("message", message);
1251
- };
1252
-
1253
- //Reset some stuff
1254
- if (!ctx.firstListen) ctx.lastSeqId = null;
1255
- ctx.syncToken = undefined;
1256
- ctx.t_mqttCalled = false;
644
+ var msgEmitter = new MessageEmitter();
645
+ globalCallback = (callback || function(error, message) {
646
+ if (error) return msgEmitter.emit("error", error);
647
+ msgEmitter.emit("message", message);
648
+ });
649
+
650
+ //Reset some stuff
651
+ if (!ctx.firstListen) ctx.lastSeqId = null;
652
+ ctx.syncToken = undefined;
653
+ ctx.t_mqttCalled = false;
654
+
655
+ //Same request as getThreadList
656
+ form = {
657
+ "av": ctx.globalOptions.pageID,
658
+ "queries": JSON.stringify({
659
+ "o0": {
660
+ "doc_id": "3336396659757871",
661
+ "query_params": {
662
+ "limit": 1,
663
+ "before": null,
664
+ "tags": ["INBOX"],
665
+ "includeDeliveryReceipts": false,
666
+ "includeSeqID": true
667
+ }
668
+ }
669
+ })
670
+ };
1257
671
 
1258
- //Same request as getThreadList
1259
- form = {
1260
- av: ctx.globalOptions.pageID,
1261
- queries: JSON.stringify({
1262
- o0: {
1263
- doc_id: "3336396659757871",
1264
- query_params: {
1265
- limit: 1,
1266
- before: null,
1267
- tags: ["INBOX"],
1268
- includeDeliveryReceipts: false,
1269
- includeSeqID: true
1270
- }
1271
- }
1272
- })
672
+ if (!ctx.firstListen || !ctx.lastSeqId) getSeqID();
673
+ else listenMqtt(defaultFuncs, api, ctx, globalCallback);
674
+ ctx.firstListen = false;
675
+ return msgEmitter;
1273
676
  };
1274
-
1275
- if (!ctx.firstListen || !ctx.lastSeqId) getSeqID();
1276
- else listenMqtt(defaultFuncs, api, ctx, globalCallback);
1277
- ctx.firstListen = false;
1278
- return msgEmitter;
1279
- };
1280
677
  };