@vangbanlanhat/fca-unofficial 1.4.2

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 (115) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/workflows/nodejs.yml +26 -0
  3. package/.github/workflows/npmpublish.yml +30 -0
  4. package/.travis.yml +6 -0
  5. package/CHANGELOG.md +2 -0
  6. package/DOCS.md +1932 -0
  7. package/LICENSE-MIT +21 -0
  8. package/README.md +198 -0
  9. package/jest.config.js +10 -0
  10. package/package.json +86 -0
  11. package/pnpm-workspace.yaml +3 -0
  12. package/src/actions/addExternalModule.js +34 -0
  13. package/src/actions/addUserToGroup.js +113 -0
  14. package/src/actions/changeAdminStatus.js +79 -0
  15. package/src/actions/changeArchivedStatus.js +55 -0
  16. package/src/actions/changeBio.js +77 -0
  17. package/src/actions/changeBlockedStatus.js +47 -0
  18. package/src/actions/changeGroupImage.js +129 -0
  19. package/src/actions/changeNickname.js +59 -0
  20. package/src/actions/changeThreadColor.js +71 -0
  21. package/src/actions/changeThreadEmoji.js +55 -0
  22. package/src/actions/createNewGroup.js +86 -0
  23. package/src/actions/createPoll.js +71 -0
  24. package/src/actions/deleteMessage.js +56 -0
  25. package/src/actions/deleteThread.js +56 -0
  26. package/src/actions/editMessage.js +81 -0
  27. package/src/actions/forwardAttachment.js +60 -0
  28. package/src/actions/getAvatarUser.js +77 -0
  29. package/src/actions/getCurrentUserID.js +11 -0
  30. package/src/actions/getEmojiUrl.js +37 -0
  31. package/src/actions/getFriendsList.js +84 -0
  32. package/src/actions/getMessage.js +833 -0
  33. package/src/actions/getRegion.js +11 -0
  34. package/src/actions/getThreadHistory.js +702 -0
  35. package/src/actions/getThreadHistoryDeprecated.js +93 -0
  36. package/src/actions/getThreadInfo.js +265 -0
  37. package/src/actions/getThreadInfoDeprecated.js +80 -0
  38. package/src/actions/getThreadList.js +274 -0
  39. package/src/actions/getThreadListDeprecated.js +91 -0
  40. package/src/actions/getThreadPictures.js +79 -0
  41. package/src/actions/getUserID.js +66 -0
  42. package/src/actions/getUserInfo.js +92 -0
  43. package/src/actions/handleFriendRequest.js +61 -0
  44. package/src/actions/handleMessageRequest.js +65 -0
  45. package/src/actions/httpGet.js +70 -0
  46. package/src/actions/httpPost.js +70 -0
  47. package/src/actions/index.js +69 -0
  48. package/src/actions/listenMqtt.js +818 -0
  49. package/src/actions/logout.js +136 -0
  50. package/src/actions/markAsDelivered.js +58 -0
  51. package/src/actions/markAsRead.js +92 -0
  52. package/src/actions/markAsReadAll.js +50 -0
  53. package/src/actions/markAsSeen.js +59 -0
  54. package/src/actions/muteThread.js +52 -0
  55. package/src/actions/pinMessage.js +86 -0
  56. package/src/actions/refreshFb_dtsg.js +89 -0
  57. package/src/actions/removeUserFromGroup.js +79 -0
  58. package/src/actions/resolvePhotoUrl.js +45 -0
  59. package/src/actions/searchForThread.js +53 -0
  60. package/src/actions/searchStickers.js +53 -0
  61. package/src/actions/sendMessage.js +490 -0
  62. package/src/actions/sendMessageMqtt.js +235 -0
  63. package/src/actions/sendTypingIndicator.js +59 -0
  64. package/src/actions/setMessageReaction.js +140 -0
  65. package/src/actions/setMessageReactionMqtt.js +72 -0
  66. package/src/actions/setPostReaction.js +76 -0
  67. package/src/actions/setTitle.js +86 -0
  68. package/src/actions/stopListenMqtt.js +63 -0
  69. package/src/actions/threadColors.js +57 -0
  70. package/src/actions/unfriend.js +52 -0
  71. package/src/actions/unsendMessage.js +61 -0
  72. package/src/index.js +659 -0
  73. package/src/service/uploadAttachment.js +318 -0
  74. package/src/utils/base-parts/auth.js +286 -0
  75. package/src/utils/base-parts/formatters.js +751 -0
  76. package/src/utils/base-parts/identity.js +169 -0
  77. package/src/utils/base-parts/network.js +159 -0
  78. package/src/utils/base-parts/parsing.js +53 -0
  79. package/src/utils/base-parts/type.js +9 -0
  80. package/src/utils/base.js +18 -0
  81. package/src/utils/defaults.js +10 -0
  82. package/src/utils/format-attachments.js +7 -0
  83. package/src/utils/format-core.js +8 -0
  84. package/src/utils/format-events.js +11 -0
  85. package/src/utils/format-messages.js +10 -0
  86. package/src/utils/format-presence.js +9 -0
  87. package/src/utils/format-threads.js +8 -0
  88. package/src/utils/formatters.js +18 -0
  89. package/src/utils/identity.js +12 -0
  90. package/src/utils/index.js +15 -0
  91. package/src/utils/network.js +12 -0
  92. package/src/utils/parsing.js +11 -0
  93. package/src/utils.js +3 -0
  94. package/test/config.env.example +30 -0
  95. package/test/data/shareAttach.js +146 -0
  96. package/test/data/something.mov +0 -0
  97. package/test/data/test.png +0 -0
  98. package/test/data/test.txt +7 -0
  99. package/test/example-appstate.txt +11 -0
  100. package/test/integration/actions.appstate.integration.test.js +233 -0
  101. package/test/integration/api.integration.test.js +387 -0
  102. package/test/integration/env-test-config.js +46 -0
  103. package/test/integration/login.appstate.integration.test.js +47 -0
  104. package/test/integration/page.integration.test.js +139 -0
  105. package/test/jest.setup.js +54 -0
  106. package/test/unit/actions/actions.basic.test.js +116 -0
  107. package/test/unit/actions/actions.registry.test.js +36 -0
  108. package/test/unit/index/index.test.js +109 -0
  109. package/test/unit/utils/base-parts/auth.test.js +92 -0
  110. package/test/unit/utils/base-parts/formatters.test.js +53 -0
  111. package/test/unit/utils/base-parts/identity.test.js +43 -0
  112. package/test/unit/utils/base-parts/parsing.test.js +38 -0
  113. package/test/unit/utils/base-parts/type.test.js +23 -0
  114. package/test/unit/utils/base.test.js +35 -0
  115. package/vangbanlanhat-fca-unofficial-1.4.2.tgz +0 -0
