nexus-fca 3.2.3 → 3.2.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.
- package/README.md +1 -0
- package/lib/factory/ApiFactory.js +24 -7
- package/lib/safety/FacebookSafety.js +16 -15
- package/package.json +2 -2
- package/utils.js +28 -7
package/README.md
CHANGED
|
@@ -187,6 +187,7 @@ const login = require('nexus-fca');
|
|
|
187
187
|
## 📚 Documentation Map
|
|
188
188
|
| Resource | Location |
|
|
189
189
|
|----------|----------|
|
|
190
|
+
| **Usage Guide (Examples)** | `USAGE-GUIDE.md` |
|
|
190
191
|
| Full API Reference | `DOCS.md` |
|
|
191
192
|
| Feature Guides | `docs/*.md` |
|
|
192
193
|
| Configuration Reference | `docs/configuration-reference.md` |
|
|
@@ -183,6 +183,9 @@ class ApiFactory {
|
|
|
183
183
|
globalOptions[key] = options[key];
|
|
184
184
|
});
|
|
185
185
|
},
|
|
186
|
+
autoTyping: (enable = true) => {
|
|
187
|
+
globalOptions.autoTyping = !!enable;
|
|
188
|
+
},
|
|
186
189
|
getAppState: function () {
|
|
187
190
|
const appState = utils.getAppState(ctx.jar);
|
|
188
191
|
return appState.filter((item, index, self) =>
|
|
@@ -217,6 +220,11 @@ class ApiFactory {
|
|
|
217
220
|
}
|
|
218
221
|
};
|
|
219
222
|
|
|
223
|
+
// Default options
|
|
224
|
+
if (typeof globalOptions.autoTyping === 'undefined') {
|
|
225
|
+
globalOptions.autoTyping = true; // Enabled by default for safety
|
|
226
|
+
}
|
|
227
|
+
|
|
220
228
|
// Default edit settings
|
|
221
229
|
if (!globalOptions.editSettings) {
|
|
222
230
|
globalOptions.editSettings = {
|
|
@@ -293,9 +301,18 @@ class ApiFactory {
|
|
|
293
301
|
globalOptions.groupQueueIdleMs = 30 * 60 * 1000;
|
|
294
302
|
|
|
295
303
|
api._sendMessageDirect = DIRECT_FN;
|
|
296
|
-
api.sendMessage = function (message, threadID, cb) {
|
|
304
|
+
api.sendMessage = function (message, threadID, cb, replyToMessage) {
|
|
305
|
+
// New: Auto-Typing support for improved human-like behavior
|
|
306
|
+
if (globalOptions.autoTyping) {
|
|
307
|
+
try {
|
|
308
|
+
api.sendTypingIndicator(threadID, (err) => {
|
|
309
|
+
// Ignore typing errors to avoid blocking the message
|
|
310
|
+
});
|
|
311
|
+
} catch (_) { /* ignore */ }
|
|
312
|
+
}
|
|
313
|
+
|
|
297
314
|
if (!globalOptions.groupQueueEnabled || !isGroupThread(threadID)) {
|
|
298
|
-
return api._sendMessageDirect(message, threadID, cb);
|
|
315
|
+
return api._sendMessageDirect(message, threadID, cb, replyToMessage);
|
|
299
316
|
}
|
|
300
317
|
let entry = groupQueues.get(threadID);
|
|
301
318
|
if (!entry) { entry = { q: [], sending: false, lastActive: Date.now() }; groupQueues.set(threadID, entry); }
|
|
@@ -304,7 +321,7 @@ class ApiFactory {
|
|
|
304
321
|
entry.q.shift();
|
|
305
322
|
if (ctx.health) ctx.health.recordGroupQueuePrune(0, 0, 1);
|
|
306
323
|
}
|
|
307
|
-
entry.q.push({ message, threadID, cb });
|
|
324
|
+
entry.q.push({ message, threadID, cb, replyToMessage });
|
|
308
325
|
processQueue(threadID, entry);
|
|
309
326
|
};
|
|
310
327
|
|
|
@@ -312,13 +329,13 @@ class ApiFactory {
|
|
|
312
329
|
if (entry.sending) return;
|
|
313
330
|
if (!entry.q.length) return;
|
|
314
331
|
entry.sending = true;
|
|
315
|
-
const
|
|
316
|
-
api._sendMessageDirect(message,
|
|
332
|
+
const item = entry.q.shift();
|
|
333
|
+
api._sendMessageDirect(item.message, item.threadID, function (err, res) {
|
|
317
334
|
try { if (!err && this.globalSafety) this.globalSafety.recordEvent(); } catch (_) { }
|
|
318
|
-
if (typeof cb === 'function') cb(err, res);
|
|
335
|
+
if (typeof item.cb === 'function') item.cb(err, res);
|
|
319
336
|
entry.sending = false;
|
|
320
337
|
setImmediate(() => processQueue(threadID, entry));
|
|
321
|
-
}.bind(this));
|
|
338
|
+
}.bind(this), item.replyToMessage);
|
|
322
339
|
}
|
|
323
340
|
|
|
324
341
|
api._flushGroupQueue = function (threadID) {
|
|
@@ -49,13 +49,13 @@ class FacebookSafety {
|
|
|
49
49
|
this.regions = ['ASH', 'ATL', 'DFW', 'ORD', 'PHX', 'SJC', 'IAD'];
|
|
50
50
|
this.currentRegion = this.regions[Math.floor(Math.random() * this.regions.length)];
|
|
51
51
|
|
|
52
|
-
// ULTRA-SAFE human delay patterns -
|
|
52
|
+
// ULTRA-SAFE human delay patterns - More conservative
|
|
53
53
|
this.humanDelayPatterns = {
|
|
54
|
-
typing: { min:
|
|
55
|
-
reading: { min:
|
|
56
|
-
thinking: { min:
|
|
57
|
-
browsing: { min:
|
|
58
|
-
messageDelay: { min:
|
|
54
|
+
typing: { min: 800, max: 2500 }, // Normal typing (0.8-2.5s)
|
|
55
|
+
reading: { min: 1500, max: 5000 }, // Normal reading (1.5-5s)
|
|
56
|
+
thinking: { min: 1500, max: 6000 }, // Normal thinking (1.5-6s)
|
|
57
|
+
browsing: { min: 1000, max: 3000 }, // Normal browsing (1-3s)
|
|
58
|
+
messageDelay: { min: 1500, max: 4000 } // 1.5-4s between messages (Conservative)
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
this.sessionMetrics = {
|
|
@@ -800,16 +800,17 @@ class FacebookSafety {
|
|
|
800
800
|
const risk = this.sessionMetrics.riskLevel;
|
|
801
801
|
const since = Date.now() - this._lastHeavyMaintenanceTs;
|
|
802
802
|
const inWindow = since < this._adaptivePacingWindowMs;
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
} else {
|
|
809
|
-
|
|
810
|
-
|
|
803
|
+
|
|
804
|
+
let min = 1000, max = 2500; // Default baseline human pace
|
|
805
|
+
|
|
806
|
+
if (risk === 'high') {
|
|
807
|
+
min = 3500; max = 6500;
|
|
808
|
+
} else if (risk === 'medium') {
|
|
809
|
+
min = 2000; max = 4500;
|
|
810
|
+
} else if (inWindow) {
|
|
811
|
+
min = 1500; max = 3000;
|
|
811
812
|
}
|
|
812
|
-
|
|
813
|
+
|
|
813
814
|
return Math.floor(min + Math.random() * (max - min));
|
|
814
815
|
}
|
|
815
816
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-fca",
|
|
3
|
-
"version": "3.2.
|
|
4
|
-
"description": "Nexus-FCA 3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
4
|
+
"description": "Nexus-FCA 3.2.4 – Advanced, Secure & Stable Facebook Messenger API.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
package/utils.js
CHANGED
|
@@ -87,23 +87,44 @@ function getJar() {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
function getHeaders(url, options, ctx, customHeader) {
|
|
90
|
+
const ua = (options?.userAgent || "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36");
|
|
91
|
+
const isWindows = ua.includes("Windows NT");
|
|
92
|
+
const isAndroid = ua.includes("Android");
|
|
93
|
+
const isChrome = ua.includes("Chrome") && !ua.includes("Edg");
|
|
94
|
+
|
|
90
95
|
var headers = {
|
|
91
96
|
Referer: "https://www.facebook.com/",
|
|
92
97
|
Host: url.replace("https://", "").split("/")[0],
|
|
93
98
|
Origin: "https://www.facebook.com",
|
|
94
|
-
"user-agent":
|
|
99
|
+
"user-agent": ua,
|
|
95
100
|
Connection: "keep-alive",
|
|
96
|
-
"sec-fetch-site": 'same-origin',
|
|
97
|
-
"sec-fetch-mode": 'cors',
|
|
98
|
-
"sec-fetch-dest": "empty",
|
|
99
101
|
"accept": "*/*",
|
|
100
102
|
"accept-language": "en-US,en;q=0.9",
|
|
101
|
-
"sec-ch-ua": '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
|
|
102
|
-
"sec-ch-ua-mobile": "?0",
|
|
103
|
-
"sec-ch-ua-platform": '"Windows"',
|
|
104
103
|
"dnt": "1",
|
|
105
104
|
"upgrade-insecure-requests": "1"
|
|
106
105
|
};
|
|
106
|
+
|
|
107
|
+
// Human-like Fetch headers
|
|
108
|
+
if (url.includes("/api/graphql/") || url.includes("/messaging/")) {
|
|
109
|
+
headers["sec-fetch-site"] = 'same-origin';
|
|
110
|
+
headers["sec-fetch-mode"] = 'cors';
|
|
111
|
+
headers["sec-fetch-dest"] = "empty";
|
|
112
|
+
} else {
|
|
113
|
+
headers["sec-fetch-site"] = 'none';
|
|
114
|
+
headers["sec-fetch-mode"] = 'navigate';
|
|
115
|
+
headers["sec-fetch-dest"] = "document";
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Dynamic Client Hints - CRITICAL: Must match User-Agent
|
|
119
|
+
if (isChrome && isWindows) {
|
|
120
|
+
headers["sec-ch-ua"] = '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"';
|
|
121
|
+
headers["sec-ch-ua-mobile"] = "?0";
|
|
122
|
+
headers["sec-ch-ua-platform"] = '"Windows"';
|
|
123
|
+
} else if (isAndroid) {
|
|
124
|
+
headers["sec-ch-ua-mobile"] = "?1";
|
|
125
|
+
// Remove Windows-specific headers for Android UAs
|
|
126
|
+
}
|
|
127
|
+
|
|
107
128
|
if (customHeader) Object.assign(headers, customHeader);
|
|
108
129
|
if (ctx && ctx.region) headers["X-MSGR-Region"] = ctx.region;
|
|
109
130
|
|