@cexy/hoonfca 1.0.1 → 1.0.2

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 (170) hide show
  1. package/.travis.yml +6 -0
  2. package/LICENSE-MIT +21 -0
  3. package/index.d.ts +620 -0
  4. package/index.js +778 -1
  5. package/package.json +31 -84
  6. package/src/{apis/addExternalModule.js → addExternalModule.js} +4 -5
  7. package/src/addUserToGroup.js +113 -0
  8. package/src/changeAdminStatus.js +95 -0
  9. package/src/changeApprovalMode.js +79 -0
  10. package/src/changeArchivedStatus.js +55 -0
  11. package/src/changeBio.js +76 -0
  12. package/src/changeBlockedStatus.js +47 -0
  13. package/src/changeBlockedStatusMqtt.js +86 -0
  14. package/src/changeGroupImage.js +133 -0
  15. package/src/changeNickname.js +59 -0
  16. package/src/changeThreadColor.js +71 -0
  17. package/src/{apis/changeThreadEmoji.js → changeThreadEmoji.js} +8 -6
  18. package/src/createNewGroup.js +88 -0
  19. package/src/createPoll.js +130 -0
  20. package/src/deleteMessage.js +56 -0
  21. package/src/deleteThread.js +56 -0
  22. package/src/editMessage.js +63 -0
  23. package/src/forwardAttachment.js +60 -0
  24. package/src/forwardMessage.js +63 -0
  25. package/src/getCurrentUserID.js +7 -0
  26. package/src/getEmojiUrl.js +29 -0
  27. package/src/getFriendsList.js +84 -0
  28. package/src/getGroupsList.js +83 -0
  29. package/src/getMarketplace.js +84 -0
  30. package/src/getNotifications.js +86 -0
  31. package/src/getPagesList.js +83 -0
  32. package/src/getStories.js +88 -0
  33. package/src/getThreadHistory.js +647 -0
  34. package/src/getThreadInfo.js +222 -0
  35. package/src/getThreadList.js +292 -0
  36. package/src/getThreadPictures.js +79 -0
  37. package/src/getUserID.js +66 -0
  38. package/src/getUserInfo.js +128 -0
  39. package/src/handleFriendRequest.js +57 -0
  40. package/src/handleMessageRequest.js +65 -0
  41. package/src/{apis/httpGet.js → httpGet.js} +15 -20
  42. package/src/httpPost.js +58 -0
  43. package/src/listenMqtt.js +1018 -0
  44. package/src/logout.js +75 -0
  45. package/src/markAsDelivered.js +58 -0
  46. package/src/{apis/markAsRead.js → markAsRead.js} +19 -30
  47. package/src/markAsReadAll.js +50 -0
  48. package/src/markAsSeen.js +61 -0
  49. package/src/muteThread.js +52 -0
  50. package/src/pinMessage.js +61 -0
  51. package/src/removeUserFromGroup.js +79 -0
  52. package/src/resolvePhotoUrl.js +45 -0
  53. package/src/searchForThread.js +53 -0
  54. package/src/searchUsers.js +89 -0
  55. package/src/sendComment.js +161 -0
  56. package/src/sendMessage.js +457 -0
  57. package/src/sendTypingIndicator.js +179 -0
  58. package/src/setBio.js +86 -0
  59. package/src/setMessageReaction.js +186 -0
  60. package/src/setPostReaction.js +71 -0
  61. package/src/setTheme.js +313 -0
  62. package/src/setTitle.js +90 -0
  63. package/src/shareContact.js +53 -0
  64. package/src/shareLink.js +62 -0
  65. package/src/threadColors.js +57 -0
  66. package/src/unfriend.js +53 -0
  67. package/src/unsendMessage.js +104 -0
  68. package/utils.js +1447 -0
  69. package/LICENSE +0 -3
  70. package/README.md +0 -491
  71. package/examples/login-with-cookies.js +0 -102
  72. package/examples/verify.js +0 -70
  73. package/src/apis/addUserToGroup.js +0 -108
  74. package/src/apis/changeAdminStatus.js +0 -148
  75. package/src/apis/changeArchivedStatus.js +0 -61
  76. package/src/apis/changeAvatar.js +0 -103
  77. package/src/apis/changeBio.js +0 -69
  78. package/src/apis/changeBlockedStatus.js +0 -54
  79. package/src/apis/changeGroupImage.js +0 -136
  80. package/src/apis/changeThreadColor.js +0 -116
  81. package/src/apis/comment.js +0 -207
  82. package/src/apis/createAITheme.js +0 -129
  83. package/src/apis/createNewGroup.js +0 -79
  84. package/src/apis/createPoll.js +0 -73
  85. package/src/apis/deleteMessage.js +0 -44
  86. package/src/apis/deleteThread.js +0 -52
  87. package/src/apis/e2ee.js +0 -17
  88. package/src/apis/editMessage.js +0 -70
  89. package/src/apis/emoji.js +0 -124
  90. package/src/apis/fetchThemeData.js +0 -82
  91. package/src/apis/follow.js +0 -81
  92. package/src/apis/forwardMessage.js +0 -52
  93. package/src/apis/friend.js +0 -243
  94. package/src/apis/gcmember.js +0 -122
  95. package/src/apis/gcname.js +0 -123
  96. package/src/apis/gcrule.js +0 -119
  97. package/src/apis/getAccess.js +0 -111
  98. package/src/apis/getBotInfo.js +0 -88
  99. package/src/apis/getBotInitialData.js +0 -43
  100. package/src/apis/getFriendsList.js +0 -79
  101. package/src/apis/getMessage.js +0 -423
  102. package/src/apis/getTheme.js +0 -95
  103. package/src/apis/getThemeInfo.js +0 -116
  104. package/src/apis/getThreadHistory.js +0 -239
  105. package/src/apis/getThreadInfo.js +0 -267
  106. package/src/apis/getThreadList.js +0 -232
  107. package/src/apis/getThreadPictures.js +0 -58
  108. package/src/apis/getUserID.js +0 -117
  109. package/src/apis/getUserInfo.js +0 -513
  110. package/src/apis/getUserInfoV2.js +0 -146
  111. package/src/apis/handleMessageRequest.js +0 -50
  112. package/src/apis/httpPost.js +0 -89
  113. package/src/apis/httpPostFormData.js +0 -69
  114. package/src/apis/listenMqtt.js +0 -1236
  115. package/src/apis/listenSpeed.js +0 -179
  116. package/src/apis/logout.js +0 -87
  117. package/src/apis/markAsDelivered.js +0 -47
  118. package/src/apis/markAsReadAll.js +0 -40
  119. package/src/apis/markAsSeen.js +0 -70
  120. package/src/apis/mqttDeltaValue.js +0 -278
  121. package/src/apis/muteThread.js +0 -45
  122. package/src/apis/nickname.js +0 -132
  123. package/src/apis/notes.js +0 -163
  124. package/src/apis/pinMessage.js +0 -150
  125. package/src/apis/produceMetaTheme.js +0 -180
  126. package/src/apis/realtime.js +0 -182
  127. package/src/apis/removeUserFromGroup.js +0 -117
  128. package/src/apis/resolvePhotoUrl.js +0 -58
  129. package/src/apis/searchForThread.js +0 -154
  130. package/src/apis/sendMessage.js +0 -354
  131. package/src/apis/sendMessageMqtt.js +0 -249
  132. package/src/apis/sendTypingIndicator.js +0 -91
  133. package/src/apis/setMessageReaction.js +0 -27
  134. package/src/apis/setMessageReactionMqtt.js +0 -61
  135. package/src/apis/setThreadTheme.js +0 -260
  136. package/src/apis/setThreadThemeMqtt.js +0 -94
  137. package/src/apis/share.js +0 -107
  138. package/src/apis/shareContact.js +0 -66
  139. package/src/apis/stickers.js +0 -257
  140. package/src/apis/story.js +0 -181
  141. package/src/apis/theme.js +0 -233
  142. package/src/apis/unfriend.js +0 -47
  143. package/src/apis/unsendMessage.js +0 -17
  144. package/src/engine/client.js +0 -92
  145. package/src/engine/models/buildAPI.js +0 -152
  146. package/src/engine/models/loginHelper.js +0 -519
  147. package/src/engine/models/setOptions.js +0 -88
  148. package/src/security/e2ee.js +0 -109
  149. package/src/types/index.d.ts +0 -498
  150. package/src/utils/antiSuspension.js +0 -506
  151. package/src/utils/auth-helpers.js +0 -149
  152. package/src/utils/autoReLogin.js +0 -336
  153. package/src/utils/axios.js +0 -436
  154. package/src/utils/cache.js +0 -54
  155. package/src/utils/clients.js +0 -282
  156. package/src/utils/constants.js +0 -410
  157. package/src/utils/formatters/data/formatAttachment.js +0 -370
  158. package/src/utils/formatters/data/formatDelta.js +0 -109
  159. package/src/utils/formatters/index.js +0 -159
  160. package/src/utils/formatters/value/formatCookie.js +0 -91
  161. package/src/utils/formatters/value/formatDate.js +0 -36
  162. package/src/utils/formatters/value/formatID.js +0 -16
  163. package/src/utils/formatters.js +0 -1373
  164. package/src/utils/headers.js +0 -230
  165. package/src/utils/index.js +0 -153
  166. package/src/utils/monitoring.js +0 -333
  167. package/src/utils/rateLimiter.js +0 -319
  168. package/src/utils/tokenRefresh.js +0 -657
  169. package/src/utils/user-agents.js +0 -238
  170. package/src/utils/validation.js +0 -157
