fca-smart-shankar 10.9.1 → 13.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 (169) hide show
  1. package/.replit +12 -3
  2. package/.upm/store.json +1 -1
  3. package/CHANGELOG.md +2 -0
  4. package/LICENSE-MIT +21 -0
  5. package/README.md +175 -30
  6. package/generated-icon.png +0 -0
  7. package/index.js +511 -414
  8. package/package.json +370 -85
  9. package/replit.nix +5 -0
  10. package/shankar-fca.json +4 -0
  11. package/src/addExternalModule.js +14 -5
  12. package/src/addUserToGroup.js +56 -20
  13. package/src/changeAdminStatus.js +44 -20
  14. package/src/changeArchivedStatus.js +25 -11
  15. package/src/changeAvatar.js +136 -0
  16. package/src/{changeAvt.js → changeAvatarV2.js} +3 -2
  17. package/src/changeBio.js +26 -15
  18. package/src/changeBlockedStatus.js +21 -8
  19. package/src/changeBlockedStatusMqtt.js +80 -0
  20. package/src/changeCover.js +73 -0
  21. package/src/changeGroupImage.js +53 -24
  22. package/src/changeName.js +79 -0
  23. package/src/changeNickname.js +27 -13
  24. package/src/changeThreadColor.js +22 -19
  25. package/src/changeThreadEmoji.js +24 -11
  26. package/src/changeUsername.js +59 -0
  27. package/src/createCommentPost.js +230 -0
  28. package/src/createNewGroup.js +38 -20
  29. package/src/createPoll.js +27 -16
  30. package/src/createPost.js +277 -0
  31. package/src/data/getThreadInfo.json +1 -0
  32. package/src/deleteMessage.js +24 -13
  33. package/src/deleteThread.js +25 -12
  34. package/src/editMessage.js +71 -53
  35. package/src/editMessageOld.js +67 -0
  36. package/src/follow.js +74 -0
  37. package/src/forwardAttachment.js +27 -15
  38. package/src/getAccess.js +112 -0
  39. package/src/getAvatarUser.js +78 -0
  40. package/src/getCurrentUserID.js +1 -1
  41. package/src/getEmojiUrl.js +10 -8
  42. package/src/getFriendsList.js +25 -15
  43. package/src/getMessage.js +813 -81
  44. package/src/getRegion.js +7 -0
  45. package/src/getThreadHistory.js +241 -98
  46. package/src/getThreadHistoryDeprecated.js +93 -0
  47. package/src/getThreadInfo.js +90 -287
  48. package/src/getThreadInfoDeprecated.js +80 -0
  49. package/src/getThreadList.js +214 -157
  50. package/src/getThreadListDeprecated.js +75 -0
  51. package/src/getThreadPictures.js +39 -19
  52. package/src/getUID.js +113 -50
  53. package/src/getUserID.js +18 -14
  54. package/src/getUserInfo.js +65 -71
  55. package/src/handleFriendRequest.js +24 -13
  56. package/src/handleMessageRequest.js +36 -20
  57. package/src/httpGet.js +34 -18
  58. package/src/httpPost.js +35 -18
  59. package/src/httpPostFormData.js +53 -24
  60. package/src/listenMqtt.js +680 -944
  61. package/src/listenNotification.js +85 -0
  62. package/src/logout.js +22 -15
  63. package/src/markAsDelivered.js +25 -15
  64. package/src/markAsRead.js +45 -27
  65. package/src/markAsReadAll.js +21 -14
  66. package/src/markAsSeen.js +28 -18
  67. package/src/muteThread.js +17 -12
  68. package/src/pinMessage.js +59 -0
  69. package/src/refreshFb_dtsg.js +89 -0
  70. package/src/removeUserFromGroup.js +47 -17
  71. package/src/resolvePhotoUrl.js +21 -13
  72. package/src/searchForThread.js +23 -13
  73. package/src/searchStickers.js +53 -0
  74. package/src/sendMessage.js +178 -117
  75. package/src/sendMessageMqtt.js +322 -0
  76. package/src/sendTypingIndicator.js +46 -16
  77. package/src/sendTypingIndicatorV2.js +28 -0
  78. package/src/setMessageReaction.js +33 -20
  79. package/src/setMessageReactionMqtt.js +62 -0
  80. package/src/setPostReaction.js +105 -95
  81. package/src/setProfileGuard.js +45 -0
  82. package/src/setStoryReaction.js +64 -0
  83. package/src/setTitle.js +34 -18
  84. package/src/shareContact.js +92 -37
  85. package/src/shareLink.js +5 -4
  86. package/src/stopListenMqtt.js +26 -0
  87. package/src/threadColors.js +110 -18
  88. package/src/unfriend.js +18 -9
  89. package/src/unsendMessage.js +31 -34
  90. package/src/uploadAttachment.js +94 -0
  91. package/test/data/shareAttach.js +1 -1
  92. package/test/test.js +1 -1
  93. package/utils.js +1393 -2918
  94. package/.cache/replit/env/latest +0 -56
  95. package/.cache/replit/env/latest.json +0 -1
  96. package/.cache/replit/modules/nodejs-14.res +0 -1
  97. package/.cache/replit/modules/replit.res +0 -1
  98. package/.cache/replit/modules/web.res +0 -1
  99. package/.cache/replit/modules.stamp +0 -0
  100. package/.cache/typescript/5.5/package.json +0 -1
  101. package/.config/configstore/update-notifier-npm.json +0 -4
  102. package/.gitattributes +0 -2
  103. package/Extra/Balancer.js +0 -49
  104. package/Extra/Bypass/956/index.js +0 -234
  105. package/Extra/Bypass/test/aaaa.json +0 -170
  106. package/Extra/Bypass/test/index.js +0 -188
  107. package/Extra/Database/index.js +0 -469
  108. package/Extra/ExtraAddons.js +0 -82
  109. package/Extra/ExtraFindUID.js +0 -62
  110. package/Extra/ExtraGetThread.js +0 -365
  111. package/Extra/ExtraScreenShot.js +0 -430
  112. package/Extra/ExtraUptimeRobot.js +0 -38
  113. package/Extra/Html/Classic/script.js +0 -119
  114. package/Extra/Html/Classic/style.css +0 -8
  115. package/Extra/Security/AES_256_GCM/index.js +0 -0
  116. package/Extra/Security/Base/Step_1.js +0 -6
  117. package/Extra/Security/Base/Step_2.js +0 -22
  118. package/Extra/Security/Base/Step_3.js +0 -22
  119. package/Extra/Security/Base/index.js +0 -191
  120. package/Extra/Security/Index.js +0 -5
  121. package/Extra/Security/Step_1.js +0 -6
  122. package/Extra/Security/Step_2.js +0 -22
  123. package/Extra/Security/Step_3.js +0 -22
  124. package/Extra/Src/Change_Environment.js +0 -24
  125. package/Extra/Src/Check_Update.js +0 -67
  126. package/Extra/Src/History.js +0 -115
  127. package/Extra/Src/Instant_Update.js +0 -65
  128. package/Extra/Src/Last-Run.js +0 -65
  129. package/Extra/Src/Premium.js +0 -81
  130. package/Extra/Src/Release_Memory.js +0 -160
  131. package/Extra/Src/Websocket.js +0 -213
  132. package/Extra/Src/image/checkmate.jpg +0 -0
  133. package/Extra/Src/test.js +0 -28
  134. package/Extra/Src/uuid.js +0 -137
  135. package/Func/AcceptAgreement.js +0 -31
  136. package/Func/ClearCache.js +0 -64
  137. package/Func/ReportV1.js +0 -54
  138. package/LICENSE +0 -678
  139. package/Language/index.json +0 -228
  140. package/Main.js +0 -1444
  141. package/SECURITY.md +0 -18
  142. package/broadcast.js +0 -44
  143. package/logger.js +0 -66
  144. package/src/Dev_Horizon_Data.js +0 -125
  145. package/src/Dev_getThreadInfoOLD.js +0 -422
  146. package/src/Dev_shareTest2.js +0 -68
  147. package/src/Dev_shareTest3.js +0 -71
  148. package/src/Premium.js +0 -25
  149. package/src/Screenshot.js +0 -83
  150. package/src/getAccessToken.js +0 -28
  151. package/src/getThreadInfoOLD.js +0 -422
  152. package/src/getThreadMain.js +0 -220
  153. package/src/getUserInfoMain.js +0 -65
  154. package/src/getUserInfoV2.js +0 -32
  155. package/src/getUserInfoV3.js +0 -63
  156. package/src/getUserInfoV4.js +0 -55
  157. package/src/getUserInfoV5.js +0 -61
  158. package/src/listenMqttV1.js +0 -846
  159. package/src/sendMqttMessage.js +0 -71
  160. package/src/unsendMqttMessage.js +0 -66
  161. package/test/Database_Test.js +0 -4
  162. package/test/Db2.js +0 -530
  163. package/test/Shankar_Database/A_README.md +0 -1
  164. package/test/Shankar_Database/Database.db +0 -0
  165. package/test/env/.env +0 -0
  166. package/test/example-db.db +0 -0
  167. package/test/memoryleak.js +0 -18
  168. package/test/testname.js +0 -1342
  169. package/test/testv2.js +0 -3
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
+ return function getThreadHistory(threadID, amount, timestamp, callback) {
8
+ var resolveFunc = function(){};
9
+ var rejectFunc = function(){};
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
21
+ };
22
+ }
23
+
24
+ if (!callback) {
25
+ throw { error: "getThreadHistory: need callback" };
26
+ }
27
+
28
+ var form = {
29
+ client: "mercury"
30
+ };
31
+
32
+ api.getUserInfo(threadID, function(err, res) {
33
+ if (err) {
34
+ return callback(err);
35
+ }
36
+ var key = Object.keys(res).length > 0 ? "user_ids" : "thread_fbids";
37
+ form["messages[" + key + "][" + threadID + "][offset]"] = 0;
38
+ form["messages[" + key + "][" + threadID + "][timestamp]"] = timestamp;
39
+ form["messages[" + key + "][" + threadID + "][limit]"] = amount;
40
+
41
+ if (ctx.globalOptions.pageID)
42
+ form.request_user_id = ctx.globalOptions.pageID;
43
+
44
+ defaultFuncs
45
+ .post(
46
+ "https://www.facebook.com/ajax/mercury/thread_info.php",
47
+ ctx.jar,
48
+ form
49
+ )
50
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
51
+ .then(function(resData) {
52
+ if (resData.error) {
53
+ throw resData;
54
+ } else if (!resData.payload) {
55
+ throw { error: "Could not retrieve thread history." };
56
+ }
57
+
58
+ // Asking for message history from a thread with no message history
59
+ // will return undefined for actions here
60
+ if (!resData.payload.actions) {
61
+ resData.payload.actions = [];
62
+ }
63
+
64
+ var userIDs = {};
65
+ resData.payload.actions.forEach(function(v) {
66
+ userIDs[v.author.split(":").pop()] = "";
67
+ });
68
+
69
+ api.getUserInfo(Object.keys(userIDs), function(err, data) {
70
+ if (err) return callback(err); //callback({error: "Could not retrieve user information in getThreadHistory."});
71
+
72
+ resData.payload.actions.forEach(function(v) {
73
+ var sender = data[v.author.split(":").pop()];
74
+ if (sender) v.sender_name = sender.name;
75
+ else v.sender_name = "Facebook User";
76
+ v.sender_fbid = v.author;
77
+ delete v.author;
78
+ });
79
+
80
+ callback(
81
+ null,
82
+ resData.payload.actions.map(utils.formatHistoryMessage)
83
+ );
84
+ });
85
+ })
86
+ .catch(function(err) {
87
+ log.error("getThreadHistory", err);
88
+ return callback(err);
89
+ });
90
+ });
91
+ return returnPromise;
92
+ };
93
+ };
@@ -1,8 +1,8 @@
1
- /* eslint-disable linebreak-style */
2
1
  "use strict";
