fca-zoebakaaa 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. package/.eslintrc.js +35 -0
  2. package/CHANGELOG.md +2 -0
  3. package/Controllers/Remote.js +4 -0
  4. package/DOCS.md +1738 -0
  5. package/Extra/ExtraAddons.js +80 -0
  6. package/Extra/ExtraFindUID.js +62 -0
  7. package/Extra/ExtraGetThread.js +118 -0
  8. package/Extra/ExtraTranslate.js +62 -0
  9. package/Extra/ExtraUptimeRobot.js +62 -0
  10. package/Extra/Html/Classic/script.js +233 -0
  11. package/Extra/Html/Classic/style.css +8 -0
  12. package/Extra/PM2/ecosystem.config.js +23 -0
  13. package/Extra/Security/Index.js +174 -0
  14. package/Extra/Security/Step_1.js +15 -0
  15. package/Extra/Security/Step_2.js +23 -0
  16. package/Extra/Security/Step_3.js +23 -0
  17. package/Extra/Src/History.js +117 -0
  18. package/Extra/Src/Last-Run.js +65 -0
  19. package/Extra/Src/Premium.js +88 -0
  20. package/Extra/Src/SecurityCheck.js +7 -0
  21. package/Extra/database/SyntheticDatabase.sqlite +0 -0
  22. package/Extra/database/index.js +360 -0
  23. package/Extra/logger.js +74 -0
  24. package/Func/AcceptAgreement.js +36 -0
  25. package/Func/ClearCache.js +68 -0
  26. package/Func/ReportV1.js +55 -0
  27. package/README.md +112 -0
  28. package/Settings/Database.js +21 -0
  29. package/Settings/Location.js +59 -0
  30. package/broadcast.js +40 -0
  31. package/index.js +1353 -0
  32. package/logger.js +75 -0
  33. package/package.json +56 -0
  34. package/src/Premium.js +39 -0
  35. package/src/addExternalModule.js +23 -0
  36. package/src/addUserToGroup.js +101 -0
  37. package/src/appstate.json +0 -0
  38. package/src/changeAdminStatus.js +95 -0
  39. package/src/changeArchivedStatus.js +47 -0
  40. package/src/changeAvt.js +95 -0
  41. package/src/changeBio.js +66 -0
  42. package/src/changeBlockedStatus.js +42 -0
  43. package/src/changeGroupImage.js +124 -0
  44. package/src/changeNickname.js +54 -0
  45. package/src/changeThreadColor.js +67 -0
  46. package/src/changeThreadEmoji.js +50 -0
  47. package/src/createNewGroup.js +78 -0
  48. package/src/createPoll.js +66 -0
  49. package/src/deleteMessage.js +51 -0
  50. package/src/deleteThread.js +49 -0
  51. package/src/forwardAttachment.js +53 -0
  52. package/src/getAccessToken.js +36 -0
  53. package/src/getCurrentUserID.js +8 -0
  54. package/src/getEmojiUrl.js +29 -0
  55. package/src/getFriendsList.js +81 -0
  56. package/src/getMessage.js +85 -0
  57. package/src/getThreadHistory.js +633 -0
  58. package/src/getThreadInfo.js +248 -0
  59. package/src/getThreadList.js +276 -0
  60. package/src/getThreadPictures.js +71 -0
  61. package/src/getUID.js +61 -0
  62. package/src/getUserID.js +62 -0
  63. package/src/getUserInfo.js +68 -0
  64. package/src/getUserInfoV2.js +32 -0
  65. package/src/getUserInfoV3.js +72 -0
  66. package/src/getUserInfoV4.js +57 -0
  67. package/src/getUserInfoV5.js +68 -0
  68. package/src/handleFriendRequest.js +47 -0
  69. package/src/handleMessageRequest.js +63 -0
  70. package/src/httpGet.js +54 -0
  71. package/src/httpPost.js +53 -0
  72. package/src/httpPostFormData.js +46 -0
  73. package/src/listenMqtt.js +1056 -0
  74. package/src/logout.js +73 -0
  75. package/src/markAsDelivered.js +54 -0
  76. package/src/markAsRead.js +82 -0
  77. package/src/markAsReadAll.js +47 -0
  78. package/src/markAsSeen.js +58 -0
  79. package/src/muteThread.js +51 -0
  80. package/src/removeUserFromGroup.js +72 -0
  81. package/src/resolvePhotoUrl.js +39 -0
  82. package/src/searchForThread.js +48 -0
  83. package/src/sendMessage.js +429 -0
  84. package/src/sendTypingIndicator.js +83 -0
  85. package/src/setMessageReaction.js +114 -0
  86. package/src/setPostReaction.js +103 -0
  87. package/src/setTitle.js +86 -0
  88. package/src/threadColors.js +40 -0
  89. package/src/toolspincoinmaster +89 -0
  90. package/src/unfriend.js +48 -0
  91. package/src/unsendMessage.js +40 -0
  92. package/utils.js +2244 -0
  93. package/zoebaka.code-workspace +8 -0
