@lazyneoaz/testfca 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 (120) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/COOKIE_LOGIN.md +208 -0
  3. package/LICENSE +3 -0
  4. package/README.md +492 -0
  5. package/index.js +2 -0
  6. package/package.json +120 -0
  7. package/scripts/build-go.mjs +54 -0
  8. package/scripts/detect-platform.mjs +36 -0
  9. package/scripts/download-prebuilt.mjs +119 -0
  10. package/scripts/package.mjs +6 -0
  11. package/scripts/postinstall.mjs +113 -0
  12. package/src/apis/addExternalModule.js +24 -0
  13. package/src/apis/addUserToGroup.js +108 -0
  14. package/src/apis/changeAdminStatus.js +148 -0
  15. package/src/apis/changeArchivedStatus.js +61 -0
  16. package/src/apis/changeAvatar.js +103 -0
  17. package/src/apis/changeBio.js +69 -0
  18. package/src/apis/changeBlockedStatus.js +54 -0
  19. package/src/apis/changeGroupImage.js +136 -0
  20. package/src/apis/changeThreadColor.js +116 -0
  21. package/src/apis/changeThreadEmoji.js +53 -0
  22. package/src/apis/comment.js +207 -0
  23. package/src/apis/createAITheme.js +129 -0
  24. package/src/apis/createNewGroup.js +79 -0
  25. package/src/apis/createPoll.js +73 -0
  26. package/src/apis/deleteMessage.js +52 -0
  27. package/src/apis/deleteThread.js +52 -0
  28. package/src/apis/e2ee.js +170 -0
  29. package/src/apis/editMessage.js +78 -0
  30. package/src/apis/emoji.js +124 -0
  31. package/src/apis/fetchThemeData.js +82 -0
  32. package/src/apis/follow.js +81 -0
  33. package/src/apis/forwardMessage.js +52 -0
  34. package/src/apis/friend.js +243 -0
  35. package/src/apis/gcmember.js +122 -0
  36. package/src/apis/gcname.js +123 -0
  37. package/src/apis/gcrule.js +119 -0
  38. package/src/apis/getAccess.js +111 -0
  39. package/src/apis/getBotInfo.js +88 -0
  40. package/src/apis/getBotInitialData.js +43 -0
  41. package/src/apis/getFriendsList.js +79 -0
  42. package/src/apis/getMessage.js +423 -0
  43. package/src/apis/getTheme.js +95 -0
  44. package/src/apis/getThemeInfo.js +116 -0
  45. package/src/apis/getThreadHistory.js +239 -0
  46. package/src/apis/getThreadInfo.js +267 -0
  47. package/src/apis/getThreadList.js +232 -0
  48. package/src/apis/getThreadPictures.js +58 -0
  49. package/src/apis/getUserID.js +117 -0
  50. package/src/apis/getUserInfo.js +513 -0
  51. package/src/apis/getUserInfoV2.js +146 -0
  52. package/src/apis/handleMessageRequest.js +50 -0
  53. package/src/apis/httpGet.js +63 -0
  54. package/src/apis/httpPost.js +89 -0
  55. package/src/apis/httpPostFormData.js +69 -0
  56. package/src/apis/listenMqtt.js +1236 -0
  57. package/src/apis/listenSpeed.js +179 -0
  58. package/src/apis/logout.js +93 -0
  59. package/src/apis/markAsDelivered.js +47 -0
  60. package/src/apis/markAsRead.js +115 -0
  61. package/src/apis/markAsReadAll.js +40 -0
  62. package/src/apis/markAsSeen.js +70 -0
  63. package/src/apis/mqttDeltaValue.js +250 -0
  64. package/src/apis/muteThread.js +45 -0
  65. package/src/apis/nickname.js +132 -0
  66. package/src/apis/notes.js +163 -0
  67. package/src/apis/pinMessage.js +150 -0
  68. package/src/apis/produceMetaTheme.js +180 -0
  69. package/src/apis/realtime.js +182 -0
  70. package/src/apis/removeUserFromGroup.js +117 -0
  71. package/src/apis/resolvePhotoUrl.js +58 -0
  72. package/src/apis/searchForThread.js +154 -0
  73. package/src/apis/sendMessage.js +346 -0
  74. package/src/apis/sendMessageMqtt.js +248 -0
  75. package/src/apis/sendTypingIndicator.js +105 -0
  76. package/src/apis/setMessageReaction.js +38 -0
  77. package/src/apis/setMessageReactionMqtt.js +61 -0
  78. package/src/apis/setThreadTheme.js +260 -0
  79. package/src/apis/setThreadThemeMqtt.js +94 -0
  80. package/src/apis/share.js +107 -0
  81. package/src/apis/shareContact.js +66 -0
  82. package/src/apis/stickers.js +257 -0
  83. package/src/apis/story.js +181 -0
  84. package/src/apis/theme.js +233 -0
  85. package/src/apis/unfriend.js +47 -0
  86. package/src/apis/unsendMessage.js +25 -0
  87. package/src/database/appStateBackup.js +298 -0
  88. package/src/database/models/index.js +56 -0
  89. package/src/database/models/thread.js +31 -0
  90. package/src/database/models/user.js +32 -0
  91. package/src/database/threadData.js +101 -0
  92. package/src/database/userData.js +90 -0
  93. package/src/e2ee/bridge.js +275 -0
  94. package/src/e2ee/index.js +60 -0
  95. package/src/engine/client.js +95 -0
  96. package/src/engine/models/buildAPI.js +152 -0
  97. package/src/engine/models/loginHelper.js +574 -0
  98. package/src/engine/models/setOptions.js +88 -0
  99. package/src/types/index.d.ts +574 -0
  100. package/src/utils/antiSuspension.js +529 -0
  101. package/src/utils/auth-helpers.js +149 -0
  102. package/src/utils/autoReLogin.js +336 -0
  103. package/src/utils/axios.js +436 -0
  104. package/src/utils/cache.js +54 -0
  105. package/src/utils/clients.js +282 -0
  106. package/src/utils/constants.js +410 -0
  107. package/src/utils/formatters/data/formatAttachment.js +370 -0
  108. package/src/utils/formatters/data/formatDelta.js +109 -0
  109. package/src/utils/formatters/index.js +159 -0
  110. package/src/utils/formatters/value/formatCookie.js +91 -0
  111. package/src/utils/formatters/value/formatDate.js +36 -0
  112. package/src/utils/formatters/value/formatID.js +16 -0
  113. package/src/utils/formatters.js +1373 -0
  114. package/src/utils/headers.js +235 -0
  115. package/src/utils/index.js +153 -0
  116. package/src/utils/monitoring.js +333 -0
  117. package/src/utils/rateLimiter.js +319 -0
  118. package/src/utils/tokenRefresh.js +680 -0
  119. package/src/utils/user-agents.js +238 -0
  120. package/src/utils/validation.js +157 -0