3
2
 
4
- var utils = require("../utils");
5
- // tương lai đi rồi fix ahahha
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
6
  function formatEventReminders(reminder) {
7
7
  return {
8
8
  reminderID: reminder.id,
@@ -10,7 +10,6 @@ function formatEventReminders(reminder) {
10
10
  time: reminder.time,
11
11
  eventType: reminder.lightweight_event_type.toLowerCase(),
12
12
  locationName: reminder.location_name,
13
- // @TODO verify this
14
13
  locationCoordinates: reminder.location_coordinates,
15
14
  locationPage: reminder.location_page,
16
15
  eventStatus: reminder.lightweight_event_status.toLowerCase(),
@@ -21,29 +20,26 @@ function formatEventReminders(reminder) {
21
20
  secondsToNotifyBefore: reminder.seconds_to_notify_before,
22
21
  allowsRsvp: reminder.allows_rsvp,
23
22
  relatedEvent: reminder.related_event,
24
- members: reminder.event_reminder_members.edges.map(function(member) {
23
+ members: reminder.event_reminder_members.edges.map(function (member) {
25
24
  return {
26
25
  memberID: member.node.id,
27
- state: member.guest_list_state.toLowerCase()
26
+ state: member.guest_list_state.toLowerCase(),
28
27
  };
29
- })
28
+ }),
30
29
  };
31
30
  }
32
31
 
33
32
  function formatThreadGraphQLResponse(data) {
34
- try{
35
- var messageThread = data.message_thread;
36
- } catch (err){
37
- console.error("GetThreadInfoGraphQL", "Can't get this thread info!");
38
- return {err: err};
39
- }
40
- var threadID = messageThread.thread_key.thread_fbid
33
+ if (data.errors) return null; // Return null if there are errors
34
+ const messageThread = data.message_thread;
35
+ if (!messageThread) return null;
36
+
37
+ const threadID = messageThread.thread_key.thread_fbid
41
38
  ? messageThread.thread_key.thread_fbid
42
39
  : messageThread.thread_key.other_user_id;
43
40
 
44
- // Remove me
45
- var lastM = messageThread.last_message;
46
- var snippetID =
41
+ const lastM = messageThread.last_message;
42
+ const snippetID =
47
43
  lastM &&
48
44
  lastM.nodes &&
49
45
  lastM.nodes[0] &&
@@ -51,10 +47,10 @@ function formatThreadGraphQLResponse(data) {
51
47
  lastM.nodes[0].message_sender.messaging_actor
52
48
  ? lastM.nodes[0].message_sender.messaging_actor.id
53
49
  : null;
54
- var snippetText =
50
+ const snippetText =
55
51
  lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
56
- var lastR = messageThread.last_read_receipt;
57
- var lastReadTimestamp =
52
+ const lastR = messageThread.last_read_receipt;
53
+ const lastReadTimestamp =
58
54
  lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise
59
55
  ? lastR.nodes[0].timestamp_precise
60
56
  : null;
@@ -62,18 +58,21 @@ function formatThreadGraphQLResponse(data) {
62
58
  return {
63
59
  threadID: threadID,
64
60
  threadName: messageThread.name,
65
- participantIDs: messageThread.all_participants.edges.map(d => d.node.messaging_actor.id),
66
- userInfo: messageThread.all_participants.edges.map(d => ({
61
+ participantIDs: messageThread.all_participants.edges.map(
62
+ (d) => d.node.messaging_actor.id,
63
+ ),
64
+ userInfo: messageThread.all_participants.edges.map((d) => ({
67
65
  id: d.node.messaging_actor.id,
68
66
  name: d.node.messaging_actor.name,
69
67
  firstName: d.node.messaging_actor.short_name,
70
68
  vanity: d.node.messaging_actor.username,
69
+ url: d.node.messaging_actor.url,
71
70
  thumbSrc: d.node.messaging_actor.big_image_src.uri,
72
71
  profileUrl: d.node.messaging_actor.big_image_src.uri,
73
72
  gender: d.node.messaging_actor.gender,
74
73
  type: d.node.messaging_actor.__typename,
75
74
  isFriend: d.node.messaging_actor.is_viewer_friend,
76
- isBirthday: !!d.node.messaging_actor.is_birthday //not sure?
75
+ isBirthday: !!d.node.messaging_actor.is_birthday,
77
76
  })),
78
77
  unreadCount: messageThread.unread_count,
79
78
  messageCount: messageThread.messages_count,
@@ -95,33 +94,30 @@ function formatThreadGraphQLResponse(data) {
95
94
  messageThread.customization_info.outgoing_bubble_color
96
95
  ? messageThread.customization_info.outgoing_bubble_color.slice(2)
97
96
  : null,
97
+ threadTheme: messageThread.thread_theme,
98
98
  nicknames:
99
99
  messageThread.customization_info &&
100
100
  messageThread.customization_info.participant_customizations
101
101
  ? messageThread.customization_info.participant_customizations.reduce(
102
- function(res, val) {
102
+ function (res, val) {
103
103
  if (val.nickname) res[val.participant_id] = val.nickname;
104
104
  return res;
105
105
  },
106
- {}
106
+ {},
107
107
  )
108
108
  : {},
109
109
  adminIDs: messageThread.thread_admins,
110
110
  approvalMode: Boolean(messageThread.approval_mode),
111
- approvalQueue: messageThread.group_approval_queue.nodes.map(a => ({
111
+ approvalQueue: messageThread.group_approval_queue.nodes.map((a) => ({
112
112
  inviterID: a.inviter.id,
113
113
  requesterID: a.requester.id,
114
114
  timestamp: a.request_timestamp,
115
- request_source: a.request_source // @Undocumented
115
+ request_source: a.request_source,
116
116
  })),
117
-
118
- // @Undocumented
119
117
  reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
120
118
  mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
121
119
  isPinProtected: messageThread.is_pin_protected,
122
120
  relatedPageThread: messageThread.related_page_thread,
123
-
124
- // @Legacy
125
121
  name: messageThread.name,
126
122
  snippet: snippetText,
127
123
  snippetSender: snippetID,
@@ -140,51 +136,30 @@ function formatThreadGraphQLResponse(data) {
140
136
  lastMessageType: "message",
141
137
  lastReadTimestamp: lastReadTimestamp,
142
138
  threadType: messageThread.thread_type == "GROUP" ? 2 : 1,
143
- TimeCreate: Date.now(),
144
- TimeUpdate: Date.now()
139
+ inviteLink: {
140
+ enable: messageThread.joinable_mode
141
+ ? messageThread.joinable_mode.mode == 1
142
+ : false,
143
+ link: messageThread.joinable_mode
144
+ ? messageThread.joinable_mode.link
145
+ : null,
146
+ },
145
147
  };
146
148
  }
147
149
 
148
- const MAX_ARRAY_LENGTH = 6; //safe
149
- var Request_Update_Time = 0;
150
- var updateInterval;
151
- var updateTimeout;
152
- let Queues = [];
153
-
154
- let onetimecook = false
155
-
156
- function addToQueues(num) {
157
- const existingArray = Queues.some(subArr => subArr.some(obj => obj.threadID == num.threadID));
158
-
159
- if (!existingArray) {
160
- if (Queues.length > 0 && Queues[Queues.length - 1].length === MAX_ARRAY_LENGTH) {
161
- Queues.push([num]);
162
- } else {
163
- const lastArray = Queues.length > 0 ? Queues[Queues.length - 1] : [];
164
- lastArray.push(num);
165
-
166
- if (Queues.length === 0) {
167
- Queues.push(lastArray);
168
- }
169
- }
170
- }
171
- }
172
-
173
-
174
- module.exports = function(defaultFuncs, api, ctx) {
175
-
176
- var { createData,getData,hasData,updateData, getAll } = require('../Extra/ExtraGetThread');
177
- var Database = require('../Extra/Database');
178
-
179
- return async function getThreadInfoGraphQL(threadID, callback) {
180
- var resolveFunc = function(){};
181
- var rejectFunc = function(){};
182
- var returnPromise = new Promise(function (resolve, reject) {
150
+ module.exports = function (defaultFuncs, api, ctx) {
151
+ return function getThreadInfoGraphQL(threadID, callback) {
152
+ let resolveFunc = function () {};
153
+ let rejectFunc = function () {};
154
+ const returnPromise = new Promise(function (resolve, reject) {
183
155
  resolveFunc = resolve;
184
156
  rejectFunc = reject;
185
157
  });
186
158
 
187
- if (utils.getType(callback) != "Function" && utils.getType(callback) != "AsyncFunction") {
159
+ if (
160
+ utils.getType(callback) != "Function" &&
161
+ utils.getType(callback) != "AsyncFunction"
162
+ ) {
188
163
  callback = function (err, data) {
189
164
  if (err) {
190
165
  return rejectFunc(err);
@@ -192,233 +167,61 @@ module.exports = function(defaultFuncs, api, ctx) {
192
167
  resolveFunc(data);
193
168
  };
194
169
  }
195
-
196
- if (utils.getType(threadID) !== "Array") threadID = [threadID];
197
170
 
171
+ if (utils.getType(threadID) !== "Array") {
172
+ threadID = [threadID];
173
+ }
198
174
 
199
- if (utils.getType(global.Fca.Data.Userinfo) == "Array" || global.Fca.Data.Userinfo == undefined) global.Fca.Data.Userinfo = new Map();
175
+ let form = {};
176
+ threadID.map(function (t, i) {
177
+ form["o" + i] = {
178
+ doc_id: "3449967031715030",
179
+ query_params: {
180
+ id: t,
181
+ message_limit: 0,
182
+ load_messages: false,
183
+ load_read_receipts: false,
184
+ before: null,
185
+ },
186
+ };
187
+ });
200
188
 
201
- const updateUserInfo = (threadInfo) => {
202
- if (!global.Fca.Data.Userinfo) {
203
- global.Fca.Data.Userinfo = new Map();
204
- }
205
-
206
- threadInfo.forEach(thread => {
207
- const userInfo = thread.userInfo;
208
-
209
- if (Array.isArray(userInfo)) {
210
- const userInfoMap = new Map(userInfo.map(user => [user.id, user]));
211
- for (const [id, user] of userInfoMap) {
212
- global.Fca.Data.Userinfo.set(id, user);
213
- }
214
- }
215
- });
189
+ form = {
190
+ queries: JSON.stringify(form),
191
+ batch_name: "MessengerGraphQLThreadFetcher",
216
192
  };
217
-
218
- const getMultiInfo = async function (threadIDs) {
219
- let form = {};
220
- let tempThreadInf = [];
221
- threadIDs.forEach((x,y) => {
222
- form["o" + y] = {
223
- doc_id: "3449967031715030",
224
- query_params: { id: x, message_limit: 0, load_messages: false, load_read_receipts: false, before: null }
225
- };
226
- });
227
- let Submit = { queries: JSON.stringify(form), batch_name: "MessengerGraphQLThreadFetcher" };
228
-
229
- const promise = new Promise((resolve, reject) => {
230
- defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, Submit)
231
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
232
- .then(resData => {
233
- if (resData.error || resData[resData.length - 1].error_results !== 0) throw "Lỗi: getThreadInfoGraphQL Có Thể Do Bạn Spam Quá Nhiều";
234
- resData = resData.slice(0, -1).sort((a, b) => Object.keys(a)[0].localeCompare(Object.keys(b)[0]));
235
- resData.forEach((x, y) => tempThreadInf.push(formatThreadGraphQLResponse(x["o" + y].data)));
236
- return resolve({
237
- Success: true,
238
- Data: tempThreadInf
239
- });
240
- })
241
- .catch(() => {
242
- reject({ Success: false, Data: '' })
243
- });
244
- })
245
-
246
- return await promise;
247
- }
248
-
249
- const formatAndUpdateData = (AllThreadInfo) => {
250
- try {
251
- AllThreadInfo.forEach(threadInf => { updateData(threadInf.threadID, threadInf); })
252
- updateUserInfo(AllThreadInfo) // [ {}, {} ]
253
-
254
- } catch (e) {
255
- console.log(e);
256
- }
257
- }
258
193
 
259
- const formatAndCreateData = (AllThreadInfo) => {
260
- try {
261
- AllThreadInfo.forEach(threadInf => { createData(threadInf.threadID, threadInf); })
262
- updateUserInfo(AllThreadInfo) // [ {}, {} ]
194
+ defaultFuncs
195
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
196
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
197
+ .then(function (resData) {
198
+ if (resData.error) {
199
+ throw resData;
200
+ }
263
201
 
264
- } catch (e) {
265
- console.log(e);
266
- }
267
- }
268
-
269
- const checkAverageStaticTimestamp = function (avgTimeStamp) {
270
- const DEFAULT_UPDATE_TIME = 900 * 1000; //thời gian cập nhật tối đa + với thời gian trung bình của tổng request 1 mảng
271
- //khi request phút thứ 3, 1 req ở phút thứ 7, 1 req ở phút thứ 10, vậy trung bình là (3+7+1) / time.length (3) + với 15p = tg trung bình để cập nhật 1 mảng
272
- const MAXIMUM_ERROR_TIME = 10 * 1000;
273
- return { //khi check = false thì cần cập nhật vì đã hơn thời gian tb + 15p
274
- Check: (parseInt(avgTimeStamp) + parseInt(DEFAULT_UPDATE_TIME)) + parseInt(MAXIMUM_ERROR_TIME) >= Date.now(), // ở đây avgTimeStamp là thời gian cố định của 1 mảng queue khi đầy
275
- timeLeft: (parseInt(avgTimeStamp) + parseInt(DEFAULT_UPDATE_TIME)) - Date.now() + parseInt(MAXIMUM_ERROR_TIME)
276
- }
277
- }
278
-
279
- const autoCheckAndUpdateRecallTime = () => {
280
- let holdTime = [];
281
- let oneTimeCall = false;
282
- //lấy tất cả trung bình thời gian của tất cả mảng và tìm thời gian còn lại ngắn nhất, nếu có sẵn id cần cập nhật thì cập nhật ngày lập tức
283
- Queues.forEach((i, index) => {
284
- // [ { threadID, TimeCreate }, {} ]
285
- const averageTimestamp = Math.round(i.reduce((acc, obj) => acc + obj.TimeCreate, 0) / i.length);
286
- const DataAvg = checkAverageStaticTimestamp(averageTimestamp);
287
- if (DataAvg.Check) {
288
- //cần chờ
289
- // holdTime.push(DataAvg.timeLeft);
290
- //cho thi cho 10s sau check lai roi cho tiep nhe =))
202
+ const threadInfos = {};
203
+ for (let i = resData.length - 2; i >= 0; i--) {
204
+ const threadInfo = formatThreadGraphQLResponse(
205
+ resData[i][Object.keys(resData[i])[0]].data,
206
+ );
207
+ if (threadInfo) { // Only add valid threadInfo
208
+ threadInfos[
209
+ threadInfo.threadID || threadID[threadID.length - 1 - i]
210
+ ] = threadInfo;
291
211
  }
292
- else {
293
- oneTimeCall = true;
294
- }
295
- });
296
-
297
- if (oneTimeCall) autoUpdateData(); // cập nhật ngay, nhin la biet tot hon hold roi =))
298
-
299
- // if (holdTime.length >= 1) {
300
- // holdTime.sort((a,b) => a - b) //low to high time
301
- // if (holdTime[0] > Request_Update_Time) {
302
- // Request_Update_Time = holdTime[0];
303
- // clearInterval(updateInterval);
304
- // updateInterval = setInterval(() => { autoUpdateData(); }, holdTime[0])
305
- // }
306
- // }
307
-
308
- //hold lam cai cho gi khi ta co check lien tuc 10s 1 lan 😔
212
+ }
309
213
 
310
- const MAXIMUM_RECALL_TIME = 30 * 1000;
311
- clearTimeout(updateTimeout);
312
- updateTimeout = setTimeout(() => { autoCheckAndUpdateRecallTime(); }, MAXIMUM_RECALL_TIME)
313
- }
314
-
315
- const autoUpdateData = async function() {
316
- //[ [ {}, {} ], [ {}, {} ] ]
317
- let doUpdate = [];
318
- let holdTime = [];
319
-
320
- Queues.forEach((i, index) => {
321
- // [ {}, {} ]
322
- const averageTimestamp = Math.round(i.reduce((acc, obj) => acc + obj.TimeCreate, 0) / i.length);
323
- // thời gian trung bình của 1 mảng từ lúc bắt đầu request lần đầu, cần + thêm thời gian cố định là 15p !
324
-
325
- const DataAvg = checkAverageStaticTimestamp(averageTimestamp)
326
- if (DataAvg.Check) {
327
- // chờ tiếp
328
- }
329
- else {
330
- // đã hơn thời gian 15p
331
- doUpdate.push(i) // [ {}, {} ]
332
- Queues.splice(index, 1); //đạt điều kiện nên xoá để tý nó tự thêm 💀
333
- }
334
-
335
- });
336
-
337
- if (doUpdate.length >= 1) {
338
- // maybe [ [ {}, {} ] [ {}, {} ] ]
339
- let ids = []; // [ id, id ]
340
- doUpdate.forEach(i => {
341
- //[ {} {} ]
342
- const onlyThreadID = [...new Set(i.map(obj => obj.threadID))]; // [ id1, id2 ]
343
- ids.push(onlyThreadID) //[ [ id1, id2 ] ]
344
- })
345
-
346
- // [ [ id1, id2 ],[ id1, id2 ] ] 5 per arr
347
-
348
- ids.forEach(async function(i) {
349
- const dataResp = await getMultiInfo(i);
350
- if (dataResp.Success == true) {
351
- let MultiThread = dataResp.Data;
352
- formatAndUpdateData(MultiThread)
353
- }
354
- else {
355
- global.Fca.Require.logger.Warning('CANT NOT GET THREADINFO 💀 MAYBE U HAS BEEN BLOCKED FROM FACEBOOK');
356
- }
357
- })
358
- }
359
- }
360
-
361
- const createOrTakeDataFromDatabase = async (threadIDs) => {
362
- let inDb = []; //NOTE: xử lý resp thành 1 mảng nếu có nhiều hơn 1 threadID và obj nếu 1 threadID
363
- let inFastArr = [];
364
- let createNow = [];
365
- let cbThreadInfos = [];
366
- // kiểm tra và phân ra 2 loại 1 là chưa có 2 là có =))
367
- // kiểm tra
368
-
369
- threadIDs.forEach(id => {
370
- // id, id ,id
371
- hasData(id) == true ? inDb.push(id) : createNow.push(id)
214
+ if (Object.values(threadInfos).length == 1) {
215
+ callback(null, Object.values(threadInfos)[0]);
216
+ } else {
217
+ callback(null, threadInfos);
218
+ }
219
+ })
220
+ .catch(function () {
221
+ // Do nothing on error
222
+ callback(null, null);
372
223
  });
373
224
 
374
- if (inDb.length >= 1) {
375
- let threadInfos = inDb.map(id => getData(id));
376
- cbThreadInfos = cbThreadInfos.concat(threadInfos);
377
- updateUserInfo(threadInfos);
378
-
379
- //request update queue
380
- threadInfos.forEach(i => addToQueues({ threadID: i.threadID, TimeCreate: Date.now() }));
381
- }
382
- if (createNow.length >= 1) {
383
- //5 data per chunk []
384
- const chunkSize = 5;
385
- const totalChunk = []; // [ [ id, id ], [ id,id ] ]
386
-
387
- for (let i = 0; i < createNow.length; i += chunkSize) {
388
- const chunk = createNow.slice(i, i + chunkSize);
389
- totalChunk.push(chunk);
390
- }
391
-
392
- for (let i of totalChunk) {
393
- //i = [ id,id ]
394
- const newThreadInf = await getMultiInfo(i); // always [ {} ] or [ {}, {} ]
395
- if (newThreadInf.Success == true) {
396
- let MultiThread = newThreadInf.Data;
397
- formatAndCreateData(MultiThread)
398
- cbThreadInfos = cbThreadInfos.concat(MultiThread)
399
-
400
- //request update queue
401
- MultiThread.forEach(i => addToQueues({ threadID: i.threadID, TimeCreate: Date.now() }));
402
- }
403
- else {
404
- global.Fca.Require.logger.Warning('CANT NOT GET THREADINFO 💀 MAYBE U HAS BEEN BLOCKED FROM FACEBOOK');
405
- }
406
- }
407
- }
408
- return cbThreadInfos.length == 1 ? callback(null, cbThreadInfos[0]) : callback(null, cbThreadInfos)
409
- }
410
-
411
- if (global.Fca.Data.Already != true) {
412
- global.Fca.Data.Already = true;
413
- autoCheckAndUpdateRecallTime();
414
- setInterval(function(){
415
- const MapToArray = Array.from(global.Fca.Data.Userinfo, ([name, value]) => (value));
416
- Database(true).set('UserInfo', MapToArray);
417
- }, 420 * 1000);
418
- }
419
-
420
- await createOrTakeDataFromDatabase(threadID);
421
-
422
225
  return returnPromise;
423
226
  };
424
- };
227
+ };
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
+ return function getThreadInfo(threadID, callback) {
8
+ var resolveFunc = function(){};
9
+ var rejectFunc = function(){};
10
+ var returnPromise = new Promise(function (resolve, reject) {
11
+ resolveFunc = resolve;
12
+ rejectFunc = reject;
13
+ });
14
+
15
+ if (!callback) {
16
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
21
+ };
22
+ }
23
+
24
+ var form = {
25
+ client: "mercury"
26
+ };
27
+
28
+ api.getUserInfo(threadID, function(err, userRes) {
29
+ if (err) {
30
+ return callback(err);
31
+ }
32
+ var key = Object.keys(userRes).length > 0 ? "user_ids" : "thread_fbids";
33
+ form["threads[" + key + "][0]"] = threadID;
34
+
35
+ if (ctx.globalOptions.pageId)
36
+ form.request_user_id = ctx.globalOptions.pageId;
37
+
38
+ defaultFuncs
39
+ .post(
40
+ "https://www.facebook.com/ajax/mercury/thread_info.php",
41
+ ctx.jar,
42
+ form
43
+ )
44
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
45
+ .then(function(resData) {
46
+ if (resData.error) {
47
+ throw resData;
48
+ } else if (!resData.payload) {
49
+ throw {
50
+ error: "Could not retrieve thread Info."
51
+ };
52
+ }
53
+ var threadData = resData.payload.threads[0];
54
+ var userData = userRes[threadID];
55
+
56
+ if (threadData == null) {
57
+ throw {
58
+ error: "ThreadData is null"
59
+ };
60
+ }
61
+
62
+ threadData.name =
63
+ userData != null && userData.name != null
64
+ ? userData.name
65
+ : threadData.name;
66
+ threadData.image_src =
67
+ userData != null && userData.thumbSrc != null
68
+ ? userData.thumbSrc
69
+ : threadData.image_src;
70
+
71
+ callback(null, utils.formatThread(threadData));
72
+ })
73
+ .catch(function(err) {
74
+ log.error("getThreadInfo", err);
75
+ return callback(err);
76
+ });
77
+ });
78
+ return returnPromise;
79
+ };
80
+ };