@dongdev/fca-unofficial 3.0.29 → 3.0.31

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 (100) hide show
  1. package/CHANGELOG.md +232 -132
  2. package/DOCS.md +82 -3
  3. package/README.md +524 -632
  4. package/func/logAdapter.js +33 -0
  5. package/index.d.ts +6 -0
  6. package/module/config.js +11 -1
  7. package/module/loginHelper.js +63 -4
  8. package/package.json +89 -81
  9. package/src/api/action/changeAvatar.js +1 -1
  10. package/src/api/action/changeBio.js +1 -1
  11. package/src/api/action/handleFriendRequest.js +1 -1
  12. package/src/api/action/logout.js +1 -1
  13. package/src/api/action/refreshFb_dtsg.js +1 -1
  14. package/src/api/action/setPostReaction.js +1 -1
  15. package/src/api/action/unfriend.js +1 -1
  16. package/src/api/http/httpGet.js +2 -2
  17. package/src/api/http/postFormData.js +1 -1
  18. package/src/api/messaging/addUserToGroup.js +1 -1
  19. package/src/api/messaging/changeArchivedStatus.js +1 -1
  20. package/src/api/messaging/changeBlockedStatus.js +1 -1
  21. package/src/api/messaging/changeGroupImage.js +2 -2
  22. package/src/api/messaging/changeNickname.js +2 -2
  23. package/src/api/messaging/changeThreadColor.js +1 -1
  24. package/src/api/messaging/changeThreadEmoji.js +1 -1
  25. package/src/api/messaging/createNewGroup.js +1 -1
  26. package/src/api/messaging/createThemeAI.js +1 -1
  27. package/src/api/messaging/deleteMessage.js +1 -1
  28. package/src/api/messaging/deleteThread.js +1 -1
  29. package/src/api/messaging/editMessage.js +1 -1
  30. package/src/api/messaging/getFriendsList.js +1 -1
  31. package/src/api/messaging/getMessage.js +1 -1
  32. package/src/api/messaging/getThemePictures.js +1 -1
  33. package/src/api/messaging/handleMessageRequest.js +1 -1
  34. package/src/api/messaging/markAsDelivered.js +1 -1
  35. package/src/api/messaging/markAsRead.js +1 -1
  36. package/src/api/messaging/markAsReadAll.js +1 -1
  37. package/src/api/messaging/markAsSeen.js +1 -1
  38. package/src/api/messaging/muteThread.js +1 -1
  39. package/src/api/messaging/resolvePhotoUrl.js +1 -1
  40. package/src/api/messaging/searchForThread.js +2 -1
  41. package/src/api/messaging/sendMessage.js +1 -1
  42. package/src/api/messaging/sendTypingIndicator.js +1 -1
  43. package/src/api/messaging/setMessageReaction.js +3 -4
  44. package/src/api/messaging/setTitle.js +1 -1
  45. package/src/api/messaging/unsendMessage.js +2 -2
  46. package/src/api/messaging/uploadAttachment.js +1 -1
  47. package/src/api/socket/core/connectMqtt.js +16 -8
  48. package/src/api/socket/core/emitAuth.js +4 -0
  49. package/src/api/socket/core/getSeqID.js +6 -8
  50. package/src/api/socket/core/getTaskResponseData.js +3 -0
  51. package/src/api/socket/core/parseDelta.js +9 -0
  52. package/src/api/socket/detail/buildStream.js +11 -4
  53. package/src/api/socket/detail/constants.js +4 -0
  54. package/src/api/socket/listenMqtt.js +11 -5
  55. package/src/api/threads/getThreadHistory.js +1 -1
  56. package/src/api/threads/getThreadInfo.js +246 -388
  57. package/src/api/threads/getThreadList.js +1 -1
  58. package/src/api/threads/getThreadPictures.js +1 -1
  59. package/src/api/users/getUserID.js +1 -1
  60. package/src/api/users/getUserInfo.js +87 -12
  61. package/src/database/helpers.js +53 -0
  62. package/src/database/models/index.js +2 -1
  63. package/src/database/models/thread.js +5 -0
  64. package/src/database/threadData.js +49 -53
  65. package/src/database/userData.js +46 -37
  66. package/src/remote/remoteClient.js +123 -0
  67. package/src/utils/broadcast.js +51 -0
  68. package/src/utils/format/attachment.js +357 -0
  69. package/src/utils/format/cookie.js +9 -0
  70. package/src/utils/format/date.js +50 -0
  71. package/src/utils/format/decode.js +44 -0
  72. package/src/utils/format/delta.js +194 -0
  73. package/src/utils/format/ids.js +64 -0
  74. package/src/utils/format/index.js +64 -0
  75. package/src/utils/format/message.js +88 -0
  76. package/src/utils/format/presence.js +132 -0
  77. package/src/utils/format/readTyp.js +44 -0
  78. package/src/utils/format/thread.js +42 -0
  79. package/src/utils/format/utils.js +141 -0
  80. package/src/utils/loginParser/autoLogin.js +125 -0
  81. package/src/utils/loginParser/helpers.js +43 -0
  82. package/src/utils/loginParser/index.js +10 -0
  83. package/src/utils/loginParser/parseAndCheckLogin.js +220 -0
  84. package/src/utils/loginParser/textUtils.js +28 -0
  85. package/src/utils/request/client.js +26 -0
  86. package/src/utils/request/config.js +23 -0
  87. package/src/utils/request/defaults.js +46 -0
  88. package/src/utils/request/helpers.js +46 -0
  89. package/src/utils/request/index.js +17 -0
  90. package/src/utils/request/methods.js +163 -0
  91. package/src/utils/request/proxy.js +21 -0
  92. package/src/utils/request/retry.js +77 -0
  93. package/src/utils/request/sanitize.js +49 -0
  94. package/.gitattributes +0 -2
  95. package/Fca_Database/database.sqlite +0 -0
  96. package/LICENSE-MIT +0 -21
  97. package/src/utils/format.js +0 -1174
  98. package/src/utils/loginParser.js +0 -347
  99. package/src/utils/messageFormat.js +0 -1173
  100. package/src/utils/request.js +0 -305