@@ -0,0 +1,633 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ function formatAttachmentsGraphQLResponse(attachment) {
7
+ switch (attachment.__typename) {
8
+ case "MessageImage":
9
+ return {
10
+ type: "photo",
11
+ ID: attachment.legacy_attachment_id,
12
+ filename: attachment.filename,
13
+ thumbnailUrl: attachment.thumbnail.uri,
14
+
15
+ previewUrl: attachment.preview.uri,
16
+ previewWidth: attachment.preview.width,
17
+ previewHeight: attachment.preview.height,
18
+
19
+ largePreviewUrl: attachment.large_preview.uri,
20
+ largePreviewHeight: attachment.large_preview.height,
21
+ largePreviewWidth: attachment.large_preview.width,
22
+
23
+ // You have to query for the real image. See below.
24
+ url: attachment.large_preview.uri, // @Legacy
25
+ width: attachment.large_preview.width, // @Legacy
26
+ height: attachment.large_preview.height, // @Legacy
27
+ name: attachment.filename, // @Legacy
28
+
29
+ // @Undocumented
30
+ attributionApp: attachment.attribution_app
31
+ ? {
32
+ attributionAppID: attachment.attribution_app.id,
33
+ name: attachment.attribution_app.name,
34
+ logo: attachment.attribution_app.square_logo,
35
+ }
36
+ : null,
37
+
38
+ // @TODO No idea what this is, should we expose it?
39
+ // Ben - July 15th 2017
40
+ // renderAsSticker: attachment.render_as_sticker,
41
+
42
+ // This is _not_ the real URI, this is still just a large preview.
43
+ // To get the URL we'll need to support a POST query to
44
+ //
45
+ // https://www.facebook.com/webgraphql/query/
46
+ //
47
+ // With the following query params:
48
+ //
49
+ // query_id:728987990612546
50
+ // variables:{"id":"100009069356507","photoID":"10213724771692996"}
51
+ // dpr:1
52
+ //
53
+ // No special form though.
54
+ };
55
+ case "MessageAnimatedImage":
56
+ return {
57
+ type: "animated_image",
58
+ ID: attachment.legacy_attachment_id,
59
+ filename: attachment.filename,
60
+
61
+ previewUrl: attachment.preview_image.uri,
62
+ previewWidth: attachment.preview_image.width,
63
+ previewHeight: attachment.preview_image.height,
64
+
65
+ url: attachment.animated_image.uri,
66
+ width: attachment.animated_image.width,
67
+ height: attachment.animated_image.height,
68
+
69
+ thumbnailUrl: attachment.preview_image.uri, // @Legacy
70
+ name: attachment.filename, // @Legacy
71
+ facebookUrl: attachment.animated_image.uri, // @Legacy
72
+ rawGifImage: attachment.animated_image.uri, // @Legacy
73
+ animatedGifUrl: attachment.animated_image.uri, // @Legacy
74
+ animatedGifPreviewUrl: attachment.preview_image.uri, // @Legacy
75
+ animatedWebpUrl: attachment.animated_image.uri, // @Legacy
76
+ animatedWebpPreviewUrl: attachment.preview_image.uri, // @Legacy
77
+
78
+ // @Undocumented
79
+ attributionApp: attachment.attribution_app
80
+ ? {
81
+ attributionAppID: attachment.attribution_app.id,
82
+ name: attachment.attribution_app.name,
83
+ logo: attachment.attribution_app.square_logo,
84
+ }
85
+ : null,
86
+ };
87
+ case "MessageVideo":
88
+ return {
89
+ type: "video",
90
+ filename: attachment.filename,
91
+ ID: attachment.legacy_attachment_id,
92
+
93
+ thumbnailUrl: attachment.large_image.uri, // @Legacy
94
+
95
+ previewUrl: attachment.large_image.uri,
96
+ previewWidth: attachment.large_image.width,
97
+ previewHeight: attachment.large_image.height,
98
+
99
+ url: attachment.playable_url,
100
+ width: attachment.original_dimensions.x,
101
+ height: attachment.original_dimensions.y,
102
+
103
+ duration: attachment.playable_duration_in_ms,
104
+ videoType: attachment.video_type.toLowerCase(),
105
+ };
106
+ case "MessageFile":
107
+ return {
108
+ type: "file",
109
+ filename: attachment.filename,
110
+ ID: attachment.message_file_fbid,
111
+
112
+ url: attachment.url,
113
+ isMalicious: attachment.is_malicious,
114
+ contentType: attachment.content_type,
115
+
116
+ name: attachment.filename, // @Legacy
117
+ mimeType: "", // @Legacy
118
+ fileSize: -1, // @Legacy
119
+ };
120
+ case "MessageAudio":
121
+ return {
122
+ type: "audio",
123
+ filename: attachment.filename,
124
+ ID: attachment.url_shimhash, // Not fowardable
125
+
126
+ audioType: attachment.audio_type,
127
+ duration: attachment.playable_duration_in_ms,
128
+ url: attachment.playable_url,
129
+
130
+ isVoiceMail: attachment.is_voicemail,
131
+ };
132
+ default:
133
+ return {
134
+ error: "Don't know about attachment type " + attachment.__typename,
135
+ };
136
+ }
137
+ }
138
+
139
+ function formatExtensibleAttachment(attachment) {
140
+ if (attachment.story_attachment) {
141
+ return {
142
+ type: "share",
143
+ ID: attachment.legacy_attachment_id,
144
+ url: attachment.story_attachment.url,
145
+
146
+ title: attachment.story_attachment.title_with_entities.text,
147
+ description:
148
+ attachment.story_attachment.description &&
149
+ attachment.story_attachment.description.text,
150
+ source:
151
+ attachment.story_attachment.source == null
152
+ ? null
153
+ : attachment.story_attachment.source.text,
154
+
155
+ image:
156
+ attachment.story_attachment.media == null
157
+ ? null
158
+ : attachment.story_attachment.media.animated_image == null &&
159
+ attachment.story_attachment.media.image == null
160
+ ? null
161
+ : (
162
+ attachment.story_attachment.media.animated_image ||
163
+ attachment.story_attachment.media.image
164
+ ).uri,
165
+ width:
166
+ attachment.story_attachment.media == null
167
+ ? null
168
+ : attachment.story_attachment.media.animated_image == null &&
169
+ attachment.story_attachment.media.image == null
170
+ ? null
171
+ : (
172
+ attachment.story_attachment.media.animated_image ||
173
+ attachment.story_attachment.media.image
174
+ ).width,
175
+ height:
176
+ attachment.story_attachment.media == null
177
+ ? null
178
+ : attachment.story_attachment.media.animated_image == null &&
179
+ attachment.story_attachment.media.image == null
180
+ ? null
181
+ : (
182
+ attachment.story_attachment.media.animated_image ||
183
+ attachment.story_attachment.media.image
184
+ ).height,
185
+ playable:
186
+ attachment.story_attachment.media == null
187
+ ? null
188
+ : attachment.story_attachment.media.is_playable,
189
+ duration:
190
+ attachment.story_attachment.media == null
191
+ ? null
192
+ : attachment.story_attachment.media.playable_duration_in_ms,
193
+ playableUrl:
194
+ attachment.story_attachment.media == null
195
+ ? null
196
+ : attachment.story_attachment.media.playable_url,
197
+
198
+ subattachments: attachment.story_attachment.subattachments,
199
+
200
+ // Format example:
201
+ //
202
+ // [{
203
+ // key: "width",
204
+ // value: { text: "1280" }
205
+ // }]
206
+ //
207
+ // That we turn into:
208
+ //
209
+ // {
210
+ // width: "1280"
211
+ // }
212
+ //
213
+ properties: attachment.story_attachment.properties.reduce(function (
214
+ obj,
215
+ cur,
216
+ ) {
217
+ obj[cur.key] = cur.value.text;
218
+ return obj;
219
+ }, {}),
220
+
221
+ // Deprecated fields
222
+ animatedImageSize: "", // @Legacy
223
+ facebookUrl: "", // @Legacy
224
+ styleList: "", // @Legacy
225
+ target: "", // @Legacy
226
+ thumbnailUrl:
227
+ attachment.story_attachment.media == null
228
+ ? null
229
+ : attachment.story_attachment.media.animated_image == null &&
230
+ attachment.story_attachment.media.image == null
231
+ ? null
232
+ : (
233
+ attachment.story_attachment.media.animated_image ||
234
+ attachment.story_attachment.media.image
235
+ ).uri, // @Legacy
236
+ thumbnailWidth:
237
+ attachment.story_attachment.media == null
238
+ ? null
239
+ : attachment.story_attachment.media.animated_image == null &&
240
+ attachment.story_attachment.media.image == null
241
+ ? null
242
+ : (
243
+ attachment.story_attachment.media.animated_image ||
244
+ attachment.story_attachment.media.image
245
+ ).width, // @Legacy
246
+ thumbnailHeight:
247
+ attachment.story_attachment.media == null
248
+ ? null
249
+ : attachment.story_attachment.media.animated_image == null &&
250
+ attachment.story_attachment.media.image == null
251
+ ? null
252
+ : (
253
+ attachment.story_attachment.media.animated_image ||
254
+ attachment.story_attachment.media.image
255
+ ).height, // @Legacy
256
+ };
257
+ } else return { error: "Don't know what to do with extensible_attachment." };
258
+ }
259
+
260
+ function formatReactionsGraphQL(reaction) {
261
+ return {
262
+ reaction: reaction.reaction,
263
+ userID: reaction.user.id,
264
+ };
265
+ }
266
+
267
+ function formatEventData(event) {
268
+ if (event == null) return {};
269
+
270
+ switch (event.__typename) {
271
+ case "ThemeColorExtensibleMessageAdminText":
272
+ return { color: event.theme_color };
273
+ case "ThreadNicknameExtensibleMessageAdminText":
274
+ return {
275
+ nickname: event.nickname,
276
+ participantID: event.participant_id,
277
+ };
278
+ case "ThreadIconExtensibleMessageAdminText":
279
+ return { threadIcon: event.thread_icon };
280
+ case "InstantGameUpdateExtensibleMessageAdminText":
281
+ return {
282
+ gameID: event.game == null ? null : event.game.id,
283
+ update_type: event.update_type,
284
+ collapsed_text: event.collapsed_text,
285
+ expanded_text: event.expanded_text,
286
+ instant_game_update_data: event.instant_game_update_data,
287
+ };
288
+ case "GameScoreExtensibleMessageAdminText":
289
+ return { game_type: event.game_type };
290
+ case "RtcCallLogExtensibleMessageAdminText":
291
+ return {
292
+ event: event.event,
293
+ is_video_call: event.is_video_call,
294
+ server_info_data: event.server_info_data,
295
+ };
296
+ case "GroupPollExtensibleMessageAdminText":
297
+ return {
298
+ event_type: event.event_type,
299
+ total_count: event.total_count,
300
+ question: event.question,
301
+ };
302
+ case "AcceptPendingThreadExtensibleMessageAdminText":
303
+ return {
304
+ accepter_id: event.accepter_id,
305
+ requester_id: event.requester_id,
306
+ };
307
+ case "ConfirmFriendRequestExtensibleMessageAdminText":
308
+ return {
309
+ friend_request_recipient: event.friend_request_recipient,
310
+ friend_request_sender: event.friend_request_sender,
311
+ };
312
+ case "AddContactExtensibleMessageAdminText":
313
+ return {
314
+ contact_added_id: event.contact_added_id,
315
+ contact_adder_id: event.contact_adder_id,
316
+ };
317
+ case "AdExtensibleMessageAdminText":
318
+ return {
319
+ ad_client_token: event.ad_client_token,
320
+ ad_id: event.ad_id,
321
+ ad_preferences_link: event.ad_preferences_link,
322
+ ad_properties: event.ad_properties,
323
+ };
324
+ // never data
325
+ case "ParticipantJoinedGroupCallExtensibleMessageAdminText":
326
+ case "ThreadEphemeralTtlModeExtensibleMessageAdminText":
327
+ case "StartedSharingVideoExtensibleMessageAdminText":
328
+ case "LightweightEventCreateExtensibleMessageAdminText":
329
+ case "LightweightEventNotifyExtensibleMessageAdminText":
330
+ case "LightweightEventNotifyBeforeEventExtensibleMessageAdminText":
331
+ case "LightweightEventUpdateTitleExtensibleMessageAdminText":
332
+ case "LightweightEventUpdateTimeExtensibleMessageAdminText":
333
+ case "LightweightEventUpdateLocationExtensibleMessageAdminText":
334
+ case "LightweightEventDeleteExtensibleMessageAdminText":
335
+ return {};
336
+ default:
337
+ return {
338
+ error: "Don't know what to with event data type " + event.__typename,
339
+ };
340
+ }
341
+ }
342
+
343
+ function formatMessagesGraphQLResponse(data) {
344
+ var messageThread = data.o0.data.message_thread;
345
+ var threadID = messageThread.thread_key.thread_fbid
346
+ ? messageThread.thread_key.thread_fbid
347
+ : messageThread.thread_key.other_user_id;
348
+
349
+ var messages = messageThread.messages.nodes.map(function (d) {
350
+ switch (d.__typename) {
351
+ case "UserMessage":
352
+ // Give priority to stickers. They're seen as normal messages but we've
353
+ // been considering them as attachments.
354
+ var maybeStickerAttachment;
355
+ if (d.sticker) {
356
+ maybeStickerAttachment = [
357
+ {
358
+ type: "sticker",
359
+ ID: d.sticker.id,
360
+ url: d.sticker.url,
361
+
362
+ packID: d.sticker.pack.id,
363
+ spriteUrl: d.sticker.sprite_image,
364
+ spriteUrl2x: d.sticker.sprite_image_2x,
365
+ width: d.sticker.width,
366
+ height: d.sticker.height,
367
+
368
+ caption: d.snippet, // Not sure what the heck caption was.
369
+ description: d.sticker.label, // Not sure about this one either.
370
+
371
+ frameCount: d.sticker.frame_count,
372
+ frameRate: d.sticker.frame_rate,
373
+ framesPerRow: d.sticker.frames_per_row,
374
+ framesPerCol: d.sticker.frames_per_col,
375
+
376
+ stickerID: d.sticker.id, // @Legacy
377
+ spriteURI: d.sticker.sprite_image, // @Legacy
378
+ spriteURI2x: d.sticker.sprite_image_2x, // @Legacy
379
+ },
380
+ ];
381
+ }
382
+
383
+ var mentionsObj = {};
384
+ if (d.message !== null) {
385
+ d.message.ranges.forEach(
386
+ (e) =>
387
+ (mentionsObj[e.entity.id] = d.message.text.substr(
388
+ e.offset,
389
+ e.length,
390
+ )),
391
+ );
392
+ }
393
+
394
+ return {
395
+ type: "message",
396
+ attachments: maybeStickerAttachment
397
+ ? maybeStickerAttachment
398
+ : d.blob_attachments && d.blob_attachments.length > 0
399
+ ? d.blob_attachments.map(formatAttachmentsGraphQLResponse)
400
+ : d.extensible_attachment
401
+ ? [formatExtensibleAttachment(d.extensible_attachment)]
402
+ : [],
403
+ body: d.message !== null ? d.message.text : "",
404
+ isGroup: messageThread.thread_type === "GROUP",
405
+ messageID: d.message_id,
406
+ senderID: d.message_sender.id,
407
+ threadID: threadID,
408
+ timestamp: d.timestamp_precise,
409
+
410
+ mentions: mentionsObj,
411
+ isUnread: d.unread,
412
+
413
+ // New
414
+ messageReactions: d.message_reactions
415
+ ? d.message_reactions.map(formatReactionsGraphQL)
416
+ : null,
417
+ isSponsored: d.is_sponsored,
418
+ snippet: d.snippet,
419
+ };
420
+ case "ThreadNameMessage":
421
+ return {
422
+ type: "event",
423
+ messageID: d.message_id,
424
+ threadID: threadID,
425
+ isGroup: messageThread.thread_type === "GROUP",
426
+ senderID: d.message_sender.id,
427
+ timestamp: d.timestamp_precise,
428
+ eventType: "change_thread_name",
429
+ snippet: d.snippet,
430
+ eventData: { threadName: d.thread_name },
431
+
432
+ // @Legacy
433
+ author: d.message_sender.id,
434
+ logMessageType: "log:thread-name",
435
+ logMessageData: { name: d.thread_name },
436
+ };
437
+ case "ThreadImageMessage":
438
+ return {
439
+ type: "event",
440
+ messageID: d.message_id,
441
+ threadID: threadID,
442
+ isGroup: messageThread.thread_type === "GROUP",
443
+ senderID: d.message_sender.id,
444
+ timestamp: d.timestamp_precise,
445
+ eventType: "change_thread_image",
446
+ snippet: d.snippet,
447
+ eventData:
448
+ d.image_with_metadata == null
449
+ ? {} /* removed image */
450
+ : {
451
+ /* image added */
452
+ threadImage: {
453
+ attachmentID: d.image_with_metadata.legacy_attachment_id,
454
+ width: d.image_with_metadata.original_dimensions.x,
455
+ height: d.image_with_metadata.original_dimensions.y,
456
+ url: d.image_with_metadata.preview.uri,
457
+ },
458
+ },
459
+
460
+ // @Legacy
461
+ logMessageType: "log:thread-icon",
462
+ logMessageData: {
463
+ thread_icon: d.image_with_metadata
464
+ ? d.image_with_metadata.preview.uri
465
+ : null,
466
+ },
467
+ };
468
+ case "ParticipantLeftMessage":
469
+ return {
470
+ type: "event",
471
+ messageID: d.message_id,
472
+ threadID: threadID,
473
+ isGroup: messageThread.thread_type === "GROUP",
474
+ senderID: d.message_sender.id,
475
+ timestamp: d.timestamp_precise,
476
+ eventType: "remove_participants",
477
+ snippet: d.snippet,
478
+ eventData: {
479
+ // Array of IDs.
480
+ participantsRemoved: d.participants_removed.map(function (p) {
481
+ return p.id;
482
+ }),
483
+ },
484
+
485
+ // @Legacy
486
+ logMessageType: "log:unsubscribe",
487
+ logMessageData: {
488
+ leftParticipantFbId: d.participants_removed.map(function (p) {
489
+ return p.id;
490
+ }),
491
+ },
492
+ };
493
+ case "ParticipantsAddedMessage":
494
+ return {
495
+ type: "event",
496
+ messageID: d.message_id,
497
+ threadID: threadID,
498
+ isGroup: messageThread.thread_type === "GROUP",
499
+ senderID: d.message_sender.id,
500
+ timestamp: d.timestamp_precise,
501
+ eventType: "add_participants",
502
+ snippet: d.snippet,
503
+ eventData: {
504
+ // Array of IDs.
505
+ participantsAdded: d.participants_added.map(function (p) {
506
+ return p.id;
507
+ }),
508
+ },
509
+
510
+ // @Legacy
511
+ logMessageType: "log:subscribe",
512
+ logMessageData: {
513
+ addedParticipants: d.participants_added.map(function (p) {
514
+ return p.id;
515
+ }),
516
+ },
517
+ };
518
+ case "VideoCallMessage":
519
+ return {
520
+ type: "event",
521
+ messageID: d.message_id,
522
+ threadID: threadID,
523
+ isGroup: messageThread.thread_type === "GROUP",
524
+ senderID: d.message_sender.id,
525
+ timestamp: d.timestamp_precise,
526
+ eventType: "video_call",
527
+ snippet: d.snippet,
528
+
529
+ // @Legacy
530
+ logMessageType: "other",
531
+ };
532
+ case "VoiceCallMessage":
533
+ return {
534
+ type: "event",
535
+ messageID: d.message_id,
536
+ threadID: threadID,
537
+ isGroup: messageThread.thread_type === "GROUP",
538
+ senderID: d.message_sender.id,
539
+ timestamp: d.timestamp_precise,
540
+ eventType: "voice_call",
541
+ snippet: d.snippet,
542
+
543
+ // @Legacy
544
+ logMessageType: "other",
545
+ };
546
+ case "GenericAdminTextMessage":
547
+ return {
548
+ type: "event",
549
+ messageID: d.message_id,
550
+ threadID: threadID,
551
+ isGroup: messageThread.thread_type === "GROUP",
552
+ senderID: d.message_sender.id,
553
+ timestamp: d.timestamp_precise,
554
+ snippet: d.snippet,
555
+ eventType: d.extensible_message_admin_text_type.toLowerCase(),
556
+ eventData: formatEventData(d.extensible_message_admin_text),
557
+
558
+ // @Legacy
559
+ logMessageType: utils.getAdminTextMessageType(
560
+ d.extensible_message_admin_text_type,
561
+ ),
562
+ logMessageData: d.extensible_message_admin_text, // Maybe different?
563
+ };
564
+ default:
565
+ return { error: "Don't know about message type " + d.__typename };
566
+ }
567
+ });
568
+ return messages;
569
+ }
570
+
571
+ module.exports = function (defaultFuncs, api, ctx) {
572
+ return function getThreadHistoryGraphQL(
573
+ threadID,
574
+ amount,
575
+ timestamp,
576
+ callback,
577
+ ) {
578
+ var resolveFunc = function () {};
579
+ var rejectFunc = function () {};
580
+ var returnPromise = new Promise(function (resolve, reject) {
581
+ resolveFunc = resolve;
582
+ rejectFunc = reject;
583
+ });
584
+
585
+ if (!callback) {
586
+ callback = function (err, data) {
587
+ if (err) return rejectFunc(err);
588
+ resolveFunc(data);
589
+ };
590
+ }
591
+
592
+ // `queries` has to be a string. I couldn't tell from the dev console. This
593
+ // took me a really long time to figure out. I deserve a cookie for this.
594
+ var form = {
595
+ av: ctx.globalOptions.pageID,
596
+ queries: JSON.stringify({
597
+ o0: {
598
+ // This doc_id was valid on February 2nd 2017.
599
+ doc_id: "1498317363570230",
600
+ query_params: {
601
+ id: threadID,
602
+ message_limit: amount,
603
+ load_messages: 1,
604
+ load_read_receipts: false,
605
+ before: timestamp,
606
+ },
607
+ },
608
+ }),
609
+ };
610
+
611
+ defaultFuncs
612
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
613
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
614
+ .then(function (resData) {
615
+ if (resData.error) throw resData;
616
+ // This returns us an array of things. The last one is the success /
617
+ // failure one.
618
+ // @TODO What do we do in this case?
619
+ if (resData[resData.length - 1].error_results !== 0)
620
+ throw new Error("There was an error_result.");
621
+ callback(null, formatMessagesGraphQLResponse(resData[0]));
622
+ })
623
+ .catch(function (err) {
624
+ log.error(
625
+ "getThreadHistoryGraphQL",
626
+ "Lỗi getThreadHistoryGraphQL Có Thể Do Bạn Spam Quá Nhiều, Hãy Thử Lại !",
627
+ );
628
+ return callback(err);
629
+ });
630
+
631
+ return returnPromise;
632
+ };
633
+ };