@cexy/hoonfca 1.0.0 → 1.0.1

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 (188) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +451 -43
  3. package/examples/login-with-cookies.js +102 -0
  4. package/examples/verify.js +70 -0
  5. package/index.js +1 -466
  6. package/package.json +98 -6
  7. package/src/apis/addExternalModule.js +24 -0
  8. package/src/apis/addUserToGroup.js +108 -0
  9. package/src/apis/changeAdminStatus.js +148 -0
  10. package/src/apis/changeArchivedStatus.js +61 -0
  11. package/src/apis/changeAvatar.js +103 -0
  12. package/src/apis/changeBio.js +69 -0
  13. package/src/apis/changeBlockedStatus.js +54 -0
  14. package/src/apis/changeGroupImage.js +136 -0
  15. package/src/apis/changeThreadColor.js +116 -0
  16. package/src/{changeThreadEmoji.js → apis/changeThreadEmoji.js} +7 -8
  17. package/src/apis/comment.js +207 -0
  18. package/src/apis/createAITheme.js +129 -0
  19. package/src/apis/createNewGroup.js +79 -0
  20. package/src/apis/createPoll.js +73 -0
  21. package/src/apis/deleteMessage.js +44 -0
  22. package/src/apis/deleteThread.js +52 -0
  23. package/src/apis/e2ee.js +17 -0
  24. package/src/apis/editMessage.js +70 -0
  25. package/src/apis/emoji.js +124 -0
  26. package/src/apis/fetchThemeData.js +82 -0
  27. package/src/apis/follow.js +81 -0
  28. package/src/apis/forwardMessage.js +52 -0
  29. package/src/apis/friend.js +243 -0
  30. package/src/apis/gcmember.js +122 -0
  31. package/src/apis/gcname.js +123 -0
  32. package/src/apis/gcrule.js +119 -0
  33. package/src/apis/getAccess.js +111 -0
  34. package/src/apis/getBotInfo.js +88 -0
  35. package/src/apis/getBotInitialData.js +43 -0
  36. package/src/apis/getFriendsList.js +79 -0
  37. package/src/apis/getMessage.js +423 -0
  38. package/src/apis/getTheme.js +95 -0
  39. package/src/apis/getThemeInfo.js +116 -0
  40. package/src/apis/getThreadHistory.js +239 -0
  41. package/src/apis/getThreadInfo.js +267 -0
  42. package/src/apis/getThreadList.js +232 -0
  43. package/src/apis/getThreadPictures.js +58 -0
  44. package/src/apis/getUserID.js +117 -0
  45. package/src/apis/getUserInfo.js +513 -0
  46. package/src/apis/getUserInfoV2.js +146 -0
  47. package/src/apis/handleMessageRequest.js +50 -0
  48. package/src/apis/httpGet.js +63 -0
  49. package/src/apis/httpPost.js +89 -0
  50. package/src/apis/httpPostFormData.js +69 -0
  51. package/src/apis/listenMqtt.js +1236 -0
  52. package/src/apis/listenSpeed.js +179 -0
  53. package/src/apis/logout.js +87 -0
  54. package/src/apis/markAsDelivered.js +47 -0
  55. package/src/apis/markAsRead.js +99 -0
  56. package/src/apis/markAsReadAll.js +40 -0
  57. package/src/apis/markAsSeen.js +70 -0
  58. package/src/apis/mqttDeltaValue.js +278 -0
  59. package/src/apis/muteThread.js +45 -0
  60. package/src/apis/nickname.js +132 -0
  61. package/src/apis/notes.js +163 -0
  62. package/src/apis/pinMessage.js +150 -0
  63. package/src/apis/produceMetaTheme.js +180 -0
  64. package/src/apis/realtime.js +182 -0
  65. package/src/apis/removeUserFromGroup.js +117 -0
  66. package/src/apis/resolvePhotoUrl.js +58 -0
  67. package/src/apis/searchForThread.js +154 -0
  68. package/src/apis/sendMessage.js +354 -0
  69. package/src/apis/sendMessageMqtt.js +249 -0
  70. package/src/apis/sendTypingIndicator.js +91 -0
  71. package/src/apis/setMessageReaction.js +27 -0
  72. package/src/apis/setMessageReactionMqtt.js +61 -0
  73. package/src/apis/setThreadTheme.js +260 -0
  74. package/src/apis/setThreadThemeMqtt.js +94 -0
  75. package/src/apis/share.js +107 -0
  76. package/src/apis/shareContact.js +66 -0
  77. package/src/apis/stickers.js +257 -0
  78. package/src/apis/story.js +181 -0
  79. package/src/apis/theme.js +233 -0
  80. package/src/apis/unfriend.js +47 -0
  81. package/src/apis/unsendMessage.js +17 -0
  82. package/src/engine/client.js +92 -0
  83. package/src/engine/models/buildAPI.js +152 -0
  84. package/src/engine/models/loginHelper.js +519 -0
  85. package/src/engine/models/setOptions.js +88 -0
  86. package/src/security/e2ee.js +109 -0
  87. package/src/types/index.d.ts +498 -0
  88. package/src/utils/antiSuspension.js +506 -0
  89. package/src/utils/auth-helpers.js +149 -0
  90. package/src/utils/autoReLogin.js +336 -0
  91. package/src/utils/axios.js +436 -0
  92. package/src/utils/cache.js +54 -0
  93. package/src/utils/clients.js +282 -0
  94. package/src/utils/constants.js +410 -0
  95. package/src/utils/formatters/data/formatAttachment.js +370 -0
  96. package/src/utils/formatters/data/formatDelta.js +109 -0
  97. package/src/utils/formatters/index.js +159 -0
  98. package/src/utils/formatters/value/formatCookie.js +91 -0
  99. package/src/utils/formatters/value/formatDate.js +36 -0
  100. package/src/utils/formatters/value/formatID.js +16 -0
  101. package/src/utils/formatters.js +1373 -0
  102. package/src/utils/headers.js +230 -0
  103. package/src/utils/index.js +153 -0
  104. package/src/utils/monitoring.js +333 -0
  105. package/src/utils/rateLimiter.js +319 -0
  106. package/src/utils/tokenRefresh.js +657 -0
  107. package/src/utils/user-agents.js +238 -0
  108. package/src/utils/validation.js +157 -0
  109. package/replit.nix +0 -3
  110. package/src/addExternalModule.js +0 -25
  111. package/src/addUserToGroup.js +0 -98
  112. package/src/changeAdminStatus.js +0 -98
  113. package/src/changeArchivedStatus.js +0 -51
  114. package/src/changeAvatar.js +0 -89
  115. package/src/changeBio.js +0 -74
  116. package/src/changeBlockedStatus.js +0 -45
  117. package/src/changeBlockedStatusMqtt.js +0 -65
  118. package/src/changeCover.js +0 -92
  119. package/src/changeGroupImage.js +0 -110
  120. package/src/changeName.js +0 -106
  121. package/src/changeNickname.js +0 -58
  122. package/src/changeThreadColor.js +0 -62
  123. package/src/changeUsername.js +0 -80
  124. package/src/createCommentPost.js +0 -196
  125. package/src/createNewGroup.js +0 -81
  126. package/src/createPoll.js +0 -64
  127. package/src/createPost.js +0 -285
  128. package/src/data/getThreadInfo.json +0 -1
  129. package/src/deleteMessage.js +0 -55
  130. package/src/deleteThread.js +0 -55
  131. package/src/editMessage.js +0 -66
  132. package/src/follow.js +0 -71
  133. package/src/forwardAttachment.js +0 -57
  134. package/src/getAccess.js +0 -130
  135. package/src/getAvatarUser.js +0 -88
  136. package/src/getBotInitialData.js +0 -59
  137. package/src/getCtx.js +0 -5
  138. package/src/getCurrentUserID.js +0 -5
  139. package/src/getEmojiUrl.js +0 -18
  140. package/src/getFriendsList.js +0 -81
  141. package/src/getMessage.js +0 -827
  142. package/src/getOptions.js +0 -5
  143. package/src/getRegion.js +0 -7
  144. package/src/getThreadHistory.js +0 -496
  145. package/src/getThreadHistoryDeprecated.js +0 -95
  146. package/src/getThreadInfo.js +0 -194
  147. package/src/getThreadInfoDeprecated.js +0 -77
  148. package/src/getThreadList.js +0 -219
  149. package/src/getThreadListDeprecated.js +0 -86
  150. package/src/getThreadPictures.js +0 -85
  151. package/src/getUserID.js +0 -67
  152. package/src/getUserInfo.js +0 -89
  153. package/src/handleFriendRequest.js +0 -56
  154. package/src/handleMessageRequest.js +0 -65
  155. package/src/httpGet.js +0 -53
  156. package/src/httpPost.js +0 -53
  157. package/src/httpPostFormData.js +0 -58
  158. package/src/listenMqtt.js +0 -683
  159. package/src/listenNotification.js +0 -96
  160. package/src/logout.js +0 -77
  161. package/src/markAsDelivered.js +0 -53
  162. package/src/markAsRead.js +0 -74
  163. package/src/markAsReadAll.js +0 -46
  164. package/src/markAsSeen.js +0 -57
  165. package/src/muteThread.js +0 -49
  166. package/src/pinMessage.js +0 -60
  167. package/src/refreshFb_dtsg.js +0 -75
  168. package/src/removeUserFromGroup.js +0 -59
  169. package/src/resolvePhotoUrl.js +0 -47
  170. package/src/searchForThread.js +0 -55
  171. package/src/searchStickers.js +0 -59
  172. package/src/sendMessage.js +0 -444
  173. package/src/sendMessageMqtt.js +0 -326
  174. package/src/sendTypingIndicator.js +0 -54
  175. package/src/setMessageReaction.js +0 -126
  176. package/src/setMessageReactionMqtt.js +0 -74
  177. package/src/setPostReaction.js +0 -103
  178. package/src/setProfileGuard.js +0 -66
  179. package/src/setStoryReaction.js +0 -97
  180. package/src/setTitle.js +0 -100
  181. package/src/shareContact.js +0 -101
  182. package/src/shareLink.js +0 -105
  183. package/src/stopListenMqtt.js +0 -47
  184. package/src/threadColors.js +0 -119
  185. package/src/unfriend.js +0 -58
  186. package/src/unsendMessage.js +0 -51
  187. package/src/uploadAttachment.js +0 -98
  188. package/utils.js +0 -919
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function deleteThread(threadOrThreads, callback) {
7
+ let resolveFunc = () => {};
8
+ let rejectFunc = () => {};
9
+ const returnPromise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ if (!callback) {
15
+ callback = (err, result) => {
16
+ if (err) return rejectFunc(err);
17
+ resolveFunc(result);
18
+ };
19
+ }
20
+
21
+ try {
22
+ const form = {
23
+ client: "mercury"
24
+ };
25
+
26
+ if (utils.getType(threadOrThreads) !== "Array") {
27
+ threadOrThreads = [threadOrThreads];
28
+ }
29
+
30
+ for (let i = 0; i < threadOrThreads.length; i++) {
31
+ form["ids[" + i + "]"] = threadOrThreads[i];
32
+ }
33
+
34
+ const res = await defaultFuncs.post(
35
+ "https://www.facebook.com/ajax/mercury/delete_thread.php",
36
+ ctx.jar,
37
+ form
38
+ ).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
39
+
40
+ if (res && res.error) {
41
+ throw res;
42
+ }
43
+
44
+ callback(null, { success: true });
45
+ } catch (err) {
46
+ utils.error("deleteThread", err);
47
+ callback(err);
48
+ }
49
+
50
+ return returnPromise;
51
+ };
52
+ };
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ const e2ee = require('../security/e2ee');
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return {
7
+ enable() { e2ee.enable(ctx); },
8
+ disable() { e2ee.disable(ctx); },
9
+ isEnabled() { return e2ee.isEnabled(ctx); },
10
+ getPublicKey() { return e2ee.getPublicKey(ctx); },
11
+ setPeerKey(threadID, peerPublicKeyB64) { e2ee.setPeerKey(ctx, threadID, peerPublicKeyB64); },
12
+ clearPeerKey(threadID) { e2ee.clearPeerKey(ctx, threadID); },
13
+ hasPeer(threadID) { return e2ee.hasPeer(ctx, threadID); },
14
+ encrypt(threadID, text) { return e2ee.encrypt(ctx, threadID, text); },
15
+ decrypt(threadID, armored) { return e2ee.decrypt(ctx, threadID, armored); }
16
+ };
17
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /**
3
+ * @author RFS-ADRENO
4
+ * @rewrittenBy Isai Ivanov
5
+ */
6
+
7
+ const utils = require('../utils');
8
+
9
+ function canBeCalled(func) {
10
+ try {
11
+ Reflect.apply(func, null, []);
12
+ return true;
13
+ } catch (error) {
14
+ return false;
15
+ }
16
+ }
17
+
18
+ /**
19
+ * A function for editing bot's messages.
20
+ * @param {string} text - The text with which the bot will edit its messages.
21
+ * @param {string} messageID - The message ID of the message the bot will edit.
22
+ * @param {Object} callback - Callback for the function.
23
+ */
24
+
25
+ module.exports = function (defaultFuncs, api, ctx) {
26
+ return function editMessage(text, messageID, callback) {
27
+ if (!ctx.mqttClient) {
28
+ throw new Error('Not connected to MQTT');
29
+ }
30
+
31
+ ctx.wsReqNumber += 1;
32
+ ctx.wsTaskNumber += 1;
33
+
34
+ const queryPayload = {
35
+ message_id: messageID,
36
+ text
37
+ };
38
+
39
+ const query = {
40
+ failure_count: null,
41
+ label: '742',
42
+ payload: JSON.stringify(queryPayload),
43
+ queue_name: 'edit_message',
44
+ task_id: ctx.wsTaskNumber
45
+ };
46
+
47
+ const context = {
48
+ app_id: '2220391788200892',
49
+ payload: {
50
+ data_trace_id: null,
51
+ epoch_id: parseInt(utils.generateOfflineThreadingID()),
52
+ tasks: [query],
53
+ version_id: '6903494529735864'
54
+ },
55
+ request_id: ctx.wsReqNumber,
56
+ type: 3
57
+ };
58
+
59
+ context.payload = JSON.stringify(context.payload);
60
+
61
+
62
+
63
+
64
+
65
+ ctx.mqttClient.publish('/ls_req', JSON.stringify(context), {
66
+ qos: 1, retain: false
67
+ });
68
+ };
69
+ };
70
+
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ /**
7
+ * Made by Choru Official
8
+ * Mqtt
9
+ * Sets the custom emoji for a specific Facebook thread via MQTT.
10
+ *
11
+ * @param {string} emoji The emoji character to set as the custom emoji (e.g., "👍", "❤️").
12
+ * @param {string} threadID The ID of the thread where the emoji will be set.
13
+ * @param {Function} [callback] Optional callback function to be invoked upon completion.
14
+ * @param {string} [initiatorID] The ID of the user who initiated the emoji change (e.g., from event.senderID).
15
+ * @returns {Promise<object>} A promise that resolves with a structured event object on success or rejects on error.
16
+ */
17
+ return function emoji(emoji, threadID, callback, initiatorID) {
18
+ let _callback;
19
+ let _initiatorID;
20
+
21
+ let _resolvePromise;
22
+ let _rejectPromise;
23
+ const returnPromise = new Promise((resolve, reject) => {
24
+ _resolvePromise = resolve;
25
+ _rejectPromise = reject;
26
+ });
27
+
28
+ if (utils.getType(callback) === "Function" || utils.getType(callback) === "AsyncFunction") {
29
+ _callback = callback;
30
+ _initiatorID = initiatorID;
31
+ } else if (utils.getType(threadID) === "Function" || utils.getType(threadID) === "AsyncFunction") {
32
+ _callback = threadID;
33
+ threadID = null;
34
+ _initiatorID = callback;
35
+ } else if (utils.getType(callback) === "string") {
36
+ _initiatorID = callback;
37
+ _callback = undefined;
38
+ } else {
39
+ _callback = undefined;
40
+ _initiatorID = undefined;
41
+ }
42
+
43
+ if (!_callback) {
44
+ _callback = function (__err, __data) {
45
+ if (__err) _rejectPromise(__err);
46
+ else _resolvePromise(__data);
47
+ };
48
+ } else {
49
+ const originalCallback = _callback;
50
+ _callback = function(__err, __data) {
51
+ if (__err) {
52
+ originalCallback(__err);
53
+ _rejectPromise(__err);
54
+ } else {
55
+ originalCallback(null, __data);
56
+ _resolvePromise(__data);
57
+ }
58
+ };
59
+ }
60
+
61
+ _initiatorID = _initiatorID || ctx.userID;
62
+
63
+ threadID = threadID || ctx.threadID;
64
+
65
+ if (!threadID) {
66
+ return _callback(new Error("threadID is required to set an emoji."));
67
+ }
68
+ if (!emoji) {
69
+ return _callback(new Error("An emoji character is required."));
70
+ }
71
+
72
+ if (!ctx.mqttClient) {
73
+ return _callback(new Error("Not connected to MQTT"));
74
+ }
75
+
76
+ ctx.wsReqNumber += 1;
77
+ ctx.wsTaskNumber += 1;
78
+
79
+ const queryPayload = {
80
+ thread_key: threadID.toString(),
81
+ custom_emoji: emoji,
82
+ avatar_sticker_instruction_key_id: null,
83
+ sync_group: 1,
84
+ };
85
+
86
+ const query = {
87
+ failure_count: null,
88
+ label: '100003',
89
+ payload: JSON.stringify(queryPayload),
90
+ queue_name: 'thread_quick_reaction',
91
+ task_id: ctx.wsTaskNumber,
92
+ };
93
+
94
+ const context = {
95
+ app_id: ctx.appID,
96
+ payload: {
97
+ epoch_id: parseInt(utils.generateOfflineThreadingID()),
98
+ tasks: [query],
99
+ version_id: '24631415369801570',
100
+ },
101
+ request_id: ctx.wsReqNumber,
102
+ type: 3,
103
+ };
104
+ context.payload = JSON.stringify(context.payload);
105
+
106
+ ctx.mqttClient.publish('/ls_req', JSON.stringify(context), { qos: 1, retain: false }, (err) => {
107
+ if (err) {
108
+ return _callback(new Error(`MQTT publish failed for emoji: ${err.message || err}`));
109
+ }
110
+
111
+ const emojiChangeEvent = {
112
+ type: "thread_emoji_update",
113
+ threadID: threadID,
114
+ newEmoji: emoji,
115
+ senderID: _initiatorID,
116
+ BotID: ctx.userID,
117
+ timestamp: Date.now(),
118
+ };
119
+ _callback(null, emojiChangeEvent);
120
+ });
121
+
122
+ return returnPromise;
123
+ };
124
+ };
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ const log = require("npmlog");
4
+ const utils = require("../utils");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function fetchThemeData(themeID, callback) {
8
+ let resolveFunc, rejectFunc;
9
+ const promise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ const done = callback || function (err, data) {
15
+ if (err) return rejectFunc(err);
16
+ resolveFunc(data);
17
+ };
18
+
19
+ if (!themeID) {
20
+ done({ error: "Theme ID is a required parameter" });
21
+ return promise;
22
+ }
23
+
24
+ const payload = {
25
+ av: ctx.userID,
26
+ __user: ctx.userID,
27
+ __a: 1,
28
+ __req: utils.getSignatureID(),
29
+ fb_dtsg: ctx.fb_dtsg,
30
+ lsd: ctx.fb_dtsg,
31
+ jazoest: ctx.jazoest,
32
+ fb_api_caller_class: "RelayModern",
33
+ fb_api_req_friendly_name: "MWPThreadThemeProviderQuery",
34
+ variables: JSON.stringify({ id: themeID.toString() }),
35
+ server_timestamps: true,
36
+ doc_id: "9734829906576883"
37
+ };
38
+
39
+ defaultFuncs
40
+ .post("https://www.facebook.com/api/graphql/", ctx.jar, payload)
41
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
42
+ .then(async (res) => {
43
+ if (res.errors) throw res.errors;
44
+
45
+ const data = res?.data?.messenger_thread_theme;
46
+ if (!data) throw new Error("Theme data could not be located in the response");
47
+
48
+ const output = {
49
+ id: data.id,
50
+ name: data.accessibility_label,
51
+ description: data.description,
52
+ gradient_colors: data.gradient_colors || [data.fallback_color],
53
+ message_text_color: data.message_text_color || data.fallback_color,
54
+ title_bar_button_tint_color: data.title_bar_button_tint_color || data.fallback_color,
55
+ inbound_message_gradient_colors: data.inbound_message_gradient_colors || data.gradient_colors || [data.fallback_color],
56
+ composer_input_background_color: data.composer_input_background_color || data.fallback_color,
57
+ background_asset: data.background_asset || null,
58
+ alternative_themes: data.alternative_themes || [],
59
+ primary_color: data.gradient_colors?.[0] || data.fallback_color,
60
+ backgroundImage: data.background_asset?.image?.uri || null
61
+ };
62
+
63
+ // Fetch detailed data for the first alternative theme if available
64
+ if (output.alternative_themes.length > 0) {
65
+ try {
66
+ output.alternative_themes[0] = await api.fetchThemeData(output.alternative_themes[0]);
67
+ } catch (e) {
68
+ // If fetching fails, keep as ID
69
+ log.warn("fetchThemeData", `Failed to fetch alternative theme ${output.alternative_themes[0]}: ${e.message}`);
70
+ }
71
+ }
72
+
73
+ done(null, output);
74
+ })
75
+ .catch((err) => {
76
+ log.error("fetchThemeData", err);
77
+ done(err);
78
+ });
79
+
80
+ return promise;
81
+ };
82
+ };
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Author @YanMaglinte
5
+ * https://github.com/YANDEVA
6
+ * * Example:
7
+ * api.follow("100090794779367", true);
8
+ * jsdocs @ChoruOfficial
9
+ */
10
+
11
+ /**
12
+ * @param {object} defaultFuncs The default functions for making API requests.
13
+ * @param {object} api The full API object.
14
+ * @param {object} ctx The context object.
15
+ * @returns {function(senderID: string, boolean: boolean, callback?: (err: any, data?: any) => void): void} The follow function.
16
+ */
17
+ module.exports = function (defaultFuncs, api, ctx) {
18
+ /**
19
+ * Follows or unfollows a user on Facebook.
20
+ * @param {string} senderID The ID of the user to follow or unfollow.
21
+ * @param {boolean} boolean Set to `true` to follow the user, `false` to unfollow.
22
+ * @param {(err: any, data?: any) => void} [callback] An optional callback function.
23
+ */
24
+ return function follow(senderID, boolean, callback) {
25
+ let form;
26
+ if (boolean) {
27
+ form = {
28
+ av: ctx.userID,
29
+ fb_api_req_friendly_name: "CometUserFollowMutation",
30
+ fb_api_caller_class: "RelayModern",
31
+ doc_id: "25472099855769847",
32
+ variables: JSON.stringify({
33
+ input: {
34
+ attribution_id_v2:
35
+ "ProfileCometTimelineListViewRoot.react,comet.profile.timeline.list,via_cold_start,1717249218695,723451,250100865708545,,",
36
+ is_tracking_encrypted: true,
37
+ subscribe_location: "PROFILE",
38
+ subscribee_id: senderID,
39
+ tracking: null,
40
+ actor_id: ctx.userID,
41
+ client_mutation_id: "1",
42
+ },
43
+ scale: 1,
44
+ }),
45
+ };
46
+ } else {
47
+ form = {
48
+ av: ctx.userID,
49
+ fb_api_req_friendly_name: "CometUserUnfollowMutation",
50
+ fb_api_caller_class: "RelayModern",
51
+ doc_id: "25472099855769847",
52
+ variables: JSON.stringify({
53
+ action_render_location: "WWW_COMET_FRIEND_MENU",
54
+ input: {
55
+ attribution_id_v2:
56
+ "ProfileCometTimelineListViewRoot.react,comet.profile.timeline.list,tap_search_bar,1717294006136,602597,250100865708545,,",
57
+ is_tracking_encrypted: true,
58
+ subscribe_location: "PROFILE",
59
+ tracking: null,
60
+ unsubscribee_id: senderID,
61
+ actor_id: ctx.userID,
62
+ client_mutation_id: "10",
63
+ },
64
+ scale: 1,
65
+ }),
66
+ };
67
+ }
68
+
69
+ api.httpPost("https://www.facebook.com/api/graphql/", form, (err, data) => {
70
+ if (err) {
71
+ if (typeof callback === "function") {
72
+ callback(err);
73
+ }
74
+ } else {
75
+ if (typeof callback === "function") {
76
+ callback(null, data);
77
+ }
78
+ }
79
+ });
80
+ };
81
+ };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function forwardMessage(messageID, threadIDs, callback) {
7
+ let resolveFunc = () => {};
8
+ let rejectFunc = () => {};
9
+ const returnPromise = new Promise((resolve, reject) => {
10
+ resolveFunc = resolve;
11
+ rejectFunc = reject;
12
+ });
13
+
14
+ if (!callback) {
15
+ callback = (err, result) => {
16
+ if (err) return rejectFunc(err);
17
+ resolveFunc(result);
18
+ };
19
+ }
20
+
21
+ try {
22
+ if (!Array.isArray(threadIDs)) {
23
+ threadIDs = [threadIDs];
24
+ }
25
+
26
+ const form = {
27
+ message_id: messageID
28
+ };
29
+
30
+ threadIDs.forEach(id => {
31
+ form[`recipient_ids[${id}]`] = id;
32
+ });
33
+
34
+ const res = await defaultFuncs.post(
35
+ "https://www.facebook.com/ajax/mercury/forward_message.php",
36
+ ctx.jar,
37
+ form
38
+ ).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
39
+
40
+ if (res && res.error) {
41
+ throw res;
42
+ }
43
+
44
+ callback(null, { success: true, forwardedTo: threadIDs });
45
+ } catch (err) {
46
+ utils.error("forwardMessage", err);
47
+ callback(err);
48
+ }
49
+
50
+ return returnPromise;
51
+ };
52
+ };