shadowx-fca 8.0.0

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 (174) hide show
  1. package/README.md +1066 -0
  2. package/build/messagix.dll +0 -0
  3. package/build/messagix.so +0 -0
  4. package/checkUpdate.js +393 -0
  5. package/config.json +17 -0
  6. package/e2ee.js +563 -0
  7. package/e2eetest.js +356 -0
  8. package/index.js +611 -0
  9. package/lib/index.mjs +1412 -0
  10. package/logger.js +500 -0
  11. package/package.json +65 -0
  12. package/src/GetBotInfo.js +66 -0
  13. package/src/OldMessage.js +182 -0
  14. package/src/Screenshot.js +83 -0
  15. package/src/addExternalModule.js +13 -0
  16. package/src/addUserToGroup.js +33 -0
  17. package/src/approveGroupJoinRequests.js +18 -0
  18. package/src/changeAdminStatus.js +16 -0
  19. package/src/changeArchivedStatus.js +17 -0
  20. package/src/changeAvatar.js +136 -0
  21. package/src/changeAvatarV2.js +86 -0
  22. package/src/changeAvt.js +85 -0
  23. package/src/changeBio.js +76 -0
  24. package/src/changeBlockedStatus.js +20 -0
  25. package/src/changeBlockedStatusMqtt.js +80 -0
  26. package/src/changeCover.js +72 -0
  27. package/src/changeGroupImage.js +16 -0
  28. package/src/changeName.js +79 -0
  29. package/src/changeNickname.js +16 -0
  30. package/src/changeThreadColor.js +15 -0
  31. package/src/changeThreadEmoji.js +15 -0
  32. package/src/changeThreadMemberNickname.js +6 -0
  33. package/src/changeUsername.js +59 -0
  34. package/src/createCommentPost.js +230 -0
  35. package/src/createNewGroup.js +38 -0
  36. package/src/createNote.js +35 -0
  37. package/src/createPoll.js +27 -0
  38. package/src/createPost.js +276 -0
  39. package/src/createThemeAI.js +129 -0
  40. package/src/data/cache/system/data.json +4 -0
  41. package/src/data/cache/system/datahandle.js +21 -0
  42. package/src/data/getThreadInfo.json +1 -0
  43. package/src/deleteComment.js +23 -0
  44. package/src/deleteMessage.js +15 -0
  45. package/src/deleteThread.js +15 -0
  46. package/src/denyGroupJoinRequests.js +18 -0
  47. package/src/e2ee/crypto.js +173 -0
  48. package/src/e2ee/index.js +144 -0
  49. package/src/e2ee/proto/ArmadilloApplication.proto +281 -0
  50. package/src/e2ee/proto/ArmadilloICDC.proto +14 -0
  51. package/src/e2ee/proto/ConsumerApplication.proto +232 -0
  52. package/src/e2ee/proto/MessageApplication.proto +82 -0
  53. package/src/e2ee/proto/MessageTransport.proto +77 -0
  54. package/src/e2ee/proto/WACommon.proto +66 -0
  55. package/src/e2ee/proto/WAMediaTransport.proto +176 -0
  56. package/src/e2ee/proto/proto-writer.ts +76 -0
  57. package/src/e2ee/protocol.js +196 -0
  58. package/src/e2ee/ratchet.js +219 -0
  59. package/src/e2ee/store.js +182 -0
  60. package/src/e2ee.js +8 -0
  61. package/src/editMessage.js +56 -0
  62. package/src/editMessageOld.js +67 -0
  63. package/src/enableReactions.js +24 -0
  64. package/src/follow.js +74 -0
  65. package/src/followUser.js +23 -0
  66. package/src/forwardAttachment.js +16 -0
  67. package/src/friendList.js +98 -0
  68. package/src/getAccess.js +112 -0
  69. package/src/getAppState.js +13 -0
  70. package/src/getAvatarUser.js +11 -0
  71. package/src/getBio.js +24 -0
  72. package/src/getBotInitialData.js +42 -0
  73. package/src/getCtx.js +5 -0
  74. package/src/getCurrentUserID.js +6 -0
  75. package/src/getEmojiUrl.js +29 -0
  76. package/src/getFriendsList.js +36 -0
  77. package/src/getMessage.js +37 -0
  78. package/src/getNotes.js +17 -0
  79. package/src/getOptions.js +5 -0
  80. package/src/getPinnedMessages.js +33 -0
  81. package/src/getPostInfo.js +17 -0
  82. package/src/getProfileInfo.js +17 -0
  83. package/src/getPublicData.js +25 -0
  84. package/src/getRegion.js +7 -0
  85. package/src/getRepInfo.js +17 -0
  86. package/src/getStickerPacks.js +25 -0
  87. package/src/getStickers.js +39 -0
  88. package/src/getStoryReactions.js +18 -0
  89. package/src/getThreadHistory.js +45 -0
  90. package/src/getThreadHistoryDeprecated.js +71 -0
  91. package/src/getThreadInfo.js +73 -0
  92. package/src/getThreadInfoDeprecated.js +56 -0
  93. package/src/getThreadList.js +76 -0
  94. package/src/getThreadListDeprecated.js +46 -0
  95. package/src/getThreadPictures.js +59 -0
  96. package/src/getThreadTheme.js +77 -0
  97. package/src/getUID.js +17 -0
  98. package/src/getUserID.js +17 -0
  99. package/src/getUserInfo.js +28 -0
  100. package/src/handleFriendRequest.js +21 -0
  101. package/src/handleMessageRequest.js +15 -0
  102. package/src/httpGet.js +13 -0
  103. package/src/httpPost.js +12 -0
  104. package/src/httpPostFormData.js +12 -0
  105. package/src/listenE2EE.js +75 -0
  106. package/src/listenMqtt.js +802 -0
  107. package/src/listenNotification.js +85 -0
  108. package/src/logout.js +22 -0
  109. package/src/markAsDelivered.js +17 -0
  110. package/src/markAsRead.js +14 -0
  111. package/src/markAsReadAll.js +15 -0
  112. package/src/markAsSeen.js +15 -0
  113. package/src/metaTheme.js +185 -0
  114. package/src/muteThread.js +52 -0
  115. package/src/note.js +228 -0
  116. package/src/pin.js +53 -0
  117. package/src/pinMessage.js +6 -0
  118. package/src/postComment.js +29 -0
  119. package/src/postFormData.js +46 -0
  120. package/src/reactToComment.js +31 -0
  121. package/src/reactToPost.js +32 -0
  122. package/src/refreshFb_dtsg.js +31 -0
  123. package/src/removeSuspiciousAccount.js +74 -0
  124. package/src/removeUserFromGroup.js +15 -0
  125. package/src/reply.js +442 -0
  126. package/src/resolvePhotoUrl.js +15 -0
  127. package/src/searchForThread.js +20 -0
  128. package/src/searchFriends.js +28 -0
  129. package/src/searchStickers.js +53 -0
  130. package/src/send.js +46 -0
  131. package/src/sendAudio.js +8 -0
  132. package/src/sendBroadcast.js +93 -0
  133. package/src/sendButtons.js +161 -0
  134. package/src/sendComment.js +159 -0
  135. package/src/sendEmoji.js +10 -0
  136. package/src/sendFile.js +9 -0
  137. package/src/sendFriendRequest.js +33 -0
  138. package/src/sendGif.js +24 -0
  139. package/src/sendImage.js +9 -0
  140. package/src/sendLocation.js +9 -0
  141. package/src/sendMessage.js +487 -0
  142. package/src/sendMessage1.js +309 -0
  143. package/src/sendMessageMqtt.js +68 -0
  144. package/src/sendSticker.js +8 -0
  145. package/src/sendTypingIndicator.js +36 -0
  146. package/src/sendTypingIndicatorV2.js +28 -0
  147. package/src/sendVideo.js +9 -0
  148. package/src/sessionGuard.js +130 -0
  149. package/src/setActiveStatus.js +16 -0
  150. package/src/setMessageReaction.js +61 -0
  151. package/src/setMessageReactionMqtt.js +62 -0
  152. package/src/setOptions.js +22 -0
  153. package/src/setPollVote.js +17 -0
  154. package/src/setPostReaction.js +112 -0
  155. package/src/setProfileGuard.js +44 -0
  156. package/src/setProfileLock.js +93 -0
  157. package/src/setStoryReaction.js +129 -0
  158. package/src/setStorySeen.js +99 -0
  159. package/src/setThreadTheme.js +17 -0
  160. package/src/setTitle.js +15 -0
  161. package/src/shareContact.js +33 -0
  162. package/src/shareLink.js +8 -0
  163. package/src/sharePost.js +31 -0
  164. package/src/stopListenMqtt.js +23 -0
  165. package/src/storyManager.js +353 -0
  166. package/src/suggestFriend.js +128 -0
  167. package/src/threadColors.js +131 -0
  168. package/src/unfollowUser.js +23 -0
  169. package/src/unfriend.js +15 -0
  170. package/src/unpinMessage.js +6 -0
  171. package/src/unsendMessage.js +14 -0
  172. package/src/uploadAttachment.js +58 -0
  173. package/src/uploadImageToImgbb.js +29 -0
  174. package/utils.js +2945 -0
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function getPinnedMessages(threadID, callback) {
7
+ var { promise, callback: cb } = utils.wrapCallback(callback);
8
+
9
+ api.getThreadInfo(threadID)
10
+ .then(function (threadInfo) {
11
+ var pinnedIDs = threadInfo.pinnedMessageIDs || [];
12
+
13
+ if (pinnedIDs.length === 0) {
14
+ return cb(null, []);
15
+ }
16
+
17
+ var fetches = pinnedIDs.map(function (msgID) {
18
+ return api.getMessage(threadID, msgID).catch(function () {
19
+ return { messageID: msgID, body: null, senderID: null };
20
+ });
21
+ });
22
+
23
+ return Promise.all(fetches).then(function (messages) {
24
+ cb(null, messages);
25
+ });
26
+ })
27
+ .catch(function (err) {
28
+ cb(err);
29
+ });
30
+
31
+ return promise;
32
+ };
33
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getPostInfo(postID, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, {
7
+ fb_api_req_friendly_name: "CometFeedStoryQuery",
8
+ fb_api_caller_class: "RelayModern",
9
+ doc_id: "5025565174182042",
10
+ variables: JSON.stringify({ storyID: String(postID), feedLocation: "PERMALINK", privacySelectorRenderLocation: "COMET_STREAM" })
11
+ })
12
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
13
+ .then(resData => { if (resData.error) throw resData; cb(null, resData && resData.data && resData.data.node); })
14
+ .catch(err => cb(err));
15
+ return promise;
16
+ };
17
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getProfileInfo(userID, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, {
7
+ fb_api_req_friendly_name: "ProfileCometHeaderQuery",
8
+ fb_api_caller_class: "RelayModern",
9
+ doc_id: "4288341514541020",
10
+ variables: JSON.stringify({ userID: String(userID), scale: 3 })
11
+ })
12
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
13
+ .then(resData => { if (resData.error) throw resData; cb(null, resData && resData.data && resData.data.user); })
14
+ .catch(err => cb(err));
15
+ return promise;
16
+ };
17
+ };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getPublicData(userIDOrUrl, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ var isUrl = typeof userIDOrUrl === "string" && userIDOrUrl.includes("facebook.com");
7
+ var url = isUrl ? userIDOrUrl : ("https://www.facebook.com/profile.php?id=" + userIDOrUrl);
8
+ defaultFuncs.get(url, ctx.jar, {})
9
+ .then(res => {
10
+ var body = res.body || "";
11
+ var nameMatch = body.match(/"name":"([^"]+)"/);
12
+ var idMatch = body.match(/"userID":"(\d+)"/);
13
+ var vanityMatch = body.match(/"vanity":"([^"]+)"/);
14
+ var thumbMatch = body.match(/"uri":"(https:\/\/[^"]+profile[^"]+)"/);
15
+ cb(null, {
16
+ name: nameMatch && nameMatch[1],
17
+ userID: idMatch && idMatch[1],
18
+ vanity: vanityMatch && vanityMatch[1],
19
+ thumbSrc: thumbMatch && thumbMatch[1]
20
+ });
21
+ })
22
+ .catch(err => cb(err));
23
+ return promise;
24
+ };
25
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getRegion() {
5
+ return ctx?.region;
6
+ };
7
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getRepInfo(callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, {
7
+ fb_api_req_friendly_name: "MessengerRepInfoQuery",
8
+ fb_api_caller_class: "RelayModern",
9
+ doc_id: "6193148430750882",
10
+ variables: JSON.stringify({ userID: ctx.userID })
11
+ })
12
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
13
+ .then(resData => { if (resData.error) throw resData; cb(null, resData && resData.data); })
14
+ .catch(err => cb(err));
15
+ return promise;
16
+ };
17
+ };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getStickerPacks(callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, {
7
+ fb_api_req_friendly_name: "ComposerStickerPackQuery",
8
+ fb_api_caller_class: "RelayModern",
9
+ doc_id: "4022506321100228",
10
+ variables: JSON.stringify({ scale: 3 })
11
+ })
12
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
13
+ .then(resData => {
14
+ if (resData.error) throw resData;
15
+ var packs = (resData.data && resData.data.viewer && resData.data.viewer.sticker_packs && resData.data.viewer.sticker_packs.nodes) || [];
16
+ cb(null, packs.map(p => ({
17
+ id: p.id,
18
+ name: p.name,
19
+ coverSticker: p.cover_sticker && p.cover_sticker.image && p.cover_sticker.image.uri
20
+ })));
21
+ })
22
+ .catch(err => cb(err));
23
+ return promise;
24
+ };
25
+ };
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getStickers(query, stickerPackID, callback) {
5
+ if (typeof stickerPackID === "function") { callback = stickerPackID; stickerPackID = null; }
6
+ var { promise, callback: cb } = utils.wrapCallback(callback);
7
+ var form = {
8
+ fb_api_req_friendly_name: "ComposerStickersSearchRoot",
9
+ fb_api_caller_class: "RelayModern",
10
+ doc_id: "5566756003355488",
11
+ variables: JSON.stringify({
12
+ query: query || "",
13
+ stickerPackID: stickerPackID || null,
14
+ scale: 3
15
+ })
16
+ };
17
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
18
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
19
+ .then(resData => {
20
+ if (resData.error) throw resData;
21
+ var packs = (resData.data && resData.data.sticker_search && resData.data.sticker_search.groups) || [];
22
+ var stickers = [];
23
+ packs.forEach(pack => {
24
+ (pack.stickers && pack.stickers.nodes || []).forEach(s => {
25
+ stickers.push({
26
+ id: s.id,
27
+ label: s.label,
28
+ stickerPackID: s.pack && s.pack.id,
29
+ spriteImage: s.sprite_image && s.sprite_image.uri,
30
+ image: s.image && s.image.uri
31
+ });
32
+ });
33
+ });
34
+ cb(null, stickers);
35
+ })
36
+ .catch(err => cb(err));
37
+ return promise;
38
+ };
39
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getStoryReactions(feedbackID, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ var encodedID = Buffer.from("feedback:" + feedbackID).toString("base64");
7
+ defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, {
8
+ fb_api_req_friendly_name: "CometUFIReactionCountWithoutSummaryQuery",
9
+ fb_api_caller_class: "RelayModern",
10
+ doc_id: "6148258561870311",
11
+ variables: JSON.stringify({ feedbackID: encodedID })
12
+ })
13
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
14
+ .then(resData => { if (resData.error) throw resData; cb(null, resData && resData.data && resData.data.feedback); })
15
+ .catch(err => cb(err));
16
+ return promise;
17
+ };
18
+ };
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getThreadHistory(threadID, amount, timestamp, callback) {
5
+ if (typeof timestamp === "function") { callback = timestamp; timestamp = undefined; }
6
+ var { promise, callback: cb } = utils.wrapCallback(callback);
7
+ defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
8
+ av: ctx.globalOptions.pageID,
9
+ queries: JSON.stringify({
10
+ o0: {
11
+ doc_id: "1498317363570230",
12
+ query_params: {
13
+ id: String(threadID),
14
+ message_limit: amount || 20,
15
+ load_messages: 1,
16
+ load_read_receipts: false,
17
+ before: timestamp || null
18
+ }
19
+ }
20
+ })
21
+ })
22
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
23
+ .then(resData => {
24
+ if (!Array.isArray(resData)) throw { error: "Not logged in" };
25
+ if (resData[resData.length - 1].error_results !== 0) throw new Error("getThreadHistory: error_results returned.");
26
+ var thread = resData[0].o0 && resData[0].o0.data && resData[0].o0.data.message_thread;
27
+ var messages = (thread && thread.messages && thread.messages.nodes) || [];
28
+ cb(null, messages.map(m => ({
29
+ type: "message",
30
+ messageID: m.message_id,
31
+ senderID: m.message_sender && m.message_sender.id,
32
+ body: m.message && m.message.text || "",
33
+ timestamp: m.timestamp_precise,
34
+ threadID: String(threadID),
35
+ isUnsent: !!m.is_unsent,
36
+ attachments: (m.message && m.message.blob_attachments || []).map(a => {
37
+ try { return utils._formatAttachment({ blob_attachment: a }); }
38
+ catch (_) { return { type: "unknown" }; }
39
+ })
40
+ })));
41
+ })
42
+ .catch(err => cb(err));
43
+ return promise;
44
+ };
45
+ };
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function getThreadHistory(threadID, amount, timestamp, callback) {
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, threadInfo) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc(threadInfo);
19
+ };
20
+ }
21
+
22
+ if (!callback) throw { error: "getThreadHistory: need callback" };
23
+ var form = {
24
+ client: "mercury"
25
+ };
26
+
27
+ api.getUserInfo(threadID, function (err, res) {
28
+ if (err) return callback(err);
29
+ var key = Object.keys(res).length > 0 ? "user_ids" : "thread_fbids";
30
+ form["messages[" + key + "][" + threadID + "][offset]"] = 0;
31
+ form["messages[" + key + "][" + threadID + "][timestamp]"] = timestamp;
32
+ form["messages[" + key + "][" + threadID + "][limit]"] = amount;
33
+
34
+ if (ctx.globalOptions.pageID) form.request_user_id = ctx.globalOptions.pageID;
35
+
36
+ defaultFuncs
37
+ .post("https://www.facebook.com/ajax/mercury/thread_info.php", ctx.jar, form)
38
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
39
+ .then(function (resData) {
40
+ if (resData.error) throw resData;
41
+ else if (!resData.payload) throw { error: "Could not retrieve thread history." };
42
+
43
+ // Asking for message history from a thread with no message history
44
+ // will return undefined for actions here
45
+ if (!resData.payload.actions) resData.payload.actions = [];
46
+
47
+ var userIDs = {};
48
+ resData.payload.actions.forEach(v => userIDs[v.author.split(":").pop()] = "");
49
+
50
+ api.getUserInfo(Object.keys(userIDs), function (err, data) {
51
+ if (err) return callback(err); //callback({error: "Could not retrieve user information in getThreadHistory."});
52
+
53
+ resData.payload.actions.forEach(function (v) {
54
+ var sender = data[v.author.split(":").pop()];
55
+ if (sender) v.sender_name = sender.name;
56
+ else v.sender_name = "Facebook User";
57
+ v.sender_fbid = v.author;
58
+ delete v.author;
59
+ });
60
+
61
+ callback(null, resData.payload.actions.map(utils.formatHistoryMessage));
62
+ });
63
+ })
64
+ .catch(function (err) {
65
+ log.error("getThreadHistory", err);
66
+ return callback(err);
67
+ });
68
+ });
69
+ return returnPromise;
70
+ };
71
+ };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ function formatThread(data) {
5
+ if (data.errors) return data.errors;
6
+ var mt = data.message_thread;
7
+ if (!mt) return null;
8
+ var threadID = mt.thread_key.thread_fbid || mt.thread_key.other_user_id;
9
+ var lastM = mt.last_message;
10
+ var snippetID = lastM && lastM.nodes && lastM.nodes[0] && lastM.nodes[0].message_sender && lastM.nodes[0].message_sender.messaging_actor ? lastM.nodes[0].message_sender.messaging_actor.id : null;
11
+ var snippetText = lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
12
+ var lastR = mt.last_read_receipt;
13
+ var lastReadTimestamp = lastR && lastR.nodes && lastR.nodes[0] ? lastR.nodes[0].timestamp_precise : null;
14
+ return {
15
+ threadID: String(threadID),
16
+ threadName: mt.name,
17
+ participantIDs: mt.all_participants.edges.map(d => d.node.messaging_actor.id),
18
+ userInfo: mt.all_participants.edges.map(d => ({
19
+ id: d.node.messaging_actor.id,
20
+ name: d.node.messaging_actor.name,
21
+ firstName: d.node.messaging_actor.short_name,
22
+ vanity: d.node.messaging_actor.username,
23
+ url: d.node.messaging_actor.url,
24
+ thumbSrc: d.node.messaging_actor.big_image_src && d.node.messaging_actor.big_image_src.uri,
25
+ gender: d.node.messaging_actor.gender,
26
+ type: d.node.messaging_actor.__typename,
27
+ isFriend: d.node.messaging_actor.is_viewer_friend,
28
+ isBirthday: !!d.node.messaging_actor.is_birthday
29
+ })),
30
+ unreadCount: mt.unread_count,
31
+ messageCount: mt.messages_count,
32
+ timestamp: mt.updated_time_precise,
33
+ muteUntil: mt.mute_until,
34
+ isGroup: !!mt.thread_key.thread_fbid,
35
+ isSubscribed: mt.is_viewer_subscribed,
36
+ isArchived: mt.has_viewer_archived,
37
+ folder: mt.folder,
38
+ canReply: mt.can_viewer_reply,
39
+ lastReadTimestamp,
40
+ snippet: snippetText,
41
+ snippetSenderID: snippetID,
42
+ adminIDs: (mt.thread_admins || []).map(a => a.id),
43
+ approvalMode: mt.approval_mode,
44
+ approvalQueue: (mt.approval_requests && mt.approval_requests.edges.map(e => e.node.requester.id)) || [],
45
+ image: mt.image && mt.image.uri,
46
+ emoji: mt.customization_info && mt.customization_info.emoji,
47
+ color: mt.customization_info && mt.customization_info.outgoing_bubble_color,
48
+ nicknames: mt.customization_info && mt.customization_info.participant_customizations
49
+ ? mt.customization_info.participant_customizations.reduce((acc, p) => { acc[p.participant_id] = p.nickname; return acc; }, {})
50
+ : {}
51
+ };
52
+ }
53
+
54
+ return function getThreadInfo(threadID, callback) {
55
+ var { promise, callback: cb } = utils.wrapCallback(callback);
56
+ defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
57
+ av: ctx.globalOptions.pageID,
58
+ queries: JSON.stringify({
59
+ o0: {
60
+ doc_id: "3449967031715030",
61
+ query_params: { id: String(threadID), message_limit: 0, load_messages: 0, load_read_receipts: false, before: null }
62
+ }
63
+ })
64
+ })
65
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
66
+ .then(resData => {
67
+ if (!Array.isArray(resData) || resData[resData.length - 1].error_results > 0) throw resData[0] && resData[0].o0 && resData[0].o0.errors;
68
+ cb(null, formatThread(resData[0].o0.data));
69
+ })
70
+ .catch(err => cb(err));
71
+ return promise;
72
+ };
73
+ };
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function getThreadInfo(threadID, callback) {
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, data) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc(data);
19
+ };
20
+ }
21
+
22
+ var form = {
23
+ client: "mercury"
24
+ };
25
+
26
+ api.getUserInfo(threadID, function (err, userRes) {
27
+ if (err) return callback(err);
28
+ var key = Object.keys(userRes).length > 0 ? "user_ids" : "thread_fbids";
29
+ form["threads[" + key + "][0]"] = threadID;
30
+
31
+ if (ctx.globalOptions.pageId) form.request_user_id = ctx.globalOptions.pageId;
32
+
33
+ defaultFuncs
34
+ .post("https://www.facebook.com/ajax/mercury/thread_info.php", ctx.jar, form)
35
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(function (resData) {
37
+ if (resData.error) throw resData;
38
+ else if (!resData.payload) throw { error: "Could not retrieve thread Info." };
39
+
40
+ var threadData = resData.payload.threads[0];
41
+ var userData = userRes[threadID];
42
+
43
+ if (threadData == null) throw { error: "ThreadData is null" };
44
+
45
+ threadData.name = userData != null && userData.name != null ? userData.name : threadData.name;
46
+ threadData.image_src = userData != null && userData.thumbSrc != null ? userData.thumbSrc : threadData.image_src;
47
+ callback(null, utils.formatThread(threadData));
48
+ })
49
+ .catch(function (err) {
50
+ log.error("getThreadInfo", err);
51
+ return callback(err);
52
+ });
53
+ });
54
+ return returnPromise;
55
+ };
56
+ };
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function getThreadList(limit, timestamp, tags, callback) {
5
+ if (!callback && (utils.getType(tags) === "Function" || utils.getType(tags) === "AsyncFunction")) {
6
+ callback = tags;
7
+ tags = ["INBOX"];
8
+ }
9
+ if (typeof timestamp === "function") { callback = timestamp; timestamp = null; tags = ["INBOX"]; }
10
+ if (!tags || !Array.isArray(tags)) tags = ["INBOX"];
11
+ if (utils.getType(limit) !== "Number" || !Number.isInteger(limit) || limit <= 0) {
12
+ throw { error: "getThreadList: limit must be a positive integer" };
13
+ }
14
+ var { promise, callback: cb } = utils.wrapCallback(callback);
15
+ defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
16
+ av: ctx.i_userID || ctx.userID,
17
+ queries: JSON.stringify({
18
+ o0: {
19
+ doc_id: "3426149104143726",
20
+ query_params: {
21
+ limit: limit + (timestamp ? 1 : 0),
22
+ before: timestamp,
23
+ tags: tags,
24
+ includeDeliveryReceipts: true,
25
+ includeSeqID: false
26
+ }
27
+ }
28
+ }),
29
+ batch_name: "MessengerGraphQLThreadlistFetcher"
30
+ })
31
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
32
+ .then(function (resData) {
33
+ if (!Array.isArray(resData)) throw { error: "Not logged in" };
34
+ if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
35
+ if (resData[resData.length - 1].successful_results === 0) {
36
+ throw { error: "getThreadList: there was no successful_results", res: resData };
37
+ }
38
+ var nodes = resData[0].o0.data.viewer.message_threads.nodes || [];
39
+ if (timestamp) nodes.shift();
40
+ cb(null, nodes.map(function (t) {
41
+ var lastM = t.last_message && t.last_message.nodes && t.last_message.nodes[0];
42
+ var lastR = t.last_read_receipt && t.last_read_receipt.nodes && t.last_read_receipt.nodes[0];
43
+ return {
44
+ threadID: String(t.thread_key.thread_fbid || t.thread_key.other_user_id),
45
+ threadName: t.name,
46
+ unreadCount: t.unread_count,
47
+ messageCount: t.messages_count,
48
+ timestamp: t.updated_time_precise,
49
+ muteUntil: t.mute_until,
50
+ isGroup: t.thread_type === "GROUP",
51
+ isArchived: t.has_viewer_archived,
52
+ isSubscribed: t.is_viewer_subscribed,
53
+ canReply: t.cannot_reply_reason == null,
54
+ folder: t.folder,
55
+ image: t.image && t.image.uri,
56
+ emoji: t.customization_info ? t.customization_info.emoji : null,
57
+ color: t.customization_info && t.customization_info.outgoing_bubble_color
58
+ ? t.customization_info.outgoing_bubble_color.slice(2) : null,
59
+ adminIDs: (t.thread_admins || []).map(function (a) { return a.id; }),
60
+ approvalMode: Boolean(t.approval_mode),
61
+ participantIDs: (t.all_participants && t.all_participants.edges || []).map(function (e) {
62
+ return e.node.messaging_actor.id;
63
+ }),
64
+ snippet: lastM ? lastM.snippet : null,
65
+ snippetSender: lastM && lastM.message_sender && lastM.message_sender.messaging_actor
66
+ ? utils.formatID(String(lastM.message_sender.messaging_actor.id)) : null,
67
+ lastMessageTimestamp: lastM ? lastM.timestamp_precise : null,
68
+ lastReadTimestamp: lastR ? lastR.timestamp_precise : null,
69
+ threadType: t.thread_type === "GROUP" ? 2 : 1
70
+ };
71
+ }));
72
+ })
73
+ .catch(function (err) { cb(err); });
74
+ return promise;
75
+ };
76
+ };
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function getThreadList(start, end, type, callback) {
8
+ if (utils.getType(callback) === "Undefined") {
9
+ if (utils.getType(end) !== "Number") throw { error: "Please pass a number as a second argument." };
10
+ else if (utils.getType(type) === "Function" || utils.getType(type) === "AsyncFunction") {
11
+ callback = type;
12
+ type = "inbox"; //default to inbox
13
+ }
14
+ else if (utils.getType(type) !== "String") throw { error: "Please pass a String as a third argument. Your options are: inbox, pending, and archived" };
15
+ else throw { error: "getThreadList: need callback" };
16
+ }
17
+
18
+ if (type === "archived") type = "action:archived";
19
+ else if (type !== "inbox" && type !== "pending" && type !== "other") throw { error: "type can only be one of the following: inbox, pending, archived, other" };
20
+
21
+
22
+ if (end <= start) end = start + 20;
23
+
24
+ var form = {
25
+ client: "mercury"
26
+ };
27
+
28
+ form[type + "[offset]"] = start;
29
+ form[type + "[limit]"] = end - start;
30
+
31
+ if (ctx.globalOptions.pageID) form.request_user_id = ctx.globalOptions.pageID;
32
+
33
+ defaultFuncs
34
+ .post("https://www.facebook.com/ajax/mercury/threadlist_info.php", ctx.jar, form)
35
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(function (resData) {
37
+ if (resData.error) throw resData;
38
+ log.verbose("getThreadList", JSON.stringify(resData.payload.threads));
39
+ return callback(null, (resData.payload.threads || []).map(utils.formatThread));
40
+ })
41
+ .catch(function (err) {
42
+ log.error("getThreadList", err);
43
+ return callback(err);
44
+ });
45
+ };
46
+ };
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function getThreadPictures(threadID, offset, limit, callback) {
8
+ var resolveFunc = function () { };
9
+ var rejectFunc = function () { };
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, data) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc(data);
19
+ };
20
+ }
21
+
22
+ var form = {
23
+ thread_id: threadID,
24
+ offset: offset,
25
+ limit: limit
26
+ };
27
+
28
+ defaultFuncs
29
+ .post("https://www.facebook.com/ajax/messaging/attachments/sharedphotos.php", ctx.jar, form)
30
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
31
+ .then(function (resData) {
32
+ if (resData.error) throw resData;
33
+ return Promise.all(
34
+ resData.payload.imagesData.map(function (image) {
35
+ form = {
36
+ thread_id: threadID,
37
+ image_id: image.fbid
38
+ };
39
+ return defaultFuncs
40
+ .post("https://www.facebook.com/ajax/messaging/attachments/sharedphotos.php", ctx.jar, form)
41
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
42
+ .then(function (resData) {
43
+ if (resData.error) throw resData;
44
+ // the response is pretty messy
45
+ var queryThreadID = resData.jsmods.require[0][3][1].query_metadata.query_path[0].message_thread;
46
+ var imageData = resData.jsmods.require[0][3][1].query_results[queryThreadID].message_images.edges[0].node.image2;
47
+ return imageData;
48
+ });
49
+ })
50
+ );
51
+ })
52
+ .then(resData => callback(null, resData))
53
+ .catch(function (err) {
54
+ log.error("Error in getThreadPictures", err);
55
+ callback(err);
56
+ });
57
+ return returnPromise;
58
+ };
59
+ };