@cexy/hoonfca 1.0.7 → 2.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 (191) hide show
  1. package/LICENSE +3 -0
  2. package/examples/login-with-cookies.js +102 -0
  3. package/examples/verify.js +70 -0
  4. package/index.js +2 -8
  5. package/package.json +82 -61
  6. package/src/{api/action → apis}/addExternalModule.js +24 -25
  7. package/src/apis/addUserToGroup.js +108 -0
  8. package/src/apis/changeAdminStatus.js +148 -0
  9. package/src/apis/changeArchivedStatus.js +61 -0
  10. package/src/apis/changeAvatar.js +103 -0
  11. package/src/apis/changeBio.js +69 -0
  12. package/src/apis/changeBlockedStatus.js +54 -0
  13. package/src/apis/changeGroupImage.js +136 -0
  14. package/src/apis/changeThreadColor.js +116 -0
  15. package/src/apis/changeThreadEmoji.js +53 -0
  16. package/src/apis/comment.js +207 -0
  17. package/src/apis/createAITheme.js +129 -0
  18. package/src/apis/createNewGroup.js +79 -0
  19. package/src/apis/createPoll.js +73 -0
  20. package/src/apis/deleteMessage.js +44 -0
  21. package/src/apis/deleteThread.js +52 -0
  22. package/src/apis/e2ee.js +17 -0
  23. package/src/apis/editMessage.js +70 -0
  24. package/src/apis/emoji.js +124 -0
  25. package/src/apis/fetchThemeData.js +82 -0
  26. package/src/apis/follow.js +81 -0
  27. package/src/apis/forwardMessage.js +52 -0
  28. package/src/apis/friend.js +243 -0
  29. package/src/apis/gcmember.js +122 -0
  30. package/src/apis/gcname.js +123 -0
  31. package/src/apis/gcrule.js +119 -0
  32. package/src/apis/getAccess.js +111 -0
  33. package/src/apis/getBotInfo.js +88 -0
  34. package/src/apis/getBotInitialData.js +43 -0
  35. package/src/apis/getFriendsList.js +79 -0
  36. package/src/apis/getMessage.js +423 -0
  37. package/src/apis/getTheme.js +95 -0
  38. package/src/apis/getThemeInfo.js +116 -0
  39. package/src/apis/getThreadHistory.js +239 -0
  40. package/src/apis/getThreadInfo.js +267 -0
  41. package/src/apis/getThreadList.js +232 -0
  42. package/src/apis/getThreadPictures.js +58 -0
  43. package/src/apis/getUserID.js +117 -0
  44. package/src/apis/getUserInfo.js +513 -0
  45. package/src/{api/users → apis}/getUserInfoV2.js +146 -134
  46. package/src/apis/handleMessageRequest.js +50 -0
  47. package/src/apis/httpGet.js +63 -0
  48. package/src/apis/httpPost.js +89 -0
  49. package/src/apis/httpPostFormData.js +69 -0
  50. package/src/apis/listenMqtt.js +1236 -0
  51. package/src/apis/listenSpeed.js +179 -0
  52. package/src/apis/logout.js +87 -0
  53. package/src/apis/markAsDelivered.js +47 -0
  54. package/src/{api/messaging → apis}/markAsRead.js +99 -88
  55. package/src/apis/markAsReadAll.js +40 -0
  56. package/src/apis/markAsSeen.js +70 -0
  57. package/src/apis/mqttDeltaValue.js +278 -0
  58. package/src/apis/muteThread.js +45 -0
  59. package/src/apis/nickname.js +132 -0
  60. package/src/apis/notes.js +163 -0
  61. package/src/apis/pinMessage.js +150 -0
  62. package/src/apis/produceMetaTheme.js +180 -0
  63. package/src/apis/realtime.js +182 -0
  64. package/src/apis/removeUserFromGroup.js +117 -0
  65. package/src/apis/resolvePhotoUrl.js +58 -0
  66. package/src/apis/searchForThread.js +154 -0
  67. package/src/apis/sendMessage.js +354 -0
  68. package/src/apis/sendMessageMqtt.js +249 -0
  69. package/src/apis/sendTypingIndicator.js +91 -0
  70. package/src/apis/setMessageReaction.js +27 -0
  71. package/src/apis/setMessageReactionMqtt.js +61 -0
  72. package/src/apis/setThreadTheme.js +260 -0
  73. package/src/apis/setThreadThemeMqtt.js +94 -0
  74. package/src/apis/share.js +107 -0
  75. package/src/apis/shareContact.js +66 -0
  76. package/src/apis/stickers.js +257 -0
  77. package/src/apis/story.js +181 -0
  78. package/src/apis/theme.js +233 -0
  79. package/src/apis/unfriend.js +47 -0
  80. package/src/apis/unsendMessage.js +17 -0
  81. package/src/engine/client.js +92 -0
  82. package/src/engine/models/buildAPI.js +152 -0
  83. package/src/engine/models/loginHelper.js +519 -0
  84. package/src/engine/models/setOptions.js +88 -0
  85. package/src/security/e2ee.js +109 -0
  86. package/src/types/index.d.ts +498 -0
  87. package/src/utils/antiSuspension.js +506 -0
  88. package/src/utils/auth-helpers.js +149 -0
  89. package/src/utils/autoReLogin.js +336 -0
  90. package/src/utils/axios.js +436 -0
  91. package/src/utils/cache.js +54 -0
  92. package/src/utils/clients.js +282 -0
  93. package/src/utils/constants.js +410 -23
  94. package/src/utils/formatters/data/formatAttachment.js +370 -0
  95. package/src/utils/formatters/data/formatDelta.js +109 -0
  96. package/src/utils/formatters/index.js +159 -0
  97. package/src/utils/formatters/value/formatCookie.js +91 -0
  98. package/src/utils/formatters/value/formatDate.js +36 -0
  99. package/src/utils/formatters/value/formatID.js +16 -0
  100. package/src/utils/formatters.js +1373 -0
  101. package/src/utils/headers.js +214 -99
  102. package/src/utils/index.js +153 -0
  103. package/src/utils/monitoring.js +333 -0
  104. package/src/utils/rateLimiter.js +319 -0
  105. package/src/utils/tokenRefresh.js +657 -0
  106. package/src/utils/user-agents.js +238 -0
  107. package/src/utils/validation.js +157 -0
  108. package/CHANGELOG.md +0 -181
  109. package/DOCS.md +0 -2636
  110. package/LICENSE-MIT +0 -21
  111. package/README.md +0 -632
  112. package/func/checkUpdate.js +0 -233
  113. package/func/logger.js +0 -48
  114. package/index.d.ts +0 -746
  115. package/module/config.js +0 -67
  116. package/module/login.js +0 -154
  117. package/module/loginHelper.js +0 -1034
  118. package/module/options.js +0 -54
  119. package/src/api/action/changeAvatar.js +0 -137
  120. package/src/api/action/changeBio.js +0 -75
  121. package/src/api/action/enableAutoSaveAppState.js +0 -73
  122. package/src/api/action/getCurrentUserID.js +0 -7
  123. package/src/api/action/handleFriendRequest.js +0 -57
  124. package/src/api/action/logout.js +0 -76
  125. package/src/api/action/refreshFb_dtsg.js +0 -48
  126. package/src/api/action/setPostReaction.js +0 -106
  127. package/src/api/action/unfriend.js +0 -54
  128. package/src/api/http/httpGet.js +0 -46
  129. package/src/api/http/httpPost.js +0 -52
  130. package/src/api/http/postFormData.js +0 -47
  131. package/src/api/messaging/addUserToGroup.js +0 -68
  132. package/src/api/messaging/changeAdminStatus.js +0 -122
  133. package/src/api/messaging/changeArchivedStatus.js +0 -55
  134. package/src/api/messaging/changeBlockedStatus.js +0 -48
  135. package/src/api/messaging/changeGroupImage.js +0 -90
  136. package/src/api/messaging/changeNickname.js +0 -70
  137. package/src/api/messaging/changeThreadColor.js +0 -79
  138. package/src/api/messaging/changeThreadEmoji.js +0 -106
  139. package/src/api/messaging/createNewGroup.js +0 -88
  140. package/src/api/messaging/createPoll.js +0 -43
  141. package/src/api/messaging/createThemeAI.js +0 -98
  142. package/src/api/messaging/deleteMessage.js +0 -56
  143. package/src/api/messaging/deleteThread.js +0 -56
  144. package/src/api/messaging/editMessage.js +0 -68
  145. package/src/api/messaging/forwardAttachment.js +0 -51
  146. package/src/api/messaging/getEmojiUrl.js +0 -29
  147. package/src/api/messaging/getFriendsList.js +0 -82
  148. package/src/api/messaging/getMessage.js +0 -829
  149. package/src/api/messaging/getThemePictures.js +0 -62
  150. package/src/api/messaging/handleMessageRequest.js +0 -65
  151. package/src/api/messaging/markAsDelivered.js +0 -57
  152. package/src/api/messaging/markAsReadAll.js +0 -49
  153. package/src/api/messaging/markAsSeen.js +0 -61
  154. package/src/api/messaging/muteThread.js +0 -50
  155. package/src/api/messaging/removeUserFromGroup.js +0 -106
  156. package/src/api/messaging/resolvePhotoUrl.js +0 -43
  157. package/src/api/messaging/scheduler.js +0 -264
  158. package/src/api/messaging/searchForThread.js +0 -52
  159. package/src/api/messaging/sendMessage.js +0 -272
  160. package/src/api/messaging/sendTypingIndicator.js +0 -67
  161. package/src/api/messaging/setMessageReaction.js +0 -76
  162. package/src/api/messaging/setTitle.js +0 -119
  163. package/src/api/messaging/shareContact.js +0 -49
  164. package/src/api/messaging/threadColors.js +0 -128
  165. package/src/api/messaging/unsendMessage.js +0 -81
  166. package/src/api/messaging/uploadAttachment.js +0 -94
  167. package/src/api/socket/core/connectMqtt.js +0 -255
  168. package/src/api/socket/core/emitAuth.js +0 -106
  169. package/src/api/socket/core/getSeqID.js +0 -40
  170. package/src/api/socket/core/getTaskResponseData.js +0 -22
  171. package/src/api/socket/core/markDelivery.js +0 -12
  172. package/src/api/socket/core/parseDelta.js +0 -391
  173. package/src/api/socket/detail/buildStream.js +0 -208
  174. package/src/api/socket/detail/constants.js +0 -24
  175. package/src/api/socket/listenMqtt.js +0 -364
  176. package/src/api/socket/middleware/index.js +0 -216
  177. package/src/api/threads/getThreadHistory.js +0 -664
  178. package/src/api/threads/getThreadInfo.js +0 -438
  179. package/src/api/threads/getThreadList.js +0 -293
  180. package/src/api/threads/getThreadPictures.js +0 -78
  181. package/src/api/users/getUserID.js +0 -65
  182. package/src/api/users/getUserInfo.js +0 -327
  183. package/src/core/sendReqMqtt.js +0 -96
  184. package/src/database/models/index.js +0 -87
  185. package/src/database/models/thread.js +0 -45
  186. package/src/database/models/user.js +0 -46
  187. package/src/database/threadData.js +0 -98
  188. package/src/database/userData.js +0 -89
  189. package/src/utils/client.js +0 -320
  190. package/src/utils/format.js +0 -1115
  191. package/src/utils/request.js +0 -305
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function changeArchivedStatus(threadIDs, archive, 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 (utils.getType(archive) === "Function") {
23
+ callback = archive;
24
+ archive = true;
25
+ }
26
+
27
+ if (utils.getType(archive) !== "Boolean") {
28
+ throw new Error("archive parameter must be a boolean");
29
+ }
30
+
31
+ if (!Array.isArray(threadIDs)) {
32
+ threadIDs = [threadIDs];
33
+ }
34
+
35
+ const form = {
36
+ should_archive: archive
37
+ };
38
+
39
+ threadIDs.forEach(id => {
40
+ form[`thread_fbids[${id}]`] = true;
41
+ });
42
+
43
+ const res = await defaultFuncs.post(
44
+ "https://www.facebook.com/ajax/mercury/change_archived_status.php",
45
+ ctx.jar,
46
+ form
47
+ ).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
48
+
49
+ if (res && res.error) {
50
+ throw res;
51
+ }
52
+
53
+ callback(null, { success: true });
54
+ } catch (err) {
55
+ utils.error("changeArchivedStatus", err);
56
+ callback(err);
57
+ }
58
+
59
+ return returnPromise;
60
+ };
61
+ };
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ async function handleUpload(image) {
7
+ const form = {
8
+ profile_id: ctx.userID,
9
+ photo_source: 57,
10
+ av: ctx.userID,
11
+ file: image
12
+ };
13
+
14
+ return defaultFuncs.postFormData(
15
+ "https://www.facebook.com/profile/picture/upload/",
16
+ ctx.jar,
17
+ form,
18
+ {}
19
+ ).then(utils.parseAndCheckLogin(ctx, defaultFuncs))
20
+ .then(resData => {
21
+ if (resData.error) throw resData;
22
+ return resData;
23
+ });
24
+ }
25
+
26
+ return async function changeAvatar(image, caption, timestamp, callback) {
27
+ let resolveFunc = () => {};
28
+ let rejectFunc = () => {};
29
+ const returnPromise = new Promise((resolve, reject) => {
30
+ resolveFunc = resolve;
31
+ rejectFunc = reject;
32
+ });
33
+
34
+ if (!timestamp && utils.getType(caption) === "Number") {
35
+ timestamp = caption;
36
+ caption = "";
37
+ }
38
+
39
+ if (!timestamp && !callback && (utils.getType(caption) === "Function")) {
40
+ callback = caption;
41
+ caption = "";
42
+ timestamp = null;
43
+ }
44
+
45
+ if (!callback) {
46
+ callback = (err, data) => {
47
+ if (err) return rejectFunc(err);
48
+ resolveFunc(data);
49
+ };
50
+ }
51
+
52
+ try {
53
+ if (!utils.isReadableStream(image)) {
54
+ throw new Error("Image is not a readable stream");
55
+ }
56
+
57
+ const payload = await handleUpload(image);
58
+
59
+ const form = {
60
+ av: ctx.i_userID || ctx.userID,
61
+ fb_api_req_friendly_name: "ProfileCometProfilePictureSetMutation",
62
+ fb_api_caller_class: "RelayModern",
63
+ doc_id: "5066134240065849",
64
+ variables: JSON.stringify({
65
+ input: {
66
+ caption: caption || "",
67
+ existing_photo_id: payload.payload.fbid,
68
+ expiration_time: timestamp,
69
+ profile_id: ctx.i_userID || ctx.userID,
70
+ profile_pic_method: "EXISTING",
71
+ profile_pic_source: "TIMELINE",
72
+ scaled_crop_rect: {
73
+ height: 1,
74
+ width: 1,
75
+ x: 0,
76
+ y: 0
77
+ },
78
+ skip_cropping: true,
79
+ actor_id: ctx.i_userID || ctx.userID,
80
+ client_mutation_id: Math.round(Math.random() * 19).toString()
81
+ },
82
+ isPage: false,
83
+ isProfile: true,
84
+ scale: 3
85
+ })
86
+ };
87
+
88
+ const res = await defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
89
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
90
+
91
+ if (res.errors) {
92
+ throw res;
93
+ }
94
+
95
+ callback(null, res[0].data.profile_picture_set);
96
+ } catch (err) {
97
+ utils.error("changeAvatar", err);
98
+ callback(err);
99
+ }
100
+
101
+ return returnPromise;
102
+ };
103
+ };
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function changeBio(bio, publish, 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
+ if (utils.getType(publish) === "Function") {
16
+ callback = publish;
17
+ publish = false;
18
+ } else {
19
+ callback = (err) => {
20
+ if (err) return rejectFunc(err);
21
+ resolveFunc();
22
+ };
23
+ }
24
+ }
25
+
26
+ if (utils.getType(publish) !== "Boolean") {
27
+ publish = false;
28
+ }
29
+
30
+ if (utils.getType(bio) !== "String") {
31
+ bio = "";
32
+ publish = false;
33
+ }
34
+
35
+ try {
36
+ const form = {
37
+ fb_api_caller_class: "RelayModern",
38
+ fb_api_req_friendly_name: "ProfileCometSetBioMutation",
39
+ doc_id: "2725043627607610",
40
+ variables: JSON.stringify({
41
+ input: {
42
+ bio: bio,
43
+ publish_bio_feed_story: publish,
44
+ actor_id: ctx.i_userID || ctx.userID,
45
+ client_mutation_id: Math.round(Math.random() * 1024).toString()
46
+ },
47
+ hasProfileTileViewID: false,
48
+ profileTileViewID: null,
49
+ scale: 1
50
+ }),
51
+ av: ctx.i_userID || ctx.userID
52
+ };
53
+
54
+ const res = await defaultFuncs.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
55
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
56
+
57
+ if (res.errors) {
58
+ throw res;
59
+ }
60
+
61
+ callback(null, { success: true });
62
+ } catch (err) {
63
+ utils.error("changeBio", err);
64
+ callback(err);
65
+ }
66
+
67
+ return returnPromise;
68
+ };
69
+ };
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function changeBlockedStatus(userID, block, 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 (utils.getType(block) === "Function") {
23
+ callback = block;
24
+ block = true;
25
+ }
26
+
27
+ if (utils.getType(block) !== "Boolean") {
28
+ throw new Error("block parameter must be a boolean");
29
+ }
30
+
31
+ const form = {
32
+ fbid: userID,
33
+ block: block
34
+ };
35
+
36
+ const res = await defaultFuncs.post(
37
+ "https://www.facebook.com/ajax/profile/manage_blocking.php",
38
+ ctx.jar,
39
+ form
40
+ ).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
41
+
42
+ if (res && res.error) {
43
+ throw res;
44
+ }
45
+
46
+ return callback(null, { success: true, blocked: block });
47
+ } catch (err) {
48
+ utils.error("changeBlockedStatus", err);
49
+ callback(err);
50
+ }
51
+
52
+ return returnPromise;
53
+ };
54
+ };
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ async function handleUpload(image) {
7
+ const form = {
8
+ images_only: "true",
9
+ "attachment[]": image
10
+ };
11
+ return defaultFuncs
12
+ .postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
13
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
14
+ .then(resData => {
15
+ if (resData.error) throw resData;
16
+ return resData.payload.metadata[0];
17
+ });
18
+ }
19
+
20
+ return async function changeGroupImage(image, threadID, callback) {
21
+ let resolveFunc = () => {};
22
+ let rejectFunc = () => {};
23
+ const returnPromise = new Promise((resolve, reject) => {
24
+ resolveFunc = resolve;
25
+ rejectFunc = reject;
26
+ });
27
+
28
+ if (!callback) {
29
+ callback = (err, result) => {
30
+ if (err) return rejectFunc(err);
31
+ resolveFunc(result);
32
+ };
33
+ }
34
+
35
+ try {
36
+ if (!ctx.mqttClient) {
37
+ throw new Error("Not connected to MQTT. Please use listenMqtt first.");
38
+ }
39
+
40
+ if (!threadID || typeof threadID !== "string") {
41
+ throw new Error("Invalid threadID");
42
+ }
43
+
44
+ if (!utils.isReadableStream(image)) {
45
+ throw new Error("image must be a readable stream");
46
+ }
47
+
48
+ const reqID = ++ctx.wsReqNumber;
49
+ const taskID = ++ctx.wsTaskNumber;
50
+
51
+ let responseHandled = false;
52
+ const onResponse = (topic, message) => {
53
+ if (topic !== "/ls_resp" || responseHandled) return;
54
+ let jsonMsg;
55
+ try {
56
+ jsonMsg = JSON.parse(message.toString());
57
+ jsonMsg.payload = JSON.parse(jsonMsg.payload);
58
+ } catch (err) {
59
+ return;
60
+ }
61
+ if (jsonMsg.request_id !== reqID) return;
62
+ responseHandled = true;
63
+ clearTimeout(timeout);
64
+ ctx.mqttClient.removeListener("message", onResponse);
65
+ callback(null, { success: true, response: jsonMsg.payload });
66
+ resolveFunc({ success: true, response: jsonMsg.payload });
67
+ };
68
+
69
+ const timeout = setTimeout(() => {
70
+ if (!responseHandled) {
71
+ responseHandled = true;
72
+ ctx.mqttClient.removeListener("message", onResponse);
73
+ const err = new Error("MQTT request timeout");
74
+ callback(err);
75
+ rejectFunc(err);
76
+ }
77
+ }, 30000);
78
+
79
+ ctx.mqttClient.on("message", onResponse);
80
+
81
+ const payload = await handleUpload(image);
82
+ const imageID = payload.image_id;
83
+
84
+ const taskPayload = {
85
+ thread_key: threadID,
86
+ image_id: imageID,
87
+ sync_group: 1
88
+ };
89
+
90
+ const mqttPayload = {
91
+ epoch_id: utils.generateOfflineThreadingID(),
92
+ tasks: [
93
+ {
94
+ failure_count: null,
95
+ label: "37",
96
+ payload: JSON.stringify(taskPayload),
97
+ queue_name: "thread_image",
98
+ task_id: taskID
99
+ }
100
+ ],
101
+ version_id: "8798795233522156"
102
+ };
103
+
104
+ const request = {
105
+ app_id: "2220391788200892",
106
+ payload: JSON.stringify(mqttPayload),
107
+ request_id: reqID,
108
+ type: 3
109
+ };
110
+
111
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(request), {
112
+ qos: 1,
113
+ retain: false
114
+ }, (err) => {
115
+ if (err && !responseHandled) {
116
+ responseHandled = true;
117
+ clearTimeout(timeout);
118
+ ctx.mqttClient.removeListener("message", onResponse);
119
+ callback(err);
120
+ rejectFunc(err);
121
+ }
122
+ });
123
+ } catch (err) {
124
+ if (!responseHandled) {
125
+ responseHandled = true;
126
+ clearTimeout(timeout);
127
+ ctx.mqttClient.removeListener("message", onResponse);
128
+ utils.error("changeGroupImage", err);
129
+ callback(err);
130
+ rejectFunc(err);
131
+ }
132
+ }
133
+
134
+ return returnPromise;
135
+ };
136
+ };
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+
5
+ module.exports = (defaultFuncs, api, ctx) => {
6
+ return async function changeThreadColor(color, threadID, callback) {
7
+ let reqID = ++ctx.wsReqNumber;
8
+ let resolveFunc = () => {};
9
+ let rejectFunc = () => {};
10
+ const returnPromise = new Promise((resolve, reject) => {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = (err, data) => {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc(data);
19
+ };
20
+ }
21
+
22
+ try {
23
+ if (!ctx.mqttClient) {
24
+ throw new Error("Not connected to MQTT. Please use listenMqtt first.");
25
+ }
26
+
27
+ const content = {
28
+ app_id: "2220391788200892",
29
+ payload: JSON.stringify({
30
+ data_trace_id: null,
31
+ epoch_id: parseInt(utils.generateOfflineThreadingID()),
32
+ tasks: [
33
+ {
34
+ failure_count: null,
35
+ label: "43",
36
+ payload: JSON.stringify({
37
+ thread_key: threadID,
38
+ theme_fbid: color,
39
+ source: null,
40
+ sync_group: 1,
41
+ payload: null
42
+ }),
43
+ queue_name: "thread_theme",
44
+ task_id: ++ctx.wsTaskNumber
45
+ }
46
+ ],
47
+ version_id: "8798795233522156"
48
+ }),
49
+ request_id: reqID,
50
+ type: 3
51
+ };
52
+
53
+ let responseHandled = false;
54
+
55
+ const handleRes = (topic, message) => {
56
+ if (responseHandled) return;
57
+ if (topic !== "/ls_resp") return;
58
+ let jsonMsg;
59
+ try {
60
+ jsonMsg = JSON.parse(message.toString());
61
+ jsonMsg.payload = JSON.parse(jsonMsg.payload);
62
+ } catch (err) {
63
+ return;
64
+ }
65
+ if (jsonMsg.request_id !== reqID) return;
66
+ responseHandled = true;
67
+ clearTimeout(timeout);
68
+ ctx.mqttClient.removeListener("message", handleRes);
69
+ try {
70
+ const msgID = jsonMsg.payload.step[1][2][2][1][2];
71
+ const msgReplace = jsonMsg.payload.step[1][2][2][1][4];
72
+ const bodies = {
73
+ body: msgReplace,
74
+ messageID: msgID
75
+ };
76
+ callback(null, bodies);
77
+ resolveFunc(bodies);
78
+ } catch (err) {
79
+ callback(null, { success: true });
80
+ resolveFunc({ success: true });
81
+ }
82
+ };
83
+
84
+ const timeout = setTimeout(() => {
85
+ if (!responseHandled) {
86
+ responseHandled = true;
87
+ ctx.mqttClient.removeListener("message", handleRes);
88
+ const err = new Error("MQTT request timeout");
89
+ callback(err);
90
+ rejectFunc(err);
91
+ }
92
+ }, 30000);
93
+
94
+ ctx.mqttClient.on("message", handleRes);
95
+
96
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(content), {
97
+ qos: 1,
98
+ retain: false
99
+ }, (err) => {
100
+ if (err && !responseHandled) {
101
+ responseHandled = true;
102
+ clearTimeout(timeout);
103
+ ctx.mqttClient.removeListener("message", handleRes);
104
+ callback(err);
105
+ rejectFunc(err);
106
+ }
107
+ });
108
+ } catch (err) {
109
+ utils.error("changeThreadColor", err);
110
+ callback(err);
111
+ rejectFunc(err);
112
+ }
113
+
114
+ return returnPromise;
115
+ };
116
+ };
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ module.exports = function (defaultFuncs, api, ctx) {
5
+ return function changeThreadEmoji(emoji, threadID, callback) {
6
+ let resolveFunc = function () {};
7
+ let rejectFunc = function () {};
8
+ const returnPromise = new Promise(function (resolve, reject) {
9
+ resolveFunc = resolve;
10
+ rejectFunc = reject;
11
+ });
12
+
13
+ if (!callback) {
14
+ callback = function (err) {
15
+ if (err) {
16
+ return rejectFunc(err);
17
+ }
18
+ resolveFunc();
19
+ };
20
+ }
21
+ const form = {
22
+ emoji_choice: emoji,
23
+ thread_or_other_fbid: threadID,
24
+ };
25
+
26
+ defaultFuncs
27
+ .post(
28
+ "https://www.facebook.com/messaging/save_thread_emoji/?source=thread_settings&__pc=EXP1%3Amessengerdotcom_pkg",
29
+ ctx.jar,
30
+ form,
31
+ )
32
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
33
+ .then(function (resData) {
34
+ if (resData.error === 1357031) {
35
+ throw {
36
+ error:
37
+ "Trying to change emoji of a chat that doesn't exist. Have at least one message in the thread before trying to change the emoji.",
38
+ };
39
+ }
40
+ if (resData.error) {
41
+ throw resData;
42
+ }
43
+
44
+ return callback();
45
+ })
46
+ .catch(function (err) {
47
+ utils.error("changeThreadEmoji", err);
48
+ return callback(err);
49
+ });
50
+
51
+ return returnPromise;
52
+ };
53
+ };