stfca 1.0.2 → 1.0.4

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 (142) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +45 -2
  3. package/checkUpdate.js +109 -0
  4. package/index.js +460 -1
  5. package/package.json +22 -46
  6. package/src/OldMessage.js +234 -0
  7. package/src/{api/action/addExternalModule.js → addExternalModule.js} +25 -25
  8. package/src/addUserToGroup.js +115 -0
  9. package/src/changeAdminStatus.js +103 -0
  10. package/src/changeArchivedStatus.js +55 -0
  11. package/src/{api/action/changeAvatar.js → changeAvatar.js} +136 -137
  12. package/src/changeAvatarV2.js +86 -0
  13. package/src/changeAvt.js +85 -0
  14. package/src/{api/action/changeBio.js → changeBio.js} +76 -75
  15. package/src/{api/messaging/changeBlockedStatus.js → changeBlockedStatus.js} +49 -48
  16. package/src/changeBlockedStatusMqtt.js +80 -0
  17. package/src/changeCover.js +72 -0
  18. package/src/changeGroupImage.js +135 -0
  19. package/src/changeName.js +79 -0
  20. package/src/changeNickname.js +59 -0
  21. package/src/changeThreadColor.js +65 -0
  22. package/src/changeThreadEmoji.js +55 -0
  23. package/src/changeUsername.js +59 -0
  24. package/src/createCommentPost.js +230 -0
  25. package/src/{api/messaging/createNewGroup.js → createNewGroup.js} +88 -88
  26. package/src/createPoll.js +71 -0
  27. package/src/createPost.js +276 -0
  28. package/src/{api/messaging/deleteMessage.js → deleteMessage.js} +56 -56
  29. package/src/{api/messaging/deleteThread.js → deleteThread.js} +56 -56
  30. package/src/editMessage.js +68 -0
  31. package/src/editMessageOld.js +67 -0
  32. package/src/follow.js +74 -0
  33. package/src/forwardAttachment.js +60 -0
  34. package/src/getAccess.js +112 -0
  35. package/src/getAvatarUser.js +78 -0
  36. package/src/{api/action/getCurrentUserID.js → getCurrentUserID.js} +7 -7
  37. package/src/{api/messaging/getEmojiUrl.js → getEmojiUrl.js} +2 -2
  38. package/src/{api/messaging/getFriendsList.js → getFriendsList.js} +83 -82
  39. package/src/{api/messaging/getMessage.js → getMessage.js} +847 -829
  40. package/src/getRegion.js +7 -0
  41. package/src/{api/threads/getThreadHistory.js → getThreadHistory.js} +680 -664
  42. package/src/getThreadHistoryDeprecated.js +71 -0
  43. package/src/getThreadInfo.js +232 -0
  44. package/src/getThreadInfoDeprecated.js +56 -0
  45. package/src/getThreadList.js +213 -0
  46. package/src/getThreadListDeprecated.js +46 -0
  47. package/src/getThreadPictures.js +59 -0
  48. package/src/getUID.js +119 -0
  49. package/src/{api/users/getUserID.js → getUserID.js} +61 -65
  50. package/src/getUserInfo.js +66 -0
  51. package/src/handleFriendRequest.js +46 -0
  52. package/src/handleMessageRequest.js +47 -0
  53. package/src/httpGet.js +49 -0
  54. package/src/httpPost.js +48 -0
  55. package/src/listenMqtt.js +864 -0
  56. package/src/logout.js +75 -0
  57. package/src/markAsDelivered.js +47 -0
  58. package/src/markAsRead.js +70 -0
  59. package/src/markAsReadAll.js +40 -0
  60. package/src/markAsSeen.js +48 -0
  61. package/src/muteThread.js +45 -0
  62. package/src/refreshFb_dtsg.js +89 -0
  63. package/src/removeUserFromGroup.js +79 -0
  64. package/src/{api/messaging/resolvePhotoUrl.js → resolvePhotoUrl.js} +45 -43
  65. package/src/{api/messaging/searchForThread.js → searchForThread.js} +53 -52
  66. package/src/searchStickers.js +53 -0
  67. package/src/sendMessage.js +234 -0
  68. package/src/{api/messaging/sendMessageMqtt.js → sendMessageMqtt.js} +322 -323
  69. package/src/sendTypingIndicator.js +101 -0
  70. package/src/sendTypingIndicatorV2.js +28 -0
  71. package/src/setMessageReaction.js +122 -0
  72. package/src/setMessageReactionMqtt.js +62 -0
  73. package/src/{api/action/setPostReaction.js → setPostReaction.js} +112 -106
  74. package/src/setStoryReaction.js +64 -0
  75. package/src/setTitle.js +90 -0
  76. package/src/shareContact.js +110 -0
  77. package/src/shareLink.js +59 -0
  78. package/src/stopListenMqtt.js +23 -0
  79. package/src/{api/messaging/threadColors.js → threadColors.js} +131 -128
  80. package/src/{api/action/unfriend.js → unfriend.js} +52 -54
  81. package/src/unsendMessage.js +45 -0
  82. package/src/{api/messaging/uploadAttachment.js → uploadAttachment.js} +93 -95
  83. package/utils.js +2876 -0
  84. package/LICENSE-MIT +0 -4
  85. package/index.d.ts +0 -615
  86. package/module/config.js +0 -33
  87. package/module/login.js +0 -48
  88. package/module/loginHelper.js +0 -722
  89. package/module/options.js +0 -44
  90. package/src/api/action/handleFriendRequest.js +0 -57
  91. package/src/api/action/logout.js +0 -76
  92. package/src/api/action/refreshFb_dtsg.js +0 -71
  93. package/src/api/http/httpGet.js +0 -46
  94. package/src/api/http/httpPost.js +0 -52
  95. package/src/api/http/postFormData.js +0 -47
  96. package/src/api/messaging/addUserToGroup.js +0 -68
  97. package/src/api/messaging/changeAdminStatus.js +0 -122
  98. package/src/api/messaging/changeArchivedStatus.js +0 -55
  99. package/src/api/messaging/changeGroupImage.js +0 -90
  100. package/src/api/messaging/changeNickname.js +0 -70
  101. package/src/api/messaging/changeThreadColor.js +0 -79
  102. package/src/api/messaging/changeThreadEmoji.js +0 -106
  103. package/src/api/messaging/createPoll.js +0 -43
  104. package/src/api/messaging/editMessage.js +0 -68
  105. package/src/api/messaging/forwardAttachment.js +0 -51
  106. package/src/api/messaging/handleMessageRequest.js +0 -65
  107. package/src/api/messaging/markAsDelivered.js +0 -57
  108. package/src/api/messaging/markAsRead.js +0 -88
  109. package/src/api/messaging/markAsReadAll.js +0 -49
  110. package/src/api/messaging/markAsSeen.js +0 -61
  111. package/src/api/messaging/muteThread.js +0 -50
  112. package/src/api/messaging/removeUserFromGroup.js +0 -105
  113. package/src/api/messaging/sendMessage.js +0 -379
  114. package/src/api/messaging/sendTypingIndicator.js +0 -67
  115. package/src/api/messaging/setMessageReaction.js +0 -75
  116. package/src/api/messaging/setTitle.js +0 -119
  117. package/src/api/messaging/shareContact.js +0 -49
  118. package/src/api/messaging/unsendMessage.js +0 -81
  119. package/src/api/socket/core/connectMqtt.js +0 -179
  120. package/src/api/socket/core/getSeqID.js +0 -25
  121. package/src/api/socket/core/getTaskResponseData.js +0 -22
  122. package/src/api/socket/core/markDelivery.js +0 -12
  123. package/src/api/socket/core/parseDelta.js +0 -351
  124. package/src/api/socket/detail/buildStream.js +0 -208
  125. package/src/api/socket/detail/constants.js +0 -24
  126. package/src/api/socket/listenMqtt.js +0 -133
  127. package/src/api/threads/getThreadInfo.js +0 -358
  128. package/src/api/threads/getThreadList.js +0 -248
  129. package/src/api/threads/getThreadPictures.js +0 -78
  130. package/src/api/users/getUserInfo.js +0 -319
  131. package/src/api/users/getUserInfoV2.js +0 -133
  132. package/src/core/sendReqMqtt.js +0 -63
  133. package/src/database/models/index.js +0 -49
  134. package/src/database/models/thread.js +0 -31
  135. package/src/database/models/user.js +0 -32
  136. package/src/database/threadData.js +0 -98
  137. package/src/database/userData.js +0 -89
  138. package/src/utils/client.js +0 -214
  139. package/src/utils/constants.js +0 -23
  140. package/src/utils/format.js +0 -1111
  141. package/src/utils/headers.js +0 -41
  142. package/src/utils/request.js +0 -215
