fca-horidai-remastered 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ var utils = require('../utils');
4
+ var log = require('npmlog');
5
+
6
+ module.exports = function (http, api, ctx) {
7
+ return function getAcceptList(callback) {
8
+ var form = {
9
+ av: ctx.userID,
10
+ fb_api_caller_class: "RelayModern",
11
+ fb_api_req_friendly_name: "FriendingCometFriendsBadgeCountClearMutation",
12
+ variables: JSON.stringify({
13
+ hasTopTab: true,
14
+ hasBookmark: true,
15
+ input: {
16
+ source: "friending_tab",
17
+ actor_id: ctx.userID,
18
+ client_mutation_id: Math.round(Math.random() * 19).toString()
19
+ }
20
+ }),
21
+ server_timestamps: true,
22
+ doc_id: "6500595106704138"
23
+ };
24
+
25
+ http.post('https://www.facebook.com/api/graphql/', ctx.jar, form, null, null)
26
+ .then(utils.parseAndCheckLogin(ctx, http))
27
+ .then(function (res) {
28
+ if (res.errors) {
29
+ return callback(JSON.stringify(res.errors, null, 2));
30
+ }
31
+ return callback(JSON.stringify(res.data, null, 2));
32
+ })
33
+ .catch(function (err) {
34
+ log.error('addFriends', err);
35
+ return callback(err);
36
+ });
37
+ };
38
+ };
@@ -0,0 +1,56 @@
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, data) {
17
+ if (err) return rejectFunc(err);
18
+ resolveFunc(data);
19
+ };
20
+ }
21
+
22
+ var form = {
23
+ client: "mercury"
24
+ };
25
+
26
+ api.getUserInfo(threadID, function (err, userRes) {
27
+ if (err) return callback(err);
28
+ var key = Object.keys(userRes).length > 0 ? "user_ids" : "thread_fbids";
29
+ form["threads[" + key + "][0]"] = threadID;
30
+
31
+ if (ctx.globalOptions.pageId) form.request_user_id = ctx.globalOptions.pageId;
32
+
33
+ defaultFuncs
34
+ .post("https://www.facebook.com/ajax/mercury/thread_info.php", ctx.jar, form)
35
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
36
+ .then(function (resData) {
37
+ if (resData.error) throw resData;
38
+ else if (!resData.payload) throw { error: "Could not retrieve thread Info." };
39
+
40
+ var threadData = resData.payload.threads[0];
41
+ var userData = userRes[threadID];
42
+
43
+ if (threadData == null) throw { error: "ThreadData is null" };
44
+
45
+ threadData.name = userData != null && userData.name != null ? userData.name : threadData.name;
46
+ threadData.image_src = userData != null && userData.thumbSrc != null ? userData.thumbSrc : threadData.image_src;
47
+ callback(null, utils.formatThread(threadData));
48
+ })
49
+ .catch(function (err) {
50
+ log.error("getThreadInfo", err);
51
+ return callback(err);
52
+ });
53
+ });
54
+ return returnPromise;
55
+ };
56
+ };
package/src/listenMqtt.js CHANGED
@@ -212,7 +212,7 @@ function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
212
212
  maxThreshold: 0.9,
213
213
  interval: 60 * 1000,
214
214
  logLevel: 'warn',
215
- logFile: path.join(process.cwd(), 'Horizon_Database' ,'memory.log'),
215
+ logFile: path.join(process.cwd(), 'main/database_fca' ,'memory.log'),
216
216
  smartReleaseEnabled: true,
217
217
  allowLog: (global.Fca.Require.FastConfig.AntiStuckAndMemoryLeak.LogFile.Use || false)