@@ -1,1174 +0,0 @@
1
- "use strict";
2
- var url = require("url");
3
- const querystring = require("querystring");
4
-
5
- function getType(obj) {
6
- return Object.prototype.toString.call(obj).slice(8, -1);
7
- }
8
-
9
- function generateOfflineThreadingID() {
10
- var ret = Date.now();
11
- var value = Math.floor(Math.random() * 4294967295);
12
- var str = ("0000000000000000000000" + value.toString(2)).slice(-22);
13
- var msgs = ret.toString(2) + str;
14
- return binaryToDecimal(msgs);
15
- }
16
- var h;
17
- var i = {};
18
- var j = {
19
- _: "%",
20
- A: "%2",
21
- B: "000",
22
- C: "%7d",
23
- D: "%7b%22",
24
- E: "%2c%22",
25
- F: "%22%3a",
26
- G: "%2c%22ut%22%3a1",
27
- H: "%2c%22bls%22%3a",
28
- I: "%2c%22n%22%3a%22%",
29
- J: "%22%3a%7b%22i%22%3a0%7d",
30
- K: "%2c%22pt%22%3a0%2c%22vis%22%3a",
31
- L: "%2c%22ch%22%3a%7b%22h%22%3a%22",
32
- M: "%7b%22v%22%3a2%2c%22time%22%3a1",
33
- N: ".channel%22%2c%22sub%22%3a%5b",
34
- O: "%2c%22sb%22%3a1%2c%22t%22%3a%5b",
35
- P: "%2c%22ud%22%3a100%2c%22lc%22%3a0",
36
- Q: "%5d%2c%22f%22%3anull%2c%22uct%22%3a",
37
- R: ".channel%22%2c%22sub%22%3a%5b1%5d",
38
- S: "%22%2c%22m%22%3a0%7d%2c%7b%22i%22%3a",
39
- T: "%2c%22blc%22%3a1%2c%22snd%22%3a1%2c%22ct%22%3a",
40
- U: "%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
41
- V: "%2c%22blc%22%3a0%2c%22snd%22%3a0%2c%22ct%22%3a",
42
- W: "%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a",
43
- X: "%2c%22ri%22%3a0%7d%2c%22state%22%3a%7b%22p%22%3a0%2c%22ut%22%3a1",
44
- Y: "%2c%22pt%22%3a0%2c%22vis%22%3a1%2c%22bls%22%3a0%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
45
- Z: "%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",
46
- };
47
- (function () {
48
- var l = [];
49
- for (var m in j) {
50
- i[j[m]] = m;
51
- l.push(j[m]);
52
- }
53
- l.reverse();
54
- h = new RegExp(l.join("|"), "g");
55
- })();
56
-
57
- function getAdminTextMessageType(m) {
58
- switch (m.type) {
59
- case "joinable_group_link_mode_change":
60
- return "log:link-status";
61
- case "magic_words":
62
- return "log:magic-words";
63
- case "change_thread_theme":
64
- return "log:thread-color";
65
- case "change_thread_icon":
66
- case "change_thread_quick_reaction":
67
- return "log:thread-icon";
68
- case "change_thread_nickname":
69
- return "log:user-nickname";
70
- case "change_thread_admins":
71
- return "log:thread-admins";
72
- case "group_poll":
73
- return "log:thread-poll";
74
- case "change_thread_approval_mode":
75
- return "log:thread-approval-mode";
76
- case "messenger_call_log":
77
- case "participant_joined_group_call":
78
- return "log:thread-call";
79
- case "pin_messages_v2":
80
- return "log:thread-pinned";
81
- case "unpin_messages_v2":
82
- return "log:unpin-message";
83
- default:
84
- return m.type;
85
- }
86
- }
87
-
88
- function formatDeltaEvent(m) {
89
- var logMessageType;
90
- var logMessageData;
91
- switch (m.class) {
92
- case "AdminTextMessage":
93
- logMessageType = getAdminTextMessageType(m);
94
- logMessageData = m.untypedData;
95
- break;
96
- case "ThreadName":
97
- logMessageType = "log:thread-name";
98
- logMessageData = { name: m.name };
99
- break;
100
- case "ParticipantsAddedToGroupThread":
101
- logMessageType = "log:subscribe";
102
- logMessageData = { addedParticipants: m.addedParticipants };
103
- break;
104
- case "ParticipantLeftGroupThread":
105
- logMessageType = "log:unsubscribe";
106
- logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
107
- break;
108
- case "UserLocation": {
109
- logMessageType = "log:user-location";
110
- logMessageData = {
111
- Image:
112
- m.attachments[0].mercury.extensible_attachment.story_attachment.media
113
- .image,
114
- Location:
115
- m.attachments[0].mercury.extensible_attachment.story_attachment.target
116
- .location_title,
117
- coordinates:
118
- m.attachments[0].mercury.extensible_attachment.story_attachment.target
119
- .coordinate,
120
- url: m.attachments[0].mercury.extensible_attachment.story_attachment
121
- .url,
122
- };
123
- }
124
- case "ApprovalQueue":
125
- logMessageType = "log:approval-queue";
126
- logMessageData = {
127
- approvalQueue: {
128
- action: m.action,
129
- recipientFbId: m.recipientFbId,
130
- requestSource: m.requestSource,
131
- ...m.messageMetadata,
132
- },
133
- };
134
- }
135
- return {
136
- type: "event",
137
- threadID: formatID(
138
- (
139
- m.messageMetadata.threadKey.threadFbId ||
140
- m.messageMetadata.threadKey.otherUserFbId
141
- ).toString(),
142
- ),
143
- logMessageType: logMessageType,
144
- logMessageData: logMessageData,
145
- logMessageBody: m.messageMetadata.adminText,
146
- author: m.messageMetadata.actorFbId,
147
- participantIDs: (m?.participants || []).map((e) => e.toString()),
148
- };
149
- }
150
-
151
- function _formatAttachment(attachment1, attachment2) {
152
- attachment2 = attachment2 || { id: "", image_data: {} };
153
- attachment1 = attachment1.mercury ? attachment1.mercury : attachment1;
154
- var blob = attachment1.blob_attachment;
155
- var type =
156
- blob && blob.__typename ? blob.__typename : attachment1.attach_type;
157
- if (!type && attachment1.sticker_attachment) {
158
- type = "StickerAttachment";
159
- blob = attachment1.sticker_attachment;
160
- } else if (!type && attachment1.extensible_attachment) {
161
- if (
162
- attachment1.extensible_attachment.story_attachment &&
163
- attachment1.extensible_attachment.story_attachment.target &&
164
- attachment1.extensible_attachment.story_attachment.target.__typename &&
165
- attachment1.extensible_attachment.story_attachment.target.__typename ===
166
- "MessageLocation"
167
- )
168
- type = "MessageLocation";
169
- else type = "ExtensibleAttachment";
170
-
171
- blob = attachment1.extensible_attachment;
172
- }
173
-
174
- // Add logic to extract Src or ThumbnailSrc from Payload.RealMetadata
175
- if (blob && blob.real_metadata) {
176
- const realMetadata = blob.real_metadata;
177
- if (realMetadata.Src) {
178
- attachment2.src = realMetadata.Src;
179
- }
180
- if (realMetadata.ThumbnailSrc) {
181
- attachment2.thumbnailSrc = realMetadata.ThumbnailSrc;
182
- }
183
- }
184
-
185
- switch (type) {
186
- case "sticker":
187
- return {
188
- type: "sticker",
189
- ID: attachment1.metadata.stickerID.toString(),
190
- url: attachment1.url,
191
-
192
- packID: attachment1.metadata.packID.toString(),
193
- spriteUrl: attachment1.metadata.spriteURI,
194
- spriteUrl2x: attachment1.metadata.spriteURI2x,
195
- width: attachment1.metadata.width,
196
- height: attachment1.metadata.height,
197
-
198
- caption: attachment2.caption,
199
- description: attachment2.description,
200
-
201
- frameCount: attachment1.metadata.frameCount,
202
- frameRate: attachment1.metadata.frameRate,
203
- framesPerRow: attachment1.metadata.framesPerRow,
204
- framesPerCol: attachment1.metadata.framesPerCol,
205
-
206
- stickerID: attachment1.metadata.stickerID.toString(), // @Legacy
207
- spriteURI: attachment1.metadata.spriteURI, // @Legacy
208
- spriteURI2x: attachment1.metadata.spriteURI2x, // @Legacy
209
- };
210
- case "file":
211
- return {
212
- type: "file",
213
- filename: attachment1.name,
214
- ID: attachment2.id.toString(),
215
- url: attachment1.url,
216
-
217
- isMalicious: attachment2.is_malicious,
218
- contentType: attachment2.mime_type,
219
-
220
- name: attachment1.name, // @Legacy
221
- mimeType: attachment2.mime_type, // @Legacy
222
- fileSize: attachment2.file_size, // @Legacy
223
- };
224
- case "photo":
225
- return {
226
- type: "photo",
227
- ID: attachment1.metadata.fbid.toString(),
228
- filename: attachment1.fileName,
229
- thumbnailUrl: attachment1.thumbnail_url,
230
-
231
- previewUrl: attachment1.preview_url,
232
- previewWidth: attachment1.preview_width,
233
- previewHeight: attachment1.preview_height,
234
-
235
- largePreviewUrl: attachment1.large_preview_url,
236
- largePreviewWidth: attachment1.large_preview_width,
237
- largePreviewHeight: attachment1.large_preview_height,
238
-
239
- url: attachment1.metadata.url, // @Legacy
240
- width: attachment1.metadata.dimensions.split(",")[0], // @Legacy
241
- height: attachment1.metadata.dimensions.split(",")[1], // @Legacy
242
- name: attachment1.fileName, // @Legacy
243
- };
244
- case "animated_image":
245
- return {
246
- type: "animated_image",
247
- ID: attachment2.id.toString(),
248
- filename: attachment2.filename,
249
-
250
- previewUrl: attachment1.preview_url,
251
- previewWidth: attachment1.preview_width,
252
- previewHeight: attachment1.preview_height,
253
-
254
- url: attachment2.image_data.url,
255
- width: attachment2.image_data.width,
256
- height: attachment2.image_data.height,
257
-
258
- name: attachment1.name, // @Legacy
259
- facebookUrl: attachment1.url, // @Legacy
260
- thumbnailUrl: attachment1.thumbnail_url, // @Legacy
261
- mimeType: attachment2.mime_type, // @Legacy
262
- rawGifImage: attachment2.image_data.raw_gif_image, // @Legacy
263
- rawWebpImage: attachment2.image_data.raw_webp_image, // @Legacy
264
- animatedGifUrl: attachment2.image_data.animated_gif_url, // @Legacy
265
- animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url, // @Legacy
266
- animatedWebpUrl: attachment2.image_data.animated_webp_url, // @Legacy
267
- animatedWebpPreviewUrl:
268
- attachment2.image_data.animated_webp_preview_url, // @Legacy
269
- };
270
- case "share":
271
- return {
272
- type: "share",
273
- ID: attachment1.share.share_id.toString(),
274
- url: attachment2.href,
275
-
276
- title: attachment1.share.title,
277
- description: attachment1.share.description,
278
- source: attachment1.share.source,
279
-
280
- image: attachment1.share.media.image,
281
- width: attachment1.share.media.image_size.width,
282
- height: attachment1.share.media.image_size.height,
283
- playable: attachment1.share.media.playable,
284
- duration: attachment1.share.media.duration,
285
-
286
- subattachments: attachment1.share.subattachments,
287
- properties: {},
288
-
289
- animatedImageSize: attachment1.share.media.animated_image_size, // @Legacy
290
- facebookUrl: attachment1.share.uri, // @Legacy
291
- target: attachment1.share.target, // @Legacy
292
- styleList: attachment1.share.style_list, // @Legacy
293
- };
294
- case "video":
295
- return {
296
- type: "video",
297
- ID: attachment1.metadata.fbid.toString(),
298
- filename: attachment1.name,
299
-
300
- previewUrl: attachment1.preview_url,
301
- previewWidth: attachment1.preview_width,
302
- previewHeight: attachment1.preview_height,
303
-
304
- url: attachment1.url,
305
- width: attachment1.metadata.dimensions.width,
306
- height: attachment1.metadata.dimensions.height,
307
-
308
- duration: attachment1.metadata.duration,
309
- videoType: "unknown",
310
-
311
- thumbnailUrl: attachment1.thumbnail_url, // @Legacy
312
- };
313
- case "error":
314
- return {
315
- type: "error",
316
- attachment1: attachment1,
317
- attachment2: attachment2,
318
- };
319
- case "MessageImage":
320
- return {
321
- type: "photo",
322
- ID: blob.legacy_attachment_id,
323
- filename: blob.filename,
324
- thumbnailUrl: blob.thumbnail.uri,
325
-
326
- previewUrl: blob.preview.uri,
327
- previewWidth: blob.preview.width,
328
- previewHeight: blob.preview.height,
329
-
330
- largePreviewUrl: blob.large_preview.uri,
331
- largePreviewWidth: blob.large_preview.width,
332
- largePreviewHeight: blob.large_preview.height,
333
-
334
- url: blob.large_preview.uri, // @Legacy
335
- width: blob.original_dimensions.x, // @Legacy
336
- height: blob.original_dimensions.y, // @Legacy
337
- name: blob.filename, // @Legacy
338
- };
339
- case "MessageAnimatedImage":
340
- return {
341
- type: "animated_image",
342
- ID: blob.legacy_attachment_id,
343
- filename: blob.filename,
344
-
345
- previewUrl: blob.preview_image.uri,
346
- previewWidth: blob.preview_image.width,
347
- previewHeight: blob.preview_image.height,
348
-
349
- url: blob.animated_image.uri,
350
- width: blob.animated_image.width,
351
- height: blob.animated_image.height,
352
-
353
- thumbnailUrl: blob.preview_image.uri, // @Legacy
354
- name: blob.filename, // @Legacy
355
- facebookUrl: blob.animated_image.uri, // @Legacy
356
- rawGifImage: blob.animated_image.uri, // @Legacy
357
- animatedGifUrl: blob.animated_image.uri, // @Legacy
358
- animatedGifPreviewUrl: blob.preview_image.uri, // @Legacy
359
- animatedWebpUrl: blob.animated_image.uri, // @Legacy
360
- animatedWebpPreviewUrl: blob.preview_image.uri, // @Legacy
361
- };
362
- case "MessageVideo":
363
- return {
364
- type: "video",
365
- filename: blob.filename,
366
- ID: blob.legacy_attachment_id,
367
-
368
- previewUrl: blob.large_image.uri,
369
- previewWidth: blob.large_image.width,
370
- previewHeight: blob.large_image.height,
371
-
372
- url: blob.playable_url,
373
- width: blob.original_dimensions.x,
374
- height: blob.original_dimensions.y,
375
-
376
- duration: blob.playable_duration_in_ms,
377
- videoType: blob.video_type.toLowerCase(),
378
-
379
- thumbnailUrl: blob.large_image.uri, // @Legacy
380
- };
381
- case "MessageAudio":
382
- return {
383
- type: "audio",
384
- filename: blob.filename,
385
- ID: blob.url_shimhash,
386
-
387
- audioType: blob.audio_type,
388
- duration: blob.playable_duration_in_ms,
389
- url: blob.playable_url,
390
-
391
- isVoiceMail: blob.is_voicemail,
392
- };
393
- case "StickerAttachment":
394
- return {
395
- type: "sticker",
396
- ID: blob.id,
397
- url: blob.url,
398
-
399
- packID: blob.pack ? blob.pack.id : null,
400
- spriteUrl: blob.sprite_image,
401
- spriteUrl2x: blob.sprite_image_2x,
402
- width: blob.width,
403
- height: blob.height,
404
-
405
- caption: blob.label,
406
- description: blob.label,
407
-
408
- frameCount: blob.frame_count,
409
- frameRate: blob.frame_rate,
410
- framesPerRow: blob.frames_per_row,
411
- framesPerCol: blob.frames_per_column,
412
-
413
- stickerID: blob.id, // @Legacy
414
- spriteURI: blob.sprite_image, // @Legacy
415
- spriteURI2x: blob.sprite_image_2x, // @Legacy
416
- };
417
- case "MessageLocation":
418
- var urlAttach = blob.story_attachment.url;
419
- var mediaAttach = blob.story_attachment.media;
420
-
421
- var u = querystring.parse(url.parse(urlAttach).query).u;
422
- var where1 = querystring.parse(url.parse(u).query).where1;
423
- var address = where1.split(", ");
424
-
425
- var latitude;
426
- var longitude;
427
-
428
- try {
429
- latitude = Number.parseFloat(address[0]);
430
- longitude = Number.parseFloat(address[1]);
431
- } catch (err) {
432
- /* empty */
433
- }
434
-
435
- var imageUrl;
436
- var width;
437
- var height;
438
-
439
- if (mediaAttach && mediaAttach.image) {
440
- imageUrl = mediaAttach.image.uri;
441
- width = mediaAttach.image.width;
442
- height = mediaAttach.image.height;
443
- }
444
-
445
- return {
446
- type: "location",
447
- ID: blob.legacy_attachment_id,
448
- latitude: latitude,
449
- longitude: longitude,
450
- image: imageUrl,
451
- width: width,
452
- height: height,
453
- url: u || urlAttach,
454
- address: where1,
455
-
456
- facebookUrl: blob.story_attachment.url, // @Legacy
457
- target: blob.story_attachment.target, // @Legacy
458
- styleList: blob.story_attachment.style_list, // @Legacy
459
- };
460
- case "ExtensibleAttachment":
461
- return {
462
- type: "share",
463
- ID: blob.legacy_attachment_id,
464
- url: blob.story_attachment.url,
465
-
466
- title: blob.story_attachment.title_with_entities.text,
467
- description:
468
- blob.story_attachment.description &&
469
- blob.story_attachment.description.text,
470
- source: blob.story_attachment.source
471
- ? blob.story_attachment.source.text
472
- : null,
473
-
474
- image:
475
- blob.story_attachment.media &&
476
- blob.story_attachment.media.image &&
477
- blob.story_attachment.media.image.uri,
478
- width:
479
- blob.story_attachment.media &&
480
- blob.story_attachment.media.image &&
481
- blob.story_attachment.media.image.width,
482
- height:
483
- blob.story_attachment.media &&
484
- blob.story_attachment.media.image &&
485
- blob.story_attachment.media.image.height,
486
- playable:
487
- blob.story_attachment.media &&
488
- blob.story_attachment.media.is_playable,
489
- duration:
490
- blob.story_attachment.media &&
491
- blob.story_attachment.media.playable_duration_in_ms,
492
- playableUrl:
493
- blob.story_attachment.media == null
494
- ? null
495
- : blob.story_attachment.media.playable_url,
496
-
497
- subattachments: blob.story_attachment.subattachments,
498
- properties: blob.story_attachment.properties.reduce(function (
499
- /** @type {{ [x: string]: any; }} */ obj,
500
- /** @type {{ key: string | number; value: { text: any; }; }} */ cur,
501
- ) {
502
- obj[cur.key] = cur.value.text;
503
- return obj;
504
- }, {}),
505
-
506
- facebookUrl: blob.story_attachment.url, // @Legacy
507
- target: blob.story_attachment.target, // @Legacy
508
- styleList: blob.story_attachment.style_list, // @Legacy
509
- };
510
- case "MessageFile":
511
- return {
512
- type: "file",
513
- filename: blob.filename,
514
- ID: blob.message_file_fbid,
515
-
516
- url: blob.url,
517
- isMalicious: blob.is_malicious,
518
- contentType: blob.content_type,
519
-
520
- name: blob.filename,
521
- mimeType: "",
522
- fileSize: -1,
523
- };
524
- default:
525
- throw new Error(
526
- "unrecognized attach_file of type " +
527
- type +
528
- "`" +
529
- JSON.stringify(attachment1, null, 4) +
530
- " attachment2: " +
531
- JSON.stringify(attachment2, null, 4) +
532
- "`",
533
- );
534
- }
535
- }
536
-
537
- function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
538
- attachmentMap = shareMap || attachmentMap;
539
- return attachments
540
- ? attachments.map(function (i) {
541
- if (
542
- !attachmentMap ||
543
- !attachmentIds ||
544
- !attachmentMap[attachmentIds[i]]
545
- ) {
546
- return _formatAttachment(val);
547
- }
548
- return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
549
- })
550
- : [];
551
- }
552
-
553
- /**
554
- * Extract mentions from message - supports legacy (data.prng) and new format (messageMetadata.data.data.Gb.asMap.data).
555
- * @param {Object} m - Raw message object (NewMessage delta)
556
- * @returns {Object} mentions - Map of userID -> mention text
557
- */
558
- function getMentionsFromDeltaMessage(m) {
559
- var body = m.body || "";
560
- var mentions = {};
561
- var mdata = [];
562
- if (m.data && m.data.prng) {
563
- try {
564
- mdata = JSON.parse(m.data.prng);
565
- } catch (e) {
566
- mdata = [];
567
- }
568
- }
569
- if (mdata.length > 0) {
570
- for (var i = 0; i < mdata.length; i++) {
571
- var id = mdata[i].i;
572
- var o = parseInt(mdata[i].o, 10) || 0;
573
- var l = parseInt(mdata[i].l, 10) || 0;
574
- mentions[String(id)] = body.substring(o, o + l);
575
- }
576
- return mentions;
577
- }
578
- var md = m.messageMetadata;
579
- if (
580
- md &&
581
- md.data &&
582
- md.data.data &&
583
- md.data.data.Gb &&
584
- md.data.data.Gb.asMap &&
585
- md.data.data.Gb.asMap.data
586
- ) {
587
- var gbData = md.data.data.Gb.asMap.data;
588
- for (var key in gbData) {
589
- if (!Object.prototype.hasOwnProperty.call(gbData, key)) continue;
590
- var entry = gbData[key];
591
- if (entry && entry.asMap && entry.asMap.data) {
592
- var d = entry.asMap.data;
593
- var id = d.id && d.id.asLong ? String(d.id.asLong) : null;
594
- var offset = parseInt(
595
- d.offset && d.offset.asLong ? d.offset.asLong : 0,
596
- 10,
597
- );
598
- var len = parseInt(
599
- d.length && d.length.asLong ? d.length.asLong : 0,
600
- 10,
601
- );
602
- if (id != null) {
603
- mentions[id] = body.substring(offset, offset + len);
604
- }
605
- }
606
- }
607
- }
608
- return mentions;
609
- }
610
-
611
- function formatDeltaMessage(m) {
612
- var md = m.messageMetadata;
613
- var body = m.body || "";
614
- var mentions = getMentionsFromDeltaMessage(m);
615
- var args = body === "" ? [] : body.trim().split(/\s+/);
616
- return {
617
- type: "message",
618
- senderID: formatID(md.actorFbId.toString()),
619
- threadID: formatID(
620
- (md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString(),
621
- ),
622
- messageID: md.messageId,
623
- args: args,
624
- body: body,
625
- attachments: (m.attachments || []).map((/** @type {any} */ v) =>
626
- _formatAttachment(v),
627
- ),
628
- mentions: mentions,
629
- timestamp: md.timestamp,
630
- isGroup: !!md.threadKey.threadFbId,
631
- participantIDs: (m.participants || []).map((/** @type {any} */ p) =>
632
- formatID(p.toString()),
633
- ),
634
- isUnread: md.isUnread !== undefined ? md.isUnread : false,
635
- };
636
- }
637
-
638
- function formatID(id) {
639
- if (id != undefined && id != null) return id.replace(/(fb)?id[:.]/, "");
640
- else return id;
641
- }
642
-
643
- function formatMessage(m) {
644
- var originalMessage = m.message ? m.message : m;
645
- var body = originalMessage.body || "";
646
- var args = body == "" ? [] : body.trim().split(/\s+/);
647
- var obj = {
648
- type: "message",
649
- senderName: originalMessage.sender_name,
650
- senderID: formatID(originalMessage.sender_fbid.toString()),
651
- participantNames: originalMessage.group_thread_info
652
- ? originalMessage.group_thread_info.participant_names
653
- : [originalMessage.sender_name.split(" ")[0]],
654
- participantIDs: originalMessage.group_thread_info
655
- ? originalMessage.group_thread_info.participant_ids.map(function (v) {
656
- return formatID(v.toString());
657
- })
658
- : [formatID(originalMessage.sender_fbid)],
659
- body: body,
660
- args: args,
661
- threadID: formatID(
662
- (
663
- originalMessage.thread_fbid || originalMessage.other_user_fbid
664
- ).toString(),
665
- ),
666
- threadName: originalMessage.group_thread_info
667
- ? originalMessage.group_thread_info.name
668
- : originalMessage.sender_name,
669
- location: originalMessage.coordinates ? originalMessage.coordinates : null,
670
- messageID: originalMessage.mid
671
- ? originalMessage.mid.toString()
672
- : originalMessage.message_id,
673
- attachments: formatAttachment(
674
- originalMessage.attachments,
675
- originalMessage.attachmentIds,
676
- originalMessage.attachment_map,
677
- originalMessage.share_map,
678
- ),
679
- timestamp: originalMessage.timestamp,
680
- timestampAbsolute: originalMessage.timestamp_absolute,
681
- timestampRelative: originalMessage.timestamp_relative,
682
- timestampDatetime: originalMessage.timestamp_datetime,
683
- tags: originalMessage.tags,
684
- reactions: originalMessage.reactions ? originalMessage.reactions : [],
685
- isUnread: originalMessage.is_unread,
686
- };
687
- if (m.type === "pages_messaging")
688
- obj.pageID = m.realtime_viewer_fbid.toString();
689
- obj.isGroup = obj.participantIDs.length > 2;
690
- return obj;
691
- }
692
-
693
- function formatEvent(m) {
694
- var originalMessage = m.message ? m.message : m;
695
- var logMessageType = originalMessage.log_message_type;
696
- var logMessageData;
697
- if (logMessageType === "log:generic-admin-text") {
698
- logMessageData = originalMessage.log_message_data.untypedData;
699
- logMessageType = getAdminTextMessageType(
700
- originalMessage.log_message_data.message_type,
701
- );
702
- } else logMessageData = originalMessage.log_message_data;
703
- return Object.assign(formatMessage(originalMessage), {
704
- type: "event",
705
- logMessageType: logMessageType,
706
- logMessageData: logMessageData,
707
- logMessageBody: originalMessage.log_message_body,
708
- });
709
- }
710
-
711
- function formatHistoryMessage(m) {
712
- switch (m.action_type) {
713
- case "ma-type:log-message":
714
- return formatEvent(m);
715
- default:
716
- return formatMessage(m);
717
- }
718
- }
719
-
720
- function formatDeltaReadReceipt(delta) {
721
- return {
722
- reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
723
- time: delta.actionTimestampMs,
724
- threadID: formatID(
725
- (delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString(),
726
- ),
727
- type: "read_receipt",
728
- };
729
- }
730
-
731
- function decodeClientPayload(payload) {
732
- function Utf8ArrayToStr(array) {
733
- var out, i, len, c;
734
- var char2, char3;
735
- out = "";
736
- len = array.length;
737
- i = 0;
738
- while (i < len) {
739
- c = array[i++];
740
- switch (c >> 4) {
741
- case 0:
742
- case 1:
743
- case 2:
744
- case 3:
745
- case 4:
746
- case 5:
747
- case 6:
748
- case 7:
749
- out += String.fromCharCode(c);
750
- break;
751
- case 12:
752
- case 13:
753
- char2 = array[i++];
754
- out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
755
- break;
756
- case 14:
757
- char2 = array[i++];
758
- char3 = array[i++];
759
- out += String.fromCharCode(
760
- ((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0),
761
- );
762
- break;
763
- }
764
- }
765
- return out;
766
- }
767
- return JSON.parse(Utf8ArrayToStr(payload));
768
- }
769
-
770
- function formatTyp(event) {
771
- return {
772
- isTyping: !!event.st,
773
- from: event.from.toString(),
774
- threadID: formatID(
775
- (event.to || event.thread_fbid || event.from).toString(),
776
- ),
777
- fromMobile: event.hasOwnProperty("from_mobile") ? event.from_mobile : true,
778
- userID: (event.realtime_viewer_fbid || event.from).toString(),
779
- type: "typ",
780
- };
781
- }
782
-
783
- function formatThread(data) {
784
- return {
785
- threadID: formatID(data.thread_fbid.toString()),
786
- participants: data.participants.map(formatID),
787
- participantIDs: data.participants.map(formatID),
788
- name: data.name,
789
- nicknames: data.custom_nickname,
790
- snippet: data.snippet,
791
- snippetAttachments: data.snippet_attachments,
792
- snippetSender: formatID((data.snippet_sender || "").toString()),
793
- unreadCount: data.unread_count,
794
- messageCount: data.message_count,
795
- imageSrc: data.image_src,
796
- timestamp: data.timestamp,
797
- muteUntil: data.mute_until,
798
- isCanonicalUser: data.is_canonical_user,
799
- isCanonical: data.is_canonical,
800
- isSubscribed: data.is_subscribed,
801
- folder: data.folder,
802
- isArchived: data.is_archived,
803
- recipientsLoadable: data.recipients_loadable,
804
- hasEmailParticipant: data.has_email_participant,
805
- readOnly: data.read_only,
806
- canReply: data.can_reply,
807
- cannotReplyReason: data.cannot_reply_reason,
808
- lastMessageTimestamp: data.last_message_timestamp,
809
- lastReadTimestamp: data.last_read_timestamp,
810
- lastMessageType: data.last_message_type,
811
- emoji: data.custom_like_icon,
812
- color: data.custom_color,
813
- adminIDs: data.admin_ids,
814
- threadType: data.thread_type,
815
- };
816
- }
817
-
818
- function generateThreadingID(clientID) {
819
- var k = Date.now();
820
- var l = Math.floor(Math.random() * 4294967295);
821
- var m = clientID;
822
- return "<" + k + ":" + l + "-" + m + "@mail.projektitan.com>";
823
- }
824
-
825
- function padZeros(val, len) {
826
- val = String(val);
827
- len = len || 2;
828
- while (val.length < len) val = "0" + val;
829
- return val;
830
- }
831
-
832
- function binaryToDecimal(data) {
833
- var ret = "";
834
- while (data !== "0") {
835
- var end = 0;
836
- var fullName = "";
837
- var i = 0;
838
- for (; i < data.length; i++) {
839
- end = 2 * end + parseInt(data[i], 10);
840
- if (end >= 10) {
841
- fullName += "1";
842
- end -= 10;
843
- } else fullName += "0";
844
- }
845
- ret = end.toString() + ret;
846
- data = fullName.slice(fullName.indexOf("1"));
847
- }
848
- return ret;
849
- }
850
-
851
- function presenceEncode(str) {
852
- return encodeURIComponent(str)
853
- .replace(/([_A-Z])|%../g, function (m, n) {
854
- return n ? "%" + n.charCodeAt(0).toString(16) : m;
855
- })
856
- .toLowerCase()
857
- .replace(h, function (m) {
858
- return i[m];
859
- });
860
- }
861
-
862
- function presenceDecode(str) {
863
- return decodeURIComponent(
864
- str.replace(/[_A-Z]/g, function (/** @type {string | number} */ m) {
865
- return j[m];
866
- }),
867
- );
868
- }
869
-
870
- function generatePresence(userID) {
871
- var time = Date.now();
872
- return (
873
- "E" +
874
- presenceEncode(
875
- JSON.stringify({
876
- v: 3,
877
- time: parseInt(time / 1000, 10),
878
- user: userID,
879
- state: {
880
- ut: 0,
881
- t2: [],
882
- lm2: null,
883
- uct2: time,
884
- tr: null,
885
- tw: Math.floor(Math.random() * 4294967295) + 1,
886
- at: time,
887
- },
888
- ch: {
889
- ["p_" + userID]: 0,
890
- },
891
- }),
892
- )
893
- );
894
- }
895
-
896
- function generateAccessiblityCookie() {
897
- var time = Date.now();
898
- return encodeURIComponent(
899
- JSON.stringify({
900
- sr: 0,
901
- "sr-ts": time,
902
- jk: 0,
903
- "jk-ts": time,
904
- kb: 0,
905
- "kb-ts": time,
906
- hcm: 0,
907
- "hcm-ts": time,
908
- }),
909
- );
910
- }
911
-
912
- function getGUID() {
913
- var sectionLength = Date.now();
914
- var id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
915
- /[xy]/g,
916
- function (c) {
917
- var r = Math.floor((sectionLength + Math.random() * 16) % 16);
918
- sectionLength = Math.floor(sectionLength / 16);
919
- var _guid = (c == "x" ? r : (r & 7) | 8).toString(16);
920
- return _guid;
921
- },
922
- );
923
- return id;
924
- }
925
-
926
- function formatDeltaReadReceipt(delta) {
927
- return {
928
- reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
929
- time: delta.actionTimestampMs,
930
- threadID: formatID(
931
- (delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString(),
932
- ),
933
- type: "read_receipt",
934
- };
935
- }
936
-
937
- function formatReadReceipt(event) {
938
- return {
939
- reader: event.reader.toString(),
940
- time: event.time,
941
- threadID: formatID((event.thread_fbid || event.reader).toString()),
942
- type: "read_receipt",
943
- };
944
- }
945
-
946
- function formatRead(event) {
947
- return {
948
- threadID: formatID(
949
- (
950
- (event.chat_ids && event.chat_ids[0]) ||
951
- (event.thread_fbids && event.thread_fbids[0])
952
- ).toString(),
953
- ),
954
- time: event.timestamp,
955
- type: "read",
956
- };
957
- }
958
-
959
- function arrToForm(form) {
960
- return arrayToObject(
961
- form,
962
- function (v) {
963
- return v.name;
964
- },
965
- function (v) {
966
- return v.val;
967
- },
968
- );
969
- }
970
-
971
- function arrayToObject(arr, getKey, getValue) {
972
- return arr.reduce(function (acc, val) {
973
- acc[getKey(val)] = getValue(val);
974
- return acc;
975
- }, {});
976
- }
977
-
978
- function getSignatureID() {
979
- return Math.floor(Math.random() * 2147483648).toString(16);
980
- }
981
-
982
- function generateTimestampRelative() {
983
- var d = new Date();
984
- return d.getHours() + ":" + padZeros(d.getMinutes());
985
- }
986
-
987
- var NUM_TO_MONTH = [
988
- "Jan",
989
- "Feb",
990
- "Mar",
991
- "Apr",
992
- "May",
993
- "Jun",
994
- "Jul",
995
- "Aug",
996
- "Sep",
997
- "Oct",
998
- "Nov",
999
- "Dec",
1000
- ];
1001
- var NUM_TO_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1002
-
1003
- function formatDate(date) {
1004
- var d = date.getUTCDate();
1005
- d = d >= 10 ? d : "0" + d;
1006
- var h = date.getUTCHours();
1007
- h = h >= 10 ? h : "0" + h;
1008
- var m = date.getUTCMinutes();
1009
- m = m >= 10 ? m : "0" + m;
1010
- var s = date.getUTCSeconds();
1011
- s = s >= 10 ? s : "0" + s;
1012
- return (
1013
- NUM_TO_DAY[date.getUTCDay()] +
1014
- ", " +
1015
- d +
1016
- " " +
1017
- NUM_TO_MONTH[date.getUTCMonth()] +
1018
- " " +
1019
- date.getUTCFullYear() +
1020
- " " +
1021
- h +
1022
- ":" +
1023
- m +
1024
- ":" +
1025
- s +
1026
- " GMT"
1027
- );
1028
- }
1029
-
1030
- function formatCookie(arr, url) {
1031
- return (
1032
- arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + url + ".com"
1033
- );
1034
- }
1035
-
1036
- function formatProxyPresence(presence, userID) {
1037
- if (presence.lat === undefined || presence.p === undefined) return null;
1038
- return {
1039
- type: "presence",
1040
- timestamp: presence.lat * 1000,
1041
- userID: userID || "",
1042
- statuses: presence.p,
1043
- };
1044
- }
1045
-
1046
- function formatPresence(presence, userID) {
1047
- return {
1048
- type: "presence",
1049
- timestamp: presence.la * 1000,
1050
- userID: userID || "",
1051
- statuses: presence.a,
1052
- };
1053
- }
1054
-
1055
- function getData_Path(Obj, Arr, Stt) {
1056
- if (Arr.length === 0 && Obj != undefined) {
1057
- return Obj;
1058
- } else if (Obj == undefined) {
1059
- return Stt;
1060
- }
1061
- const head = Arr[0];
1062
- if (head == undefined) {
1063
- return Stt;
1064
- }
1065
- const tail = Arr.slice(1);
1066
- return getData_Path(Obj[head], tail, Stt++);
1067
- }
1068
-
1069
- function setData_Path(obj, path, value) {
1070
- if (!path.length) {
1071
- return obj;
1072
- }
1073
- const currentKey = path[0];
1074
- let currentObj = obj[currentKey];
1075
-
1076
- if (!currentObj) {
1077
- obj[currentKey] = value;
1078
- currentObj = obj[currentKey];
1079
- }
1080
- path.shift();
1081
- if (!path.length) {
1082
- currentObj = value;
1083
- } else {
1084
- currentObj = setData_Path(currentObj, path, value);
1085
- }
1086
-
1087
- return obj;
1088
- }
1089
-
1090
- function getPaths(obj, parentPath = []) {
1091
- let paths = [];
1092
- for (let prop in obj) {
1093
- if (typeof obj[prop] === "object") {
1094
- paths = paths.concat(getPaths(obj[prop], [...parentPath, prop]));
1095
- } else {
1096
- paths.push([...parentPath, prop]);
1097
- }
1098
- }
1099
- return paths;
1100
- }
1101
-
1102
- function cleanHTML(text) {
1103
- text = text.replace(
1104
- /(<br>)|(<\/?i>)|(<\/?em>)|(<\/?b>)|(!?~)|(&amp;)|(&#039;)|(&lt;)|(&gt;)|(&quot;)/g,
1105
- (match) => {
1106
- switch (match) {
1107
- case "<br>":
1108
- return "\n";
1109
- case "<i>":
1110
- case "<em>":
1111
- case "</i>":
1112
- case "</em>":
1113
- return "*";
1114
- case "<b>":
1115
- case "</b>":
1116
- return "**";
1117
- case "~!":
1118
- case "!~":
1119
- return "||";
1120
- case "&amp;":
1121
- return "&";
1122
- case "&#039;":
1123
- return "'";
1124
- case "&lt;":
1125
- return "<";
1126
- case "&gt;":
1127
- return ">";
1128
- case "&quot;":
1129
- return '"';
1130
- }
1131
- },
1132
- );
1133
- return text;
1134
- }
1135
-
1136
- function getCurrentTimestamp() {
1137
- const date = new Date();
1138
- const unixTime = date.getTime();
1139
- return unixTime;
1140
- }
1141
-
1142
- module.exports = {
1143
- getType,
1144
- generateOfflineThreadingID,
1145
- getAdminTextMessageType,
1146
- formatDeltaEvent,
1147
- formatHistoryMessage,
1148
- formatMessage,
1149
- _formatAttachment,
1150
- formatDeltaEvent,
1151
- formatDeltaMessage,
1152
- getMentionsFromDeltaMessage,
1153
- formatDeltaReadReceipt,
1154
- getType,
1155
- formatID,
1156
- decodeClientPayload,
1157
- formatTyp,
1158
- formatThread,
1159
- generateThreadingID,
1160
- formatRead,
1161
- formatTyp,
1162
- getGUID,
1163
- getPaths,
1164
- cleanHTML,
1165
- generateTimestampRelative,
1166
- formatDate,
1167
- formatCookie,
1168
- formatProxyPresence,
1169
- formatPresence,
1170
- getData_Path,
1171
- setData_Path,
1172
- getSignatureID,
1173
- getCurrentTimestamp,
1174
- };