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,85 @@
1
+ 'use strict';
2
+
3
+ var utils = require('../utils');
4
+ //NethWs3Dev
5
+ var EventEmitter = require('node:events');
6
+
7
+ function format(res, globalCallback) {
8
+ var checkMinutes = (date_1, date_2) => {
9
+ let ms_1 = date_1.getTime();
10
+ let ms_2 = date_2.getTime();
11
+ return Math.ceil((ms_2 - ms_1) / (60 * 1000));
12
+ }
13
+
14
+ for (let index of res.notifications_page.edges) {
15
+ if (index.node.row_type !== 'NOTIFICATION') continue;
16
+
17
+ var timestamp = index.node.notif.creation_time.timestamp;
18
+ if (checkMinutes(new Date(timestamp * 1000), new Date()) <= 1)
19
+ globalCallback(null, {
20
+ id: res.node.notif.id,
21
+ noti_id: res.node.notif.notif_id,
22
+ body: index.node.notif.body.text,
23
+ url: index.node.notif.url,
24
+ timestamp: timestamp * 1000
25
+ });
26
+ }
27
+ }
28
+
29
+ module.exports = function (defaultFuncs, api, ctx) {
30
+ let globalCallback, interval;
31
+
32
+ function MessageRepeat() {
33
+ interval = setInterval(function () {
34
+ return defaultFuncs
35
+ .post('https://www.facebook.com/api/graphql/', ctx.jar, {
36
+ fb_api_req_friendly_name: 'CometNotificationsRootQuery',
37
+ doc_id: 6663491207045267,
38
+ variables: JSON.stringify({
39
+ count: 5,
40
+ environment: 'MAIN_SURFACE',
41
+ filter_tokens: ['Cg8CZnQPA2FsbAE='],
42
+ scale: 1
43
+ }),
44
+ server_timestamps: !0
45
+ })
46
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
47
+ .then(function (res) {
48
+ if (res.error || res.errors)
49
+ throw res;
50
+
51
+ return format(res.data.viewer, globalCallback);
52
+ })
53
+ .catch(function (err) {
54
+ utils.error('listenNotification', err);
55
+ clearInterval(interval);
56
+ interval = void 0;
57
+ return globalCallback(err);
58
+ });
59
+ }, 60 * 1000);
60
+ }
61
+
62
+ return function notification(callback) {
63
+ class MessageEmitter extends EventEmitter {
64
+ stop() {
65
+ globalCallback = () => {}
66
+
67
+ if (interval) {
68
+ clearInterval(interval);
69
+ interval = void 0;
70
+ }
71
+ Message.emit('stop', new Date());
72
+ }
73
+ }
74
+
75
+ var Message = new MessageEmitter();
76
+
77
+ if (typeof callback == 'function')
78
+ globalCallback = callback;
79
+ else
80
+ globalCallback = (error, message) => error ? Message.emit('error', error) : Message.emit('message', message);
81
+
82
+ MessageRepeat();
83
+ return Message;
84
+ }
85
+ }
package/src/logout.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ var logger = require("../logger");
4
+ module.exports = function (defaultFuncs, api, ctx) {
5
+ return function logout(callback) {
6
+ var { promise, callback: cb } = utils.wrapCallback(callback);
7
+ if (api.stopListening) {
8
+ try { api.stopListening(); } catch (_) { }
9
+ }
10
+ defaultFuncs.post("https://www.facebook.com/logout.php", ctx.jar, {
11
+ ref: "mb",
12
+ h: ctx.fb_dtsg || ""
13
+ })
14
+ .then(() => {
15
+ ctx.loggedIn = false;
16
+ logger.info("SHADOWX", "Logged out successfully.");
17
+ cb(null, true);
18
+ })
19
+ .catch(err => cb(err));
20
+ return promise;
21
+ };
22
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function markAsDelivered(threadID, messageID, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ var form = {
7
+ "message_ids[0]": messageID,
8
+ "status": 1,
9
+ "thread_fbid": threadID
10
+ };
11
+ defaultFuncs.post("https://www.facebook.com/ajax/mercury/delivery_receipts.php", ctx.jar, form)
12
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
13
+ .then(resData => { if (resData.error) throw resData; cb(null, true); })
14
+ .catch(err => cb(err));
15
+ return promise;
16
+ };
17
+ };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function markAsRead(threadID, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ var form = { ids: {} };
7
+ form.ids[threadID] = true;
8
+ defaultFuncs.post("https://www.facebook.com/ajax/mercury/change_read_status.php", ctx.jar, form)
9
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
10
+ .then(resData => { if (resData.error) throw resData; cb(null, true); })
11
+ .catch(err => cb(err));
12
+ return promise;
13
+ };
14
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function markAsReadAll(callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ defaultFuncs.post("https://www.facebook.com/ajax/mercury/mark_folder_as_read.php", ctx.jar, {
7
+ folder: "inbox",
8
+ __user: ctx.userID
9
+ })
10
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
11
+ .then(resData => { if (resData.error) throw resData; cb(null, true); })
12
+ .catch(err => cb(err));
13
+ return promise;
14
+ };
15
+ };
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function markAsSeen(seen_timestamp, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ seen_timestamp = seen_timestamp || Date.now();
7
+ defaultFuncs.post("https://www.facebook.com/ajax/mercury/mark_seen.php", ctx.jar, {
8
+ seen_timestamp: seen_timestamp
9
+ })
10
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
11
+ .then(resData => { if (resData.error) throw resData; cb(null, true); })
12
+ .catch(err => cb(err));
13
+ return promise;
14
+ };
15
+ };
@@ -0,0 +1,185 @@
1
+ /**
2
+ * ===========================================================
3
+ * 💫 META THEME GENERATOR MODULE 💫
4
+ * ===========================================================
5
+ * 🔰 Owner & Developer
6
+ * 🧠 Description:
7
+ * This module generates beautiful Messenger AI themes
8
+ * using Meta's hidden GraphQL endpoints. It allows you to
9
+ * create unique chat themes based on your custom prompt
10
+ * or optional image inspiration.
11
+ * -----------------------------------------------------------
12
+ * ⚙️ Features:
13
+ * • Generate AI-based Messenger chat themes.
14
+ * • Custom prompt & optional image URL input.
15
+ * • Returns structured theme data with full color mapping.
16
+ * -----------------------------------------------------------
17
+ * 🕊️ Respect the creator & give proper credits if reused.
18
+ * ===========================================================
19
+ */
20
+
21
+ "use strict";
22
+
23
+ const utils = require("../utils");
24
+ const log = require("npmlog");
25
+ module.exports = function (defaultFuncs, api, ctx) {
26
+ return function metaTheme(prompt, options, callback) {
27
+ var resolveFunc = function () { };
28
+ var rejectFunc = function () { };
29
+ var returnPromise = new Promise(function (resolve, reject) {
30
+ resolveFunc = resolve;
31
+ rejectFunc = reject;
32
+ });
33
+
34
+ // Handle optional parameters
35
+ if (typeof options === 'function') {
36
+ callback = options;
37
+ options = {};
38
+ }
39
+
40
+ if (!callback) {
41
+ callback = function (err, data) {
42
+ if (err) return rejectFunc(err);
43
+ resolveFunc(data);
44
+ };
45
+ }
46
+
47
+ if (!prompt || typeof prompt !== 'string') {
48
+ return callback({ error: "Prompt is required and must be a string" });
49
+ }
50
+
51
+ // Parse options
52
+ const numThemes = options.numThemes || 1;
53
+ const imageUrl = options.imageUrl || null;
54
+
55
+ const inputData = {
56
+ client_mutation_id: Math.floor(Math.random() * 10).toString(),
57
+ actor_id: ctx.userID,
58
+ bypass_cache: true,
59
+ caller: "MESSENGER",
60
+ num_themes: Math.min(numThemes, 5), // Limit to max 5 themes
61
+ prompt: prompt
62
+ };
63
+
64
+ // Add image URL if provided
65
+ if (imageUrl) {
66
+ inputData.image_url = imageUrl;
67
+ }
68
+
69
+ const form = {
70
+ av: ctx.userID,
71
+ __aaid: 0,
72
+ __user: ctx.userID,
73
+ __a: 1,
74
+ __req: utils.getSignatureID(),
75
+ __hs: "20358.HYP:comet_pkg.2.1...0",
76
+ dpr: 1,
77
+ __ccg: "EXCELLENT",
78
+ __rev: "1027673511",
79
+ __s: utils.getSignatureID(),
80
+ __hsi: "7554561631547849479",
81
+ __comet_req: 15,
82
+ fb_dtsg: ctx.fb_dtsg,
83
+ jazoest: ctx.ttstamp,
84
+ lsd: ctx.fb_dtsg,
85
+ __spin_r: "1027673511",
86
+ __spin_b: "trunk",
87
+ __spin_t: Date.now(),
88
+ __crn: "comet.fbweb.MWInboxHomeRoute",
89
+ qpl_active_flow_ids: "25309433,521485406",
90
+ fb_api_caller_class: "RelayModern",
91
+ fb_api_req_friendly_name: "useGenerateAIThemeMutation",
92
+ variables: JSON.stringify({ input: inputData }),
93
+ server_timestamps: true,
94
+ doc_id: "23873748445608673",
95
+ fb_api_analytics_tags: JSON.stringify(["qpl_active_flow_ids=25309433,521485406"])
96
+ };
97
+
98
+ defaultFuncs
99
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
100
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
101
+ .then(function (resData) {
102
+ if (resData.errors) {
103
+ throw resData.errors;
104
+ }
105
+
106
+ if (resData.data && resData.data.xfb_generate_ai_themes_from_prompt) {
107
+ const themeData = resData.data.xfb_generate_ai_themes_from_prompt;
108
+ if (themeData.success && themeData.themes && themeData.themes.length > 0) {
109
+ const themes = themeData.themes.map((theme, index) => ({
110
+ success: true,
111
+ themeId: theme.id,
112
+ name: theme.accessibility_label,
113
+ description: theme.description,
114
+ serialNumber: index + 1,
115
+ colors: {
116
+ composerBackground: theme.composer_background_color,
117
+ backgroundGradient: theme.background_gradient_colors,
118
+ titleBarButton: theme.title_bar_button_tint_color,
119
+ inboundMessageGradient: theme.inbound_message_gradient_colors,
120
+ titleBarText: theme.title_bar_text_color,
121
+ composerTint: theme.composer_tint_color,
122
+ messageText: theme.message_text_color,
123
+ primaryButton: theme.primary_button_background_color,
124
+ titleBarBackground: theme.title_bar_background_color,
125
+ fallback: theme.fallback_color,
126
+ gradient: theme.gradient_colors
127
+ },
128
+ backgroundImage: theme.background_asset ? theme.background_asset.image.uri : null,
129
+ iconImage: theme.icon_asset ? theme.icon_asset.image.uri : null,
130
+ images: {
131
+ background: theme.background_asset ? theme.background_asset.image.uri : null,
132
+ icon: theme.icon_asset ? theme.icon_asset.image.uri : null
133
+ },
134
+ alternativeThemes: theme.alternative_themes ? theme.alternative_themes.map(alt => ({
135
+ id: alt.id,
136
+ name: alt.accessibility_label,
137
+ backgroundImage: alt.background_asset ? alt.background_asset.image.uri : null,
138
+ iconImage: alt.icon_asset ? alt.icon_asset.image.uri : null
139
+ })) : []
140
+ }));
141
+
142
+ const result = {
143
+ success: true,
144
+ count: themes.length,
145
+ themes: themes,
146
+ // For backward compatibility, include first theme data at root level
147
+ ...themes[0]
148
+ };
149
+ return callback(null, result);
150
+ } else {
151
+ throw new Error("No themes generated for the given prompt");
152
+ }
153
+ } else {
154
+ throw new Error("Invalid response from AI theme generation");
155
+ }
156
+ })
157
+ .catch(function (err) {
158
+ log.error("metaTheme", err);
159
+
160
+ // Check for specific error conditions
161
+ let errorMessage = "An error occurred while generating themes";
162
+
163
+ if (err.message && err.message.includes("not authorized")) {
164
+ errorMessage = "Your account is not authorized to generate AI themes. This feature may not be available for your account type.";
165
+ } else if (err.message && err.message.includes("rate limit")) {
166
+ errorMessage = "Rate limit exceeded. Please wait a moment before trying again.";
167
+ } else if (err.message && err.message.includes("Invalid")) {
168
+ errorMessage = "Invalid request parameters. Please check your input.";
169
+ } else if (err.statusCode === 403) {
170
+ errorMessage = "Access denied. Your account may not support Meta AI theme generation.";
171
+ } else if (err.statusCode === 429) {
172
+ errorMessage = "Too many requests. Please wait before trying again.";
173
+ }
174
+
175
+ return callback({
176
+ error: errorMessage,
177
+ originalError: err.message || err,
178
+ statusCode: err.statusCode || null
179
+ });
180
+ });
181
+
182
+ return returnPromise;
183
+ };
184
+ };
185
+
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var utils = require("../utils");
3
+ module.exports = function (defaultFuncs, api, ctx) {
4
+ return function muteThread(threadID, muteSeconds, callback) {
5
+ var { promise, callback: cb } = utils.wrapCallback(callback);
6
+ var mqttClient = ctx.mqttClient || global.mqttClient;
7
+
8
+ if (mqttClient) {
9
+ ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
10
+ ctx.wsTaskNumber = (ctx.wsTaskNumber || 0) + 1;
11
+ var muteExpireTime = muteSeconds === 0
12
+ ? 0
13
+ : muteSeconds === -1
14
+ ? -1
15
+ : Math.floor(Date.now() / 1000) + muteSeconds;
16
+ var payload = {
17
+ thread_key: String(threadID),
18
+ mute_expire_time_ms: muteExpireTime === -1 ? -1 : muteExpireTime * 1000,
19
+ sync_group: 1
20
+ };
21
+ var content = {
22
+ app_id: '2220391788200892',
23
+ payload: JSON.stringify({
24
+ data_trace_id: null,
25
+ epoch_id: parseInt(utils.generateOfflineThreadingID()),
26
+ tasks: [{
27
+ failure_count: null,
28
+ label: '52',
29
+ payload: JSON.stringify(payload),
30
+ queue_name: String(threadID),
31
+ task_id: ctx.wsTaskNumber
32
+ }],
33
+ version_id: '7158486590867448'
34
+ }),
35
+ request_id: ctx.wsReqNumber,
36
+ type: 3
37
+ };
38
+ mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
39
+ cb(null, true);
40
+ return promise;
41
+ }
42
+
43
+ defaultFuncs.post("https://www.facebook.com/ajax/mercury/change_mute_thread.php", ctx.jar, {
44
+ thread_fbid: threadID,
45
+ mute_settings: typeof muteSeconds === "number" ? muteSeconds : -1
46
+ })
47
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
48
+ .then(resData => { if (resData && resData.error) throw resData; cb(null, true); })
49
+ .catch(err => cb(err));
50
+ return promise;
51
+ };
52
+ };
package/src/note.js ADDED
@@ -0,0 +1,228 @@
1
+
2
+ "use strict";
3
+
4
+ const utils = require('../utils');
5
+
6
+ /**
7
+ * @description Enhanced module for interacting with Facebook Messenger Notes with additional features
8
+ * @param {Object} defaultFuncs The default functions provided by the API wrapper
9
+ * @param {Object} api The full API object
10
+ * @param {Object} ctx The context object containing the user's session state
11
+ * @returns {Object} An object containing enhanced methods for note management
12
+ */
13
+ module.exports = function(defaultFuncs, api, ctx) {
14
+
15
+ /**
16
+ * @callback notesCallback
17
+ * @param {Error|null} error An error object if the request fails, otherwise null
18
+ * @param {Object} [data] The data returned from the API
19
+ */
20
+
21
+ /**
22
+ * Enhanced check note function with additional user info
23
+ */
24
+ function checkNoteAdvanced(callback) {
25
+ if (typeof callback !== 'function') {
26
+ callback = () => {};
27
+ }
28
+
29
+ const form = {
30
+ fb_api_caller_class: "RelayModern",
31
+ fb_api_req_friendly_name: "MWInboxTrayNoteCreationDialogQuery",
32
+ variables: JSON.stringify({ scale: 2 }),
33
+ doc_id: "30899655739648624",
34
+ };
35
+
36
+ defaultFuncs
37
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
38
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
39
+ .then(resData => {
40
+ if (resData && resData.errors) throw resData.errors[0];
41
+ const currentNote = resData?.data?.viewer?.actor?.msgr_user_rich_status;
42
+
43
+ // Enhanced response with additional metadata
44
+ const enhancedResponse = {
45
+ note: currentNote,
46
+ hasActiveNote: !!currentNote,
47
+ userId: ctx.userID,
48
+ timestamp: Date.now(),
49
+ expiresAt: currentNote ? (currentNote.created_time * 1000) + (24 * 60 * 60 * 1000) : null
50
+ };
51
+
52
+ callback(null, enhancedResponse);
53
+ })
54
+ .catch(err => {
55
+ utils.error && utils.error("notesv2.checkNoteAdvanced", err);
56
+ callback(err);
57
+ });
58
+ }
59
+
60
+ /**
61
+ * Create note with enhanced privacy options and validation
62
+ */
63
+ function createNoteAdvanced(text, options = {}, callback) {
64
+ if (typeof options === 'function') {
65
+ callback = options;
66
+ options = {};
67
+ }
68
+
69
+ if (typeof callback !== 'function') {
70
+ callback = () => {};
71
+ }
72
+
73
+ // Validate input
74
+ if (!text || text.trim().length === 0) {
75
+ return callback(new Error("Note text cannot be empty"));
76
+ }
77
+
78
+ if (text.length > 280) {
79
+ return callback(new Error("Note text cannot exceed 280 characters"));
80
+ }
81
+
82
+ const {
83
+ privacy = "FRIENDS",
84
+ duration = 86400,
85
+ noteType = "TEXT_NOTE"
86
+ } = options;
87
+
88
+ const variables = {
89
+ input: {
90
+ client_mutation_id: Math.round(Math.random() * 1000000).toString(),
91
+ actor_id: ctx.userID,
92
+ description: text.trim(),
93
+ duration: duration,
94
+ note_type: noteType,
95
+ privacy: privacy,
96
+ session_id: utils.getGUID(),
97
+ },
98
+ };
99
+
100
+ const form = {
101
+ fb_api_caller_class: "RelayModern",
102
+ fb_api_req_friendly_name: "MWInboxTrayNoteCreationDialogCreationStepContentMutation",
103
+ variables: JSON.stringify(variables),
104
+ doc_id: "24060573783603122",
105
+ };
106
+
107
+ defaultFuncs
108
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
109
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
110
+ .then(resData => {
111
+ if (resData && resData.errors) throw resData.errors[0];
112
+ const status = resData?.data?.xfb_rich_status_create?.status;
113
+ if (!status) throw new Error("Could not find note status in the server response.");
114
+
115
+ // Enhanced response
116
+ const enhancedResponse = {
117
+ ...status,
118
+ createdAt: Date.now(),
119
+ expiresAt: Date.now() + (duration * 1000),
120
+ characterCount: text.trim().length,
121
+ privacy: privacy
122
+ };
123
+
124
+ callback(null, enhancedResponse);
125
+ })
126
+ .catch(err => {
127
+ utils.error && utils.error("notesv2.createNoteAdvanced", err);
128
+ callback(err);
129
+ });
130
+ }
131
+
132
+ /**
133
+ * Delete note with confirmation
134
+ */
135
+ function deleteNoteAdvanced(noteID, callback) {
136
+ if (typeof callback !== 'function') {
137
+ callback = () => {};
138
+ }
139
+
140
+ if (!noteID) {
141
+ return callback(new Error("Note ID is required"));
142
+ }
143
+
144
+ const variables = {
145
+ input: {
146
+ client_mutation_id: Math.round(Math.random() * 1000000).toString(),
147
+ actor_id: ctx.userID,
148
+ rich_status_id: noteID,
149
+ },
150
+ };
151
+
152
+ const form = {
153
+ fb_api_caller_class: "RelayModern",
154
+ fb_api_req_friendly_name: "useMWInboxTrayDeleteNoteMutation",
155
+ variables: JSON.stringify(variables),
156
+ doc_id: "9532619970198958",
157
+ };
158
+
159
+ defaultFuncs
160
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
161
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
162
+ .then(resData => {
163
+ if (resData && resData.errors) throw resData.errors[0];
164
+ const deletedStatus = resData?.data?.xfb_rich_status_delete;
165
+ if (!deletedStatus) throw new Error("Could not find deletion status in the server response.");
166
+
167
+ const enhancedResponse = {
168
+ ...deletedStatus,
169
+ deletedAt: Date.now(),
170
+ noteId: noteID
171
+ };
172
+
173
+ callback(null, enhancedResponse);
174
+ })
175
+ .catch(err => {
176
+ utils.error && utils.error("notesv2.deleteNoteAdvanced", err);
177
+ callback(err);
178
+ });
179
+ }
180
+
181
+ /**
182
+ * Update existing note (delete old and create new)
183
+ */
184
+ function updateNote(oldNoteID, newText, options = {}, callback) {
185
+ if (typeof options === 'function') {
186
+ callback = options;
187
+ options = {};
188
+ }
189
+
190
+ if (typeof callback !== 'function') {
191
+ callback = () => {};
192
+ }
193
+
194
+ deleteNoteAdvanced(oldNoteID, (err, deleted) => {
195
+ if (err) {
196
+ return callback(err);
197
+ }
198
+
199
+ // Wait a bit before creating new note
200
+ setTimeout(() => {
201
+ createNoteAdvanced(newText, options, (err, created) => {
202
+ if (err) {
203
+ return callback(err);
204
+ }
205
+ callback(null, {
206
+ deleted,
207
+ created,
208
+ updatedAt: Date.now()
209
+ });
210
+ });
211
+ }, 1000);
212
+ });
213
+ }
214
+
215
+ return {
216
+ // Enhanced functions
217
+ checkAdvanced: checkNoteAdvanced,
218
+ createAdvanced: createNoteAdvanced,
219
+ deleteAdvanced: deleteNoteAdvanced,
220
+ update: updateNote,
221
+
222
+ // Backward compatibility
223
+ check: checkNoteAdvanced,
224
+ create: createNoteAdvanced,
225
+ delete: deleteNoteAdvanced,
226
+ recreate: updateNote
227
+ };
228
+ };
package/src/pin.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function pin(action, threadID, messageID, callback) {
7
+ var { promise, callback: cb } = utils.wrapCallback(callback);
8
+
9
+ var mqttClient = ctx.mqttClient || global.mqttClient;
10
+ if (!mqttClient) {
11
+ cb({ error: "MQTT not connected. Call api.listen() first." });
12
+ return promise;
13
+ }
14
+
15
+ ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
16
+ ctx.wsTaskNumber = (ctx.wsTaskNumber || 0) + 1;
17
+
18
+ var isPinning = action === "pin" || action === true || action === 1;
19
+
20
+ var taskPayload = {
21
+ thread_key: String(threadID),
22
+ message_id: String(messageID),
23
+ timestamp_ms: Date.now(),
24
+ };
25
+
26
+ var envelope = {
27
+ app_id: "2220391788200892",
28
+ payload: JSON.stringify({
29
+ data_trace_id: null,
30
+ epoch_id: parseInt(utils.generateOfflineThreadingID()),
31
+ tasks: [{
32
+ failure_count: null,
33
+ label: isPinning ? "430" : "431",
34
+ payload: JSON.stringify(taskPayload),
35
+ queue_name: (isPinning ? "pin_msg_v2_" : "unpin_msg_v2_") + String(threadID),
36
+ task_id: ctx.wsTaskNumber,
37
+ }],
38
+ version_id: "25095469420099952",
39
+ }),
40
+ request_id: ctx.wsReqNumber,
41
+ type: 3,
42
+ };
43
+
44
+ try {
45
+ mqttClient.publish("/ls_req", JSON.stringify(envelope), { qos: 1 });
46
+ cb(null, true);
47
+ } catch (e) {
48
+ cb(e);
49
+ }
50
+
51
+ return promise;
52
+ };
53
+ };