@dongdev/fca-unofficial 2.0.7 → 2.0.8

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 (74) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/func/checkUpdate.js +9 -9
  3. package/func/logger.js +40 -104
  4. package/module/login.js +4 -4
  5. package/module/loginHelper.js +3 -3
  6. package/module/options.js +5 -9
  7. package/package.json +5 -5
  8. package/src/api/action/addExternalModule.js +5 -5
  9. package/src/api/action/changeAvatar.js +11 -10
  10. package/src/api/action/changeBio.js +7 -8
  11. package/src/api/action/getCurrentUserID.js +1 -1
  12. package/src/api/action/handleFriendRequest.js +5 -5
  13. package/src/api/action/logout.js +9 -8
  14. package/src/api/action/refreshFb_dtsg.js +17 -12
  15. package/src/api/action/setPostReaction.js +10 -11
  16. package/src/api/action/unfriend.js +3 -4
  17. package/src/api/http/httpGet.js +7 -8
  18. package/src/api/http/httpPost.js +7 -8
  19. package/src/api/http/postFormData.js +6 -5
  20. package/src/api/messaging/addUserToGroup.js +0 -1
  21. package/src/api/messaging/changeAdminStatus.js +108 -89
  22. package/src/api/messaging/changeArchivedStatus.js +6 -6
  23. package/src/api/messaging/changeBlockedStatus.js +3 -4
  24. package/src/api/messaging/changeGroupImage.js +72 -117
  25. package/src/api/messaging/changeNickname.js +59 -48
  26. package/src/api/messaging/changeThreadColor.js +61 -47
  27. package/src/api/messaging/changeThreadEmoji.js +106 -0
  28. package/src/api/messaging/createNewGroup.js +5 -5
  29. package/src/api/messaging/createPoll.js +36 -63
  30. package/src/api/messaging/deleteMessage.js +4 -4
  31. package/src/api/messaging/deleteThread.js +4 -4
  32. package/src/api/messaging/forwardAttachment.js +38 -47
  33. package/src/api/messaging/getFriendsList.js +5 -6
  34. package/src/api/messaging/getMessage.js +4 -9
  35. package/src/api/messaging/handleMessageRequest.js +5 -5
  36. package/src/api/messaging/markAsDelivered.js +5 -5
  37. package/src/api/messaging/markAsRead.js +7 -7
  38. package/src/api/messaging/markAsReadAll.js +3 -4
  39. package/src/api/messaging/markAsSeen.js +7 -7
  40. package/src/api/messaging/muteThread.js +3 -4
  41. package/src/api/messaging/removeUserFromGroup.js +82 -56
  42. package/src/api/messaging/resolvePhotoUrl.js +2 -3
  43. package/src/api/messaging/searchForThread.js +2 -3
  44. package/src/api/messaging/sendMessage.js +171 -101
  45. package/src/api/messaging/sendMessageMqtt.js +14 -12
  46. package/src/api/messaging/sendTypingIndicator.js +11 -11
  47. package/src/api/messaging/setMessageReaction.js +68 -82
  48. package/src/api/messaging/setTitle.js +77 -48
  49. package/src/api/messaging/shareContact.js +2 -4
  50. package/src/api/messaging/threadColors.js +0 -3
  51. package/src/api/messaging/unsendMessage.js +74 -37
  52. package/src/api/messaging/uploadAttachment.js +11 -9
  53. package/src/api/socket/core/connectMqtt.js +180 -0
  54. package/src/api/socket/core/getSeqID.js +25 -0
  55. package/src/api/socket/core/getTaskResponseData.js +22 -0
  56. package/src/api/socket/core/markDelivery.js +12 -0
  57. package/src/api/socket/core/parseDelta.js +351 -0
  58. package/src/api/socket/detail/buildStream.js +176 -68
  59. package/src/api/socket/detail/constants.js +24 -0
  60. package/src/api/socket/listenMqtt.js +80 -1005
  61. package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
  62. package/src/api/threads/getThreadInfo.js +35 -248
  63. package/src/api/threads/getThreadList.js +20 -20
  64. package/src/api/threads/getThreadPictures.js +3 -4
  65. package/src/api/users/getUserID.js +5 -6
  66. package/src/api/users/getUserInfo.js +305 -73
  67. package/src/api/users/getUserInfoV2.js +134 -0
  68. package/src/database/models/user.js +32 -0
  69. package/src/database/userData.js +89 -0
  70. package/src/utils/constants.js +12 -2
  71. package/src/utils/format.js +1051 -0
  72. package/src/utils/request.js +75 -7
  73. package/src/api/threads/changeThreadEmoji.js +0 -55
  74. package/src/utils/index.js +0 -1497