218
218
  };
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ const { generateOfflineThreadingID, getCurrentTimestamp } = require('../utils');
4
+
5
+ function isCallable(func) {
6
+ try {
7
+ Reflect.apply(func, null, []);
8
+ return true;
9
+ } catch (error) {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ module.exports = function (defaultFuncs, api, ctx) {
15
+ return function pinMessage(pinMode, messageID, threadID, callback) {
16
+ if (!ctx.mqttClient) {
17
+ throw new Error('Not connected to MQTT');
18
+ }
19
+
20
+ ctx.wsReqNumber += 1;
21
+ ctx.wsTaskNumber += 1;
22
+
23
+ const taskLabel = pinMode ? '430' : '431';
24
+ const queueNamePrefix = pinMode ? 'pin_msg_v2_' : 'unpin_msg_v2_';
25
+
26
+ const taskPayload = {
27
+ thread_key: threadID,
28
+ message_id: messageID,
29
+ timestamp_ms: getCurrentTimestamp(),
30
+ };
31
+
32
+ const task = {
33
+ failure_count: null,
34
+ label: taskLabel,
35
+ payload: JSON.stringify(taskPayload),
36
+ queue_name: `${queueNamePrefix}${threadID}`,
37
+ task_id: ctx.wsTaskNumber,
38
+ };
39
+
40
+ const content = {
41
+ app_id: '2220391788200892',
42
+ payload: JSON.stringify({
43
+ data_trace_id: null,
44
+ epoch_id: parseInt(generateOfflineThreadingID()),
45
+ tasks: [task],
46
+ version_id: '25095469420099952',
47
+ }),
48
+ request_id: ctx.wsReqNumber,
49
+ type: 3,
50
+ };
51
+
52
+ if (isCallable(callback)) {
53
+ // to be implemented
54
+ }
55
+
56
+ ctx.mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
57
+ };
58
+ };
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ const utils = require("../utils");
4
+ const log = require("npmlog");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ /**
8
+ * Refreshes the fb_dtsg and jazoest values.
9
+ * @param {Function} callback
10
+ * @returns {Promise}
11
+ * @description if you don't update the value of fb_dtsg and jazoest for a long time an error "Please try closing and re-opening your browser window" will appear
12
+ * @description you should refresh it every 48h or less
13
+ */
14
+ return function refreshFb_dtsg(obj, callback) {
15
+ let resolveFunc = function () { };
16
+ let rejectFunc = function () { };
17
+ const returnPromise = new Promise(function (resolve, reject) {
18
+ resolveFunc = resolve;
19
+ rejectFunc = reject;
20
+ });
21
+
22
+ if (utils.getType(obj) === "Function" || utils.getType(obj) === "AsyncFunction") {
23
+ callback = obj;
24
+ obj = {};
25
+ }
26
+
27
+ if (!obj) {
28
+ obj = {};
29
+ }
30
+
31
+ if (utils.getType(obj) !== "Object") {
32
+ throw new utils.CustomError("the first parameter must be an object or a callback function");
33
+ }
34
+
35
+ if (!callback) {
36
+ callback = function (err, friendList) {
37
+ if (err) {
38
+ return rejectFunc(err);
39
+ }
40
+ resolveFunc(friendList);
41
+ };
42
+ }
43
+
44
+ if (Object.keys(obj).length == 0) {
45
+ utils
46
+ .get('https://m.facebook.com/', ctx.jar, null, ctx.globalOptions, { noRef: true })
47
+ .then(function (resData) {
48
+ const html = resData.body;
49
+ const fb_dtsg = utils.getFrom(html, 'name="fb_dtsg" value="', '"');
50
+ const jazoest = utils.getFrom(html, 'name="jazoest" value="', '"');
51
+ if (!fb_dtsg) {
52
+ throw new utils.CustomError("Could not find fb_dtsg in HTML after requesting https://www.facebook.com/");
53
+ }
54
+ ctx.fb_dtsg = fb_dtsg;
55
+ ctx.jazoest = jazoest;
56
+ callback(null, {
57
+ data: {
58
+ fb_dtsg: fb_dtsg,
59
+ jazoest: jazoest
60
+ },
61
+ message: "refreshed fb_dtsg and jazoest"
62
+ });
63
+ })
64
+ .catch(function (err) {
65
+ log.error("refreshFb_dtsg", err);
66
+ return callback(err);
67
+ });
68
+ }
69
+ else {
70
+ Object.keys(obj).forEach(function (key) {
71
+ ctx[key] = obj[key];
72
+ });
73
+ callback(null, {
74
+ data: obj,
75
+ message: "refreshed " + Object.keys(obj).join(", ")
76
+ });
77
+ }
78
+
79
+ return returnPromise;
80
+ };
81
+ };
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+ var bluebird = require("bluebird");
6
+
7
+ module.exports = function (defaultFuncs, api, ctx) {
8
+ function getGUID() {
9
+ let _0x161e32 = Date.now(),
10
+ _0x4ec135 = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
11
+ /[xy]/g,
12
+ function (_0x32f946) {
13
+ let _0x141041 = Math.floor((_0x161e32 + Math.random() * 16) % 16);
14
+ _0x161e32 = Math.floor(_0x161e32 / 16);
15
+ let _0x31fcdd = (
16
+ _0x32f946 == "x" ? _0x141041 : (_0x141041 & 0x3) | 0x8
17
+ ).toString(16);
18
+ return _0x31fcdd;
19
+ },
20
+ );
21
+ return _0x4ec135;
22
+ }
23
+
24
+ function uploadAttachment(attachment, callback) {
25
+ var uploads = [];
26
+
27
+ // create an array of promises
28
+ if (!utils.isReadableStream(attachment)) {
29
+ throw {
30
+ error:
31
+ "Attachment should be a readable stream and not " +
32
+ utils.getType(attachment) +
33
+ ".",
34
+ };
35
+ }
36
+
37
+ var form = {
38
+ file: attachment,
39
+ av: api.getCurrentUserID(),
40
+ profile_id: api.getCurrentUserID(),
41
+ source: "19",
42
+ target_id: api.getCurrentUserID(),
43
+ __user: api.getCurrentUserID(),
44
+ __a: "1",
45
+ };
46
+
47
+ uploads.push(
48
+ defaultFuncs
49
+ .postFormData(
50
+ "https://www.facebook.com/ajax/ufi/upload",
51
+ ctx.jar,
52
+ form,
53
+ {},
54
+ )
55
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
56
+ .then(function (resData) {
57
+ if (resData.error) {
58
+ throw resData;
59
+ }
60
+
61
+ // We have to return the data unformatted unless we want to change it
62
+ // back in sendMessage.
63
+ return resData.payload;
64
+ }),
65
+ );
66
+
67
+ // resolve all promises
68
+ bluebird
69
+ .all(uploads)
70
+ .then(function (resData) {
71
+ callback(null, resData);
72
+ })
73
+ .catch(function (err) {
74
+ log.error("uploadAttachment", err);
75
+ return callback(err);
76
+ });
77
+ }
78
+
79
+ async function sendCommentToFb(postId, text, fileID) {
80
+ const feedback_id = Buffer.from("feedback:" + postId).toString("base64");
81
+
82
+ const ss1 = getGUID();
83
+ const ss2 = getGUID();
84
+
85
+ const form = {
86
+ av: api.getCurrentUserID(),
87
+ fb_api_req_friendly_name: "CometUFICreateCommentMutation",
88
+ fb_api_caller_class: "RelayModern",
89
+ doc_id: "4744517358977326",
90
+ variables: JSON.stringify({
91
+ displayCommentsFeedbackContext: null,
92
+ displayCommentsContextEnableComment: null,
93
+ displayCommentsContextIsAdPreview: null,
94
+ displayCommentsContextIsAggregatedShare: null,
95
+ displayCommentsContextIsStorySet: null,
96
+ feedLocation: "TIMELINE",
97
+ feedbackSource: 0,
98
+ focusCommentID: null,
99
+ includeNestedComments: false,
100
+ input: {
101
+ attachments: fileID ? [{ media: { id: fileID } }] : null,
102
+ feedback_id: feedback_id,
103
+ formatting_style: null,
104
+ message: {
105
+ ranges: [],
106
+ text: text,
107
+ },
108
+ is_tracking_encrypted: true,
109
+ tracking: [],
110
+ feedback_source: "PROFILE",
111
+ idempotence_token: "client:" + ss1,
112
+ session_id: ss2,
113
+ actor_id: api.getCurrentUserID(),
114
+ client_mutation_id: Math.round(Math.random() * 19),
115
+ },
116
+ scale: 3,
117
+ useDefaultActor: false,
118
+ UFI2CommentsProvider_commentsKey: "ProfileCometTimelineRoute",
119
+ }),
120
+ };
121
+
122
+ const res = JSON.parse(
123
+ await api.httpPost("https://www.facebook.com/api/graphql/", form),
124
+ );
125
+ return res;
126
+ }
127
+
128
+ return async function sendComment(content, postId, callback) {
129
+ if (typeof content === "object") {
130
+ var text = content.body || "";
131
+ if (content.attachment) {
132
+ if (!utils.isReadableStream(content.attachment)) {
133
+ throw new Error("Attachment must be a ReadableStream");
134
+ }
135
+
136
+ uploadAttachment(content.attachment, async function (err, files) {
137
+ if (err) {
138
+ return callback(err);
139
+ }
140
+
141
+ await sendCommentToFb(postId, text, files[0].fbid)
142
+ .then((res) => {
143
+ return callback(null, res);
144
+ })
145
+ .catch((err) => {
146
+ return callback(err);
147
+ });
148
+ });
149
+ }
150
+ } else if (typeof content === "string") {
151
+ var text = content;
152
+ await sendCommentToFb(postId, text, null)
153
+ .then((res) => {
154
+ return callback(null, res);
155
+ })
156
+ .catch((err) => {
157
+ return callback(err);
158
+ });
159
+ } else throw new Error("Invalid content");
160
+ };
161
+ };
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const { generateOfflineThreadingID, getCurrentTimestamp } = require('../utils');
4
+
5
+ function isCallable(func) {
6
+ try {
7
+ Reflect.apply(func, null, []);
8
+ return true;
9
+ } catch (error) {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ module.exports = function (defaultFuncs, api, ctx) {
15
+ return function setMessageReactionMqtt(reaction, messageID, threadID, callback) {
16
+ if (!ctx.mqttClient) {
17
+ throw new Error('Not connected to MQTT');
18
+ }
19
+
20
+ ctx.wsReqNumber += 1;
21
+ let taskNumber = ++ctx.wsTaskNumber;
22
+
23
+ const taskPayload = {
24
+ thread_key: threadID,
25
+ timestamp_ms: getCurrentTimestamp(),
26
+ message_id: messageID,
27
+ reaction: reaction,
28
+ actor_id: ctx.userID,
29
+ reaction_style: null,
30
+ sync_group: 1,
31
+ send_attribution: Math.random() < 0.5 ? 65537 : 524289
32
+ };
33
+
34
+ const task = {
35
+ failure_count: null,
36
+ label: '29',
37
+ payload: JSON.stringify(taskPayload),
38
+ queue_name: JSON.stringify(['reaction', messageID]),
39
+ task_id: taskNumber,
40
+ };
41
+
42
+ const content = {
43
+ app_id: '2220391788200892',
44
+ payload: JSON.stringify({
45
+ data_trace_id: null,
46
+ epoch_id: parseInt(generateOfflineThreadingID()),
47
+ tasks: [task],
48
+ version_id: '7158486590867448',
49
+ }),
50
+ request_id: ctx.wsReqNumber,
51
+ type: 3,
52
+ };
53
+
54
+ if (isCallable(callback)) {
55
+ ctx["tasks"].set(taskNumber, {
56
+ type: 'set_message_reaction',
57
+ callback: callback
58
+ });
59
+ }
60
+ ctx.mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
61
+ };
62
+ };
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ var utils = require('../utils');
4
+ var log = require('npmlog');
5
+
6
+ module.exports = function (http, api, ctx) {
7
+ return function setStoryReaction(storyID, react, callback) {
8
+ var cb;
9
+ var rtPromise = new Promise(function (resolve, reject) {
10
+ cb = error => error ? reject(error) : resolve();
11
+ });
12
+
13
+ if (typeof react == 'function') {
14
+ callback = react;
15
+ react = null;
16
+ }
17
+ if (typeof callback == 'function') cb = callback;
18
+ if (typeof react != 'string') react = '👍';
19
+
20
+ var form = {
21
+ fb_api_req_friendly_name: 'useStoriesSendReplyMutation',
22
+ variables: JSON.stringify({
23
+ input: {
24
+ attribution_id_v2: `StoriesCometSuspenseRoot.react,comet.stories.viewer,unexpected,${Date.now()},538296,,;CometHomeRoot.react,comet.home,via_cold_start,${Date.now()},850302,4748854339,`,
25
+ lightweight_reaction_actions: {
26
+ offsets: [0],
27
+ reaction: react
28
+ },
29
+ message: react,
30
+ story_id: storyID,
31
+ story_reply_type: "LIGHT_WEIGHT",
32
+ actor_id: ctx.userID,
33
+ client_mutation_id: Math.round(Math.random() * 19).toString()
34
+ }
35
+ }),
36
+ doc_id: 4826141330837571
37
+ }
38
+
39
+ http
40
+ .post('https://www.facebook.com/api/graphql/', ctx.jar, form)
41
+ .then(utils.parseAndCheckLogin(ctx, http))
42
+ .then(function (res) {
43
+ if (res.errors) throw res;
44
+ return cb();
45
+ })
46
+ .catch(function (err) {
47
+ log.error('setPostReaction', err);
48
+ return cb(err);
49
+ });
50
+
51
+ return rtPromise;
52
+ }
53
+ }