@@ -0,0 +1,751 @@
1
+ /* eslint-disable no-prototype-builtins */
2
+ "use strict";
3
+
4
+ var querystring = require("querystring");
5
+ var url = require("url");
6
+
7
+ var NUM_TO_MONTH = [
8
+ "Jan",
9
+ "Feb",
10
+ "Mar",
11
+ "Apr",
12
+ "May",
13
+ "Jun",
14
+ "Jul",
15
+ "Aug",
16
+ "Sep",
17
+ "Oct",
18
+ "Nov",
19
+ "Dec"
20
+ ];
21
+ var NUM_TO_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
22
+
23
+ function _formatAttachment(attachment1, attachment2) {
24
+ attachment2 = attachment2 || { id: "", image_data: {} };
25
+ attachment1 = attachment1.mercury ? attachment1.mercury : attachment1;
26
+ var blob = attachment1.blob_attachment;
27
+ var type = blob && blob.__typename ? blob.__typename : attachment1.attach_type;
28
+
29
+ if (!type && attachment1.sticker_attachment) {
30
+ type = "StickerAttachment";
31
+ blob = attachment1.sticker_attachment;
32
+ } else if (!type && attachment1.extensible_attachment) {
33
+ if (
34
+ attachment1.extensible_attachment.story_attachment &&
35
+ attachment1.extensible_attachment.story_attachment.target &&
36
+ attachment1.extensible_attachment.story_attachment.target.__typename &&
37
+ attachment1.extensible_attachment.story_attachment.target.__typename === "MessageLocation"
38
+ ) {
39
+ type = "MessageLocation";
40
+ } else {
41
+ type = "ExtensibleAttachment";
42
+ }
43
+
44
+ blob = attachment1.extensible_attachment;
45
+ }
46
+
47
+ switch (type) {
48
+ case "sticker":
49
+ return {
50
+ type: "sticker",
51
+ ID: attachment1.metadata.stickerID.toString(),
52
+ url: attachment1.url,
53
+ packID: attachment1.metadata.packID.toString(),
54
+ spriteUrl: attachment1.metadata.spriteURI,
55
+ spriteUrl2x: attachment1.metadata.spriteURI2x,
56
+ width: attachment1.metadata.width,
57
+ height: attachment1.metadata.height,
58
+ caption: attachment2.caption,
59
+ description: attachment2.description,
60
+ frameCount: attachment1.metadata.frameCount,
61
+ frameRate: attachment1.metadata.frameRate,
62
+ framesPerRow: attachment1.metadata.framesPerRow,
63
+ framesPerCol: attachment1.metadata.framesPerCol,
64
+ stickerID: attachment1.metadata.stickerID.toString(),
65
+ spriteURI: attachment1.metadata.spriteURI,
66
+ spriteURI2x: attachment1.metadata.spriteURI2x
67
+ };
68
+ case "file":
69
+ return {
70
+ type: "file",
71
+ filename: attachment1.name,
72
+ ID: attachment2.id.toString(),
73
+ url: attachment1.url,
74
+ isMalicious: attachment2.is_malicious,
75
+ contentType: attachment2.mime_type,
76
+ name: attachment1.name,
77
+ mimeType: attachment2.mime_type,
78
+ fileSize: attachment2.file_size
79
+ };
80
+ case "photo":
81
+ return {
82
+ type: "photo",
83
+ ID: attachment1.metadata.fbid.toString(),
84
+ filename: attachment1.fileName,
85
+ thumbnailUrl: attachment1.thumbnail_url,
86
+ previewUrl: attachment1.preview_url,
87
+ previewWidth: attachment1.preview_width,
88
+ previewHeight: attachment1.preview_height,
89
+ largePreviewUrl: attachment1.large_preview_url,
90
+ largePreviewWidth: attachment1.large_preview_width,
91
+ largePreviewHeight: attachment1.large_preview_height,
92
+ url: attachment1.metadata.url,
93
+ width: attachment1.metadata.dimensions.split(",")[0],
94
+ height: attachment1.metadata.dimensions.split(",")[1],
95
+ name: attachment1.fileName
96
+ };
97
+ case "animated_image":
98
+ return {
99
+ type: "animated_image",
100
+ ID: attachment2.id.toString(),
101
+ filename: attachment2.filename,
102
+ previewUrl: attachment1.preview_url,
103
+ previewWidth: attachment1.preview_width,
104
+ previewHeight: attachment1.preview_height,
105
+ url: attachment2.image_data.url,
106
+ width: attachment2.image_data.width,
107
+ height: attachment2.image_data.height,
108
+ name: attachment1.name,
109
+ facebookUrl: attachment1.url,
110
+ thumbnailUrl: attachment1.thumbnail_url,
111
+ mimeType: attachment2.mime_type,
112
+ rawGifImage: attachment2.image_data.raw_gif_image,
113
+ rawWebpImage: attachment2.image_data.raw_webp_image,
114
+ animatedGifUrl: attachment2.image_data.animated_gif_url,
115
+ animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url,
116
+ animatedWebpUrl: attachment2.image_data.animated_webp_url,
117
+ animatedWebpPreviewUrl: attachment2.image_data.animated_webp_preview_url
118
+ };
119
+ case "share":
120
+ return {
121
+ type: "share",
122
+ ID: attachment1.share.share_id.toString(),
123
+ url: attachment2.href,
124
+ title: attachment1.share.title,
125
+ description: attachment1.share.description,
126
+ source: attachment1.share.source,
127
+ image: attachment1.share.media.image,
128
+ width: attachment1.share.media.image_size.width,
129
+ height: attachment1.share.media.image_size.height,
130
+ playable: attachment1.share.media.playable,
131
+ duration: attachment1.share.media.duration,
132
+ subattachments: attachment1.share.subattachments,
133
+ properties: {},
134
+ animatedImageSize: attachment1.share.media.animated_image_size,
135
+ facebookUrl: attachment1.share.uri,
136
+ target: attachment1.share.target,
137
+ styleList: attachment1.share.style_list
138
+ };
139
+ case "video":
140
+ return {
141
+ type: "video",
142
+ ID: attachment1.metadata.fbid.toString(),
143
+ filename: attachment1.name,
144
+ previewUrl: attachment1.preview_url,
145
+ previewWidth: attachment1.preview_width,
146
+ previewHeight: attachment1.preview_height,
147
+ url: attachment1.url,
148
+ width: attachment1.metadata.dimensions.width,
149
+ height: attachment1.metadata.dimensions.height,
150
+ duration: attachment1.metadata.duration,
151
+ videoType: "unknown",
152
+ thumbnailUrl: attachment1.thumbnail_url
153
+ };
154
+ case "error":
155
+ return {
156
+ type: "error",
157
+ attachment1: attachment1,
158
+ attachment2: attachment2
159
+ };
160
+ case "MessageImage":
161
+ return {
162
+ type: "photo",
163
+ ID: blob.legacy_attachment_id,
164
+ filename: blob.filename,
165
+ thumbnailUrl: blob.thumbnail.uri,
166
+ previewUrl: blob.preview.uri,
167
+ previewWidth: blob.preview.width,
168
+ previewHeight: blob.preview.height,
169
+ largePreviewUrl: blob.large_preview.uri,
170
+ largePreviewWidth: blob.large_preview.width,
171
+ largePreviewHeight: blob.large_preview.height,
172
+ url: blob.large_preview.uri,
173
+ width: blob.original_dimensions.x,
174
+ height: blob.original_dimensions.y,
175
+ name: blob.filename
176
+ };
177
+ case "MessageAnimatedImage":
178
+ return {
179
+ type: "animated_image",
180
+ ID: blob.legacy_attachment_id,
181
+ filename: blob.filename,
182
+ previewUrl: blob.preview_image.uri,
183
+ previewWidth: blob.preview_image.width,
184
+ previewHeight: blob.preview_image.height,
185
+ url: blob.animated_image.uri,
186
+ width: blob.animated_image.width,
187
+ height: blob.animated_image.height,
188
+ thumbnailUrl: blob.preview_image.uri,
189
+ name: blob.filename,
190
+ facebookUrl: blob.animated_image.uri,
191
+ rawGifImage: blob.animated_image.uri,
192
+ animatedGifUrl: blob.animated_image.uri,
193
+ animatedGifPreviewUrl: blob.preview_image.uri,
194
+ animatedWebpUrl: blob.animated_image.uri,
195
+ animatedWebpPreviewUrl: blob.preview_image.uri
196
+ };
197
+ case "MessageVideo":
198
+ return {
199
+ type: "video",
200
+ filename: blob.filename,
201
+ ID: blob.legacy_attachment_id,
202
+ previewUrl: blob.large_image.uri,
203
+ previewWidth: blob.large_image.width,
204
+ previewHeight: blob.large_image.height,
205
+ url: blob.playable_url,
206
+ width: blob.original_dimensions.x,
207
+ height: blob.original_dimensions.y,
208
+ duration: blob.playable_duration_in_ms,
209
+ videoType: blob.video_type.toLowerCase(),
210
+ thumbnailUrl: blob.large_image.uri
211
+ };
212
+ case "MessageAudio":
213
+ return {
214
+ type: "audio",
215
+ filename: blob.filename,
216
+ ID: blob.url_shimhash,
217
+ audioType: blob.audio_type,
218
+ duration: blob.playable_duration_in_ms,
219
+ url: blob.playable_url,
220
+ isVoiceMail: blob.is_voicemail
221
+ };
222
+ case "StickerAttachment":
223
+ return {
224
+ type: "sticker",
225
+ ID: blob.id,
226
+ url: blob.url,
227
+ packID: blob.pack ? blob.pack.id : null,
228
+ spriteUrl: blob.sprite_image,
229
+ spriteUrl2x: blob.sprite_image_2x,
230
+ width: blob.width,
231
+ height: blob.height,
232
+ caption: blob.label,
233
+ description: blob.label,
234
+ frameCount: blob.frame_count,
235
+ frameRate: blob.frame_rate,
236
+ framesPerRow: blob.frames_per_row,
237
+ framesPerCol: blob.frames_per_column,
238
+ stickerID: blob.id,
239
+ spriteURI: blob.sprite_image,
240
+ spriteURI2x: blob.sprite_image_2x
241
+ };
242
+ case "MessageLocation": {
243
+ var urlAttach = blob.story_attachment.url;
244
+ var mediaAttach = blob.story_attachment.media;
245
+
246
+ var u = querystring.parse(url.parse(urlAttach).query).u;
247
+ var where1 = querystring.parse(url.parse(u).query).where1;
248
+ var address = where1.split(", ");
249
+
250
+ var latitude;
251
+ var longitude;
252
+
253
+ try {
254
+ latitude = Number.parseFloat(address[0]);
255
+ longitude = Number.parseFloat(address[1]);
256
+ } catch (_) {
257
+ // noop
258
+ }
259
+
260
+ var imageUrl;
261
+ var width;
262
+ var height;
263
+
264
+ if (mediaAttach && mediaAttach.image) {
265
+ imageUrl = mediaAttach.image.uri;
266
+ width = mediaAttach.image.width;
267
+ height = mediaAttach.image.height;
268
+ }
269
+
270
+ return {
271
+ type: "location",
272
+ ID: blob.legacy_attachment_id,
273
+ latitude: latitude,
274
+ longitude: longitude,
275
+ image: imageUrl,
276
+ width: width,
277
+ height: height,
278
+ url: u || urlAttach,
279
+ address: where1,
280
+ facebookUrl: blob.story_attachment.url,
281
+ target: blob.story_attachment.target,
282
+ styleList: blob.story_attachment.style_list
283
+ };
284
+ }
285
+ case "ExtensibleAttachment":
286
+ return {
287
+ type: "share",
288
+ ID: blob.legacy_attachment_id,
289
+ url: blob.story_attachment.url,
290
+ title: blob.story_attachment.title_with_entities.text,
291
+ description:
292
+ blob.story_attachment.description && blob.story_attachment.description.text,
293
+ source: blob.story_attachment.source
294
+ ? blob.story_attachment.source.text
295
+ : null,
296
+ image:
297
+ blob.story_attachment.media &&
298
+ blob.story_attachment.media.image &&
299
+ blob.story_attachment.media.image.uri,
300
+ width:
301
+ blob.story_attachment.media &&
302
+ blob.story_attachment.media.image &&
303
+ blob.story_attachment.media.image.width,
304
+ height:
305
+ blob.story_attachment.media &&
306
+ blob.story_attachment.media.image &&
307
+ blob.story_attachment.media.image.height,
308
+ playable:
309
+ blob.story_attachment.media && blob.story_attachment.media.is_playable,
310
+ duration:
311
+ blob.story_attachment.media &&
312
+ blob.story_attachment.media.playable_duration_in_ms,
313
+ playableUrl:
314
+ blob.story_attachment.media == null
315
+ ? null
316
+ : blob.story_attachment.media.playable_url,
317
+ subattachments: blob.story_attachment.subattachments,
318
+ properties: blob.story_attachment.properties.reduce(function (obj, cur) {
319
+ obj[cur.key] = cur.value.text;
320
+ return obj;
321
+ }, {}),
322
+ facebookUrl: blob.story_attachment.url,
323
+ target: blob.story_attachment.target,
324
+ styleList: blob.story_attachment.style_list
325
+ };
326
+ case "MessageFile":
327
+ return {
328
+ type: "file",
329
+ filename: blob.filename,
330
+ ID: blob.message_file_fbid,
331
+ url: blob.url,
332
+ isMalicious: blob.is_malicious,
333
+ contentType: blob.content_type,
334
+ name: blob.filename,
335
+ mimeType: "",
336
+ fileSize: -1
337
+ };
338
+ default:
339
+ throw new Error(
340
+ "unrecognized attach_file of type " +
341
+ type +
342
+ "`" +
343
+ JSON.stringify(attachment1, null, 4) +
344
+ " attachment2: " +
345
+ JSON.stringify(attachment2, null, 4) +
346
+ "`"
347
+ );
348
+ }
349
+ }
350
+
351
+ function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
352
+ attachmentMap = shareMap || attachmentMap;
353
+ return attachments
354
+ ? attachments.map(function (val, i) {
355
+ if (!attachmentMap || !attachmentIds || !attachmentMap[attachmentIds[i]]) {
356
+ return _formatAttachment(val);
357
+ }
358
+ return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
359
+ })
360
+ : [];
361
+ }
362
+
363
+ function formatID(id) {
364
+ if (id != undefined && id != null) {
365
+ return id.replace(/(fb)?id[:.]/, "");
366
+ }
367
+ return id;
368
+ }
369
+
370
+ function formatDeltaMessage(m) {
371
+ var md = m.delta.messageMetadata;
372
+ var body = m.delta.body || "";
373
+
374
+ function splitCsv(value) {
375
+ if (Array.isArray(value)) return value;
376
+ if (typeof value !== "string") return [];
377
+ return value
378
+ .split(",")
379
+ .map(function (v) { return v.trim(); })
380
+ .filter(function (v) { return v !== ""; });
381
+ }
382
+
383
+ function fillMentionsFromTriples(target, ids, offsets, lengths) {
384
+ var max = Math.min(ids.length, offsets.length, lengths.length);
385
+ for (var i = 0; i < max; i++) {
386
+ var id = String(ids[i] || "").trim();
387
+ if (!id) continue;
388
+
389
+ var offset = parseInt(offsets[i], 10);
390
+ var length = parseInt(lengths[i], 10);
391
+ if (isNaN(offset) || isNaN(length) || length <= 0) continue;
392
+
393
+ target[id] = body.substring(offset, offset + length);
394
+ }
395
+ }
396
+
397
+ function readFbTypedValue(node) {
398
+ if (!node || typeof node !== "object") return undefined;
399
+ if (node.asString != null) return node.asString;
400
+ if (node.asLong != null) return node.asLong;
401
+ if (node.asInt != null) return node.asInt;
402
+ return undefined;
403
+ }
404
+
405
+ function getGbMentionMapFromMetadata(metadata) {
406
+ if (!metadata || typeof metadata !== "object") return null;
407
+ var d = metadata.data || {};
408
+ var nested = d.data || {};
409
+ var gb = nested.Gb || d.Gb;
410
+ var map = gb && gb.asMap && gb.asMap.data;
411
+ return map && typeof map === "object" ? map : null;
412
+ }
413
+
414
+ var mdata =
415
+ m.delta.data === undefined
416
+ ? []
417
+ : m.delta.data.prng === undefined
418
+ ? []
419
+ : JSON.parse(m.delta.data.prng);
420
+ var m_id = mdata.map(function (u) { return u.i; });
421
+ var m_offset = mdata.map(function (u) { return u.o; });
422
+ var m_length = mdata.map(function (u) { return u.l; });
423
+ var mentions = {};
424
+ fillMentionsFromTriples(mentions, m_id, m_offset, m_length);
425
+
426
+ // Some payloads provide mentions as CSV fields instead of prng JSON.
427
+ if (Object.keys(mentions).length === 0) {
428
+ var d = m.delta.data || {};
429
+ fillMentionsFromTriples(
430
+ mentions,
431
+ splitCsv(d.mention_ids || m.delta.mention_ids),
432
+ splitCsv(d.mention_offsets || m.delta.mention_offsets),
433
+ splitCsv(d.mention_lengths || m.delta.mention_lengths)
434
+ );
435
+ }
436
+
437
+ // Fallback for range-based metadata variants.
438
+ if (Object.keys(mentions).length === 0) {
439
+ var ranges = [];
440
+ if (Array.isArray(m.delta.ranges)) ranges = m.delta.ranges;
441
+ else if (Array.isArray((m.delta.data || {}).ranges)) ranges = m.delta.data.ranges;
442
+ else if (Array.isArray(m.delta.profileRanges)) ranges = m.delta.profileRanges;
443
+
444
+ ranges.forEach(function (r) {
445
+ var id =
446
+ (r && r.entity && r.entity.id) ||
447
+ (r && r.id) ||
448
+ (r && r.i);
449
+ var offset = (r && (r.offset != null ? r.offset : r.o));
450
+ var length = (r && (r.length != null ? r.length : r.l));
451
+ fillMentionsFromTriples(mentions, [id], [offset], [length]);
452
+ });
453
+ }
454
+
455
+ // Newer payload variant stores mention entries in messageMetadata.data.data.Gb.asMap.data.
456
+ if (Object.keys(mentions).length === 0) {
457
+ var gbMap = getGbMentionMapFromMetadata(md);
458
+ if (gbMap) {
459
+ var ids = [];
460
+ var offsets = [];
461
+ var lengths = [];
462
+
463
+ Object.keys(gbMap).forEach(function (k) {
464
+ var row = gbMap[k] && gbMap[k].asMap && gbMap[k].asMap.data;
465
+ if (!row) return;
466
+ ids.push(readFbTypedValue(row.id));
467
+ offsets.push(readFbTypedValue(row.offset));
468
+ lengths.push(readFbTypedValue(row.length));
469
+ });
470
+
471
+ fillMentionsFromTriples(mentions, ids, offsets, lengths);
472
+ }
473
+ }
474
+
475
+ return {
476
+ type: "message",
477
+ senderID: formatID(md.actorFbId.toString()),
478
+ body: body,
479
+ threadID: formatID((md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()),
480
+ messageID: md.messageId,
481
+ attachments: (m.delta.attachments || []).map(function (v) { return _formatAttachment(v); }),
482
+ mentions: mentions,
483
+ timestamp: md.timestamp,
484
+ isGroup: !!md.threadKey.threadFbId
485
+ };
486
+ }
487
+
488
+ function formatMessage(m) {
489
+ var originalMessage = m.message ? m.message : m;
490
+ var obj = {
491
+ type: "message",
492
+ senderName: originalMessage.sender_name,
493
+ senderID: formatID(originalMessage.sender_fbid.toString()),
494
+ participantNames: originalMessage.group_thread_info
495
+ ? originalMessage.group_thread_info.participant_names
496
+ : [originalMessage.sender_name.split(" ")[0]],
497
+ participantIDs: originalMessage.group_thread_info
498
+ ? originalMessage.group_thread_info.participant_ids.map(function (v) {
499
+ return formatID(v.toString());
500
+ })
501
+ : [formatID(originalMessage.sender_fbid)],
502
+ body: originalMessage.body || "",
503
+ threadID: formatID((originalMessage.thread_fbid || originalMessage.other_user_fbid).toString()),
504
+ threadName: originalMessage.group_thread_info
505
+ ? originalMessage.group_thread_info.name
506
+ : originalMessage.sender_name,
507
+ location: originalMessage.coordinates ? originalMessage.coordinates : null,
508
+ messageID: originalMessage.mid
509
+ ? originalMessage.mid.toString()
510
+ : originalMessage.message_id,
511
+ attachments: formatAttachment(
512
+ originalMessage.attachments,
513
+ originalMessage.attachmentIds,
514
+ originalMessage.attachment_map,
515
+ originalMessage.share_map
516
+ ),
517
+ timestamp: originalMessage.timestamp,
518
+ timestampAbsolute: originalMessage.timestamp_absolute,
519
+ timestampRelative: originalMessage.timestamp_relative,
520
+ timestampDatetime: originalMessage.timestamp_datetime,
521
+ tags: originalMessage.tags,
522
+ reactions: originalMessage.reactions ? originalMessage.reactions : [],
523
+ isUnread: originalMessage.is_unread
524
+ };
525
+
526
+ if (m.type === "pages_messaging") {
527
+ obj.pageID = m.realtime_viewer_fbid.toString();
528
+ }
529
+ obj.isGroup = obj.participantIDs.length > 2;
530
+
531
+ return obj;
532
+ }
533
+
534
+ function formatEvent(m) {
535
+ var originalMessage = m.message ? m.message : m;
536
+ var logMessageType = originalMessage.log_message_type;
537
+ var logMessageData;
538
+ if (logMessageType === "log:generic-admin-text") {
539
+ logMessageData = originalMessage.log_message_data.untypedData;
540
+ logMessageType = getAdminTextMessageType(
541
+ originalMessage.log_message_data.message_type
542
+ );
543
+ } else {
544
+ logMessageData = originalMessage.log_message_data;
545
+ }
546
+
547
+ return Object.assign(formatMessage(originalMessage), {
548
+ type: "event",
549
+ logMessageType: logMessageType,
550
+ logMessageData: logMessageData,
551
+ logMessageBody: originalMessage.log_message_body
552
+ });
553
+ }
554
+
555
+ function formatHistoryMessage(m) {
556
+ switch (m.action_type) {
557
+ case "ma-type:log-message":
558
+ return formatEvent(m);
559
+ default:
560
+ return formatMessage(m);
561
+ }
562
+ }
563
+
564
+ function getAdminTextMessageType(type) {
565
+ switch (type) {
566
+ case "change_thread_theme":
567
+ return "log:thread-color";
568
+ case "change_thread_nickname":
569
+ return "log:user-nickname";
570
+ case "change_thread_icon":
571
+ return "log:thread-icon";
572
+ default:
573
+ return type;
574
+ }
575
+ }
576
+
577
+ function formatDeltaEvent(m) {
578
+ var logMessageType;
579
+ var logMessageData;
580
+
581
+ switch (m.class) {
582
+ case "AdminTextMessage":
583
+ logMessageData = m.untypedData;
584
+ logMessageType = getAdminTextMessageType(m.type);
585
+ break;
586
+ case "ThreadName":
587
+ logMessageType = "log:thread-name";
588
+ logMessageData = { name: m.name };
589
+ break;
590
+ case "ParticipantsAddedToGroupThread":
591
+ logMessageType = "log:subscribe";
592
+ logMessageData = { addedParticipants: m.addedParticipants };
593
+ break;
594
+ case "ParticipantLeftGroupThread":
595
+ logMessageType = "log:unsubscribe";
596
+ logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
597
+ break;
598
+ }
599
+
600
+ return {
601
+ type: "event",
602
+ threadID: formatID((m.messageMetadata.threadKey.threadFbId || m.messageMetadata.threadKey.otherUserFbId).toString()),
603
+ logMessageType: logMessageType,
604
+ logMessageData: logMessageData,
605
+ logMessageBody: m.messageMetadata.adminText,
606
+ author: m.messageMetadata.actorFbId,
607
+ participantIDs: m.participants || []
608
+ };
609
+ }
610
+
611
+ function formatTyp(event) {
612
+ return {
613
+ isTyping: !!event.st,
614
+ from: event.from.toString(),
615
+ threadID: formatID((event.to || event.thread_fbid || event.from).toString()),
616
+ fromMobile: event.hasOwnProperty("from_mobile") ? event.from_mobile : true,
617
+ userID: (event.realtime_viewer_fbid || event.from).toString(),
618
+ type: "typ"
619
+ };
620
+ }
621
+
622
+ function formatDeltaReadReceipt(delta) {
623
+ return {
624
+ reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
625
+ time: delta.actionTimestampMs,
626
+ threadID: formatID((delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()),
627
+ type: "read_receipt"
628
+ };
629
+ }
630
+
631
+ function formatReadReceipt(event) {
632
+ return {
633
+ reader: event.reader.toString(),
634
+ time: event.time,
635
+ threadID: formatID((event.thread_fbid || event.reader).toString()),
636
+ type: "read_receipt"
637
+ };
638
+ }
639
+
640
+ function formatRead(event) {
641
+ return {
642
+ threadID: formatID(((event.chat_ids && event.chat_ids[0]) || (event.thread_fbids && event.thread_fbids[0])).toString()),
643
+ time: event.timestamp,
644
+ type: "read"
645
+ };
646
+ }
647
+
648
+ function formatDate(date) {
649
+ var d = date.getUTCDate();
650
+ d = d >= 10 ? d : "0" + d;
651
+ var h = date.getUTCHours();
652
+ h = h >= 10 ? h : "0" + h;
653
+ var m = date.getUTCMinutes();
654
+ m = m >= 10 ? m : "0" + m;
655
+ var s = date.getUTCSeconds();
656
+ s = s >= 10 ? s : "0" + s;
657
+ return (
658
+ NUM_TO_DAY[date.getUTCDay()] +
659
+ ", " +
660
+ d +
661
+ " " +
662
+ NUM_TO_MONTH[date.getUTCMonth()] +
663
+ " " +
664
+ date.getUTCFullYear() +
665
+ " " +
666
+ h +
667
+ ":" +
668
+ m +
669
+ ":" +
670
+ s +
671
+ " GMT"
672
+ );
673
+ }
674
+
675
+ function formatCookie(arr, targetUrl) {
676
+ return arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + targetUrl + ".com";
677
+ }
678
+
679
+ function formatThread(data) {
680
+ return {
681
+ threadID: formatID(data.thread_fbid.toString()),
682
+ participants: data.participants.map(formatID),
683
+ participantIDs: data.participants.map(formatID),
684
+ name: data.name,
685
+ nicknames: data.custom_nickname,
686
+ snippet: data.snippet,
687
+ snippetAttachments: data.snippet_attachments,
688
+ snippetSender: formatID((data.snippet_sender || "").toString()),
689
+ unreadCount: data.unread_count,
690
+ messageCount: data.message_count,
691
+ imageSrc: data.image_src,
692
+ timestamp: data.timestamp,
693
+ serverTimestamp: data.server_timestamp,
694
+ muteUntil: data.mute_until,
695
+ isCanonicalUser: data.is_canonical_user,
696
+ isCanonical: data.is_canonical,
697
+ isSubscribed: data.is_subscribed,
698
+ folder: data.folder,
699
+ isArchived: data.is_archived,
700
+ recipientsLoadable: data.recipients_loadable,
701
+ hasEmailParticipant: data.has_email_participant,
702
+ readOnly: data.read_only,
703
+ canReply: data.can_reply,
704
+ cannotReplyReason: data.cannot_reply_reason,
705
+ lastMessageTimestamp: data.last_message_timestamp,
706
+ lastReadTimestamp: data.last_read_timestamp,
707
+ lastMessageType: data.last_message_type,
708
+ emoji: data.custom_like_icon,
709
+ color: data.custom_color,
710
+ adminIDs: data.admin_ids,
711
+ threadType: data.thread_type
712
+ };
713
+ }
714
+
715
+ function formatProxyPresence(presence, userID) {
716
+ if (presence.lat === undefined || presence.p === undefined) return null;
717
+ return {
718
+ type: "presence",
719
+ timestamp: presence.lat * 1000,
720
+ userID: userID,
721
+ statuses: presence.p
722
+ };
723
+ }
724
+
725
+ function formatPresence(presence, userID) {
726
+ return {
727
+ type: "presence",
728
+ timestamp: presence.la * 1000,
729
+ userID: userID,
730
+ statuses: presence.a
731
+ };
732
+ }
733
+
734
+ module.exports = {
735
+ _formatAttachment,
736
+ formatHistoryMessage,
737
+ formatID,
738
+ formatMessage,
739
+ formatDeltaEvent,
740
+ formatDeltaMessage,
741
+ formatProxyPresence,
742
+ formatPresence,
743
+ formatTyp,
744
+ formatDeltaReadReceipt,
745
+ formatCookie,
746
+ formatThread,
747
+ formatReadReceipt,
748
+ formatRead,
749
+ formatDate,
750
+ getAdminTextMessageType
751
+ };