@@ -1,94 +0,0 @@
1
- 'use strict';
2
-
3
- const utils = require('../utils');
4
-
5
- module.exports = function (defaultFuncs, api, ctx) {
6
- return function setThreadThemeMqtt(threadID, themeFBID, callback) {
7
- if (!ctx.mqttClient) {
8
- throw new Error('Not connected to MQTT');
9
- }
10
-
11
- ctx.wsReqNumber += 1;
12
- let baseTaskNumber = ++ctx.wsTaskNumber;
13
-
14
- const makeTask = (label, queueName, extraPayload = {}) => ({
15
- failure_count: null,
16
- label: String(label),
17
- payload: JSON.stringify({
18
- thread_key: threadID,
19
- theme_fbid: themeFBID,
20
- sync_group: 1,
21
- ...extraPayload,
22
- }),
23
- queue_name: typeof queueName === 'string' ? queueName : JSON.stringify(queueName),
24
- task_id: baseTaskNumber++,
25
- });
26
-
27
- const messages = [
28
- {
29
- label: 1013,
30
- queue: ['ai_generated_theme', String(threadID)],
31
- },
32
- {
33
- label: 1037,
34
- queue: ['msgr_custom_thread_theme', String(threadID)],
35
- },
36
- {
37
- label: 1028,
38
- queue: ['thread_theme_writer', String(threadID)],
39
- },
40
- {
41
- label: 43,
42
- queue: 'thread_theme',
43
- extra: { source: null, payload: null },
44
- },
45
- ].map(({ label, queue, extra }) => {
46
- ctx.wsReqNumber += 1;
47
- return {
48
- app_id: '772021112871879',
49
- payload: JSON.stringify({
50
- epoch_id: parseInt(utils.generateOfflineThreadingID()),
51
- tasks: [makeTask(label, queue, extra)],
52
- version_id: '24227364673632991',
53
- }),
54
- request_id: ctx.wsReqNumber,
55
- type: 3,
56
- };
57
- });
58
-
59
- // Return promise if no callback provided
60
- if (!callback) {
61
- return new Promise((resolve, reject) => {
62
- try {
63
- messages.forEach((msg, idx) => {
64
- ctx.mqttClient.publish(
65
- '/ls_req',
66
- JSON.stringify(msg),
67
- { qos: 1, retain: false },
68
- idx === messages.length - 1 ? (err) => {
69
- if (err) reject(err);
70
- else resolve();
71
- } : undefined
72
- );
73
- });
74
- } catch (err) {
75
- reject(err);
76
- }
77
- });
78
- }
79
-
80
- // Callback mode
81
- try {
82
- messages.forEach((msg, idx) => {
83
- ctx.mqttClient.publish(
84
- '/ls_req',
85
- JSON.stringify(msg),
86
- { qos: 1, retain: false },
87
- idx === messages.length - 1 ? callback : undefined
88
- );
89
- });
90
- } catch (err) {
91
- callback(err);
92
- }
93
- };
94
- };
package/src/apis/share.js DELETED
@@ -1,107 +0,0 @@
1
- "use strict";
2
-
3
- const utils = require('../utils');
4
-
5
- function formatPreviewResult(data) {
6
- if (data.errors) {
7
- throw data.errors[0];
8
- }
9
- const previewData = data.data?.xma_preview_data;
10
- if (!previewData) {
11
- throw { error: "Could not generate a preview for this post." };
12
- }
13
- return {
14
- postID: previewData.post_id,
15
- header: previewData.header_title,
16
- subtitle: previewData.subtitle_text,
17
- title: previewData.title_text,
18
- previewImage: previewData.preview_url,
19
- favicon: previewData.favicon_url,
20
- headerImage: previewData.header_image_url
21
- };
22
- }
23
-
24
- module.exports = function(defaultFuncs, api, ctx) {
25
- return async function getPostPreview(postID, callback) {
26
- let resolveFunc, rejectFunc;
27
- const returnPromise = new Promise((resolve, reject) => {
28
- resolveFunc = resolve;
29
- rejectFunc = reject;
30
- });
31
-
32
- const cb = (err, data) => {
33
- if (callback) callback(err, data);
34
- if (err) return rejectFunc(err);
35
- resolveFunc(data);
36
- };
37
- if (!postID) {
38
- cb({ error: "A postID is required to generate a preview." });
39
- return returnPromise;
40
- }
41
-
42
- const variables = {
43
- shareable_id: postID.toString(),
44
- scale: 3,
45
- };
46
-
47
- // Use configurable doc_id or default (may be outdated)
48
- // To update:
49
- // 1. Open Facebook Messenger in browser
50
- // 2. Open DevTools (F12) → Network tab → Filter by "graphql"
51
- // 3. Trigger a share/preview action
52
- // 4. Look for CometXMAProxyShareablePreviewQuery request
53
- // 5. Copy the doc_id value from the request payload
54
- // 6. Set ctx.options.sharePreviewDocId = 'NEW_DOC_ID' when logging in
55
- //
56
- // Known doc_ids (may expire):
57
- // - 28939050904374351 (expired as of Nov 2024)
58
- // - Check ws3-fca or @dongdev packages for potential updates
59
- const docId = ctx.options?.sharePreviewDocId || '28939050904374351';
60
-
61
- const form = {
62
- fb_api_caller_class: 'RelayModern',
63
- fb_api_req_friendly_name: 'CometXMAProxyShareablePreviewQuery',
64
- variables: JSON.stringify(variables),
65
- doc_id: docId
66
- };
67
-
68
- try {
69
- const resData = await defaultFuncs
70
- .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
71
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
72
-
73
- // Check for persisted query not found error (case-insensitive)
74
- if (resData?.errors) {
75
- const persistedQueryError = resData.errors.find(e => {
76
- const msg = (e.message || '').toLowerCase();
77
- return msg.includes('persistedquerynotfound') ||
78
- msg.includes('document') && msg.includes('not found') ||
79
- msg.includes('persisted query');
80
- });
81
- if (persistedQueryError) {
82
- const error = {
83
- error: "Facebook GraphQL doc_id expired. Please update ctx.options.sharePreviewDocId",
84
- details: "Capture the current doc_id from Messenger web traffic (inspect CometXMAProxyShareablePreviewQuery request)",
85
- currentDocId: docId,
86
- fbError: persistedQueryError.message
87
- };
88
- utils.error("getPostPreview", error);
89
- cb(error);
90
- return returnPromise;
91
- }
92
- }
93
-
94
- const result = formatPreviewResult(resData);
95
- cb(null, result);
96
- return returnPromise;
97
- } catch (err) {
98
- // Add helpful context for common failure modes
99
- if (err.message?.includes('UNHANDLED_REJECTION') || err.message?.includes('not found')) {
100
- err.hint = "The GraphQL doc_id may be outdated. Set ctx.options.sharePreviewDocId with current value from Messenger traffic.";
101
- }
102
- utils.error("getPostPreview", err);
103
- cb(err);
104
- return returnPromise;
105
- }
106
- };
107
- };
@@ -1,66 +0,0 @@
1
- /* eslint-disable linebreak-style */
2
- "use strict";
3
-
4
- const utils = require('../utils');
5
-
6
- /**
7
- * @module shareContact
8
- * @param {Object} defaultFuncs - The default functions provided by the API.
9
- * @param {Object} api - The full API object.
10
- * @param {Object} ctx - The context object.
11
- * @returns {function(text: string, senderID: string, threadID: string, callback: Function): void} - A function to share a contact.
12
- */
13
- module.exports = function(defaultFuncs, api, ctx) {
14
- /**
15
- * Shares a user's contact information into a specific thread via MQTT.
16
- * @param {string} [text] - An optional message to send along with the contact card.
17
- * @param {string} senderID - The Facebook user ID of the contact you want to share.
18
- * @param {string} threadID - The ID of the thread where the contact will be shared.
19
- * @param {Function} [callback] - An optional callback function to be executed.
20
- */
21
- return function shareContact(text, senderID, threadID, callback) {
22
- if (!ctx.mqttClient) {
23
- throw new Error('Not connected to MQTT');
24
- }
25
-
26
- ctx.wsReqNumber ??= 0;
27
- ctx.wsTaskNumber ??= 0;
28
-
29
- ctx.wsReqNumber += 1;
30
- ctx.wsTaskNumber += 1;
31
-
32
- const queryPayload = {
33
- contact_id: senderID,
34
- sync_group: 1,
35
- text: text || "",
36
- thread_id: threadID
37
- };
38
-
39
- const query = {
40
- failure_count: null,
41
- label: '359',
42
- payload: JSON.stringify(queryPayload),
43
- queue_name: 'messenger_contact_sharing',
44
- task_id: Math.random() * 1001 << 0,
45
- };
46
-
47
- const context = {
48
- app_id: '2220391788200892',
49
- payload: {
50
- tasks: [query],
51
- epoch_id: utils.generateOfflineThreadingID(),
52
- version_id: '7214102258676893',
53
- },
54
- request_id: ctx.wsReqNumber,
55
- type: 3,
56
- };
57
-
58
- context.payload = JSON.stringify(context.payload);
59
-
60
- if (typeof callback === 'function') {
61
- ctx.callback_Task[ctx.wsReqNumber] = { callback, type: "shareContact" };
62
- }
63
-
64
- ctx.mqttClient.publish('/ls_req', JSON.stringify(context), { qos: 1, retain: false });
65
- };
66
- };
@@ -1,257 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * Sticker API Module
5
- * Provides access to Facebook's GraphQL-based sticker endpoints.
6
- * Made by @ChoruOfficial
7
- */
8
-
9
- const utils = require('../utils');
10
- /**
11
- * Format the sticker pack list (store or tray)
12
- * @param {object} data - Raw GraphQL response
13
- * @returns {{ packs: Array<{id: string, name: string, thumbnail: string}>, page_info: object, store_id?: string }}
14
- */
15
- function formatPackList(data) {
16
- const trayPacks = data?.data?.picker_plugins?.sticker_picker?.sticker_store?.tray_packs?.edges;
17
- const storePacks = data?.data?.viewer?.sticker_store?.available_packs?.edges;
18
-
19
- const packData = storePacks || trayPacks;
20
- if (!packData || !packData.edges) return { packs: [], page_info: { has_next_page: false } };
21
-
22
- const formattedPacks = packData.edges.map(edge => edge.node ? ({
23
- id: edge.node.id,
24
- name: edge.node.name,
25
- thumbnail: edge.node.thumbnail_image?.uri
26
- }) : null).filter(Boolean);
27
-
28
- return {
29
- packs: formattedPacks,
30
- page_info: packData.page_info,
31
- store_id: data?.data?.viewer?.sticker_store?.id
32
- };
33
- }
34
-
35
- /**
36
- * Format search result stickers
37
- * @param {object} data - Raw GraphQL response
38
- * @returns {Array<Object>}
39
- */
40
- function formatStickerSearchResults(data) {
41
- const stickers = data?.data?.sticker_search?.sticker_results?.edges;
42
- if (!stickers) return [];
43
- return stickers.map(edge => edge.node ? ({
44
- type: "sticker",
45
- ID: edge.node.id,
46
- url: edge.node.image?.uri,
47
- animatedUrl: edge.node.animated_image?.uri,
48
- packID: edge.node.pack?.id,
49
- label: edge.node.label || edge.node.accessibility_label,
50
- stickerID: edge.node.id
51
- }) : null).filter(Boolean);
52
- }
53
-
54
- /**
55
- * Format sticker pack content
56
- * @param {object} data - Raw GraphQL response
57
- * @returns {Array<Object>}
58
- */
59
- function formatStickerPackResults(data) {
60
- const stickers = data?.data?.sticker_pack?.stickers?.edges;
61
- if (!stickers) return [];
62
- return stickers.map(edge => edge.node ? ({
63
- type: "sticker",
64
- ID: edge.node.id,
65
- url: edge.node.image?.uri,
66
- animatedUrl: edge.node.animated_image?.uri,
67
- packID: edge.node.pack?.id,
68
- label: edge.node.label || edge.node.accessibility_label,
69
- stickerID: edge.node.id
70
- }) : null).filter(Boolean);
71
- }
72
-
73
- /**
74
- * Format AI-generated stickers
75
- * @param {object} data - Raw GraphQL response
76
- * @returns {Array<Object>}
77
- */
78
- function formatAiStickers(data) {
79
- const stickers = data?.data?.xfb_trending_generated_ai_stickers?.nodes;
80
- if (!stickers) return [];
81
- return stickers.map(node => ({
82
- type: "sticker",
83
- ID: node.id,
84
- url: node.url,
85
- label: node.label,
86
- stickerID: node.id
87
- })).filter(Boolean);
88
- }
89
-
90
- module.exports = function(defaultFuncs, api, ctx) {
91
- /**
92
- * Make a GraphQL request and handle login and error checking
93
- * @param {object} form - Form data for the request
94
- * @returns {Promise<object>}
95
- */
96
- async function makeRequest(form) {
97
- const resData = await defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
98
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
99
- if (!resData) throw new Error("GraphQL request returned no data.");
100
- if (resData.errors) {
101
- utils.error("StickerAPI GraphQL Error", resData.errors[0].message);
102
- throw resData.errors[0];
103
- }
104
- return resData;
105
- }
106
-
107
- return {
108
- /**
109
- * Search for stickers by keyword
110
- * @param {string} query - Search term
111
- * @returns {Promise<Array<Object>>}
112
- */
113
- search: async function(query) {
114
- const form = {
115
- fb_api_caller_class: 'RelayModern',
116
- fb_api_req_friendly_name: 'CometStickerPickerSearchResultsRootQuery',
117
- variables: JSON.stringify({
118
- scale: 3,
119
- search_query: query,
120
- sticker_height: 128,
121
- sticker_width: 128,
122
- stickerInterface: "MESSAGES"
123
- }),
124
- doc_id: '24004987559125954'
125
- };
126
- const res = await makeRequest(form);
127
- return formatStickerSearchResults(res);
128
- },
129
-
130
- /**
131
- * List user's sticker packs
132
- * @returns {Promise<Array<Object>>}
133
- */
134
- listPacks: async function() {
135
- const form = {
136
- fb_api_caller_class: 'RelayModern',
137
- fb_api_req_friendly_name: 'CometStickerPickerCardQuery',
138
- variables: JSON.stringify({ scale: 3, stickerInterface: "MESSAGES" }),
139
- doc_id: '10095807770482952'
140
- };
141
- const res = await makeRequest(form);
142
- return formatPackList(res).packs;
143
- },
144
-
145
- /**
146
- * Get all available sticker packs from the store (with pagination)
147
- * @returns {Promise<Array<Object>>}
148
- */
149
- getStorePacks: async function() {
150
- utils.log("Starting to fetch all sticker packs from store...");
151
- let allPacks = [];
152
-
153
- const initialForm = {
154
- fb_api_caller_class: 'RelayModern',
155
- fb_api_req_friendly_name: 'CometStickersStoreDialogQuery',
156
- variables: JSON.stringify({}),
157
- doc_id: '29237828849196584'
158
- };
159
- let res = await makeRequest(initialForm);
160
- let { packs, page_info, store_id } = formatPackList(res);
161
- allPacks.push(...packs);
162
- utils.log(`Fetched first page with ${packs.length} packs.`);
163
-
164
- while (page_info && page_info.has_next_page) {
165
- utils.log("Fetching next page with cursor:", page_info.end_cursor);
166
-
167
- const paginatedForm = {
168
- fb_api_caller_class: 'RelayModern',
169
- fb_api_req_friendly_name: 'CometStickersStorePackListPaginationQuery',
170
- variables: JSON.stringify({
171
- count: 20,
172
- cursor: page_info.end_cursor,
173
- id: store_id
174
- }),
175
- doc_id: '9898634630218439'
176
- };
177
- res = await makeRequest(paginatedForm);
178
- let paginatedResult = formatPackList(res);
179
- allPacks.push(...paginatedResult.packs);
180
- page_info = paginatedResult.page_info;
181
- utils.log(`Fetched ${paginatedResult.packs.length} more packs. Total now: ${allPacks.length}`);
182
- }
183
-
184
- utils.log(`Finished fetching. Total unique packs found: ${allPacks.length}`);
185
- return allPacks;
186
- },
187
-
188
- /**
189
- * Merge user's and store sticker packs into one list
190
- * @returns {Promise<Array<Object>>}
191
- */
192
- listAllPacks: async function() {
193
- const [myPacks, storePacks] = await Promise.all([
194
- this.listPacks(),
195
- this.getStorePacks()
196
- ]);
197
- const allPacksMap = new Map();
198
- myPacks.forEach(pack => allPacksMap.set(pack.id, pack));
199
- storePacks.forEach(pack => allPacksMap.set(pack.id, pack));
200
- return Array.from(allPacksMap.values());
201
- },
202
-
203
- /**
204
- * Add a sticker pack by ID
205
- * @param {string} packID - The ID of the sticker pack
206
- * @returns {Promise<Object>}
207
- */
208
- addPack: async function(packID) {
209
- const form = {
210
- fb_api_caller_class: 'RelayModern',
211
- fb_api_req_friendly_name: 'CometStickersStorePackMutationAddMutation',
212
- variables: JSON.stringify({
213
- input: {
214
- pack_id: packID,
215
- actor_id: ctx.userID,
216
- client_mutation_id: Math.round(Math.random() * 10).toString()
217
- }
218
- }),
219
- doc_id: '9877489362345320'
220
- };
221
- const res = await makeRequest(form);
222
- return res.data.sticker_pack_add.sticker_pack;
223
- },
224
-
225
- /**
226
- * Get all stickers in a pack
227
- * @param {string} packID - Sticker pack ID
228
- * @returns {Promise<Array<Object>>}
229
- */
230
- getStickersInPack: async function(packID) {
231
- const form = {
232
- fb_api_caller_class: 'RelayModern',
233
- fb_api_req_friendly_name: 'CometStickerPickerPackContentRootQuery',
234
- variables: JSON.stringify({ packID, stickerWidth: 128, stickerHeight: 128, scale: 3 }),
235
- doc_id: '23982341384707469'
236
- };
237
- const res = await makeRequest(form);
238
- return formatStickerPackResults(res);
239
- },
240
-
241
- /**
242
- * Get trending AI-generated stickers
243
- * @param {{ limit?: number }} options - Options object
244
- * @returns {Promise<Array<Object>>}
245
- */
246
- getAiStickers: async function({ limit = 10 } = {}) {
247
- const form = {
248
- fb_api_caller_class: 'RelayModern',
249
- fb_api_req_friendly_name: 'CometStickerPickerStickerGeneratedCardQuery',
250
- variables: JSON.stringify({ limit }),
251
- doc_id: '24151467751156443'
252
- };
253
- const res = await makeRequest(form);
254
- return formatAiStickers(res);
255
- }
256
- };
257
- };