@@ -1,1497 +0,0 @@
1
- "use strict";
2
- var url = require("url");
3
- const log = require("npmlog");
4
- const stream = require("stream");
5
- const bluebird = require("bluebird");
6
- const querystring = require("querystring");
7
- const request = bluebird.promisify(require("request").defaults({ jar: true }));
8
-
9
- class CustomError extends Error {
10
- constructor(obj) {
11
- if (typeof obj === "string") obj = { message: obj };
12
- if (typeof obj !== "object" || obj === null)
13
- throw new TypeError("Object required");
14
- obj.message ? super(obj.message) : super();
15
- Object.assign(this, obj);
16
- }
17
- }
18
-
19
- function tryPromise(tryFunc) {
20
- return new Promise((resolve, reject) => {
21
- try {
22
- resolve(tryFunc());
23
- } catch (error) {
24
- reject(error);
25
- }
26
- });
27
- }
28
-
29
- function delay(ms) {
30
- return new Promise(resolve => setTimeout(resolve, ms));
31
- }
32
-
33
- function setProxy(url) {
34
- if (typeof url == "undefined")
35
- return (request = bluebird.promisify(
36
- require("request").defaults({ jar: true })
37
- ));
38
- return (request = bluebird.promisify(
39
- require("request").defaults({ jar: true, proxy: url })
40
- ));
41
- }
42
-
43
- function getHeaders(url, options, ctx, customHeader) {
44
- var headers = {
45
- "Content-Type": "application/x-www-form-urlencoded",
46
- Referer: "https://www.facebook.com/",
47
- Host: url.replace("https://", "").split("/")[0],
48
- Origin: "https://www.facebook.com",
49
- "user-agent":
50
- options?.userAgent ||
51
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Safari/537.36",
52
- Connection: "keep-alive",
53
- "sec-fetch-site": "same-origin",
54
- "sec-fetch-mode": "cors"
55
- };
56
- if (customHeader) Object.assign(headers, customHeader);
57
- if (ctx && ctx.region) headers["X-MSGR-Region"] = ctx.region;
58
-
59
- return headers;
60
- }
61
-
62
- function isReadableStream(obj) {
63
- return (
64
- obj instanceof stream.Stream &&
65
- (getType(obj._read) === "Function" ||
66
- getType(obj._read) === "AsyncFunction") &&
67
- getType(obj._readableState) === "Object"
68
- );
69
- }
70
-
71
- function get(url, jar, qs, options, ctx) {
72
- if (getType(qs) === "Object")
73
- for (var prop in qs)
74
- if (qs.hasOwnProperty(prop) && getType(qs[prop]) === "Object")
75
- qs[prop] = JSON.stringify(qs[prop]);
76
- var op = {
77
- headers: getHeaders(url, options, ctx),
78
- timeout: 60000,
79
- qs: qs,
80
- url: url,
81
- method: "GET",
82
- jar: jar,
83
- gzip: true
84
- };
85
- return request(op).then(function(res) {
86
- return res;
87
- });
88
- }
89
-
90
- function get2(url, jar, headers, options, ctx) {
91
- var op = {
92
- headers: getHeaders(url, options, ctx, headers),
93
- timeout: 60000,
94
- url: url,
95
- method: "GET",
96
- jar: jar,
97
- gzip: true
98
- };
99
-
100
- return request(op).then(function(res) {
101
- return res[0];
102
- });
103
- }
104
-
105
- function post(url, jar, form, options, ctx, customHeader) {
106
- var op = {
107
- headers: getHeaders(url, options),
108
- timeout: 60000,
109
- url: url,
110
- method: "POST",
111
- form: form,
112
- jar: jar,
113
- gzip: true
114
- };
115
- return request(op).then(function(res) {
116
- return res;
117
- });
118
- }
119
-
120
- function postFormData(url, jar, form, qs, options, ctx) {
121
- var headers = getHeaders(url, options, ctx);
122
- headers["Content-Type"] = "multipart/form-data";
123
- var op = {
124
- headers: headers,
125
- timeout: 60000,
126
- url: url,
127
- method: "POST",
128
- formData: form,
129
- qs: qs,
130
- jar: jar,
131
- gzip: true
132
- };
133
-
134
- return request(op).then(function(res) {
135
- return res;
136
- });
137
- }
138
-
139
- function padZeros(val, len) {
140
- val = String(val);
141
- len = len || 2;
142
- while (val.length < len) val = "0" + val;
143
- return val;
144
- }
145
-
146
- function generateThreadingID(clientID) {
147
- var k = Date.now();
148
- var l = Math.floor(Math.random() * 4294967295);
149
- var m = clientID;
150
- return "<" + k + ":" + l + "-" + m + "@mail.projektitan.com>";
151
- }
152
-
153
- function binaryToDecimal(data) {
154
- var ret = "";
155
- while (data !== "0") {
156
- var end = 0;
157
- var fullName = "";
158
- var i = 0;
159
- for (; i < data.length; i++) {
160
- end = 2 * end + parseInt(data[i], 10);
161
- if (end >= 10) {
162
- fullName += "1";
163
- end -= 10;
164
- } else fullName += "0";
165
- }
166
- ret = end.toString() + ret;
167
- data = fullName.slice(fullName.indexOf("1"));
168
- }
169
- return ret;
170
- }
171
-
172
- function generateOfflineThreadingID() {
173
- var ret = Date.now();
174
- var value = Math.floor(Math.random() * 4294967295);
175
- var str = ("0000000000000000000000" + value.toString(2)).slice(-22);
176
- var msgs = ret.toString(2) + str;
177
- return binaryToDecimal(msgs);
178
- }
179
-
180
- var h;
181
- var i = {};
182
- var j = {
183
- _: "%",
184
- A: "%2",
185
- B: "000",
186
- C: "%7d",
187
- D: "%7b%22",
188
- E: "%2c%22",
189
- F: "%22%3a",
190
- G: "%2c%22ut%22%3a1",
191
- H: "%2c%22bls%22%3a",
192
- I: "%2c%22n%22%3a%22%",
193
- J: "%22%3a%7b%22i%22%3a0%7d",
194
- K: "%2c%22pt%22%3a0%2c%22vis%22%3a",
195
- L: "%2c%22ch%22%3a%7b%22h%22%3a%22",
196
- M: "%7b%22v%22%3a2%2c%22time%22%3a1",
197
- N: ".channel%22%2c%22sub%22%3a%5b",
198
- O: "%2c%22sb%22%3a1%2c%22t%22%3a%5b",
199
- P: "%2c%22ud%22%3a100%2c%22lc%22%3a0",
200
- Q: "%5d%2c%22f%22%3anull%2c%22uct%22%3a",
201
- R: ".channel%22%2c%22sub%22%3a%5b1%5d",
202
- S: "%22%2c%22m%22%3a0%7d%2c%7b%22i%22%3a",
203
- T: "%2c%22blc%22%3a1%2c%22snd%22%3a1%2c%22ct%22%3a",
204
- U: "%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
205
- V: "%2c%22blc%22%3a0%2c%22snd%22%3a0%2c%22ct%22%3a",
206
- W: "%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a",
207
- X: "%2c%22ri%22%3a0%7d%2c%22state%22%3a%7b%22p%22%3a0%2c%22ut%22%3a1",
208
- Y:
209
- "%2c%22pt%22%3a0%2c%22vis%22%3a1%2c%22bls%22%3a0%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
210
- Z:
211
- "%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a"
212
- };
213
- (function() {
214
- var l = [];
215
- for (var m in j) {
216
- i[j[m]] = m;
217
- l.push(j[m]);
218
- }
219
- l.reverse();
220
- h = new RegExp(l.join("|"), "g");
221
- })();
222
-
223
- function presenceEncode(str) {
224
- return encodeURIComponent(str)
225
- .replace(/([_A-Z])|%../g, function(m, n) {
226
- return n ? "%" + n.charCodeAt(0).toString(16) : m;
227
- })
228
- .toLowerCase()
229
- .replace(h, function(m) {
230
- return i[m];
231
- });
232
- }
233
-
234
- function presenceDecode(str) {
235
- return decodeURIComponent(
236
- str.replace(/[_A-Z]/g, function(/** @type {string | number} */ m) {
237
- return j[m];
238
- })
239
- );
240
- }
241
-
242
- function generatePresence(userID) {
243
- var time = Date.now();
244
- return (
245
- "E" +
246
- presenceEncode(
247
- JSON.stringify({
248
- v: 3,
249
- time: parseInt(time / 1000, 10),
250
- user: userID,
251
- state: {
252
- ut: 0,
253
- t2: [],
254
- lm2: null,
255
- uct2: time,
256
- tr: null,
257
- tw: Math.floor(Math.random() * 4294967295) + 1,
258
- at: time
259
- },
260
- ch: {
261
- ["p_" + userID]: 0
262
- }
263
- })
264
- )
265
- );
266
- }
267
-
268
- function generateAccessiblityCookie() {
269
- var time = Date.now();
270
- return encodeURIComponent(
271
- JSON.stringify({
272
- sr: 0,
273
- "sr-ts": time,
274
- jk: 0,
275
- "jk-ts": time,
276
- kb: 0,
277
- "kb-ts": time,
278
- hcm: 0,
279
- "hcm-ts": time
280
- })
281
- );
282
- }
283
-
284
- function getGUID() {
285
- /** @type {number} */
286
-
287
- var sectionLength = Date.now();
288
- /** @type {string} */
289
-
290
- var id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
291
- /** @type {number} */
292
-
293
- var r = Math.floor((sectionLength + Math.random() * 16) % 16);
294
- /** @type {number} */
295
-
296
- sectionLength = Math.floor(sectionLength / 16);
297
- /** @type {string} */
298
-
299
- var _guid = (c == "x" ? r : (r & 7) | 8).toString(16);
300
- return _guid;
301
- });
302
- return id;
303
- }
304
-
305
- function _formatAttachment(attachment1, attachment2) {
306
- attachment2 = attachment2 || { id: "", image_data: {} };
307
- attachment1 = attachment1.mercury ? attachment1.mercury : attachment1;
308
- var blob = attachment1.blob_attachment;
309
- var type =
310
- blob && blob.__typename ? blob.__typename : attachment1.attach_type;
311
- if (!type && attachment1.sticker_attachment) {
312
- type = "StickerAttachment";
313
- blob = attachment1.sticker_attachment;
314
- } else if (!type && attachment1.extensible_attachment) {
315
- if (
316
- attachment1.extensible_attachment.story_attachment &&
317
- attachment1.extensible_attachment.story_attachment.target &&
318
- attachment1.extensible_attachment.story_attachment.target.__typename &&
319
- attachment1.extensible_attachment.story_attachment.target.__typename ===
320
- "MessageLocation"
321
- )
322
- type = "MessageLocation";
323
- else type = "ExtensibleAttachment";
324
-
325
- blob = attachment1.extensible_attachment;
326
- }
327
- switch (type) {
328
- case "sticker":
329
- return {
330
- type: "sticker",
331
- ID: attachment1.metadata.stickerID.toString(),
332
- url: attachment1.url,
333
-
334
- packID: attachment1.metadata.packID.toString(),
335
- spriteUrl: attachment1.metadata.spriteURI,
336
- spriteUrl2x: attachment1.metadata.spriteURI2x,
337
- width: attachment1.metadata.width,
338
- height: attachment1.metadata.height,
339
-
340
- caption: attachment2.caption,
341
- description: attachment2.description,
342
-
343
- frameCount: attachment1.metadata.frameCount,
344
- frameRate: attachment1.metadata.frameRate,
345
- framesPerRow: attachment1.metadata.framesPerRow,
346
- framesPerCol: attachment1.metadata.framesPerCol,
347
-
348
- stickerID: attachment1.metadata.stickerID.toString(), // @Legacy
349
- spriteURI: attachment1.metadata.spriteURI, // @Legacy
350
- spriteURI2x: attachment1.metadata.spriteURI2x // @Legacy
351
- };
352
- case "file":
353
- return {
354
- type: "file",
355
- filename: attachment1.name,
356
- ID: attachment2.id.toString(),
357
- url: attachment1.url,
358
-
359
- isMalicious: attachment2.is_malicious,
360
- contentType: attachment2.mime_type,
361
-
362
- name: attachment1.name, // @Legacy
363
- mimeType: attachment2.mime_type, // @Legacy
364
- fileSize: attachment2.file_size // @Legacy
365
- };
366
- case "photo":
367
- return {
368
- type: "photo",
369
- ID: attachment1.metadata.fbid.toString(),
370
- filename: attachment1.fileName,
371
- thumbnailUrl: attachment1.thumbnail_url,
372
-
373
- previewUrl: attachment1.preview_url,
374
- previewWidth: attachment1.preview_width,
375
- previewHeight: attachment1.preview_height,
376
-
377
- largePreviewUrl: attachment1.large_preview_url,
378
- largePreviewWidth: attachment1.large_preview_width,
379
- largePreviewHeight: attachment1.large_preview_height,
380
-
381
- url: attachment1.metadata.url, // @Legacy
382
- width: attachment1.metadata.dimensions.split(",")[0], // @Legacy
383
- height: attachment1.metadata.dimensions.split(",")[1], // @Legacy
384
- name: attachment1.fileName // @Legacy
385
- };
386
- case "animated_image":
387
- return {
388
- type: "animated_image",
389
- ID: attachment2.id.toString(),
390
- filename: attachment2.filename,
391
-
392
- previewUrl: attachment1.preview_url,
393
- previewWidth: attachment1.preview_width,
394
- previewHeight: attachment1.preview_height,
395
-
396
- url: attachment2.image_data.url,
397
- width: attachment2.image_data.width,
398
- height: attachment2.image_data.height,
399
-
400
- name: attachment1.name, // @Legacy
401
- facebookUrl: attachment1.url, // @Legacy
402
- thumbnailUrl: attachment1.thumbnail_url, // @Legacy
403
- mimeType: attachment2.mime_type, // @Legacy
404
- rawGifImage: attachment2.image_data.raw_gif_image, // @Legacy
405
- rawWebpImage: attachment2.image_data.raw_webp_image, // @Legacy
406
- animatedGifUrl: attachment2.image_data.animated_gif_url, // @Legacy
407
- animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url, // @Legacy
408
- animatedWebpUrl: attachment2.image_data.animated_webp_url, // @Legacy
409
- animatedWebpPreviewUrl: attachment2.image_data.animated_webp_preview_url // @Legacy
410
- };
411
- case "share":
412
- return {
413
- type: "share",
414
- ID: attachment1.share.share_id.toString(),
415
- url: attachment2.href,
416
-
417
- title: attachment1.share.title,
418
- description: attachment1.share.description,
419
- source: attachment1.share.source,
420
-
421
- image: attachment1.share.media.image,
422
- width: attachment1.share.media.image_size.width,
423
- height: attachment1.share.media.image_size.height,
424
- playable: attachment1.share.media.playable,
425
- duration: attachment1.share.media.duration,
426
-
427
- subattachments: attachment1.share.subattachments,
428
- properties: {},
429
-
430
- animatedImageSize: attachment1.share.media.animated_image_size, // @Legacy
431
- facebookUrl: attachment1.share.uri, // @Legacy
432
- target: attachment1.share.target, // @Legacy
433
- styleList: attachment1.share.style_list // @Legacy
434
- };
435
- case "video":
436
- return {
437
- type: "video",
438
- ID: attachment1.metadata.fbid.toString(),
439
- filename: attachment1.name,
440
-
441
- previewUrl: attachment1.preview_url,
442
- previewWidth: attachment1.preview_width,
443
- previewHeight: attachment1.preview_height,
444
-
445
- url: attachment1.url,
446
- width: attachment1.metadata.dimensions.width,
447
- height: attachment1.metadata.dimensions.height,
448
-
449
- duration: attachment1.metadata.duration,
450
- videoType: "unknown",
451
-
452
- thumbnailUrl: attachment1.thumbnail_url // @Legacy
453
- };
454
- case "error":
455
- return {
456
- type: "error",
457
- attachment1: attachment1,
458
- attachment2: attachment2
459
- };
460
- case "MessageImage":
461
- return {
462
- type: "photo",
463
- ID: blob.legacy_attachment_id,
464
- filename: blob.filename,
465
- thumbnailUrl: blob.thumbnail.uri,
466
-
467
- previewUrl: blob.preview.uri,
468
- previewWidth: blob.preview.width,
469
- previewHeight: blob.preview.height,
470
-
471
- largePreviewUrl: blob.large_preview.uri,
472
- largePreviewWidth: blob.large_preview.width,
473
- largePreviewHeight: blob.large_preview.height,
474
-
475
- url: blob.large_preview.uri, // @Legacy
476
- width: blob.original_dimensions.x, // @Legacy
477
- height: blob.original_dimensions.y, // @Legacy
478
- name: blob.filename // @Legacy
479
- };
480
- case "MessageAnimatedImage":
481
- return {
482
- type: "animated_image",
483
- ID: blob.legacy_attachment_id,
484
- filename: blob.filename,
485
-
486
- previewUrl: blob.preview_image.uri,
487
- previewWidth: blob.preview_image.width,
488
- previewHeight: blob.preview_image.height,
489
-
490
- url: blob.animated_image.uri,
491
- width: blob.animated_image.width,
492
- height: blob.animated_image.height,
493
-
494
- thumbnailUrl: blob.preview_image.uri, // @Legacy
495
- name: blob.filename, // @Legacy
496
- facebookUrl: blob.animated_image.uri, // @Legacy
497
- rawGifImage: blob.animated_image.uri, // @Legacy
498
- animatedGifUrl: blob.animated_image.uri, // @Legacy
499
- animatedGifPreviewUrl: blob.preview_image.uri, // @Legacy
500
- animatedWebpUrl: blob.animated_image.uri, // @Legacy
501
- animatedWebpPreviewUrl: blob.preview_image.uri // @Legacy
502
- };
503
- case "MessageVideo":
504
- return {
505
- type: "video",
506
- filename: blob.filename,
507
- ID: blob.legacy_attachment_id,
508
-
509
- previewUrl: blob.large_image.uri,
510
- previewWidth: blob.large_image.width,
511
- previewHeight: blob.large_image.height,
512
-
513
- url: blob.playable_url,
514
- width: blob.original_dimensions.x,
515
- height: blob.original_dimensions.y,
516
-
517
- duration: blob.playable_duration_in_ms,
518
- videoType: blob.video_type.toLowerCase(),
519
-
520
- thumbnailUrl: blob.large_image.uri // @Legacy
521
- };
522
- case "MessageAudio":
523
- return {
524
- type: "audio",
525
- filename: blob.filename,
526
- ID: blob.url_shimhash,
527
-
528
- audioType: blob.audio_type,
529
- duration: blob.playable_duration_in_ms,
530
- url: blob.playable_url,
531
-
532
- isVoiceMail: blob.is_voicemail
533
- };
534
- case "StickerAttachment":
535
- return {
536
- type: "sticker",
537
- ID: blob.id,
538
- url: blob.url,
539
-
540
- packID: blob.pack ? blob.pack.id : null,
541
- spriteUrl: blob.sprite_image,
542
- spriteUrl2x: blob.sprite_image_2x,
543
- width: blob.width,
544
- height: blob.height,
545
-
546
- caption: blob.label,
547
- description: blob.label,
548
-
549
- frameCount: blob.frame_count,
550
- frameRate: blob.frame_rate,
551
- framesPerRow: blob.frames_per_row,
552
- framesPerCol: blob.frames_per_column,
553
-
554
- stickerID: blob.id, // @Legacy
555
- spriteURI: blob.sprite_image, // @Legacy
556
- spriteURI2x: blob.sprite_image_2x // @Legacy
557
- };
558
- case "MessageLocation":
559
- var urlAttach = blob.story_attachment.url;
560
- var mediaAttach = blob.story_attachment.media;
561
-
562
- var u = querystring.parse(url.parse(urlAttach).query).u;
563
- var where1 = querystring.parse(url.parse(u).query).where1;
564
- var address = where1.split(", ");
565
-
566
- var latitude;
567
- var longitude;
568
-
569
- try {
570
- latitude = Number.parseFloat(address[0]);
571
- longitude = Number.parseFloat(address[1]);
572
- } catch (err) {
573
- /* empty */
574
- }
575
-
576
- var imageUrl;
577
- var width;
578
- var height;
579
-
580
- if (mediaAttach && mediaAttach.image) {
581
- imageUrl = mediaAttach.image.uri;
582
- width = mediaAttach.image.width;
583
- height = mediaAttach.image.height;
584
- }
585
-
586
- return {
587
- type: "location",
588
- ID: blob.legacy_attachment_id,
589
- latitude: latitude,
590
- longitude: longitude,
591
- image: imageUrl,
592
- width: width,
593
- height: height,
594
- url: u || urlAttach,
595
- address: where1,
596
-
597
- facebookUrl: blob.story_attachment.url, // @Legacy
598
- target: blob.story_attachment.target, // @Legacy
599
- styleList: blob.story_attachment.style_list // @Legacy
600
- };
601
- case "ExtensibleAttachment":
602
- return {
603
- type: "share",
604
- ID: blob.legacy_attachment_id,
605
- url: blob.story_attachment.url,
606
-
607
- title: blob.story_attachment.title_with_entities.text,
608
- description:
609
- blob.story_attachment.description &&
610
- blob.story_attachment.description.text,
611
- source: blob.story_attachment.source
612
- ? blob.story_attachment.source.text
613
- : null,
614
-
615
- image:
616
- blob.story_attachment.media &&
617
- blob.story_attachment.media.image &&
618
- blob.story_attachment.media.image.uri,
619
- width:
620
- blob.story_attachment.media &&
621
- blob.story_attachment.media.image &&
622
- blob.story_attachment.media.image.width,
623
- height:
624
- blob.story_attachment.media &&
625
- blob.story_attachment.media.image &&
626
- blob.story_attachment.media.image.height,
627
- playable:
628
- blob.story_attachment.media &&
629
- blob.story_attachment.media.is_playable,
630
- duration:
631
- blob.story_attachment.media &&
632
- blob.story_attachment.media.playable_duration_in_ms,
633
- playableUrl:
634
- blob.story_attachment.media == null
635
- ? null
636
- : blob.story_attachment.media.playable_url,
637
-
638
- subattachments: blob.story_attachment.subattachments,
639
- properties: blob.story_attachment.properties.reduce(function(
640
- /** @type {{ [x: string]: any; }} */ obj,
641
- /** @type {{ key: string | number; value: { text: any; }; }} */ cur
642
- ) {
643
- obj[cur.key] = cur.value.text;
644
- return obj;
645
- },
646
- {}),
647
-
648
- facebookUrl: blob.story_attachment.url, // @Legacy
649
- target: blob.story_attachment.target, // @Legacy
650
- styleList: blob.story_attachment.style_list // @Legacy
651
- };
652
- case "MessageFile":
653
- return {
654
- type: "file",
655
- filename: blob.filename,
656
- ID: blob.message_file_fbid,
657
-
658
- url: blob.url,
659
- isMalicious: blob.is_malicious,
660
- contentType: blob.content_type,
661
-
662
- name: blob.filename,
663
- mimeType: "",
664
- fileSize: -1
665
- };
666
- default:
667
- throw new Error(
668
- "unrecognized attach_file of type " +
669
- type +
670
- "`" +
671
- JSON.stringify(attachment1, null, 4) +
672
- " attachment2: " +
673
- JSON.stringify(attachment2, null, 4) +
674
- "`"
675
- );
676
- }
677
- }
678
-
679
- function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
680
- attachmentMap = shareMap || attachmentMap;
681
- return attachments
682
- ? attachments.map(function(i) {
683
- if (
684
- !attachmentMap ||
685
- !attachmentIds ||
686
- !attachmentMap[attachmentIds[i]]
687
- ) {
688
- return _formatAttachment(val);
689
- }
690
- return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
691
- })
692
- : [];
693
- }
694
-
695
- function formatDeltaMessage(m) {
696
- var md = m.messageMetadata;
697
- var mdata =
698
- m.data === undefined
699
- ? []
700
- : m.data.prng === undefined
701
- ? []
702
- : JSON.parse(m.data.prng);
703
- var m_id = mdata.map((/** @type {{ i: any; }} */ u) => u.i);
704
- var m_offset = mdata.map((/** @type {{ o: any; }} */ u) => u.o);
705
- var m_length = mdata.map((/** @type {{ l: any; }} */ u) => u.l);
706
- var mentions = {};
707
- var body = m.body || "";
708
- var args = body == "" ? [] : body.trim().split(/\s+/);
709
- for (var i = 0; i < m_id.length; i++)
710
- mentions[m_id[i]] = m.body.substring(
711
- m_offset[i],
712
- m_offset[i] + m_length[i]
713
- );
714
- return {
715
- type: "message",
716
- senderID: formatID(md.actorFbId.toString()),
717
- threadID: formatID(
718
- (md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()
719
- ),
720
- messageID: md.messageId,
721
- args: args,
722
- body: body,
723
- attachments: (m.attachments || []).map((/** @type {any} */ v) =>
724
- _formatAttachment(v)
725
- ),
726
- mentions: mentions,
727
- timestamp: md.timestamp,
728
- isGroup: !!md.threadKey.threadFbId,
729
- participantIDs: m.participants || []
730
- };
731
- }
732
-
733
- function formatID(id) {
734
- if (id != undefined && id != null) return id.replace(/(fb)?id[:.]/, "");
735
- else return id;
736
- }
737
-
738
- function formatMessage(m) {
739
- var originalMessage = m.message ? m.message : m;
740
- var obj = {
741
- type: "message",
742
- senderName: originalMessage.sender_name,
743
- senderID: formatID(originalMessage.sender_fbid.toString()),
744
- participantNames: originalMessage.group_thread_info
745
- ? originalMessage.group_thread_info.participant_names
746
- : [originalMessage.sender_name.split(" ")[0]],
747
- participantIDs: originalMessage.group_thread_info
748
- ? originalMessage.group_thread_info.participant_ids.map(function(v) {
749
- return formatID(v.toString());
750
- })
751
- : [formatID(originalMessage.sender_fbid)],
752
- body: originalMessage.body || "",
753
- threadID: formatID(
754
- (
755
- originalMessage.thread_fbid || originalMessage.other_user_fbid
756
- ).toString()
757
- ),
758
- threadName: originalMessage.group_thread_info
759
- ? originalMessage.group_thread_info.name
760
- : originalMessage.sender_name,
761
- location: originalMessage.coordinates ? originalMessage.coordinates : null,
762
- messageID: originalMessage.mid
763
- ? originalMessage.mid.toString()
764
- : originalMessage.message_id,
765
- attachments: formatAttachment(
766
- originalMessage.attachments,
767
- originalMessage.attachmentIds,
768
- originalMessage.attachment_map,
769
- originalMessage.share_map
770
- ),
771
- timestamp: originalMessage.timestamp,
772
- timestampAbsolute: originalMessage.timestamp_absolute,
773
- timestampRelative: originalMessage.timestamp_relative,
774
- timestampDatetime: originalMessage.timestamp_datetime,
775
- tags: originalMessage.tags,
776
- reactions: originalMessage.reactions ? originalMessage.reactions : [],
777
- isUnread: originalMessage.is_unread
778
- };
779
- if (m.type === "pages_messaging")
780
- obj.pageID = m.realtime_viewer_fbid.toString();
781
- obj.isGroup = obj.participantIDs.length > 2;
782
- return obj;
783
- }
784
-
785
- function formatEvent(m) {
786
- var originalMessage = m.message ? m.message : m;
787
- var logMessageType = originalMessage.log_message_type;
788
- var logMessageData;
789
- if (logMessageType === "log:generic-admin-text") {
790
- logMessageData = originalMessage.log_message_data.untypedData;
791
- logMessageType = getAdminTextMessageType(
792
- originalMessage.log_message_data.message_type
793
- );
794
- } else logMessageData = originalMessage.log_message_data;
795
- return Object.assign(formatMessage(originalMessage), {
796
- type: "event",
797
- logMessageType: logMessageType,
798
- logMessageData: logMessageData,
799
- logMessageBody: originalMessage.log_message_body
800
- });
801
- }
802
-
803
- function formatHistoryMessage(m) {
804
- switch (m.action_type) {
805
- case "ma-type:log-message":
806
- return formatEvent(m);
807
- default:
808
- return formatMessage(m);
809
- }
810
- }
811
-
812
- function getAdminTextMessageType(m) {
813
- switch (m.type) {
814
- case "joinable_group_link_mode_change":
815
- return "log:link-status";
816
- case "magic_words":
817
- return "log:magic-words";
818
- case "change_thread_theme":
819
- return "log:thread-color";
820
- case "change_thread_icon":
821
- case "change_thread_quick_reaction":
822
- return "log:thread-icon";
823
- case "change_thread_nickname":
824
- return "log:user-nickname";
825
- case "change_thread_admins":
826
- return "log:thread-admins";
827
- case "group_poll":
828
- return "log:thread-poll";
829
- case "change_thread_approval_mode":
830
- return "log:thread-approval-mode";
831
- case "messenger_call_log":
832
- case "participant_joined_group_call":
833
- return "log:thread-call";
834
- case "pin_messages_v2":
835
- return "log:thread-pinned";
836
- case "unpin_messages_v2":
837
- return "log:unpin-message";
838
- default:
839
- return m.type;
840
- }
841
- }
842
-
843
- function formatDeltaEvent(m) {
844
- var logMessageType;
845
- var logMessageData;
846
- switch (m.class) {
847
- case "AdminTextMessage":
848
- logMessageType = getAdminTextMessageType(m);
849
- logMessageData = m.untypedData;
850
- break;
851
- case "ThreadName":
852
- logMessageType = "log:thread-name";
853
- logMessageData = { name: m.name };
854
- break;
855
- case "ParticipantsAddedToGroupThread":
856
- logMessageType = "log:subscribe";
857
- logMessageData = { addedParticipants: m.addedParticipants };
858
- break;
859
- case "ParticipantLeftGroupThread":
860
- logMessageType = "log:unsubscribe";
861
- logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
862
- break;
863
- case "UserLocation": {
864
- logMessageType = "log:user-location";
865
- logMessageData = {
866
- Image:
867
- m.attachments[0].mercury.extensible_attachment.story_attachment.media
868
- .image,
869
- Location:
870
- m.attachments[0].mercury.extensible_attachment.story_attachment.target
871
- .location_title,
872
- coordinates:
873
- m.attachments[0].mercury.extensible_attachment.story_attachment.target
874
- .coordinate,
875
- url: m.attachments[0].mercury.extensible_attachment.story_attachment.url
876
- };
877
- }
878
- case "ApprovalQueue":
879
- logMessageType = "log:approval-queue";
880
- logMessageData = {
881
- approvalQueue: {
882
- action: m.action,
883
- recipientFbId: m.recipientFbId,
884
- requestSource: m.requestSource,
885
- ...m.messageMetadata
886
- }
887
- };
888
- }
889
- return {
890
- type: "event",
891
- threadID: formatID(
892
- (
893
- m.messageMetadata.threadKey.threadFbId ||
894
- m.messageMetadata.threadKey.otherUserFbId
895
- ).toString()
896
- ),
897
- logMessageType: logMessageType,
898
- logMessageData: logMessageData,
899
- logMessageBody: m.messageMetadata.adminText,
900
- author: m.messageMetadata.actorFbId,
901
- participantIDs: (m?.participants || []).map(e => e.toString())
902
- };
903
- }
904
-
905
- function formatTyp(event) {
906
- return {
907
- isTyping: !!event.st,
908
- from: event.from.toString(),
909
- threadID: formatID(
910
- (event.to || event.thread_fbid || event.from).toString()
911
- ),
912
- fromMobile: event.hasOwnProperty("from_mobile") ? event.from_mobile : true,
913
- userID: (event.realtime_viewer_fbid || event.from).toString(),
914
- type: "typ"
915
- };
916
- }
917
-
918
- function formatDeltaReadReceipt(delta) {
919
- return {
920
- reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
921
- time: delta.actionTimestampMs,
922
- threadID: formatID(
923
- (delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()
924
- ),
925
- type: "read_receipt"
926
- };
927
- }
928
-
929
- function formatReadReceipt(event) {
930
- return {
931
- reader: event.reader.toString(),
932
- time: event.time,
933
- threadID: formatID((event.thread_fbid || event.reader).toString()),
934
- type: "read_receipt"
935
- };
936
- }
937
-
938
- function formatRead(event) {
939
- return {
940
- threadID: formatID(
941
- (
942
- (event.chat_ids && event.chat_ids[0]) ||
943
- (event.thread_fbids && event.thread_fbids[0])
944
- ).toString()
945
- ),
946
- time: event.timestamp,
947
- type: "read"
948
- };
949
- }
950
-
951
- function getFrom(str, startToken, endToken) {
952
- var start = str.indexOf(startToken) + startToken.length;
953
- if (start < startToken.length) return "";
954
- var lastHalf = str.substring(start);
955
- var end = lastHalf.indexOf(endToken);
956
- if (end === -1)
957
- throw Error(
958
- "Could not find endTime `" + endToken + "` in the given string."
959
- );
960
- return lastHalf.substring(0, end);
961
- }
962
-
963
- function getFroms(str, startToken, endToken) {
964
- let results = [];
965
- let currentIndex = 0;
966
- while (true) {
967
- let start = str.indexOf(startToken, currentIndex);
968
- if (start === -1) break;
969
- start += startToken.length;
970
- let lastHalf = str.substring(start);
971
- let end = lastHalf.indexOf(endToken);
972
- if (end === -1) {
973
- if (results.length === 0) {
974
- throw Error(
975
- "Could not find endToken `" + endToken + "` in the given string."
976
- );
977
- }
978
- break;
979
- }
980
- results.push(lastHalf.substring(0, end));
981
- currentIndex = start + end + endToken.length;
982
- }
983
- return results.length === 0
984
- ? ""
985
- : results.length === 1
986
- ? results[0]
987
- : results;
988
- }
989
-
990
- function makeParsable(html) {
991
- let withoutForLoop = html.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, "");
992
- let maybeMultipleObjects = withoutForLoop.split(/\}\r\n *\{/);
993
- if (maybeMultipleObjects.length === 1) return maybeMultipleObjects;
994
- return "[" + maybeMultipleObjects.join("},{") + "]";
995
- }
996
-
997
- function arrToForm(form) {
998
- return arrayToObject(
999
- form,
1000
- function(v) {
1001
- return v.name;
1002
- },
1003
- function(v) {
1004
- return v.val;
1005
- }
1006
- );
1007
- }
1008
-
1009
- function arrayToObject(arr, getKey, getValue) {
1010
- return arr.reduce(function(acc, val) {
1011
- acc[getKey(val)] = getValue(val);
1012
- return acc;
1013
- }, {});
1014
- }
1015
-
1016
- function getSignatureID() {
1017
- return Math.floor(Math.random() * 2147483648).toString(16);
1018
- }
1019
-
1020
- function generateTimestampRelative() {
1021
- var d = new Date();
1022
- return d.getHours() + ":" + padZeros(d.getMinutes());
1023
- }
1024
-
1025
- function makeDefaults(html, userID, ctx) {
1026
- var reqCounter = 1;
1027
- const fb_dtsg = getFrom(html, '"DTSGInitData",[],{"token":"', '",');
1028
- var ttstamp = "2";
1029
- for (var i = 0; i < fb_dtsg.length; i++) ttstamp += fb_dtsg.charCodeAt(i);
1030
- var revision = getFrom(html, 'revision":', ",");
1031
- function mergeWithDefaults(obj) {
1032
- var newObj = {
1033
- __user: userID,
1034
- __req: (reqCounter++).toString(36),
1035
- __rev: revision,
1036
- __a: 1,
1037
- fb_dtsg: ctx.fb_dtsg ? ctx.fb_dtsg : fb_dtsg,
1038
- jazoest: ctx.ttstamp ? ctx.ttstamp : ttstamp
1039
- };
1040
- if (!obj) return newObj;
1041
- for (var prop in obj)
1042
- if (obj.hasOwnProperty(prop)) if (!newObj[prop]) newObj[prop] = obj[prop];
1043
- return newObj;
1044
- }
1045
- function postWithDefaults(url, jar, form, ctxx) {
1046
- return post(
1047
- url,
1048
- jar,
1049
- mergeWithDefaults(form),
1050
- ctx.globalOptions,
1051
- ctxx || ctx
1052
- );
1053
- }
1054
- function getWithDefaults(url, jar, qs, ctxx) {
1055
- return get(url, jar, mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx);
1056
- }
1057
- function postFormDataWithDefault(url, jar, form, qs, ctxx) {
1058
- return postFormData(
1059
- url,
1060
- jar,
1061
- mergeWithDefaults(form),
1062
- mergeWithDefaults(qs),
1063
- ctx.globalOptions,
1064
- ctxx || ctx
1065
- );
1066
- }
1067
- return {
1068
- get: getWithDefaults,
1069
- post: postWithDefaults,
1070
- postFormData: postFormDataWithDefault
1071
- };
1072
- }
1073
-
1074
- function parseAndCheckLogin(ctx, http, retryCount = 0) {
1075
- const delay = ms => new Promise(r => setTimeout(r, ms));
1076
- const hval = (headers, name) => {
1077
- if (!headers) return;
1078
- const k = Object.keys(headers).find(k => k.toLowerCase() === name.toLowerCase());
1079
- return k ? headers[k] : undefined;
1080
- };
1081
- return async (resp) => {
1082
- const status = resp?.status ?? resp?.statusCode ?? 0;
1083
- if (status >= 500 && status < 600) {
1084
- if (retryCount >= 5) {
1085
- const err = new Error("Request retry failed. Check the `res` and `statusCode` property on this error.");
1086
- err.statusCode = status;
1087
- err.res = resp?.data ?? resp?.body;
1088
- err.error = "Request retry failed. Check the `res` and `statusCode` property on this error.";
1089
- throw err;
1090
- }
1091
- const retryTime = Math.floor(Math.random() * 5000);
1092
- await delay(retryTime);
1093
- const url = resp?.config?.url || (resp?.request?.res?.responseUrl) || "";
1094
- const ctype = String(hval(resp?.config?.headers, "content-type") || "").toLowerCase();
1095
- const isMultipart = ctype.includes("multipart/form-data");
1096
- const payload = resp?.config?.data;
1097
- const params = resp?.config?.params || resp?.config?.qs;
1098
- retryCount += 1;
1099
- if (isMultipart) {
1100
- const newData = await http.postFormData(url, ctx.jar, payload, params, ctx.globalOptions, ctx);
1101
- return await parseAndCheckLogin(ctx, http, retryCount)(newData);
1102
- } else {
1103
- const newData = await http.post(url, ctx.jar, payload, ctx.globalOptions, ctx);
1104
- return await parseAndCheckLogin(ctx, http, retryCount)(newData);
1105
- }
1106
- }
1107
- if (status === 404) return;
1108
- if (status !== 200) {
1109
- const err = new Error("parseAndCheckLogin got status code: " + status + ". Bailing out of trying to parse response.");
1110
- err.statusCode = status;
1111
- err.res = resp?.data ?? resp?.body;
1112
- throw err;
1113
- }
1114
- let res = null;
1115
- const body = resp?.data ?? resp?.body;
1116
- if (body && typeof body === "object") {
1117
- res = body;
1118
- } else if (typeof body === "string") {
1119
- try {
1120
- res = JSON.parse(makeParsable(body));
1121
- } catch (e) {
1122
- const err = new Error("JSON.parse error. Check the `detail` property on this error.");
1123
- err.error = "JSON.parse error. Check the `detail` property on this error.";
1124
- err.detail = e;
1125
- err.res = body;
1126
- throw err;
1127
- }
1128
- } else {
1129
- const err = new Error("Unknown response body type: " + typeof body);
1130
- err.res = body;
1131
- throw err;
1132
- }
1133
- const method = String(resp?.config?.method || resp?.request?.method || "GET").toUpperCase();
1134
- if (res.redirect && method === "GET") {
1135
- const redirectRes = await http.get(res.redirect, ctx.jar, null, ctx.globalOptions, ctx);
1136
- return await parseAndCheckLogin(ctx, http)(redirectRes);
1137
- }
1138
- if (res.jsmods && res.jsmods.require && Array.isArray(res.jsmods.require[0]) && res.jsmods.require[0][0] === "Cookie") {
1139
- res.jsmods.require[0][3][0] = res.jsmods.require[0][3][0].replace("_js_", "");
1140
- const requireCookie = res.jsmods.require[0][3];
1141
- ctx.jar.setCookie(formatCookie(requireCookie, "facebook"), "https://www.facebook.com");
1142
- ctx.jar.setCookie(formatCookie(requireCookie, "messenger"), "https://www.messenger.com");
1143
- }
1144
- if (res.jsmods && Array.isArray(res.jsmods.require)) {
1145
- for (const item of res.jsmods.require) {
1146
- if (item[0] === "DTSG" && item[1] === "setToken") {
1147
- ctx.fb_dtsg = item[3][0];
1148
- ctx.ttstamp = "2";
1149
- for (let j = 0; j < ctx.fb_dtsg.length; j++) ctx.ttstamp += ctx.fb_dtsg.charCodeAt(j);
1150
- break;
1151
- }
1152
- }
1153
- }
1154
- if (res.error === 1357001) {
1155
- const err = new Error("Facebook blocked the login");
1156
- err.error = "Not logged in.";
1157
- throw err;
1158
- }
1159
- return res;
1160
- };
1161
- }
1162
-
1163
- function saveCookies(jar) {
1164
- return res => {
1165
- try {
1166
- const setCookie = res?.headers?.["set-cookie"];
1167
- if (Array.isArray(setCookie) && setCookie.length) {
1168
- const url = res?.request?.res?.responseUrl || (res?.config?.baseURL ? new URL(res.config.url || "/", res.config.baseURL).toString() : res?.config?.url || "https://www.facebook.com");
1169
- for (const c of setCookie) {
1170
- try {
1171
- jar.setCookieSync(c, url);
1172
- } catch { }
1173
- }
1174
- }
1175
- } catch { }
1176
- return res;
1177
- };
1178
- }
1179
-
1180
- var NUM_TO_MONTH = [
1181
- "Jan",
1182
- "Feb",
1183
- "Mar",
1184
- "Apr",
1185
- "May",
1186
- "Jun",
1187
- "Jul",
1188
- "Aug",
1189
- "Sep",
1190
- "Oct",
1191
- "Nov",
1192
- "Dec"
1193
- ];
1194
- var NUM_TO_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1195
-
1196
- function formatDate(date) {
1197
- var d = date.getUTCDate();
1198
- d = d >= 10 ? d : "0" + d;
1199
- var h = date.getUTCHours();
1200
- h = h >= 10 ? h : "0" + h;
1201
- var m = date.getUTCMinutes();
1202
- m = m >= 10 ? m : "0" + m;
1203
- var s = date.getUTCSeconds();
1204
- s = s >= 10 ? s : "0" + s;
1205
- return (
1206
- NUM_TO_DAY[date.getUTCDay()] +
1207
- ", " +
1208
- d +
1209
- " " +
1210
- NUM_TO_MONTH[date.getUTCMonth()] +
1211
- " " +
1212
- date.getUTCFullYear() +
1213
- " " +
1214
- h +
1215
- ":" +
1216
- m +
1217
- ":" +
1218
- s +
1219
- " GMT"
1220
- );
1221
- }
1222
-
1223
- function formatCookie(arr, url) {
1224
- return (
1225
- arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + url + ".com"
1226
- );
1227
- }
1228
-
1229
- function formatThread(data) {
1230
- return {
1231
- threadID: formatID(data.thread_fbid.toString()),
1232
- participants: data.participants.map(formatID),
1233
- participantIDs: data.participants.map(formatID),
1234
- name: data.name,
1235
- nicknames: data.custom_nickname,
1236
- snippet: data.snippet,
1237
- snippetAttachments: data.snippet_attachments,
1238
- snippetSender: formatID((data.snippet_sender || "").toString()),
1239
- unreadCount: data.unread_count,
1240
- messageCount: data.message_count,
1241
- imageSrc: data.image_src,
1242
- timestamp: data.timestamp,
1243
- muteUntil: data.mute_until,
1244
- isCanonicalUser: data.is_canonical_user,
1245
- isCanonical: data.is_canonical,
1246
- isSubscribed: data.is_subscribed,
1247
- folder: data.folder,
1248
- isArchived: data.is_archived,
1249
- recipientsLoadable: data.recipients_loadable,
1250
- hasEmailParticipant: data.has_email_participant,
1251
- readOnly: data.read_only,
1252
- canReply: data.can_reply,
1253
- cannotReplyReason: data.cannot_reply_reason,
1254
- lastMessageTimestamp: data.last_message_timestamp,
1255
- lastReadTimestamp: data.last_read_timestamp,
1256
- lastMessageType: data.last_message_type,
1257
- emoji: data.custom_like_icon,
1258
- color: data.custom_color,
1259
- adminIDs: data.admin_ids,
1260
- threadType: data.thread_type
1261
- };
1262
- }
1263
-
1264
- function getType(obj) {
1265
- return Object.prototype.toString.call(obj).slice(8, -1);
1266
- }
1267
-
1268
- function formatProxyPresence(presence, userID) {
1269
- if (presence.lat === undefined || presence.p === undefined) return null;
1270
- return {
1271
- type: "presence",
1272
- timestamp: presence.lat * 1000,
1273
- userID: userID || "",
1274
- statuses: presence.p
1275
- };
1276
- }
1277
-
1278
- function formatPresence(presence, userID) {
1279
- return {
1280
- type: "presence",
1281
- timestamp: presence.la * 1000,
1282
- userID: userID || "",
1283
- statuses: presence.a
1284
- };
1285
- }
1286
-
1287
- function decodeClientPayload(payload) {
1288
- function Utf8ArrayToStr(array) {
1289
- var out, i, len, c;
1290
- var char2, char3;
1291
- out = "";
1292
- len = array.length;
1293
- i = 0;
1294
- while (i < len) {
1295
- c = array[i++];
1296
- switch (c >> 4) {
1297
- case 0:
1298
- case 1:
1299
- case 2:
1300
- case 3:
1301
- case 4:
1302
- case 5:
1303
- case 6:
1304
- case 7:
1305
- out += String.fromCharCode(c);
1306
- break;
1307
- case 12:
1308
- case 13:
1309
- char2 = array[i++];
1310
- out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
1311
- break;
1312
- case 14:
1313
- char2 = array[i++];
1314
- char3 = array[i++];
1315
- out += String.fromCharCode(
1316
- ((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
1317
- );
1318
- break;
1319
- }
1320
- }
1321
- return out;
1322
- }
1323
- return JSON.parse(Utf8ArrayToStr(payload));
1324
- }
1325
-
1326
- function getAppState(jar) {
1327
- return jar
1328
- .getCookies("https://www.facebook.com")
1329
- .concat(jar.getCookies("https://facebook.com"))
1330
- .concat(jar.getCookies("https://www.messenger.com"));
1331
- }
1332
-
1333
- function getData_Path(Obj, Arr, Stt) {
1334
- if (Arr.length === 0 && Obj != undefined) {
1335
- return Obj;
1336
- } else if (Obj == undefined) {
1337
- return Stt;
1338
- }
1339
- const head = Arr[0];
1340
- if (head == undefined) {
1341
- return Stt;
1342
- }
1343
- const tail = Arr.slice(1);
1344
- return getData_Path(Obj[head], tail, Stt++);
1345
- }
1346
-
1347
- function setData_Path(obj, path, value) {
1348
- if (!path.length) {
1349
- return obj;
1350
- }
1351
- const currentKey = path[0];
1352
- let currentObj = obj[currentKey];
1353
-
1354
- if (!currentObj) {
1355
- obj[currentKey] = value;
1356
- currentObj = obj[currentKey];
1357
- }
1358
- path.shift();
1359
- if (!path.length) {
1360
- currentObj = value;
1361
- } else {
1362
- currentObj = setData_Path(currentObj, path, value);
1363
- }
1364
-
1365
- return obj;
1366
- }
1367
-
1368
- function getPaths(obj, parentPath = []) {
1369
- let paths = [];
1370
- for (let prop in obj) {
1371
- if (typeof obj[prop] === "object") {
1372
- paths = paths.concat(getPaths(obj[prop], [...parentPath, prop]));
1373
- } else {
1374
- paths.push([...parentPath, prop]);
1375
- }
1376
- }
1377
- return paths;
1378
- }
1379
-
1380
- function cleanHTML(text) {
1381
- text = text.replace(
1382
- /(<br>)|(<\/?i>)|(<\/?em>)|(<\/?b>)|(!?~)|(&amp;)|(&#039;)|(&lt;)|(&gt;)|(&quot;)/g,
1383
- match => {
1384
- switch (match) {
1385
- case "<br>":
1386
- return "\n";
1387
- case "<i>":
1388
- case "<em>":
1389
- case "</i>":
1390
- case "</em>":
1391
- return "*";
1392
- case "<b>":
1393
- case "</b>":
1394
- return "**";
1395
- case "~!":
1396
- case "!~":
1397
- return "||";
1398
- case "&amp;":
1399
- return "&";
1400
- case "&#039;":
1401
- return "'";
1402
- case "&lt;":
1403
- return "<";
1404
- case "&gt;":
1405
- return ">";
1406
- case "&quot;":
1407
- return '"';
1408
- }
1409
- }
1410
- );
1411
- return text;
1412
- }
1413
-
1414
- function checkLiveCookie(ctx, defaultFuncs) {
1415
- return defaultFuncs
1416
- .get("https://m.facebook.com/me", ctx.jar)
1417
- .then(function(res) {
1418
- if (res.body.indexOf(ctx.userID) === -1) {
1419
- throw new CustomError({
1420
- message: "Not logged in.",
1421
- error: "Not logged in."
1422
- });
1423
- }
1424
- return true;
1425
- });
1426
- }
1427
-
1428
- function getAccessFromBusiness(jar, Options) {
1429
- return function(res) {
1430
- var html = res ? res.body : null;
1431
- return get(
1432
- "https://business.facebook.com/content_management",
1433
- jar,
1434
- null,
1435
- Options,
1436
- null,
1437
- { noRef: true }
1438
- )
1439
- .then(function(res) {
1440
- var token = /"accessToken":"([^.]+)","clientID":/g.exec(res.body)[1];
1441
- return [html, token];
1442
- })
1443
- .catch(function() {
1444
- return [html, null];
1445
- });
1446
- };
1447
- }
1448
-
1449
- module.exports = {
1450
- CustomError,
1451
- cleanHTML,
1452
- isReadableStream: isReadableStream,
1453
- get: get,
1454
- get2: get2,
1455
- post: post,
1456
- postFormData: postFormData,
1457
- generateThreadingID: generateThreadingID,
1458
- generateOfflineThreadingID: generateOfflineThreadingID,
1459
- getGUID: getGUID,
1460
- getFrom: getFrom,
1461
- makeParsable: makeParsable,
1462
- arrToForm: arrToForm,
1463
- getSignatureID: getSignatureID,
1464
- getJar: request.jar,
1465
- generateTimestampRelative: generateTimestampRelative,
1466
- makeDefaults: makeDefaults,
1467
- parseAndCheckLogin: parseAndCheckLogin,
1468
- getData_Path,
1469
- setData_Path,
1470
- getPaths,
1471
- saveCookies,
1472
- getType,
1473
- _formatAttachment,
1474
- formatHistoryMessage,
1475
- formatID,
1476
- formatMessage,
1477
- formatDeltaEvent,
1478
- formatDeltaMessage,
1479
- formatProxyPresence,
1480
- formatPresence,
1481
- formatTyp,
1482
- formatDeltaReadReceipt,
1483
- formatCookie,
1484
- formatThread,
1485
- formatReadReceipt,
1486
- formatRead,
1487
- generatePresence,
1488
- generateAccessiblityCookie,
1489
- formatDate,
1490
- decodeClientPayload,
1491
- getAppState,
1492
- getAdminTextMessageType,
1493
- setProxy,
1494
- checkLiveCookie,
1495
- getAccessFromBusiness,
1496
- getFroms
1497
- };