package/package.json CHANGED
@@ -1,69 +1,45 @@
1
+
1
2
  {
2
3
  "name": "stfca",
3
- "version": "1.0.2",
4
- "description": "Unofficial Facebook Chat API for Node.js",
4
+ "version": "1.0.4",
5
+ "description": "Unofficial Facebook Chat API for Node.js - Enhanced by ST | Sheikh Tamim",
5
6
  "main": "index.js",
6
7
  "scripts": {
7
- "test": "echo \"No tests specified\" && exit 0",
8
- "lint": "eslint .",
9
- "prepublishOnly": "echo \"Preparing to publish...\""
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "start": "node index.js"
10
10
  },
11
11
  "repository": {
12
12
  "type": "git",
13
- "url": "git+https://github.com/sheikhtamimlover/fca-unofficial.git"
13
+ "url": "git+https://github.com/sheikhtamimlover/ST-FCA.git"
14
14
  },
15
15
  "keywords": [
16
16
  "facebook",
17
17
  "chat",
18
18
  "api",
19
- "messenger",
20
19
  "bot",
20
+ "messenger",
21
21
  "unofficial",
22
- "automation",
23
- "facebook-api",
24
- "facebook-chat",
25
- "facebook-messenger",
26
- "chatbot",
27
- "nodejs",
28
- "fca"
22
+ "fca",
23
+ "st-fca",
24
+ "sheikh-tamim"
29
25
  ],
30
- "author": {
31
- "name": "ST | Sheikh Tamim",
32
- "url": "https://www.facebook.com/hamza.chudena"
33
- },
26
+ "author": "ST | Sheikh Tamim",
34
27
  "license": "MIT",
35
28
  "bugs": {
36
- "url": "https://github.com/sheikhtamimlover/fca-unofficial/issues"
37
- },
38
- "homepage": "https://github.com/sheikhtamimlover/fca-unofficial#readme",
39
- "engines": {
40
- "node": ">=12.0.0"
29
+ "url": "https://github.com/sheikhtamimlover/ST-FCA/issues"
41
30
  },
31
+ "homepage": "https://github.com/sheikhtamimlover/ST-FCA#readme",
42
32
  "dependencies": {
43
- "axios": "latest",
44
- "axios-cookiejar-support": "^5.0.5",
33
+ "axios": "^1.4.0",
45
34
  "bluebird": "^3.7.2",
46
- "chalk": "^4.1.2",
47
- "cheerio": "^1.0.0-rc.10",
48
- "duplexify": "^4.1.3",
49
- "gradient-string": "^2.0.2",
50
- "https-proxy-agent": "^4.0.0",
51
- "mqtt": "^4.3.8",
52
- "npmlog": "^1.2.0",
53
- "request": "^2.53.0",
54
- "sequelize": "^6.37.6",
55
- "sqlite3": "^5.1.7",
56
- "totp-generator": "^1.0.0",
57
- "ws": "^8.18.1"
58
- },
59
- "devDependencies": {
60
- "eslint": "^8.50.0",
61
- "mocha": "^10.2.0"
35
+ "cheerio": "^1.0.0-rc.12",
36
+ "https-proxy-agent": "^5.0.1",
37
+ "mqtt": "^4.3.7",
38
+ "npmlog": "^7.0.1",
39
+ "request": "^2.88.2",
40
+ "websocket-stream": "^5.5.2"
62
41
  },
63
- "optionalDependencies": {},
64
- "peerDependencies": {},
65
- "publishConfig": {
66
- "access": "public",
67
- "registry": "https://registry.npmjs.org/"
42
+ "engines": {
43
+ "node": ">=14.0.0"
68
44
  }
69
45
  }
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+
3
+ const utils = require('../utils');
4
+ // @NethWs3Dev
5
+
6
+ const allowedProperties = {
7
+ attachment: true,
8
+ url: true,
9
+ sticker: true,
10
+ emoji: true,
11
+ emojiSize: true,
12
+ body: true,
13
+ mentions: true,
14
+ location: true,
15
+ };
16
+
17
+ module.exports = (defaultFuncs, api, ctx) => {
18
+ async function uploadAttachment(attachments) {
19
+ var uploads = [];
20
+ for (var i = 0; i < attachments.length; i++) {
21
+ if (!utils.isReadableStream(attachments[i])) {
22
+ throw new Error("Attachment should be a readable stream and not " + utils.getType(attachments[i]) + ".");
23
+ }
24
+ const oksir = await defaultFuncs.postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar,{
25
+ upload_1024: attachments[i],
26
+ voice_clip: "true"
27
+ }, {}).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
28
+ if (oksir.error) {
29
+ throw new Error(resData);
30
+ }
31
+ uploads.push(oksir.payload.metadata[0]);
32
+ }
33
+ return uploads;
34
+ }
35
+
36
+ async function getUrl(url) {
37
+ const resData = await defaultFuncs.post("https://www.facebook.com/message_share_attachment/fromURI/", ctx.jar, {
38
+ image_height: 960,
39
+ image_width: 960,
40
+ uri: url
41
+ }).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
42
+ if (!resData || resData.error || !resData.payload){
43
+ throw new Error(resData);
44
+ }
45
+ }
46
+
47
+ async function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
48
+ // There are three cases here:
49
+ // 1. threadID is of type array, where we're starting a new group chat with users
50
+ // specified in the array.
51
+ // 2. User is sending a message to a specific user.
52
+ // 3. No additional form params and the message goes to an existing group chat.
53
+ if (utils.getType(threadID) === "Array") {
54
+ for (var i = 0; i < threadID.length; i++) {
55
+ form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
56
+ }
57
+ form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
58
+ form["client_thread_id"] = "root:" + messageAndOTID;
59
+ utils.log("sendMessage", "Sending message to multiple users: " + threadID);
60
+ } else {
61
+ const threadIDStr = threadID.toString();
62
+ // Check if it's a DM: doesn't start with numeric group ID pattern or explicitly marked as single user
63
+ const isDM = !threadIDStr.match(/^\d{15,}$/) || isSingleUser === true;
64
+
65
+ // This means that threadID is the id of a user, and the chat
66
+ // is a single person chat
67
+ if (isDM) {
68
+ form["specific_to_list[0]"] = "fbid:" + threadID;
69
+ form["specific_to_list[1]"] = "fbid:" + ctx.userID;
70
+ form["other_user_fbid"] = threadID;
71
+ } else {
72
+ form["thread_fbid"] = threadID;
73
+ }
74
+ }
75
+
76
+ if (ctx.globalOptions.pageID) {
77
+ form["author"] = "fbid:" + ctx.globalOptions.pageID;
78
+ form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
79
+ form["creator_info[creatorID]"] = ctx.userID;
80
+ form["creator_info[creatorType]"] = "direct_admin";
81
+ form["creator_info[labelType]"] = "sent_message";
82
+ form["creator_info[pageID]"] = ctx.globalOptions.pageID;
83
+ form["request_user_id"] = ctx.globalOptions.pageID;
84
+ form["creator_info[profileURI]"] =
85
+ "https://www.facebook.com/profile.php?id=" + ctx.userID;
86
+ }
87
+
88
+ const resData = await defaultFuncs.post("https://www.facebook.com/messaging/send/", ctx.jar, form).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
89
+ if (!resData) {
90
+ throw new Error("Send message failed.");
91
+ }
92
+ if (resData.error) {
93
+ if (resData.error === 1545012) {
94
+ utils.warn("sendMessage", "Got error 1545012. This might mean that you're not part of the conversation " + threadID);
95
+ throw new Error(`Cannot send message to thread ${threadID}: Bot is not part of this conversation (Error 1545012)`);
96
+ }
97
+ throw new Error(resData);
98
+ }
99
+ const messageInfo = resData.payload.actions.reduce((p, v) => {
100
+ return { threadID: v.thread_fbid, messageID: v.message_id, timestamp: v.timestamp } || p;
101
+ }, null);
102
+ return messageInfo;
103
+ }
104
+
105
+ return async (msg, threadID, callback, replyToMessage, isSingleUser = false) => {
106
+ // Handle different parameter patterns for backward compatibility
107
+ if (typeof callback === "string" || (callback && typeof callback === "object")) {
108
+ // callback is actually replyToMessage, shift parameters
109
+ isSingleUser = replyToMessage;
110
+ replyToMessage = callback;
111
+ callback = function() {};
112
+ } else if (typeof callback !== "function") {
113
+ callback = function() {};
114
+ }
115
+
116
+ let msgType = utils.getType(msg);
117
+ let threadIDType = utils.getType(threadID);
118
+ let messageIDType = utils.getType(replyToMessage);
119
+ if (msgType !== "String" && msgType !== "Object") throw new Error("Message should be of type string or object and not " + msgType + ".");
120
+ if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") throw new Error("ThreadID should be of type number, string, or array and not " + threadIDType + ".");
121
+ if (replyToMessage && messageIDType !== 'String' && messageIDType !== 'string') throw new Error("MessageID should be of type string and not " + messageIDType + ".");
122
+ if (msgType === "String") {
123
+ msg = { body: msg };
124
+ }
125
+ let disallowedProperties = Object.keys(msg).filter(prop => !allowedProperties[prop]);
126
+ if (disallowedProperties.length > 0) {
127
+ throw new Error("Dissallowed props: `" + disallowedProperties.join(", ") + "`");
128
+ }
129
+ let messageAndOTID = utils.generateOfflineThreadingID();
130
+ let form = {
131
+ client: "mercury",
132
+ action_type: "ma-type:user-generated-message",
133
+ author: "fbid:" + ctx.userID,
134
+ timestamp: Date.now(),
135
+ timestamp_absolute: "Today",
136
+ timestamp_relative: utils.generateTimestampRelative(),
137
+ timestamp_time_passed: "0",
138
+ is_unread: false,
139
+ is_cleared: false,
140
+ is_forward: false,
141
+ is_filtered_content: false,
142
+ is_filtered_content_bh: false,
143
+ is_filtered_content_account: false,
144
+ is_filtered_content_quasar: false,
145
+ is_filtered_content_invalid_app: false,
146
+ is_spoof_warning: false,
147
+ source: "source:chat:web",
148
+ "source_tags[0]": "source:chat",
149
+ ...(msg.body && {
150
+ body: msg.body
151
+ }),
152
+ html_body: false,
153
+ ui_push_phase: "V3",
154
+ status: "0",
155
+ offline_threading_id: messageAndOTID,
156
+ message_id: messageAndOTID,
157
+ threading_id: utils.generateThreadingID(ctx.clientID),
158
+ "ephemeral_ttl_mode:": "0",
159
+ manual_retry_cnt: "0",
160
+ has_attachment: !!(msg.attachment || msg.url || msg.sticker),
161
+ signatureID: utils.getSignatureID(),
162
+ ...(replyToMessage && {
163
+ replied_to_message_id: replyToMessage
164
+ })
165
+ };
166
+
167
+ if (msg.location) {
168
+ if (!msg.location.latitude || !msg.location.longitude) throw new Error("location property needs both latitude and longitude");
169
+ form["location_attachment[coordinates][latitude]"] = msg.location.latitude;
170
+ form["location_attachment[coordinates][longitude]"] = msg.location.longitude;
171
+ form["location_attachment[is_current_location]"] = !!msg.location.current;
172
+ }
173
+ if (msg.sticker) {
174
+ form["sticker_id"] = msg.sticker;
175
+ }
176
+ if (msg.attachment) {
177
+ form.image_ids = [];
178
+ form.gif_ids = [];
179
+ form.file_ids = [];
180
+ form.video_ids = [];
181
+ form.audio_ids = [];
182
+ if (utils.getType(msg.attachment) !== "Array") {
183
+ msg.attachment = [msg.attachment];
184
+ }
185
+ const files = await uploadAttachment(msg.attachment);
186
+ files.forEach(file => {
187
+ const type = Object.keys(file)[0];
188
+ form["" + type + "s"].push(file[type]);
189
+ });
190
+ }
191
+ if (msg.url) {
192
+ form["shareable_attachment[share_type]"] = "100";
193
+ const params = await getUrl(msg.url);
194
+ form["shareable_attachment[share_params]"] = params;
195
+ }
196
+ if (msg.emoji) {
197
+ if (!msg.emojiSize) {
198
+ msg.emojiSize = "medium";
199
+ }
200
+ if (msg.emojiSize !== "small" && msg.emojiSize !== "medium" && msg.emojiSize !== "large") {
201
+ throw new Error("emojiSize property is invalid");
202
+ }
203
+ if (!form.body) {
204
+ throw new Error("body is not empty");
205
+ }
206
+ form.body = msg.emoji;
207
+ form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
208
+ }
209
+ if (msg.mentions) {
210
+ for (let i = 0; i < msg.mentions.length; i++) {
211
+ const mention = msg.mentions[i];
212
+ const tag = mention.tag;
213
+ if (typeof tag !== "string") {
214
+ throw new Error("Mention tags must be strings.");
215
+ }
216
+ const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
217
+ if (offset < 0) utils.warn("handleMention", 'Mention for "' + tag + '" not found in message string.');
218
+ if (!mention.id) utils.warn("handleMention", "Mention id should be non-null.");
219
+ const id = mention.id || 0;
220
+ const emptyChar = '\u200E';
221
+ form["body"] = emptyChar + msg.body;
222
+ form["profile_xmd[" + i + "][offset]"] = offset + 1;
223
+ form["profile_xmd[" + i + "][length]"] = tag.length;
224
+ form["profile_xmd[" + i + "][id]"] = id;
225
+ form["profile_xmd[" + i + "][type]"] = "p";
226
+ }
227
+ }
228
+ const result = await sendContent(form, threadID, isSingleUser, messageAndOTID);
229
+ if (callback && typeof callback === "function") {
230
+ callback(null, result);
231
+ }
232
+ return result;
233
+ };
234
+ };
@@ -1,25 +1,25 @@
1
- "use strict";
2
-
3
- const { getType } = require("../../utils/format");
4
-
5
- module.exports = function(defaultFuncs, api, ctx) {
6
- return function addExternalModule(moduleObj) {
7
- if (getType(moduleObj) == "Object") {
8
- for (const apiName in moduleObj) {
9
- if (getType(moduleObj[apiName]) == "Function") {
10
- api[apiName] = moduleObj[apiName](defaultFuncs, api, ctx);
11
- } else {
12
- throw new Error(
13
- `Item "${apiName}" in moduleObj must be a function, not ${getType(
14
- moduleObj[apiName]
15
- )}!`
16
- );
17
- }
18
- }
19
- } else {
20
- throw new Error(
21
- `moduleObj must be an object, not ${getType(moduleObj)}!`
22
- );
23
- }
24
- };
25
- };
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return function addExternalModule(moduleObj) {
7
+ if (utils.getType(moduleObj) == "Object") {
8
+ for (const apiName in moduleObj) {
9
+ if (utils.getType(moduleObj[apiName]) == "Function") {
10
+ api[apiName] = moduleObj[apiName](defaultFuncs, api, ctx);
11
+ } else {
12
+ throw new Error(
13
+ `Item "${apiName}" in moduleObj must be a function, not ${utils.getType(
14
+ moduleObj[apiName],
15
+ )}!`,
16
+ );
17
+ }
18
+ }
19
+ } else {
20
+ throw new Error(
21
+ `moduleObj must be an object, not ${utils.getType(moduleObj)}!`,
22
+ );
23
+ }
24
+ };
25
+ };
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ // @NethWs3Dev
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function addUserToGroup(userID, threadID, callback) {
8
+ let resolveFunc = function () {};
9
+ let rejectFunc = function () {};
10
+ const returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (
16
+ !callback &&
17
+ (utils.getType(threadID) === "Function" ||
18
+ utils.getType(threadID) === "AsyncFunction")
19
+ ) {
20
+ throw new utils.CustomError({
21
+ error: "please pass a threadID as a second argument.",
22
+ });
23
+ }
24
+
25
+ if (!callback) {
26
+ callback = function (err) {
27
+ if (err) {
28
+ return rejectFunc(err);
29
+ }
30
+ resolveFunc();
31
+ };
32
+ }
33
+
34
+ if (
35
+ utils.getType(threadID) !== "Number" &&
36
+ utils.getType(threadID) !== "String"
37
+ ) {
38
+ throw new utils.CustomError({
39
+ error:
40
+ "ThreadID should be of type Number or String and not " +
41
+ utils.getType(threadID) +
42
+ ".",
43
+ });
44
+ }
45
+
46
+ if (utils.getType(userID) !== "Array") {
47
+ userID = [userID];
48
+ }
49
+
50
+ const messageAndOTID = utils.generateOfflineThreadingID();
51
+ const form = {
52
+ client: "mercury",
53
+ action_type: "ma-type:log-message",
54
+ author: "fbid:" + (ctx.userID),
55
+ thread_id: "",
56
+ timestamp: Date.now(),
57
+ timestamp_absolute: "Today",
58
+ timestamp_relative: utils.generateTimestampRelative(),
59
+ timestamp_time_passed: "0",
60
+ is_unread: false,
61
+ is_cleared: false,
62
+ is_forward: false,
63
+ is_filtered_content: false,
64
+ is_filtered_content_bh: false,
65
+ is_filtered_content_account: false,
66
+ is_spoof_warning: false,
67
+ source: "source:chat:web",
68
+ "source_tags[0]": "source:chat",
69
+ log_message_type: "log:subscribe",
70
+ status: "0",
71
+ offline_threading_id: messageAndOTID,
72
+ message_id: messageAndOTID,
73
+ threading_id: utils.generateThreadingID(ctx.clientID),
74
+ manual_retry_cnt: "0",
75
+ thread_fbid: threadID,
76
+ };
77
+
78
+ for (let i = 0; i < userID.length; i++) {
79
+ if (
80
+ utils.getType(userID[i]) !== "Number" &&
81
+ utils.getType(userID[i]) !== "String"
82
+ ) {
83
+ throw new utils.CustomError({
84
+ error:
85
+ "Elements of userID should be of type Number or String and not " +
86
+ utils.getType(userID[i]) +
87
+ ".",
88
+ });
89
+ }
90
+
91
+ form["log_message_data[added_participants][" + i + "]"] =
92
+ "fbid:" + userID[i];
93
+ }
94
+
95
+ defaultFuncs
96
+ .post("https://www.facebook.com/messaging/send/", ctx.jar, form)
97
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
98
+ .then(function (resData) {
99
+ if (!resData) {
100
+ throw new utils.CustomError({ error: "Add to group failed." });
101
+ }
102
+ if (resData.error) {
103
+ throw new utils.CustomError(resData);
104
+ }
105
+
106
+ return callback();
107
+ })
108
+ .catch(function (err) {
109
+ console.error("addUserToGroup", err);
110
+ return callback(err);
111
+ });
112
+
113
+ return returnPromise;
114
+ };
115
+ };
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ // @NethWs3Dev
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function changeAdminStatus(threadID, adminIDs, adminStatus, callback) {
8
+ if (utils.getType(threadID) !== "String") {
9
+ throw new utils.CustomError({
10
+ error: "changeAdminStatus: threadID must be a string",
11
+ });
12
+ }
13
+
14
+ if (utils.getType(adminIDs) === "String") {
15
+ adminIDs = [adminIDs];
16
+ }
17
+
18
+ if (utils.getType(adminIDs) !== "Array") {
19
+ throw new utils.CustomError({
20
+ error: "changeAdminStatus: adminIDs must be an array or string",
21
+ });
22
+ }
23
+
24
+ if (utils.getType(adminStatus) !== "Boolean") {
25
+ throw new utils.CustomError({
26
+ error: "changeAdminStatus: adminStatus must be a string",
27
+ });
28
+ }
29
+
30
+ let resolveFunc = function () {};
31
+ let rejectFunc = function () {};
32
+ const returnPromise = new Promise(function (resolve, reject) {
33
+ resolveFunc = resolve;
34
+ rejectFunc = reject;
35
+ });
36
+
37
+ if (!callback) {
38
+ callback = function (err) {
39
+ if (err) {
40
+ return rejectFunc(err);
41
+ }
42
+ resolveFunc();
43
+ };
44
+ }
45
+
46
+ if (
47
+ utils.getType(callback) !== "Function" &&
48
+ utils.getType(callback) !== "AsyncFunction"
49
+ ) {
50
+ throw new utils.CustomError({
51
+ error: "changeAdminStatus: callback is not a function",
52
+ });
53
+ }
54
+
55
+ const form = {
56
+ thread_fbid: threadID,
57
+ };
58
+
59
+ let i = 0;
60
+ for (const u of adminIDs) {
61
+ form[`admin_ids[${i++}]`] = u;
62
+ }
63
+ form["add"] = adminStatus;
64
+
65
+ defaultFuncs
66
+ .post(
67
+ "https://www.facebook.com/messaging/save_admins/?dpr=1",
68
+ ctx.jar,
69
+ form,
70
+ )
71
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
72
+ .then(function (resData) {
73
+ if (resData.error) {
74
+ switch (resData.error) {
75
+ case 1976004:
76
+ throw new utils.CustomError({
77
+ error: "Cannot alter admin status: you are not an admin.",
78
+ rawResponse: resData,
79
+ });
80
+ case 1357031:
81
+ throw new utils.CustomError({
82
+ error:
83
+ "Cannot alter admin status: this thread is not a group chat.",
84
+ rawResponse: resData,
85
+ });
86
+ default:
87
+ throw new utils.CustomError({
88
+ error: "Cannot alter admin status: unknown error.",
89
+ rawResponse: resData,
90
+ });
91
+ }
92
+ }
93
+
94
+ callback();
95
+ })
96
+ .catch(function (err) {
97
+ console.error("changeAdminStatus", err);
98
+ return callback(err);
99
+ });
100
+
101
+ return returnPromise;
102
+ };
103
+ };
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ // @NethWs3Dev
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function changeArchivedStatus(threadOrThreads, archive, callback) {
8
+ let resolveFunc = function () {};
9
+ let rejectFunc = function () {};
10
+ const returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc();
21
+ };
22
+ }
23
+
24
+ const form = {};
25
+
26
+ if (utils.getType(threadOrThreads) === "Array") {
27
+ for (let i = 0; i < threadOrThreads.length; i++) {
28
+ form["ids[" + threadOrThreads[i] + "]"] = archive;
29
+ }
30
+ } else {
31
+ form["ids[" + threadOrThreads + "]"] = archive;
32
+ }
33
+
34
+ defaultFuncs
35
+ .post(
36
+ "https://www.facebook.com/ajax/mercury/change_archived_status.php",
37
+ ctx.jar,
38
+ form,
39
+ )
40
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
41
+ .then(function (resData) {
42
+ if (resData.error) {
43
+ throw resData;
44
+ }
45
+
46
+ return callback();
47
+ })
48
+ .catch(function (err) {
49
+ console.error("changeArchivedStatus", err);
50
+ return callback(err);
51
+ });
52
+
53
+ return returnPromise;
54
+ };
55
+ };