@lazyneoaz/metachat 1.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 (122) hide show
  1. package/LICENSE +3 -0
  2. package/README.md +199 -0
  3. package/index.js +2 -0
  4. package/package.json +86 -0
  5. package/src/apis/addExternalModule.js +24 -0
  6. package/src/apis/addUserToGroup.js +108 -0
  7. package/src/apis/changeAdminStatus.js +148 -0
  8. package/src/apis/changeArchivedStatus.js +61 -0
  9. package/src/apis/changeAvatar.js +103 -0
  10. package/src/apis/changeBio.js +69 -0
  11. package/src/apis/changeBlockedStatus.js +54 -0
  12. package/src/apis/changeGroupImage.js +136 -0
  13. package/src/apis/changeThreadColor.js +116 -0
  14. package/src/apis/changeThreadEmoji.js +53 -0
  15. package/src/apis/comment.js +207 -0
  16. package/src/apis/createAITheme.js +129 -0
  17. package/src/apis/createNewGroup.js +79 -0
  18. package/src/apis/createPoll.js +73 -0
  19. package/src/apis/deleteMessage.js +44 -0
  20. package/src/apis/deleteThread.js +52 -0
  21. package/src/apis/editMessage.js +70 -0
  22. package/src/apis/emoji.js +124 -0
  23. package/src/apis/enableAutoSaveAppState.js +69 -0
  24. package/src/apis/fetchThemeData.js +113 -0
  25. package/src/apis/follow.js +81 -0
  26. package/src/apis/forwardAttachment.js +195 -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/getEmojiUrl.js +40 -0
  36. package/src/apis/getFriendsList.js +79 -0
  37. package/src/apis/getMessage.js +423 -0
  38. package/src/apis/getTheme.js +123 -0
  39. package/src/apis/getThemeInfo.js +116 -0
  40. package/src/apis/getThemePictures.js +87 -0
  41. package/src/apis/getThreadColors.js +119 -0
  42. package/src/apis/getThreadHistory.js +239 -0
  43. package/src/apis/getThreadInfo.js +271 -0
  44. package/src/apis/getThreadList.js +236 -0
  45. package/src/apis/getThreadPictures.js +58 -0
  46. package/src/apis/getUserID.js +117 -0
  47. package/src/apis/getUserInfo.js +513 -0
  48. package/src/apis/getUserInfoV2.js +146 -0
  49. package/src/apis/handleFriendRequest.js +66 -0
  50. package/src/apis/handleMessageRequest.js +50 -0
  51. package/src/apis/httpGet.js +63 -0
  52. package/src/apis/httpPost.js +89 -0
  53. package/src/apis/httpPostFormData.js +69 -0
  54. package/src/apis/listenMqtt.js +1081 -0
  55. package/src/apis/listenSpeed.js +178 -0
  56. package/src/apis/logout.js +63 -0
  57. package/src/apis/markAsDelivered.js +47 -0
  58. package/src/apis/markAsRead.js +82 -0
  59. package/src/apis/markAsReadAll.js +40 -0
  60. package/src/apis/markAsSeen.js +70 -0
  61. package/src/apis/mqttDeltaValue.js +252 -0
  62. package/src/apis/muteThread.js +45 -0
  63. package/src/apis/nickname.js +132 -0
  64. package/src/apis/notes.js +163 -0
  65. package/src/apis/pinMessage.js +150 -0
  66. package/src/apis/produceMetaTheme.js +160 -0
  67. package/src/apis/realtime.js +182 -0
  68. package/src/apis/refreshFb_dtsg.js +94 -0
  69. package/src/apis/removeUserFromGroup.js +117 -0
  70. package/src/apis/resolvePhotoUrl.js +58 -0
  71. package/src/apis/scheduler.js +129 -0
  72. package/src/apis/searchForThread.js +154 -0
  73. package/src/apis/sendEffect.js +311 -0
  74. package/src/apis/sendMessage.js +341 -0
  75. package/src/apis/sendMessageMqtt.js +271 -0
  76. package/src/apis/sendTypingIndicator.js +74 -0
  77. package/src/apis/setMessageReaction.js +27 -0
  78. package/src/apis/setMessageReactionMqtt.js +61 -0
  79. package/src/apis/setPostReaction.js +118 -0
  80. package/src/apis/setThreadTheme.js +210 -0
  81. package/src/apis/setThreadThemeMqtt.js +94 -0
  82. package/src/apis/setTitle.js +26 -0
  83. package/src/apis/share.js +106 -0
  84. package/src/apis/shareContact.js +66 -0
  85. package/src/apis/stickers.js +257 -0
  86. package/src/apis/story.js +181 -0
  87. package/src/apis/theme.js +233 -0
  88. package/src/apis/unfriend.js +47 -0
  89. package/src/apis/unsendMessage.js +17 -0
  90. package/src/apis/uploadAttachment.js +87 -0
  91. package/src/database/appStateBackup.js +189 -0
  92. package/src/database/models/index.js +56 -0
  93. package/src/database/models/thread.js +31 -0
  94. package/src/database/models/user.js +32 -0
  95. package/src/database/threadData.js +101 -0
  96. package/src/database/userData.js +90 -0
  97. package/src/engine/client.js +92 -0
  98. package/src/engine/models/buildAPI.js +118 -0
  99. package/src/engine/models/loginHelper.js +492 -0
  100. package/src/engine/models/setOptions.js +88 -0
  101. package/src/types/index.d.ts +498 -0
  102. package/src/utils/antiSuspension.js +516 -0
  103. package/src/utils/auth-helpers.js +149 -0
  104. package/src/utils/autoReLogin.js +239 -0
  105. package/src/utils/axios.js +368 -0
  106. package/src/utils/cache.js +54 -0
  107. package/src/utils/clients.js +279 -0
  108. package/src/utils/constants.js +525 -0
  109. package/src/utils/formatters/data/formatAttachment.js +370 -0
  110. package/src/utils/formatters/data/formatDelta.js +109 -0
  111. package/src/utils/formatters/index.js +159 -0
  112. package/src/utils/formatters/value/formatCookie.js +91 -0
  113. package/src/utils/formatters/value/formatDate.js +36 -0
  114. package/src/utils/formatters/value/formatID.js +16 -0
  115. package/src/utils/formatters.js +1369 -0
  116. package/src/utils/headers.js +235 -0
  117. package/src/utils/index.js +153 -0
  118. package/src/utils/monitoring.js +333 -0
  119. package/src/utils/rateLimiter.js +251 -0
  120. package/src/utils/tokenRefresh.js +285 -0
  121. package/src/utils/user-agents.js +238 -0
  122. package/src/utils/validation.js +157 -0
@@ -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
+ };