@dongdev/fca-unofficial 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/func/checkUpdate.js +9 -9
- package/func/logger.js +40 -104
- package/module/login.js +4 -4
- package/module/loginHelper.js +3 -3
- package/module/options.js +5 -9
- package/package.json +5 -5
- package/src/api/action/addExternalModule.js +5 -5
- package/src/api/action/changeAvatar.js +11 -10
- package/src/api/action/changeBio.js +7 -8
- package/src/api/action/getCurrentUserID.js +1 -1
- package/src/api/action/handleFriendRequest.js +5 -5
- package/src/api/action/logout.js +9 -8
- package/src/api/action/refreshFb_dtsg.js +17 -12
- package/src/api/action/setPostReaction.js +10 -11
- package/src/api/action/unfriend.js +3 -4
- package/src/api/http/httpGet.js +7 -8
- package/src/api/http/httpPost.js +7 -8
- package/src/api/http/postFormData.js +6 -5
- package/src/api/messaging/addUserToGroup.js +0 -1
- package/src/api/messaging/changeAdminStatus.js +108 -89
- package/src/api/messaging/changeArchivedStatus.js +6 -6
- package/src/api/messaging/changeBlockedStatus.js +3 -4
- package/src/api/messaging/changeGroupImage.js +72 -117
- package/src/api/messaging/changeNickname.js +59 -48
- package/src/api/messaging/changeThreadColor.js +61 -47
- package/src/api/messaging/changeThreadEmoji.js +106 -0
- package/src/api/messaging/createNewGroup.js +5 -5
- package/src/api/messaging/createPoll.js +36 -63
- package/src/api/messaging/deleteMessage.js +4 -4
- package/src/api/messaging/deleteThread.js +4 -4
- package/src/api/messaging/forwardAttachment.js +38 -47
- package/src/api/messaging/getFriendsList.js +5 -6
- package/src/api/messaging/getMessage.js +4 -9
- package/src/api/messaging/handleMessageRequest.js +5 -5
- package/src/api/messaging/markAsDelivered.js +5 -5
- package/src/api/messaging/markAsRead.js +7 -7
- package/src/api/messaging/markAsReadAll.js +3 -4
- package/src/api/messaging/markAsSeen.js +7 -7
- package/src/api/messaging/muteThread.js +3 -4
- package/src/api/messaging/removeUserFromGroup.js +82 -56
- package/src/api/messaging/resolvePhotoUrl.js +2 -3
- package/src/api/messaging/searchForThread.js +2 -3
- package/src/api/messaging/sendMessage.js +171 -101
- package/src/api/messaging/sendMessageMqtt.js +14 -12
- package/src/api/messaging/sendTypingIndicator.js +11 -11
- package/src/api/messaging/setMessageReaction.js +68 -82
- package/src/api/messaging/setTitle.js +77 -48
- package/src/api/messaging/shareContact.js +2 -4
- package/src/api/messaging/threadColors.js +0 -3
- package/src/api/messaging/unsendMessage.js +74 -37
- package/src/api/messaging/uploadAttachment.js +11 -9
- package/src/api/socket/core/connectMqtt.js +180 -0
- package/src/api/socket/core/getSeqID.js +25 -0
- package/src/api/socket/core/getTaskResponseData.js +22 -0
- package/src/api/socket/core/markDelivery.js +12 -0
- package/src/api/socket/core/parseDelta.js +351 -0
- package/src/api/socket/detail/buildStream.js +176 -68
- package/src/api/socket/detail/constants.js +24 -0
- package/src/api/socket/listenMqtt.js +80 -1005
- package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
- package/src/api/threads/getThreadInfo.js +35 -248
- package/src/api/threads/getThreadList.js +20 -20
- package/src/api/threads/getThreadPictures.js +3 -4
- package/src/api/users/getUserID.js +5 -6
- package/src/api/users/getUserInfo.js +305 -73
- package/src/api/users/getUserInfoV2.js +134 -0
- package/src/database/models/user.js +32 -0
- package/src/database/userData.js +89 -0
- package/src/utils/constants.js +12 -2
- package/src/utils/format.js +1051 -0
- package/src/utils/request.js +75 -7
- package/src/api/threads/changeThreadEmoji.js +0 -55
- package/src/utils/index.js +0 -1497
@@ -1,8 +1,8 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
3
|
const log = require("npmlog");
|
5
|
-
|
4
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
5
|
+
const { getAdminTextMessageType } = require("../../utils/format");
|
6
6
|
function getExtension(original_extension, filename = "") {
|
7
7
|
if (original_extension) {
|
8
8
|
return original_extension;
|
@@ -51,23 +51,6 @@ function formatAttachmentsGraphQLResponse(attachment) {
|
|
51
51
|
logo: attachment.attribution_app.square_logo
|
52
52
|
}
|
53
53
|
: null
|
54
|
-
|
55
|
-
// @TODO No idea what this is, should we expose it?
|
56
|
-
// Ben - July 15th 2017
|
57
|
-
// renderAsSticker: attachment.render_as_sticker,
|
58
|
-
|
59
|
-
// This is _not_ the real URI, this is still just a large preview.
|
60
|
-
// To get the URL we'll need to support a POST query to
|
61
|
-
//
|
62
|
-
// https://www.facebook.com/webgraphql/query/
|
63
|
-
//
|
64
|
-
// With the following query params:
|
65
|
-
//
|
66
|
-
// query_id:728987990612546
|
67
|
-
// variables:{"id":"100009069356507","photoID":"10213724771692996"}
|
68
|
-
// dpr:1
|
69
|
-
//
|
70
|
-
// No special form though.
|
71
54
|
};
|
72
55
|
case "MessageAnimatedImage":
|
73
56
|
return {
|
@@ -601,7 +584,7 @@ function formatMessagesGraphQLResponse(data) {
|
|
601
584
|
eventData: formatEventData(d.extensible_message_admin_text),
|
602
585
|
|
603
586
|
// @Legacy
|
604
|
-
logMessageType:
|
587
|
+
logMessageType: getAdminTextMessageType(
|
605
588
|
d.extensible_message_admin_text_type
|
606
589
|
),
|
607
590
|
logMessageData: d.extensible_message_admin_text // Maybe different?
|
@@ -639,7 +622,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
639
622
|
// `queries` has to be a string. I couldn't tell from the dev console. This
|
640
623
|
// took me a really long time to figure out. I deserve a cookie for this.
|
641
624
|
const form = {
|
642
|
-
av: ctx.
|
625
|
+
av: ctx.userID,
|
643
626
|
queries: JSON.stringify({
|
644
627
|
o0: {
|
645
628
|
// This doc_id was valid on February 2nd 2017.
|
@@ -657,7 +640,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
657
640
|
|
658
641
|
defaultFuncs
|
659
642
|
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
660
|
-
.then(
|
643
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
661
644
|
.then(function(resData) {
|
662
645
|
if (resData.error) {
|
663
646
|
throw resData;
|
@@ -1,10 +1,10 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
|
-
const log = require("npmlog");
|
5
3
|
const fs = require("fs");
|
6
4
|
const path = require("path");
|
7
5
|
const logger = require("../../../func/logger");
|
6
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
7
|
+
const { formatID, getType } = require("../../utils/format");
|
8
8
|
|
9
9
|
function formatEventReminders(reminder) {
|
10
10
|
return {
|
@@ -149,7 +149,7 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
149
149
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
150
150
|
try {
|
151
151
|
const Submit = buildQueries();
|
152
|
-
const resData = await defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, Submit).then(
|
152
|
+
const resData = await defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, Submit).then(parseAndCheckLogin(ctx, defaultFuncs));
|
153
153
|
if (!Array.isArray(resData) || resData.length === 0) throw new Error("EmptyGraphBatch");
|
154
154
|
const tail = resData[resData.length - 1];
|
155
155
|
if (tail?.error_results && tail.error_results !== 0) throw new Error("GraphErrorResults");
|
@@ -171,13 +171,39 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
171
171
|
acc[path.basename(file, ".js")] = require(path.join(__dirname, "../../database", file))(api);
|
172
172
|
return acc;
|
173
173
|
}, {});
|
174
|
-
const { threadData } = dbFiles;
|
174
|
+
const { threadData, userData } = dbFiles;
|
175
175
|
const { create, get, update, getAll } = threadData;
|
176
|
+
const { update: updateUser } = userData;
|
176
177
|
|
177
178
|
function isValidThread(d) {
|
178
179
|
return d && d.threadID;
|
179
180
|
}
|
180
181
|
|
182
|
+
async function upsertUsersFromThreadInfo(info) {
|
183
|
+
try {
|
184
|
+
if (!info || !Array.isArray(info.userInfo) || info.userInfo.length === 0) return;
|
185
|
+
const tasks = info.userInfo.filter(u => u && u.id).map(u => {
|
186
|
+
const data = {
|
187
|
+
id: u.id,
|
188
|
+
name: u.name || null,
|
189
|
+
firstName: u.firstName || null,
|
190
|
+
vanity: u.vanity || null,
|
191
|
+
url: u.url || null,
|
192
|
+
thumbSrc: u.thumbSrc || null,
|
193
|
+
profileUrl: u.profileUrl || null,
|
194
|
+
gender: u.gender || null,
|
195
|
+
type: u.type || null,
|
196
|
+
isFriend: !!u.isFriend,
|
197
|
+
isBirthday: !!u.isBirthday,
|
198
|
+
};
|
199
|
+
return updateUser(u.id, { data });
|
200
|
+
});
|
201
|
+
await Promise.allSettled(tasks);
|
202
|
+
} catch (e) {
|
203
|
+
logger(`upsertUsers error: ${e?.message || e}`, "warn");
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
181
207
|
async function fetchThreadInfo(tID, isNew) {
|
182
208
|
try {
|
183
209
|
const response = await getMultiInfo([tID]);
|
@@ -187,6 +213,7 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
187
213
|
return;
|
188
214
|
}
|
189
215
|
const threadInfo = response.Data[0];
|
216
|
+
await upsertUsersFromThreadInfo(threadInfo);
|
190
217
|
if (isNew) {
|
191
218
|
await create(tID, { data: threadInfo });
|
192
219
|
logger(`Success create data thread: ${tID}`, "info");
|
@@ -250,16 +277,17 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
250
277
|
resolveFunc = resolve;
|
251
278
|
rejectFunc = reject;
|
252
279
|
});
|
253
|
-
if (
|
280
|
+
if (getType(callback) != "Function" && getType(callback) != "AsyncFunction") {
|
254
281
|
callback = function (err, data) {
|
255
282
|
if (err) return rejectFunc(err);
|
256
283
|
resolveFunc(data);
|
257
284
|
};
|
258
285
|
}
|
259
|
-
if (
|
286
|
+
if (getType(threadID) !== "Array") threadID = [threadID];
|
260
287
|
try {
|
261
288
|
const cached = await get(threadID[0]);
|
262
289
|
if (cached?.data && isValidThread(cached.data)) {
|
290
|
+
await upsertUsersFromThreadInfo(cached.data);
|
263
291
|
callback(null, cached.data);
|
264
292
|
return returnPromise;
|
265
293
|
}
|
@@ -269,6 +297,7 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
269
297
|
const response = await getMultiInfo(threadID);
|
270
298
|
if (response.Success && response.Data && isValidThread(response.Data[0])) {
|
271
299
|
const data = response.Data[0];
|
300
|
+
await upsertUsersFromThreadInfo(data);
|
272
301
|
await create(threadID[0], { data });
|
273
302
|
callback(null, data);
|
274
303
|
} else {
|
@@ -328,245 +357,3 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
328
357
|
return returnPromise;
|
329
358
|
};
|
330
359
|
};
|
331
|
-
|
332
|
-
// "use strict";
|
333
|
-
|
334
|
-
// const utils = require("../../utils");
|
335
|
-
// const log = require("npmlog");
|
336
|
-
|
337
|
-
// function formatEventReminders(reminder) {
|
338
|
-
// return {
|
339
|
-
// reminderID: reminder.id,
|
340
|
-
// eventCreatorID: reminder.lightweight_event_creator.id,
|
341
|
-
// time: reminder.time,
|
342
|
-
// eventType: reminder.lightweight_event_type.toLowerCase(),
|
343
|
-
// locationName: reminder.location_name,
|
344
|
-
// // @TODO verify this
|
345
|
-
// locationCoordinates: reminder.location_coordinates,
|
346
|
-
// locationPage: reminder.location_page,
|
347
|
-
// eventStatus: reminder.lightweight_event_status.toLowerCase(),
|
348
|
-
// note: reminder.note,
|
349
|
-
// repeatMode: reminder.repeat_mode.toLowerCase(),
|
350
|
-
// eventTitle: reminder.event_title,
|
351
|
-
// triggerMessage: reminder.trigger_message,
|
352
|
-
// secondsToNotifyBefore: reminder.seconds_to_notify_before,
|
353
|
-
// allowsRsvp: reminder.allows_rsvp,
|
354
|
-
// relatedEvent: reminder.related_event,
|
355
|
-
// members: reminder.event_reminder_members.edges.map(function(member) {
|
356
|
-
// return {
|
357
|
-
// memberID: member.node.id,
|
358
|
-
// state: member.guest_list_state.toLowerCase()
|
359
|
-
// };
|
360
|
-
// })
|
361
|
-
// };
|
362
|
-
// }
|
363
|
-
|
364
|
-
// function formatThreadGraphQLResponse(data) {
|
365
|
-
// if (data.errors) return data.errors;
|
366
|
-
// const messageThread = data.message_thread;
|
367
|
-
// if (!messageThread) return null;
|
368
|
-
// const threadID = messageThread.thread_key.thread_fbid
|
369
|
-
// ? messageThread.thread_key.thread_fbid
|
370
|
-
// : messageThread.thread_key.other_user_id;
|
371
|
-
|
372
|
-
// // Remove me
|
373
|
-
// const lastM = messageThread.last_message;
|
374
|
-
// const snippetID =
|
375
|
-
// lastM &&
|
376
|
-
// lastM.nodes &&
|
377
|
-
// lastM.nodes[0] &&
|
378
|
-
// lastM.nodes[0].message_sender &&
|
379
|
-
// lastM.nodes[0].message_sender.messaging_actor
|
380
|
-
// ? lastM.nodes[0].message_sender.messaging_actor.id
|
381
|
-
// : null;
|
382
|
-
// const snippetText =
|
383
|
-
// lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
|
384
|
-
// const lastR = messageThread.last_read_receipt;
|
385
|
-
// const lastReadTimestamp =
|
386
|
-
// lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise
|
387
|
-
// ? lastR.nodes[0].timestamp_precise
|
388
|
-
// : null;
|
389
|
-
|
390
|
-
// return {
|
391
|
-
// threadID: threadID,
|
392
|
-
// threadName: messageThread.name,
|
393
|
-
// participantIDs: messageThread.all_participants.edges.map(
|
394
|
-
// d => d.node.messaging_actor.id
|
395
|
-
// ),
|
396
|
-
// userInfo: messageThread.all_participants.edges.map(d => ({
|
397
|
-
// id: d.node.messaging_actor.id,
|
398
|
-
// name: d.node.messaging_actor.name,
|
399
|
-
// firstName: d.node.messaging_actor.short_name,
|
400
|
-
// vanity: d.node.messaging_actor.username,
|
401
|
-
// url: d.node.messaging_actor.url,
|
402
|
-
// thumbSrc: d.node.messaging_actor.big_image_src.uri,
|
403
|
-
// profileUrl: d.node.messaging_actor.big_image_src.uri,
|
404
|
-
// gender: d.node.messaging_actor.gender,
|
405
|
-
// type: d.node.messaging_actor.__typename,
|
406
|
-
// isFriend: d.node.messaging_actor.is_viewer_friend,
|
407
|
-
// isBirthday: !!d.node.messaging_actor.is_birthday //not sure?
|
408
|
-
// })),
|
409
|
-
// unreadCount: messageThread.unread_count,
|
410
|
-
// messageCount: messageThread.messages_count,
|
411
|
-
// timestamp: messageThread.updated_time_precise,
|
412
|
-
// muteUntil: messageThread.mute_until,
|
413
|
-
// isGroup: messageThread.thread_type == "GROUP",
|
414
|
-
// isSubscribed: messageThread.is_viewer_subscribed,
|
415
|
-
// isArchived: messageThread.has_viewer_archived,
|
416
|
-
// folder: messageThread.folder,
|
417
|
-
// cannotReplyReason: messageThread.cannot_reply_reason,
|
418
|
-
// eventReminders: messageThread.event_reminders
|
419
|
-
// ? messageThread.event_reminders.nodes.map(formatEventReminders)
|
420
|
-
// : null,
|
421
|
-
// emoji: messageThread.customization_info
|
422
|
-
// ? messageThread.customization_info.emoji
|
423
|
-
// : null,
|
424
|
-
// color:
|
425
|
-
// messageThread.customization_info &&
|
426
|
-
// messageThread.customization_info.outgoing_bubble_color
|
427
|
-
// ? messageThread.customization_info.outgoing_bubble_color.slice(2)
|
428
|
-
// : null,
|
429
|
-
// threadTheme: messageThread.thread_theme,
|
430
|
-
// nicknames:
|
431
|
-
// messageThread.customization_info &&
|
432
|
-
// messageThread.customization_info.participant_customizations
|
433
|
-
// ? messageThread.customization_info.participant_customizations.reduce(
|
434
|
-
// function(res, val) {
|
435
|
-
// if (val.nickname) res[val.participant_id] = val.nickname;
|
436
|
-
// return res;
|
437
|
-
// },
|
438
|
-
// {}
|
439
|
-
// )
|
440
|
-
// : {},
|
441
|
-
// adminIDs: messageThread.thread_admins,
|
442
|
-
// approvalMode: Boolean(messageThread.approval_mode),
|
443
|
-
// approvalQueue: messageThread.group_approval_queue.nodes.map(a => ({
|
444
|
-
// inviterID: a.inviter.id,
|
445
|
-
// requesterID: a.requester.id,
|
446
|
-
// timestamp: a.request_timestamp,
|
447
|
-
// request_source: a.request_source // @Undocumented
|
448
|
-
// })),
|
449
|
-
|
450
|
-
// // @Undocumented
|
451
|
-
// reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
|
452
|
-
// mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
|
453
|
-
// isPinProtected: messageThread.is_pin_protected,
|
454
|
-
// relatedPageThread: messageThread.related_page_thread,
|
455
|
-
|
456
|
-
// // @Legacy
|
457
|
-
// name: messageThread.name,
|
458
|
-
// snippet: snippetText,
|
459
|
-
// snippetSender: snippetID,
|
460
|
-
// snippetAttachments: [],
|
461
|
-
// serverTimestamp: messageThread.updated_time_precise,
|
462
|
-
// imageSrc: messageThread.image ? messageThread.image.uri : null,
|
463
|
-
// isCanonicalUser: messageThread.is_canonical_neo_user,
|
464
|
-
// isCanonical: messageThread.thread_type != "GROUP",
|
465
|
-
// recipientsLoadable: true,
|
466
|
-
// hasEmailParticipant: false,
|
467
|
-
// readOnly: false,
|
468
|
-
// canReply: messageThread.cannot_reply_reason == null,
|
469
|
-
// lastMessageTimestamp: messageThread.last_message
|
470
|
-
// ? messageThread.last_message.timestamp_precise
|
471
|
-
// : null,
|
472
|
-
// lastMessageType: "message",
|
473
|
-
// lastReadTimestamp: lastReadTimestamp,
|
474
|
-
// threadType: messageThread.thread_type == "GROUP" ? 2 : 1,
|
475
|
-
|
476
|
-
// // update in Wed, 13 Jul 2022 19:41:12 +0700
|
477
|
-
// inviteLink: {
|
478
|
-
// enable: messageThread.joinable_mode
|
479
|
-
// ? messageThread.joinable_mode.mode == 1
|
480
|
-
// : false,
|
481
|
-
// link: messageThread.joinable_mode
|
482
|
-
// ? messageThread.joinable_mode.link
|
483
|
-
// : null
|
484
|
-
// }
|
485
|
-
// };
|
486
|
-
// }
|
487
|
-
|
488
|
-
// module.exports = function(defaultFuncs, api, ctx) {
|
489
|
-
// return function getThreadInfoGraphQL(threadID, callback) {
|
490
|
-
// let resolveFunc = function() {};
|
491
|
-
// let rejectFunc = function() {};
|
492
|
-
// const returnPromise = new Promise(function(resolve, reject) {
|
493
|
-
// resolveFunc = resolve;
|
494
|
-
// rejectFunc = reject;
|
495
|
-
// });
|
496
|
-
|
497
|
-
// if (
|
498
|
-
// utils.getType(callback) != "Function" &&
|
499
|
-
// utils.getType(callback) != "AsyncFunction"
|
500
|
-
// ) {
|
501
|
-
// callback = function(err, data) {
|
502
|
-
// if (err) {
|
503
|
-
// return rejectFunc(err);
|
504
|
-
// }
|
505
|
-
// resolveFunc(data);
|
506
|
-
// };
|
507
|
-
// }
|
508
|
-
|
509
|
-
// if (utils.getType(threadID) !== "Array") {
|
510
|
-
// threadID = [threadID];
|
511
|
-
// }
|
512
|
-
|
513
|
-
// let form = {};
|
514
|
-
// // `queries` has to be a string. I couldn't tell from the dev console. This
|
515
|
-
// // took me a really long time to figure out. I deserve a cookie for this.
|
516
|
-
// threadID.map(function(t, i) {
|
517
|
-
// form["o" + i] = {
|
518
|
-
// doc_id: "3449967031715030",
|
519
|
-
// query_params: {
|
520
|
-
// id: t,
|
521
|
-
// message_limit: 0,
|
522
|
-
// load_messages: false,
|
523
|
-
// load_read_receipts: false,
|
524
|
-
// before: null
|
525
|
-
// }
|
526
|
-
// };
|
527
|
-
// });
|
528
|
-
|
529
|
-
// form = {
|
530
|
-
// queries: JSON.stringify(form),
|
531
|
-
// batch_name: "MessengerGraphQLThreadFetcher"
|
532
|
-
// };
|
533
|
-
|
534
|
-
// defaultFuncs
|
535
|
-
// .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
536
|
-
// .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
537
|
-
// .then(function(resData) {
|
538
|
-
// if (resData.error) {
|
539
|
-
// throw resData;
|
540
|
-
// }
|
541
|
-
// // This returns us an array of things. The last one is the success /
|
542
|
-
// // failure one.
|
543
|
-
// // @TODO What do we do in this case?
|
544
|
-
// // if (resData[resData.length - 1].error_results !== 0) {
|
545
|
-
// // throw resData[0].o0.errors[0];
|
546
|
-
// // }
|
547
|
-
// // if (!resData[0].o0.data.message_thread) {
|
548
|
-
// // throw new Error("can't find this thread");
|
549
|
-
// // }
|
550
|
-
// const threadInfos = {};
|
551
|
-
// for (let i = resData.length - 2; i >= 0; i--) {
|
552
|
-
// const threadInfo = formatThreadGraphQLResponse(
|
553
|
-
// resData[i][Object.keys(resData[i])[0]].data
|
554
|
-
// );
|
555
|
-
// threadInfos[
|
556
|
-
// threadInfo?.threadID || threadID[threadID.length - 1 - i]
|
557
|
-
// ] = threadInfo;
|
558
|
-
// }
|
559
|
-
// if (Object.values(threadInfos).length == 1) {
|
560
|
-
// callback(null, Object.values(threadInfos)[0]);
|
561
|
-
// } else {
|
562
|
-
// callback(null, threadInfos);
|
563
|
-
// }
|
564
|
-
// })
|
565
|
-
// .catch(function(err) {
|
566
|
-
// log.error("getThreadInfoGraphQL", err);
|
567
|
-
// return callback(err);
|
568
|
-
// });
|
569
|
-
|
570
|
-
// return returnPromise;
|
571
|
-
// };
|
572
|
-
// };
|
@@ -1,12 +1,12 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
3
|
const log = require("npmlog");
|
5
|
-
|
4
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
5
|
+
const { formatID, getType } = require("../../utils/format");
|
6
6
|
function createProfileUrl(url, username, id) {
|
7
7
|
if (url) return url;
|
8
8
|
return (
|
9
|
-
"https://www.facebook.com/" + (username ||
|
9
|
+
"https://www.facebook.com/" + (username || formatID(id.toString()))
|
10
10
|
);
|
11
11
|
}
|
12
12
|
|
@@ -17,7 +17,7 @@ function formatParticipants(participants) {
|
|
17
17
|
case "User":
|
18
18
|
return {
|
19
19
|
accountType: p["__typename"],
|
20
|
-
userID:
|
20
|
+
userID: formatID(p.id.toString()), // do we need .toString()? when it is not a string?
|
21
21
|
name: p.name,
|
22
22
|
shortName: p.short_name,
|
23
23
|
gender: p.gender,
|
@@ -35,7 +35,7 @@ function formatParticipants(participants) {
|
|
35
35
|
case "Page":
|
36
36
|
return {
|
37
37
|
accountType: p["__typename"],
|
38
|
-
userID:
|
38
|
+
userID: formatID(p.id.toString()), // or maybe... pageID?
|
39
39
|
name: p.name,
|
40
40
|
url: p.url,
|
41
41
|
profilePicture: p.big_image_src.uri,
|
@@ -51,7 +51,7 @@ function formatParticipants(participants) {
|
|
51
51
|
case "UnavailableMessagingActor":
|
52
52
|
return {
|
53
53
|
accountType: p["__typename"],
|
54
|
-
userID:
|
54
|
+
userID: formatID(p.id.toString()),
|
55
55
|
name: p.name,
|
56
56
|
url: createProfileUrl(p.url, p.username, p.id), // in this case p.url is null all the time
|
57
57
|
profilePicture: p.big_image_src.uri, // in this case it is default facebook photo, we could determine gender using it
|
@@ -66,7 +66,7 @@ function formatParticipants(participants) {
|
|
66
66
|
);
|
67
67
|
return {
|
68
68
|
accountType: p["__typename"],
|
69
|
-
userID:
|
69
|
+
userID: formatID(p.id.toString()),
|
70
70
|
name: p.name || `[unknown ${p["__typename"]}]` // probably it will always be something... but fallback to [unknown], just in case
|
71
71
|
};
|
72
72
|
}
|
@@ -108,7 +108,7 @@ function formatThreadList(data) {
|
|
108
108
|
: null;
|
109
109
|
return {
|
110
110
|
threadID: t.thread_key
|
111
|
-
?
|
111
|
+
? formatID(t.thread_key.thread_fbid || t.thread_key.other_user_id)
|
112
112
|
: null, // shall never be null
|
113
113
|
name: getThreadName(t),
|
114
114
|
unreadCount: t.unread_count,
|
@@ -140,7 +140,7 @@ function formatThreadList(data) {
|
|
140
140
|
? lastMessageNode.extensible_attachment
|
141
141
|
: null, // TODO: not sure if it works
|
142
142
|
snippetSender: lastMessageNode
|
143
|
-
?
|
143
|
+
? formatID(
|
144
144
|
(lastMessageNode.message_sender.messaging_actor.id || "").toString()
|
145
145
|
)
|
146
146
|
: null,
|
@@ -171,25 +171,25 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
171
171
|
return function getThreadList(limit, timestamp, tags, callback) {
|
172
172
|
if (
|
173
173
|
!callback &&
|
174
|
-
(
|
175
|
-
|
174
|
+
(getType(tags) === "Function" ||
|
175
|
+
getType(tags) === "AsyncFunction")
|
176
176
|
) {
|
177
177
|
callback = tags;
|
178
178
|
tags = [""];
|
179
179
|
}
|
180
180
|
if (
|
181
|
-
|
181
|
+
getType(limit) !== "Number" ||
|
182
182
|
!Number.isInteger(limit) ||
|
183
183
|
limit <= 0
|
184
184
|
)
|
185
185
|
throw { error: "getThreadList: limit must be a positive integer" };
|
186
186
|
if (
|
187
|
-
|
188
|
-
(
|
187
|
+
getType(timestamp) !== "Null" &&
|
188
|
+
(getType(timestamp) !== "Number" || !Number.isInteger(timestamp))
|
189
189
|
)
|
190
190
|
throw { error: "getThreadList: timestamp must be an integer or null" };
|
191
|
-
if (
|
192
|
-
if (
|
191
|
+
if (getType(tags) === "String") tags = [tags];
|
192
|
+
if (getType(tags) !== "Array")
|
193
193
|
throw { error: "getThreadList: tags must be an array" };
|
194
194
|
var resolveFunc = function() {};
|
195
195
|
var rejectFunc = function() {};
|
@@ -198,8 +198,8 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
198
198
|
rejectFunc = reject;
|
199
199
|
});
|
200
200
|
if (
|
201
|
-
|
202
|
-
|
201
|
+
getType(callback) !== "Function" &&
|
202
|
+
getType(callback) !== "AsyncFunction"
|
203
203
|
) {
|
204
204
|
callback = function(err, data) {
|
205
205
|
if (err) return rejectFunc(err);
|
@@ -207,7 +207,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
207
207
|
};
|
208
208
|
}
|
209
209
|
const form = {
|
210
|
-
av: ctx.
|
210
|
+
av: ctx.userID,
|
211
211
|
queries: JSON.stringify({
|
212
212
|
o0: {
|
213
213
|
doc_id: "3336396659757871",
|
@@ -224,7 +224,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
224
224
|
};
|
225
225
|
defaultFuncs
|
226
226
|
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
227
|
-
.then(
|
227
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
228
228
|
.then(resData => {
|
229
229
|
if (resData[resData.length - 1].error_results > 0)
|
230
230
|
throw resData[0].o0.errors;
|
@@ -1,8 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
3
|
const log = require("npmlog");
|
5
|
-
|
4
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
6
5
|
module.exports = function(defaultFuncs, api, ctx) {
|
7
6
|
return function getThreadPictures(threadID, offset, limit, callback) {
|
8
7
|
let resolveFunc = function() {};
|
@@ -33,7 +32,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
33
32
|
ctx.jar,
|
34
33
|
form
|
35
34
|
)
|
36
|
-
.then(
|
35
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
37
36
|
.then(function(resData) {
|
38
37
|
if (resData.error) {
|
39
38
|
throw resData;
|
@@ -50,7 +49,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
50
49
|
ctx.jar,
|
51
50
|
form
|
52
51
|
)
|
53
|
-
.then(
|
52
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
54
53
|
.then(function(resData) {
|
55
54
|
if (resData.error) {
|
56
55
|
throw resData;
|
@@ -1,11 +1,10 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
3
|
const log = require("npmlog");
|
5
|
-
|
4
|
+
const { formatID } = require("../../utils/format");
|
6
5
|
function formatData(data) {
|
7
6
|
return {
|
8
|
-
userID:
|
7
|
+
userID: formatID(data.uid.toString()),
|
9
8
|
photoUrl: data.photo,
|
10
9
|
indexRank: data.index_rank,
|
11
10
|
name: data.text,
|
@@ -37,16 +36,16 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
37
36
|
|
38
37
|
const form = {
|
39
38
|
value: name.toLowerCase(),
|
40
|
-
viewer: ctx.
|
39
|
+
viewer: ctx.userID,
|
41
40
|
rsp: "search",
|
42
41
|
context: "search",
|
43
42
|
path: "/home.php",
|
44
|
-
request_id:
|
43
|
+
request_id: ctx.clientId
|
45
44
|
};
|
46
45
|
|
47
46
|
defaultFuncs
|
48
47
|
.get("https://www.facebook.com/ajax/typeahead/search.php", ctx.jar, form)
|
49
|
-
.then(
|
48
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
50
49
|
.then(function(resData) {
|
51
50
|
if (resData.error) {
|
52
51
|
throw resData;
|