package/README.md ADDED
@@ -0,0 +1,492 @@
1
+ # nkxfca
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@neoaz07/nkxfca.svg)](https://www.npmjs.com/package/@neoaz07/nkxfca)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@neoaz07/nkxfca.svg)](https://www.npmjs.com/package/@neoaz07/nkxfca)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Node.js Version](https://img.shields.io/node/v/@neoaz07/nkxfca.svg)](https://nodejs.org)
7
+
8
+ **nkxfca** is an advanced Facebook Chat API (FCA) client built for **reliable**, **real-time**, and **modular** interaction with Facebook Messenger.
9
+
10
+ Developed and maintained by **[NeoKEX](https://github.com/NeoKEX)**.
11
+ Inspired by **ws3-fca** and **@dongdev/fca-unofficial**
12
+
13
+ ---
14
+
15
+ ## Documentation
16
+
17
+ - **[Cookie Login Guide](COOKIE_LOGIN.md)** — Authenticate using browser cookies
18
+ - **[Changelog](CHANGELOG.md)** — Version history and updates
19
+ - **[Examples](examples/)** — Code examples and usage patterns
20
+
21
+ ### Support & Issues
22
+
23
+ - GitHub: [https://github.com/NeoKEX](https://github.com/NeoKEX)
24
+ - Issues: [https://github.com/NeoKEX/nkxfca/issues](https://github.com/NeoKEX/nkxfca/issues)
25
+
26
+ ---
27
+
28
+ ## Features
29
+
30
+ **Authentication**
31
+ - Cookie array login (`appState`) — the safest method for long-running bots
32
+ - Email/password login with TOTP/2FA support
33
+ - Session fingerprint locking — User-Agent, Sec-Ch-Ua, locale, timezone locked per session to prevent detection
34
+ - AppState auto-backup and restore on restart
35
+
36
+ **Real-time Messaging**
37
+ - MQTT and HTTP messaging with automatic protocol fallback
38
+ - Send text, attachments, stickers, emoji, mentions, and location
39
+ - Message editing, unsend, forward, and delete
40
+ - Message reactions via HTTP and MQTT
41
+ - Pin/unpin messages, list pinned messages
42
+
43
+ **Anti-Suspension System**
44
+ - Circuit breaker — halts activity after repeated suspension signals, resumes after cooldown
45
+ - 60+ suspension signal patterns: checkpoints, spam flags, rate limits, identity verification, policy violations, session expiry, and more
46
+ - Adaptive per-thread delay that increases with session volume
47
+ - Hourly and daily message volume limits with automatic warning pauses
48
+ - Warmup mode for fresh sessions — gradually increases allowed message rate
49
+ - Humanized typing simulation before every send
50
+ - Randomized request intervals and jitter to avoid periodicity detection
51
+ - Session fingerprint locking to maintain consistent browser identity
52
+ - PostSafe guard: detects auth failures and checkpoint responses in real-time
53
+ - MQTT watchdog: detects stale connections and forces clean reconnect
54
+
55
+ **Stability & Reliability**
56
+ - MQTT auto-reconnect with exponential backoff and jitter
57
+ - Auto re-login using refreshed AppState when session expires
58
+ - TokenRefreshManager with randomized intervals to keep sessions alive
59
+ - Sliding-window rate limiter with per-endpoint tracking and accurate concurrency control
60
+ - SQLite-backed thread and user data cache for fast lookups
61
+
62
+ **Thread & Group Management**
63
+ - Get thread info, history, pictures, and lists
64
+ - Create groups, add/remove members, change admin status
65
+ - Update group image, name, color, emoji
66
+ - Archive, mute, delete threads
67
+ - Create polls, manage notes and rules
68
+ - Search threads by name, handle message requests
69
+
70
+ **User & Friends**
71
+ - Get user info (basic and extended), resolve user IDs
72
+ - Get full friends list, send/cancel friend requests, unfriend, block/unblock
73
+
74
+ **Social**
75
+ - Comment on posts, share posts, follow/unfollow users
76
+
77
+ **Themes & Stickers**
78
+ - Browse 90+ Messenger themes, apply themes via MQTT
79
+ - Generate AI-powered themes with text prompts
80
+ - Search stickers, browse packs, add packs, get AI stickers
81
+
82
+ **E2EE (Opt-In)**
83
+ - Application-layer end-to-end encryption for DMs using X25519 + HKDF + AES-256-GCM
84
+
85
+ **Monitoring**
86
+ - `api.getHealthStatus()` — MQTT status, token refresh stats, rate limiter metrics
87
+ - Built-in `ProductionMonitor` for request/error/performance telemetry
88
+
89
+ **Proxy Support**
90
+ - Full proxy support via the `proxy` login option
91
+
92
+ ---
93
+
94
+ ## Installation
95
+
96
+ > **Requirements:** Node.js v20.0.0 or higher
97
+
98
+ ```bash
99
+ npm install @neoaz07/nkxfca
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Quick Start
105
+
106
+ ```js
107
+ const fs = require("fs");
108
+ const { login } = require("@neoaz07/nkxfca");
109
+
110
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
111
+
112
+ login({ appState }, {
113
+ online: true,
114
+ listenEvents: true,
115
+ autoMarkRead: true,
116
+ autoReconnect: true,
117
+ simulateTyping: true
118
+ }, (err, api) => {
119
+ if (err) return console.error("Login error:", err);
120
+
121
+ console.log("Logged in as:", api.getCurrentUserID());
122
+
123
+ api.listenMqtt((err, event) => {
124
+ if (err || event.type !== "message" || !event.body) return;
125
+
126
+ if (event.body === "/ping") {
127
+ api.sendMessage("pong!", event.threadID);
128
+ }
129
+ });
130
+ });
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Anti-Suspension Configuration
136
+
137
+ The anti-suspension system is active by default. You can tune it through login options:
138
+
139
+ ```js
140
+ login({ appState }, {
141
+ autoReconnect: true,
142
+ listenEvents: true,
143
+ autoMarkRead: true,
144
+ simulateTyping: true, // humanized typing delays before send
145
+ randomUserAgent: true, // rotate user agent on each session
146
+ persona: "desktop", // "desktop" or "android"
147
+ maxConcurrentRequests: 5, // max parallel HTTP requests
148
+ maxRequestsPerMinute: 50, // sliding-window rate cap
149
+ requestCooldownMs: 60000, // per-endpoint cooldown duration
150
+ errorCacheTtlMs: 300000 // how long to suppress repeated errors
151
+ }, (err, api) => {
152
+ if (err) throw err;
153
+
154
+ // Check anti-suspension and rate limiter status
155
+ console.log(api.getHealthStatus());
156
+ });
157
+ ```
158
+
159
+ ### Circuit Breaker
160
+
161
+ The circuit breaker trips automatically after detecting 2 or more suspension signals (checkpoints, spam flags, rate limits, etc.). It pauses all activity for 45 minutes by default.
162
+
163
+ You can also trip or reset it manually:
164
+
165
+ ```js
166
+ const { globalAntiSuspension } = require("@neoaz07/nkxfca/src/utils/antiSuspension");
167
+
168
+ // Manually trip (e.g. after you detect a warning in a response)
169
+ globalAntiSuspension.tripCircuitBreaker("manual_pause", 30 * 60 * 1000); // 30 min
170
+
171
+ // Reset after you've resolved the issue
172
+ globalAntiSuspension.resetCircuitBreaker();
173
+
174
+ // Check status
175
+ console.log(globalAntiSuspension.getConfig());
176
+ ```
177
+
178
+ ### Warmup Mode
179
+
180
+ Use warmup mode when starting a fresh or recovered session:
181
+
182
+ ```js
183
+ const { globalAntiSuspension } = require("@neoaz07/nkxfca/src/utils/antiSuspension");
184
+ globalAntiSuspension.enableWarmup(); // limits to 25 msg/hour for 20 minutes
185
+ ```
186
+
187
+ ---
188
+
189
+ ## End-to-End Encryption for DMs (Opt-In)
190
+
191
+ Encrypt and decrypt message bodies in direct chats using X25519 + HKDF + AES-256-GCM.
192
+
193
+ ```js
194
+ api.e2ee.enable();
195
+
196
+ // Share your bot's public key with the peer
197
+ const botPubKey = api.e2ee.getPublicKey();
198
+
199
+ // Register the peer's public key for a DM thread
200
+ api.e2ee.setPeerKey(threadID, peerPublicKeyBase64);
201
+
202
+ // Messages to that thread are now auto-encrypted on send
203
+ // and auto-decrypted on receive
204
+ api.sendMessage("Top secret message", threadID);
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Security Warning
210
+
211
+ `appstate.json` contains your Facebook session and must be treated like a password:
212
+
213
+ - **Never commit `appstate.json` to version control**
214
+ - **Never share your `appstate.json` publicly**
215
+ - Add it to `.gitignore`
216
+ - Use environment variables or a secrets manager in production
217
+
218
+ ---
219
+
220
+ ## Getting Started — Generate `appstate.json`
221
+
222
+ 1. Install a cookie export extension:
223
+ - Chrome/Edge: **C3C FbState** or **CookieEditor**
224
+ - Firefox: **Cookie-Editor**
225
+
226
+ 2. Log in to Facebook in your browser
227
+
228
+ 3. Export cookies as JSON and save as `appstate.json`:
229
+
230
+ ```json
231
+ [
232
+ { "key": "c_user", "value": "your-user-id" },
233
+ { "key": "xs", "value": "your-xs-value" }
234
+ ]
235
+ ```
236
+
237
+ 4. Use in your bot:
238
+
239
+ ```js
240
+ const { login } = require("@neoaz07/nkxfca");
241
+ const appState = require("./appstate.json");
242
+ login({ appState }, {}, (err, api) => { ... });
243
+ ```
244
+
245
+ See **[COOKIE_LOGIN.md](COOKIE_LOGIN.md)** for more formats and troubleshooting.
246
+
247
+ ---
248
+
249
+ ## Bot Example with Commands
250
+
251
+ ```js
252
+ const fs = require("fs");
253
+ const path = require("path");
254
+ const { login } = require("@neoaz07/nkxfca");
255
+
256
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
257
+
258
+ login({ appState }, {
259
+ online: true,
260
+ selfListen: false,
261
+ simulateTyping: true,
262
+ autoReconnect: true
263
+ }, async (err, api) => {
264
+ if (err) return console.error("Login error:", err);
265
+
266
+ console.log("Logged in as:", api.getCurrentUserID());
267
+
268
+ const commandsDir = path.join(__dirname, "commands");
269
+ const commands = new Map();
270
+
271
+ if (fs.existsSync(commandsDir)) {
272
+ for (const file of fs.readdirSync(commandsDir).filter(f => f.endsWith(".js"))) {
273
+ const cmd = require(path.join(commandsDir, file));
274
+ if (cmd.name && typeof cmd.execute === "function") {
275
+ commands.set(cmd.name, cmd);
276
+ }
277
+ }
278
+ }
279
+
280
+ api.listenMqtt(async (err, event) => {
281
+ if (err || event.type !== "message" || !event.body) return;
282
+
283
+ const prefix = "/";
284
+ if (!event.body.startsWith(prefix)) return;
285
+
286
+ const args = event.body.slice(prefix.length).trim().split(/ +/);
287
+ const name = args.shift().toLowerCase();
288
+ const cmd = commands.get(name);
289
+ if (!cmd) return;
290
+
291
+ try {
292
+ await cmd.execute({ api, event, args });
293
+ } catch (e) {
294
+ console.error(`Error in /${name}:`, e.message);
295
+ api.sendMessage("An error occurred.", event.threadID);
296
+ }
297
+ });
298
+ });
299
+ ```
300
+
301
+ ---
302
+
303
+ ## AI Themes
304
+
305
+ ```js
306
+ // Generate an AI theme from a text prompt
307
+ const aiThemes = await api.createAITheme("vibrant ocean sunset purple");
308
+ if (aiThemes && aiThemes.length > 0) {
309
+ await api.setThreadThemeMqtt(threadID, aiThemes[0].id);
310
+ }
311
+
312
+ // Browse standard themes
313
+ const themes = await api.getTheme(threadID);
314
+ await api.setThreadThemeMqtt(threadID, themes[0].id);
315
+
316
+ // Check current theme
317
+ const info = await api.getThemeInfo(threadID);
318
+ console.log(info.color, info.emoji);
319
+ ```
320
+
321
+ ---
322
+
323
+ ## API Reference
324
+
325
+ ### Authentication
326
+ | Method | Description |
327
+ |---|---|
328
+ | `login(credentials, options, callback)` | Log in and receive the API object |
329
+ | `api.logout()` | End the session |
330
+ | `api.getAppState()` | Get current session cookies |
331
+ | `api.getCurrentUserID()` | Get logged-in user ID |
332
+
333
+ ### Messaging
334
+ | Method | Description |
335
+ |---|---|
336
+ | `api.sendMessage(msg, threadID)` | Send (HTTP + MQTT fallback) |
337
+ | `api.sendMessageMqtt(msg, threadID)` | Send over MQTT |
338
+ | `api.editMessage(text, messageID)` | Edit a message |
339
+ | `api.unsendMessage(messageID, threadID)` | Retract a message |
340
+ | `api.forwardMessage(messageID, threadID)` | Forward a message |
341
+ | `api.deleteMessage(messageIDs)` | Delete locally |
342
+ | `api.shareContact(senderID, threadID)` | Share a contact card |
343
+
344
+ ### Reactions & Status
345
+ | Method | Description |
346
+ |---|---|
347
+ | `api.setMessageReaction(reaction, messageID)` | React via HTTP |
348
+ | `api.setMessageReactionMqtt(reaction, messageID, threadID)` | React via MQTT |
349
+ | `api.sendTypingIndicator(isTyping, threadID)` | Show/hide typing |
350
+ | `api.markAsRead(threadID)` | Mark thread as read |
351
+ | `api.markAsReadAll()` | Mark all threads as read |
352
+ | `api.markAsSeen()` | Mark as seen |
353
+ | `api.markAsDelivered(threadID, messageID)` | Mark as delivered |
354
+
355
+ ### Threads
356
+ | Method | Description |
357
+ |---|---|
358
+ | `api.getThreadInfo(threadID)` | Thread metadata |
359
+ | `api.getThreadList(limit, timestamp, tags)` | List threads |
360
+ | `api.getThreadHistory(threadID, amount, timestamp)` | Message history |
361
+ | `api.getThreadPictures(threadID, offset, limit)` | Thread images |
362
+ | `api.searchForThread(name)` | Search by name |
363
+ | `api.createNewGroup(participantIDs, name?)` | Create group |
364
+ | `api.deleteThread(threadID)` | Delete thread |
365
+ | `api.muteThread(threadID, muteSeconds)` | Mute thread |
366
+ | `api.changeArchivedStatus(threadID, archive)` | Archive/unarchive |
367
+ | `api.pinMessage(action, threadID, messageID?)` | Pin/unpin/list |
368
+ | `api.createPoll(title, threadID, options?)` | Create poll |
369
+ | `api.handleMessageRequest(threadID, accept)` | Accept/decline |
370
+
371
+ ### Group Admin
372
+ | Method | Description |
373
+ |---|---|
374
+ | `api.addUserToGroup(userID, threadID)` | Add member |
375
+ | `api.removeUserFromGroup(userID, threadID)` | Remove member |
376
+ | `api.changeAdminStatus(threadID, userID, isAdmin)` | Promote/demote |
377
+ | `api.changeGroupImage(image, threadID)` | Group photo |
378
+ | `api.gcname(name, threadID)` | Rename group |
379
+
380
+ ### Users
381
+ | Method | Description |
382
+ |---|---|
383
+ | `api.getUserInfo(id)` | Basic user info |
384
+ | `api.getUserInfoV2(id)` | Extended user info |
385
+ | `api.getUserID(name)` | Resolve name to ID |
386
+ | `api.getFriendsList()` | Friends list |
387
+ | `api.getBotInfo()` | Bot account info |
388
+
389
+ ### Themes & Customization
390
+ | Method | Description |
391
+ |---|---|
392
+ | `api.getTheme(threadID)` | List available themes |
393
+ | `api.getThemeInfo(threadID)` | Current theme |
394
+ | `api.setThreadThemeMqtt(threadID, themeID)` | Apply theme |
395
+ | `api.createAITheme(prompt)` | AI theme |
396
+ | `api.changeThreadColor(color, threadID)` | Thread color |
397
+ | `api.changeThreadEmoji(emoji, threadID)` | Thread emoji |
398
+ | `api.nickname(nickname, threadID, participantID)` | Set nickname |
399
+ | `api.emoji(emoji, threadID)` | Thread emoji shorthand |
400
+
401
+ ### Stickers
402
+ | Method | Description |
403
+ |---|---|
404
+ | `api.stickers.search(query)` | Search stickers |
405
+ | `api.stickers.listPacks()` | Installed packs |
406
+ | `api.stickers.getStorePacks()` | Sticker store |
407
+ | `api.stickers.addPack(packID)` | Add pack |
408
+ | `api.stickers.getStickersInPack(packID)` | Stickers in pack |
409
+ | `api.stickers.getAiStickers(options?)` | AI stickers |
410
+
411
+ ### E2EE
412
+ | Method | Description |
413
+ |---|---|
414
+ | `api.e2ee.enable()` | Enable E2EE |
415
+ | `api.e2ee.disable()` | Disable E2EE |
416
+ | `api.e2ee.getPublicKey()` | Get public key |
417
+ | `api.e2ee.setPeerKey(threadID, key)` | Set peer key |
418
+ | `api.e2ee.hasPeer(threadID)` | Has peer key |
419
+ | `api.e2ee.clearPeerKey(threadID)` | Remove peer key |
420
+
421
+ ### Social
422
+ | Method | Description |
423
+ |---|---|
424
+ | `api.comment(msg, postID)` | Comment on post |
425
+ | `api.share(postID)` | Share post |
426
+ | `api.follow(userID, follow)` | Follow/unfollow |
427
+ | `api.unfriend(userID)` | Unfriend |
428
+ | `api.changeBlockedStatus(userID, block)` | Block/unblock |
429
+
430
+ ### Health
431
+ | Method | Description |
432
+ |---|---|
433
+ | `api.getHealthStatus()` | MQTT, token, rate limiter stats |
434
+
435
+ ---
436
+
437
+ ## Login Options
438
+
439
+ | Option | Type | Default | Description |
440
+ |---|---|---|---|
441
+ | `online` | `boolean` | `true` | Appear online |
442
+ | `selfListen` | `boolean` | `false` | Receive own messages |
443
+ | `listenEvents` | `boolean` | `true` | Receive thread events |
444
+ | `listenTyping` | `boolean` | `false` | Receive typing events |
445
+ | `updatePresence` | `boolean` | `false` | Broadcast presence |
446
+ | `autoMarkDelivery` | `boolean` | `false` | Auto-mark delivered |
447
+ | `autoMarkRead` | `boolean` | `true` | Auto-mark read |
448
+ | `autoReconnect` | `boolean` | `true` | MQTT auto-reconnect |
449
+ | `simulateTyping` | `boolean` | `true` | Humanized typing delays |
450
+ | `randomUserAgent` | `boolean` | `false` | Random User-Agent |
451
+ | `persona` | `"desktop"\|"android"` | `"desktop"` | Browser persona |
452
+ | `proxy` | `string` | — | Proxy URL |
453
+ | `forceLogin` | `boolean` | `false` | Force fresh login |
454
+ | `maxConcurrentRequests` | `number` | `5` | Max parallel requests |
455
+ | `maxRequestsPerMinute` | `number` | `50` | Rate cap per minute |
456
+ | `requestCooldownMs` | `number` | `60000` | Endpoint cooldown |
457
+ | `errorCacheTtlMs` | `number` | `300000` | Error suppression TTL |
458
+ | `stealthMode` | `boolean` | `false` | Extra stealth headers |
459
+
460
+ ---
461
+
462
+ ## Examples
463
+
464
+ See the **[examples/](examples/)** directory:
465
+ - `login-with-cookies.js` — Cookie-based authentication guide
466
+ - `verify.js` — Verify the library loads correctly
467
+
468
+ ---
469
+
470
+ ## Credits
471
+
472
+ - **Developed and maintained by [NeoKEX](https://github.com/NeoKEX)**
473
+ - **NeoKEX Team** — development, maintenance, and feature contributions
474
+ - **Inspired by ws3-fca** — by @NethWs3Dev and @CommunityExocore
475
+
476
+ > Copyright (c) 2026 NeoKEX
477
+
478
+ ---
479
+
480
+ ## License
481
+
482
+ **MIT** — Free to use, modify, and distribute. Attribution appreciated.
483
+
484
+ See [LICENSE](LICENSE) for full license text.
485
+
486
+ ---
487
+
488
+ ## Links
489
+
490
+ - **npm:** [https://www.npmjs.com/package/@neoaz07/nkxfca](https://www.npmjs.com/package/@neoaz07/nkxfca)
491
+ - **GitHub:** [https://github.com/NeoKEX](https://github.com/NeoKEX)
492
+ - **Issues:** [https://github.com/NeoKEX/nkxfca/issues](https://github.com/NeoKEX/nkxfca/issues)
package/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ module.exports = require('./src/engine/client');
package/package.json ADDED
@@ -0,0 +1,120 @@
1
+ {
2
+ "name": "@lazyneoaz/testfca",
3
+ "version": "1.0.0",
4
+ "type": "commonjs",
5
+ "description": "Advanced Facebook Chat API client for building Messenger bots — supports real-time messaging, thread management, MQTT, session stability, anti-automation protection, and real E2EE via Signal Protocol.",
6
+ "main": "index.js",
7
+ "types": "src/types/index.d.ts",
8
+ "exports": {
9
+ ".": "./index.js"
10
+ },
11
+ "files": [
12
+ "index.js",
13
+ "src/",
14
+ "scripts/",
15
+ "prebuilt/",
16
+ "LICENSE",
17
+ "README.md",
18
+ "CHANGELOG.md",
19
+ "COOKIE_LOGIN.md"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/NeoKEX/nkxfca.git"
27
+ },
28
+ "author": "NeoKEX",
29
+ "contributors": [
30
+ "NeoKEX Team"
31
+ ],
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/NeoKEX/nkxfca/issues"
35
+ },
36
+ "homepage": "https://github.com/NeoKEX/nkxfca#readme",
37
+ "keywords": [
38
+ "facebook",
39
+ "messenger",
40
+ "chat",
41
+ "bot",
42
+ "fca",
43
+ "mqtt",
44
+ "messaging",
45
+ "api",
46
+ "automation",
47
+ "facebook-chat-api",
48
+ "nkxfca",
49
+ "neoaz07",
50
+ "e2ee",
51
+ "signal-protocol",
52
+ "anti-suspension"
53
+ ],
54
+ "dependencies": {
55
+ "axios": "^1.9.0",
56
+ "axios-cookiejar-support": "^4.0.7",
57
+ "bluebird": "^3.7.2",
58
+ "cheerio": "^1.0.0",
59
+ "deepdash": "^5.3.9",
60
+ "duplexify": "^4.1.3",
61
+ "form-data": "^4.0.4",
62
+ "https-proxy-agent": "^7.0.6",
63
+ "jsonpath-plus": "^10.3.0",
64
+ "koffi": "^3.0.2",
65
+ "lodash": "^4.17.21",
66
+ "mqtt": "^4.3.8",
67
+ "node-cron": "^3.0.3",
68
+ "npmlog": "^7.0.1",
69
+ "sequelize": "^6.37.5",
70
+ "sqlite3": "^6.0.1",
71
+ "totp-generator": "^2.0.1",
72
+ "tough-cookie": "^5.1.2",
73
+ "undici": "^7.8.0",
74
+ "uuid": "^11.1.0",
75
+ "websocket-stream": "^5.5.2",
76
+ "ws": "^8.18.2"
77
+ },
78
+ "devDependencies": {
79
+ "@types/node": "^22.15.17",
80
+ "eslint": "^9.26.0",
81
+ "mocha": "^11.3.0",
82
+ "prettier": "^3.5.3",
83
+ "ts-node": "^10.9.2",
84
+ "typescript": "^5.8.3"
85
+ },
86
+ "engines": {
87
+ "node": ">=22.12.0"
88
+ },
89
+ "scripts": {
90
+ "prepack": "echo 'Preparing package for npm...'",
91
+ "test": "echo 'No tests configured yet'",
92
+ "lint": "eslint src/",
93
+ "format": "prettier --write src/**/*.js",
94
+ "postinstall": "node scripts/postinstall.mjs",
95
+ "build:go": "node scripts/build-go.mjs",
96
+ "validate": "npm pack --dry-run"
97
+ },
98
+ "overrides": {
99
+ "undici": "^7.8.0",
100
+ "ws": "^8.18.2",
101
+ "tough-cookie": "^5.1.2",
102
+ "glob": "^11.0.2",
103
+ "prebuild-install": "^7.1.3",
104
+ "npmlog": "^7.0.1",
105
+ "are-we-there-yet": "^4.0.2",
106
+ "gauge": "^5.0.2",
107
+ "serialize-javascript": "^6.0.2",
108
+ "cacache": "^18.0.4",
109
+ "make-fetch-happen": "^13.0.3",
110
+ "@tootallnate/once": "^3.0.1",
111
+ "mocha": {
112
+ "serialize-javascript": "^6.0.2",
113
+ "debug": "^4.4.0",
114
+ "diff": "^7.0.0",
115
+ "js-yaml": "^4.1.0",
116
+ "minimatch": "^10.0.1",
117
+ "glob": "^11.0.2"
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,54 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, mkdirSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ import { detectPlatform } from "./detect-platform.mjs";
7
+ import { packageJson } from "./package.mjs";
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const { ext } = detectPlatform();
11
+ const { name } = packageJson;
12
+ const bridgeDir = join(__dirname, "..", "bridge-e2ee", "bridge-go");
13
+ const vendorDir = join(bridgeDir, "vendor");
14
+ const hasVendor = existsSync(vendorDir);
15
+
16
+ function runGo(args) {
17
+ const res = spawnSync(process.env.GO_BIN || "go", args, {
18
+ cwd: bridgeDir,
19
+ stdio: "inherit",
20
+ env: { ...process.env, CGO_ENABLED: "1" },
21
+ });
22
+ if (res.error) {
23
+ console.error(`[${name}] Failed to spawn Go: ${res.error.message}`);
24
+ process.exit(1);
25
+ }
26
+ if (res.status !== 0) process.exit(res.status || 1);
27
+ }
28
+
29
+ const buildDir = join(__dirname, "..", "build");
30
+ if (!existsSync(buildDir)) mkdirSync(buildDir, { recursive: true });
31
+
32
+ // Skip mod tidy when vendor directory is present — tidy can break vendor/go.mod consistency
33
+ // and would overwrite the patched prekeys.go with the unpatched upstream version.
34
+ if (!hasVendor) {
35
+ console.log(`[${name}] Tidying Go modules...`);
36
+ runGo(["mod", "tidy"]);
37
+ } else {
38
+ console.log(`[${name}] Vendor directory present — skipping mod tidy to preserve patches.`);
39
+ }
40
+
41
+ const buildArgs = [
42
+ "build",
43
+ ...(hasVendor ? ["-mod=vendor"] : []),
44
+ "-buildmode=c-shared",
45
+ "-ldflags=-s -w",
46
+ "-o",
47
+ join("..", "..", "build", `messagix.${ext}`),
48
+ ".",
49
+ ];
50
+
51
+ console.log(`[${name}] Building native library (release mode)...`);
52
+ runGo(buildArgs);
53
+
54
+ console.log(`[${name}] Built native: build/messagix.${ext}`);
@@ -0,0 +1,36 @@
1
+ import { execSync } from "node:child_process";
2
+
3
+ export function detectPlatform() {
4
+ const { platform } = process;
5
+ const { arch } = process;
6
+ const isMusl = detectMusl();
7
+
8
+ const libc = platform === "linux" ? (isMusl ? "musl" : "gnu") : "";
9
+ const triplet = platform === "linux" ? `${platform}-${arch}-${libc}` : `${platform}-${arch}`;
10
+
11
+ const ext = platform === "win32" ? "dll" : platform === "darwin" ? "dylib" : "so";
12
+
13
+ return { platform, arch, libc, triplet, ext };
14
+ }
15
+
16
+ function detectMusl() {
17
+ try {
18
+ if (process.platform !== "linux") return false;
19
+ if (process.report && typeof process.report.getReport === "function") {
20
+ const rep = process.report.getReport();
21
+ const glibc = rep.header && rep.header.glibcVersionRuntime;
22
+ return !glibc;
23
+ }
24
+ } catch {
25
+ //
26
+ }
27
+ try {
28
+ const out = execSync("ldd --version 2>&1 || true", { encoding: "utf8" });
29
+ return /musl/i.test(out);
30
+ } catch {
31
+ //
32
+ }
33
+ return false;
34
+ }
35
+
36
+ export default detectPlatform;