toru-fca 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 (113) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +319 -0
  3. package/advancedSystem.js +95 -0
  4. package/build/messagix.dll +0 -0
  5. package/build/messagix.so +0 -0
  6. package/checkUpdate.js +37 -0
  7. package/config.json +45 -0
  8. package/e2ee.js +719 -0
  9. package/index.js +715 -0
  10. package/lib/index.mjs +1412 -0
  11. package/package.json +69 -0
  12. package/src/OldMessage.js +357 -0
  13. package/src/addExternalModule.js +25 -0
  14. package/src/addUserToGroup.js +117 -0
  15. package/src/changeAdminStatus.js +105 -0
  16. package/src/changeArchivedStatus.js +57 -0
  17. package/src/changeAvatar.js +138 -0
  18. package/src/changeAvatarV2.js +86 -0
  19. package/src/changeAvt.js +85 -0
  20. package/src/changeBio.js +78 -0
  21. package/src/changeBlockedStatus.js +51 -0
  22. package/src/changeBlockedStatusMqtt.js +80 -0
  23. package/src/changeCover.js +72 -0
  24. package/src/changeGroupImage.js +137 -0
  25. package/src/changeName.js +79 -0
  26. package/src/changeNickname.js +61 -0
  27. package/src/changeThreadColor.js +67 -0
  28. package/src/changeThreadEmoji.js +57 -0
  29. package/src/changeUsername.js +59 -0
  30. package/src/createCommentPost.js +230 -0
  31. package/src/createNewGroup.js +90 -0
  32. package/src/createPoll.js +73 -0
  33. package/src/createPost.js +276 -0
  34. package/src/data/getThreadInfo.json +1 -0
  35. package/src/deleteMessage.js +58 -0
  36. package/src/deleteThread.js +58 -0
  37. package/src/editMessage.js +81 -0
  38. package/src/editMessageOld.js +67 -0
  39. package/src/follow.js +74 -0
  40. package/src/forwardAttachment.js +62 -0
  41. package/src/friendList.js +104 -0
  42. package/src/getAccess.js +112 -0
  43. package/src/getAvatarUser.js +78 -0
  44. package/src/getBotInitialData.js +42 -0
  45. package/src/getCtx.js +5 -0
  46. package/src/getCurrentUserID.js +7 -0
  47. package/src/getEmojiUrl.js +29 -0
  48. package/src/getFriendsList.js +85 -0
  49. package/src/getMessage.js +849 -0
  50. package/src/getOptions.js +5 -0
  51. package/src/getRegion.js +7 -0
  52. package/src/getThreadHistory.js +682 -0
  53. package/src/getThreadHistoryDeprecated.js +71 -0
  54. package/src/getThreadInfo.js +232 -0
  55. package/src/getThreadInfoDeprecated.js +56 -0
  56. package/src/getThreadList.js +213 -0
  57. package/src/getThreadListDeprecated.js +46 -0
  58. package/src/getThreadPictures.js +59 -0
  59. package/src/getThreadTheme.js +81 -0
  60. package/src/getUID.js +119 -0
  61. package/src/getUserID.js +61 -0
  62. package/src/getUserInfo.js +66 -0
  63. package/src/handleFriendRequest.js +46 -0
  64. package/src/handleMessageRequest.js +47 -0
  65. package/src/httpGet.js +49 -0
  66. package/src/httpPost.js +48 -0
  67. package/src/httpPostFormData.js +70 -0
  68. package/src/listenMqtt.js +955 -0
  69. package/src/listenNotification.js +85 -0
  70. package/src/logout.js +19 -0
  71. package/src/markAsDelivered.js +47 -0
  72. package/src/markAsRead.js +72 -0
  73. package/src/markAsReadAll.js +40 -0
  74. package/src/markAsSeen.js +48 -0
  75. package/src/metaTheme.js +189 -0
  76. package/src/muteThread.js +45 -0
  77. package/src/note.js +228 -0
  78. package/src/pinMessage.js +59 -0
  79. package/src/refreshFb_dtsg.js +91 -0
  80. package/src/removeSuspiciousAccount.js +78 -0
  81. package/src/removeUserFromGroup.js +81 -0
  82. package/src/reply.js +442 -0
  83. package/src/resolvePhotoUrl.js +47 -0
  84. package/src/searchForThread.js +53 -0
  85. package/src/searchFriends.js +140 -0
  86. package/src/searchStickers.js +53 -0
  87. package/src/send.js +46 -0
  88. package/src/sendButtons.js +163 -0
  89. package/src/sendComment.js +159 -0
  90. package/src/sendFriendRequest.js +112 -0
  91. package/src/sendMessage.js +440 -0
  92. package/src/sendMessageMqtt.js +323 -0
  93. package/src/sendTypingIndicator.js +54 -0
  94. package/src/setActiveStatus.js +92 -0
  95. package/src/setMessageReaction.js +149 -0
  96. package/src/setMessageReactionMqtt.js +62 -0
  97. package/src/setPostReaction.js +114 -0
  98. package/src/setProfileGuard.js +44 -0
  99. package/src/setProfileLock.js +97 -0
  100. package/src/setStoryReaction.js +133 -0
  101. package/src/setStorySeen.js +108 -0
  102. package/src/setThreadTheme.js +102 -0
  103. package/src/setTitle.js +92 -0
  104. package/src/shareContact.js +110 -0
  105. package/src/shareLink.js +59 -0
  106. package/src/stopListenMqtt.js +37 -0
  107. package/src/storyManager.js +357 -0
  108. package/src/suggestFriend.js +132 -0
  109. package/src/threadColors.js +131 -0
  110. package/src/unfriend.js +54 -0
  111. package/src/unsendMessage.js +68 -0
  112. package/src/uploadAttachment.js +115 -0
  113. package/utils.js +3044 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,64 @@
1
+ # Changelog — alpha-fca
2
+
3
+ ## v1.0.0 (2026-09-01) — Initial Release
4
+
5
+ ### 🎯 What This Is
6
+ A clean, merged, audited Facebook Chat API built from analyzing 6 FCA variants.
7
+
8
+ ### ✅ Inclusions (Best-of-all merge)
9
+
10
+ **From hridoy-custom (base):**
11
+ - Full E2EE bridge with Node.js < 22 undici webidl compatibility patch
12
+ - Self-listen filter for E2EE messages (both ID-map and cookie-UID approaches)
13
+ - Multi-domain cookie collection for E2EE (`_cookiesFromJar`)
14
+ - `stopped` flag on bridge to prevent reconnect loops after `disconnect()`
15
+ - MQTT patch stream (fixes Facebook's non-standard PUBACK/SUBACK flag bits)
16
+ - MQTT spinner + connection banner
17
+ - `sessionGuard()` — auto-save appstate with debounce
18
+ - Layered config system (FCA config → bot CWD config → runtime options)
19
+ - Logout disabled (no-op) to preserve Facebook session
20
+ - AdvancedSystem queue for controlled task execution
21
+
22
+ **From hridoy-akash:**
23
+ - Global `process.on("unhandledRejection")` handler with network-error classification
24
+ - Global `process.on("uncaughtException")` handler (non-exit)
25
+ - Clean `BOOL_OPTIONS` setOptions pattern
26
+
27
+ **From ST-FCA (extra API methods):**
28
+ - `sendButtons` — send interactive buttons
29
+ - `sendFriendRequest` — send friend request
30
+ - `searchFriends` — search friends list
31
+ - `setActiveStatus` — set active/online status
32
+ - `setProfileLock` — lock profile visibility
33
+ - `storyManager` — story management utilities
34
+ - `suggestFriend` — suggest a friend
35
+ - `setThreadTheme` — set thread theme
36
+ - `setStorySeen` — mark story as seen
37
+ - `metaTheme` — Meta theme utilities
38
+ - `note` — note utilities
39
+
40
+ **Architecture improvements:**
41
+ - Size-capped E2EE message maps (`_cappedMapSet`, cap: 2000) — prevents memory leak
42
+ - Jittered E2EE reconnect delay (3–4s) — prevents thundering-herd on restarts
43
+ - Fresh `sid` + `cid` on every MQTT reconnect (strips stale params from endpoint)
44
+ - Reconnect state object (`ctx._reconnectState`) with `stopped` flag
45
+ - `stopListenMqtt()` properly cleans up reconnect timers
46
+ - `stopListeningAsync()` on the message emitter
47
+ - Health monitor via `api.getHealth()`
48
+ - Non-blocking update check via `checkUpdate.js`
49
+ - E2EE `devicePath` parent directory auto-created on first use
50
+
51
+ ### ❌ Removed / Disabled
52
+ - All background polling/automation (off by default)
53
+ - Aggressive repeated requests
54
+ - Unnecessary logout flows
55
+ - Duplicate event listeners
56
+ - Dead code from outdated API patterns
57
+ - Third-party image upload to unknown accounts (imgbb/imagekit keys must be user-supplied)
58
+ - Sequelize/SQLite database dependency (removed bloat)
59
+ - `fca-unofficial` package dependency (inlined)
60
+
61
+ ### ⚠️ Known Limitations
62
+ - E2EE binary (`messagix.so` / `.dll`) is pre-built for x86_64; ARM support depends on available binaries
63
+ - Live MQTT/E2EE behavior cannot be statically tested — depends on active Facebook endpoints
64
+ - Facebook API changes may break parsing without warning (inherent to all unofficial FCAs)
package/README.md ADDED
@@ -0,0 +1,319 @@
1
+ # alpha-fca v1.0.0
2
+
3
+ > **Ultimate Merged Facebook Chat API** — Stable Inbox · E2EE Bridge · E2EE Group · Low Automation · Clean Architecture
4
+
5
+ Built by analyzing, comparing, auditing and merging the best implementations from **6 FCA variants**:
6
+ `hridoy-akash` · `fca-unofficial` · `ST-FCA` · `fca-azad` · `mahmud-fca` · `hridoy-custom`
7
+
8
+ ---
9
+
10
+ ## ✨ Features
11
+
12
+ | Feature | Status | Details |
13
+ |---|---|---|
14
+ | 📩 Inbox / Normal Messages | ✅ Stable | MQTT-based, auto-reconnect, no duplicate listeners |
15
+ | 🔐 E2EE Bridge | ✅ Working | Labyrinth native bridge, auto-reconnect with jitter |
16
+ | 👥 E2EE Group Messages | ✅ Working | Group JID detection, full event mapping |
17
+ | 🔄 Session / Reconnect | ✅ Stable | sessionGuard, backoff reconnect, no unnecessary logouts |
18
+ | ⚙️ Low Automation | ✅ Enforced | No background polling; automation off by default |
19
+ | 🛡️ Error Handling | ✅ Robust | Global unhandledRejection + uncaughtException guards |
20
+ | 🧠 Memory Safety | ✅ Capped | E2EE message maps size-capped at 2000 entries |
21
+ | 📦 Node.js 18–22 | ✅ Compatible | undici webidl patch for Node < 22 |
22
+
23
+ ---
24
+
25
+ ## 📦 Installation
26
+
27
+ ```bash
28
+ # Clone or copy the folder, then:
29
+ npm install
30
+ ```
31
+
32
+ **Requirements:**
33
+ - Node.js >= 18.0.0
34
+ - `build/messagix.so` (Linux) or `build/messagix.dll` (Windows) — included
35
+ - `lib/index.mjs` — E2EE ESM bundle — included
36
+
37
+ ---
38
+
39
+ ## 🚀 Quick Start
40
+
41
+ ### 1. Prepare your appstate
42
+
43
+ Export your Facebook cookies as JSON (using a browser extension like [c3c-fbstate](https://github.com/c3cbot/c3c-fbstate) or similar), save as `appstate.json`.
44
+
45
+ ### 2. Basic bot
46
+
47
+ ```js
48
+ const login = require("alpha-fca");
49
+ const fs = require("fs");
50
+
51
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
52
+
53
+ login({ appState }, { listenEvents: true, autoReconnect: true }, (err, api) => {
54
+ if (err) return console.error(err);
55
+
56
+ console.log("Logged in as:", api.getCurrentUserID());
57
+
58
+ // Auto-save session every 3 minutes
59
+ api.sessionGuard("appstate.json", { interval: 3 * 60 * 1000 });
60
+
61
+ // Listen for messages
62
+ api.listenMqtt((err, event) => {
63
+ if (err) return console.error(err);
64
+ if (event.type === "message") {
65
+ console.log(`[${event.threadID}] ${event.senderID}: ${event.body}`);
66
+ if (event.body === "ping") api.sendMessage("pong!", event.threadID);
67
+ }
68
+ });
69
+ });
70
+ ```
71
+
72
+ ### 3. E2EE bot
73
+
74
+ Enable E2EE in `config.json`:
75
+ ```json
76
+ {
77
+ "e2ee": { "enable": true, "saveType": "memory" }
78
+ }
79
+ ```
80
+
81
+ Then:
82
+ ```js
83
+ // After login:
84
+ api.connectE2EE((err, event) => {
85
+ if (err) return console.error(err);
86
+ // event.type === "e2ee_ready" → "e2ee_fully_ready"
87
+ // event.type === "message" with event.isE2EE = true → E2EE message
88
+ if (event.type === "message" && event.isE2EE) {
89
+ api.sendMessage("Hello E2EE!", event.threadID);
90
+ }
91
+ });
92
+ ```
93
+
94
+ See `examples/e2ee-bot.js` for a complete example.
95
+
96
+ ---
97
+
98
+ ## ⚙️ Configuration (`config.json`)
99
+
100
+ ```json
101
+ {
102
+ "automation": { "enabled": false },
103
+ "inbox": { "enabled": true },
104
+ "smooth": { "enabled": false, "messageDelay": 400 },
105
+ "e2ee": {
106
+ "enable": false,
107
+ "saveType": "memory",
108
+ "devicePath": "./data/e2ee-device.json",
109
+ "autoReconnect": true,
110
+ "logLevel": "none"
111
+ },
112
+ "enableTypingIndicator": false,
113
+ "typingDuration": 4000
114
+ }
115
+ ```
116
+
117
+ | Key | Default | Description |
118
+ |---|---|---|
119
+ | `automation.enabled` | `false` | Background task automation. **Keep false.** |
120
+ | `inbox.enabled` | `true` | Enables getThreadList / inbox access |
121
+ | `smooth.enabled` | `false` | Shows typing indicator before sending |
122
+ | `e2ee.enable` | `false` | Activates E2EE Labyrinth bridge |
123
+ | `e2ee.saveType` | `"memory"` | `"memory"` = keys lost on restart · `"path"` = persistent |
124
+ | `e2ee.devicePath` | `"./data/e2ee-device.json"` | Used only when saveType = `"path"` |
125
+ | `enableTypingIndicator` | `false` | Auto typing indicator on sendMessage |
126
+
127
+ ---
128
+
129
+ ## 📚 API Reference
130
+
131
+ ### Login
132
+
133
+ ```js
134
+ login(loginData, options, callback)
135
+ // or: await login(loginData, options)
136
+ ```
137
+
138
+ **loginData:**
139
+ - `{ appState }` — cookie-based login (recommended)
140
+ - `{ email, password }` — credentials (use appState instead)
141
+
142
+ **options (defaults):**
143
+ ```js
144
+ {
145
+ selfListen : false,
146
+ listenEvents : true,
147
+ listenTyping : false,
148
+ updatePresence: false,
149
+ autoMarkRead : false,
150
+ autoReconnect : true,
151
+ online : false
152
+ }
153
+ ```
154
+
155
+ ---
156
+
157
+ ### Messaging
158
+
159
+ ```js
160
+ api.sendMessage(msg, threadID, [callback], [replyToMessageID])
161
+ api.sendMessage({ body, attachment, sticker, emoji, mentions, url }, threadID)
162
+ api.unsendMessage(messageID, [callback])
163
+ api.editMessage(body, messageID, [callback])
164
+ api.setMessageReaction(reaction, messageID, [callback])
165
+ api.forwardMessage(messageID, threadID, [callback])
166
+ api.forwardAttachment(attachmentID, userIDs, [callback])
167
+ ```
168
+
169
+ ### Threads
170
+
171
+ ```js
172
+ api.getThreadList(limit, cursor, tags, [callback])
173
+ api.getThreadInfo(threadID, [callback])
174
+ api.getThreadHistory(threadID, amount, timestamp, [callback])
175
+ api.createNewGroup(participantIDs, [groupTitle], [callback])
176
+ api.addUserToGroup(userID, threadID, [callback])
177
+ api.removeUserFromGroup(userID, threadID, [callback])
178
+ api.changeAdminStatus(threadID, adminID, adminStatus, [callback])
179
+ api.setTitle(newTitle, threadID, [callback])
180
+ api.changeGroupImage(imageStream, threadID, [callback])
181
+ api.muteThread(threadID, muteSeconds, [callback])
182
+ api.deleteThread(threadID, [callback])
183
+ api.changeArchivedStatus(threadID, archive, [callback])
184
+ api.createPoll(title, threadID, options, [callback])
185
+ api.pinMessage(messageID, threadID, [callback])
186
+ api.markAsRead(threadID, [read], [callback])
187
+ api.markAsDelivered(threadID, messageID, [callback])
188
+ api.markAsSeen([callback])
189
+ ```
190
+
191
+ ### Users
192
+
193
+ ```js
194
+ api.getUserInfo(userIDs, [callback])
195
+ api.getUserID(name, [callback])
196
+ api.getFriendsList([callback])
197
+ api.handleFriendRequest(userID, accept, [callback])
198
+ api.addFriend(userID, [callback])
199
+ api.unfriend(userID, [callback])
200
+ ```
201
+
202
+ ### E2EE
203
+
204
+ ```js
205
+ api.connectE2EE(callback) // Start E2EE bridge
206
+ api.getE2EEBridge() // Get live bridge instance
207
+ api.getE2EEDeviceData([callback]) // Get E2EE device keys
208
+ api.downloadE2EEMedia(options) // Decrypt E2EE attachment
209
+ api.resolveE2EEAttachment(att) // Download + return local URL
210
+ api.sendTypingE2EE(chatJid, bool) // Send E2EE typing indicator
211
+ ```
212
+
213
+ ### Session
214
+
215
+ ```js
216
+ api.sessionGuard(accountPath, { interval, debounce })
217
+ api.getAppState() // Get current cookie state
218
+ api.setOptions(options) // Update runtime options
219
+ api.getHealth() // Health status object
220
+ ```
221
+
222
+ ### Listening
223
+
224
+ ```js
225
+ const msgEmitter = api.listenMqtt(callback)
226
+ msgEmitter.stopListening([callback])
227
+ await msgEmitter.stopListeningAsync()
228
+ api.stopListenMqtt()
229
+ ```
230
+
231
+ ---
232
+
233
+ ## 🔐 E2EE Events
234
+
235
+ | event.type | Description |
236
+ |---|---|
237
+ | `e2ee_ready` | Bridge loaded, syncing device |
238
+ | `e2ee_fully_ready` | Ready to send/receive messages |
239
+ | `e2ee_connected` | Transport connected |
240
+ | `e2ee_disconnected` | Transport lost (auto-reconnects) |
241
+ | `e2ee_device_data_changed` | Device keys updated |
242
+ | `message` + `isE2EE: true` | Incoming E2EE message (DM or group) |
243
+ | `e2ee_message_edit` | Message was edited |
244
+ | `e2ee_message_reaction` | Reaction added |
245
+ | `e2ee_receipt` | Read/delivery receipt |
246
+
247
+ > **Normal and E2EE listeners never conflict.** The MQTT inbox handles normal chats; the E2EE bridge handles encrypted chats. Both can run simultaneously.
248
+
249
+ ---
250
+
251
+ ## 🔄 Session Stability
252
+
253
+ alpha-fca never calls logout automatically. Session is preserved as long as:
254
+ 1. `api.sessionGuard(path)` is active (auto-saves fresh cookies)
255
+ 2. The Facebook account is not independently logged out
256
+
257
+ On MQTT disconnect, auto-reconnect fires with exponential backoff (3s–60s).
258
+
259
+ ---
260
+
261
+ ## ⚠️ Limitations
262
+
263
+ - **Cannot test live network behavior** — all MQTT/E2EE behavior depends on Facebook's active endpoints and your account cookies.
264
+ - **E2EE requires** the native `build/messagix.so` (Linux) or `build/messagix.dll` (Windows) binary. These are pre-built for x86_64.
265
+ - **Facebook API changes** may break parsing without warning — this is inherent to all unofficial FCAs.
266
+ - **Rate limits** — avoid bulk-sending. alpha-fca does not bypass Facebook's rate limits.
267
+
268
+ ---
269
+
270
+ ## 📁 Project Structure
271
+
272
+ ```
273
+ alpha-fca/
274
+ ├── index.js # Main entry — login() function
275
+ ├── utils.js # HTTP helpers, cookie management
276
+ ├── e2ee.js # E2EE bridge (Labyrinth)
277
+ ├── advancedSystem.js # Minimal task queue + health monitor
278
+ ├── checkUpdate.js # Non-blocking version check
279
+ ├── config.json # Default config
280
+ ├── fca-config.example.json # Documented config template
281
+ ├── package.json
282
+ ├── README.md
283
+ ├── CHANGELOG.md
284
+ ├── build/
285
+ │ ├── messagix.so # E2EE native binary (Linux x86_64)
286
+ │ └── messagix.dll # E2EE native binary (Windows x64)
287
+ ├── lib/
288
+ │ └── index.mjs # E2EE ESM bundle (Labyrinth client)
289
+ ├── src/ # API method modules (95+ files)
290
+ │ ├── listenMqtt.js # Core inbox listener
291
+ │ ├── sendMessage.js # Message sending (normal + E2EE routing)
292
+ │ ├── OldMessage.js # Legacy DM fallback
293
+ │ ├── stopListenMqtt.js
294
+ │ ├── logout.js # No-op (session preserved)
295
+ │ └── ... (all other FCA methods)
296
+ └── examples/
297
+ ├── basic-bot.js # Normal inbox bot
298
+ └── e2ee-bot.js # E2EE + normal combined bot
299
+ ```
300
+
301
+ ---
302
+
303
+ ## 🔬 Merge Analysis
304
+
305
+ | Feature | Winner | Reason |
306
+ |---|---|---|
307
+ | E2EE Bridge | hridoy-custom | undici Node<22 patch, self-listen filter, capped maps, stopped flag |
308
+ | MQTT Core | hridoy-custom | MQTT patch stream, spinner, clean reconnect state |
309
+ | Login/Session | hridoy-custom | Cookie parsing, 2FA, sessionGuard, no unnecessary logouts |
310
+ | Error Handling | hridoy-akash | Global unhandledRejection/uncaughtException with network-specific handling |
311
+ | Extra API Methods | ST-FCA | sendButtons, sendFriendRequest, searchFriends, setActiveStatus, etc. |
312
+ | Low Automation | alpha-fca | All background polling disabled by default, config-driven opt-in only |
313
+ | Config System | alpha-fca | Layered config (FCA defaults → bot CWD override → runtime options) |
314
+
315
+ ---
316
+
317
+ ## 📄 License
318
+
319
+ MIT
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * AdvancedSystem — minimal queue + health monitor for alpha-fca.
5
+ * Automation is OFF by default. No background polling, no aggressive requests.
6
+ * Only runs tasks you explicitly enqueue.
7
+ */
8
+
9
+ const EventEmitter = require("events");
10
+
11
+ class AdvancedSystem extends EventEmitter {
12
+ constructor(options) {
13
+ super();
14
+ options = options || {};
15
+ this.options = Object.assign({
16
+ automationEnabled: false,
17
+ minDelayMs: 1000,
18
+ maxDelayMs: 30000,
19
+ maxQueue: 50
20
+ }, options);
21
+ this.startedAt = Date.now();
22
+ this._queue = [];
23
+ this._running = false;
24
+ this._stats = { enqueued: 0, completed: 0, failed: 0 };
25
+ }
26
+
27
+ /** @returns {boolean} */
28
+ isAutomationEnabled() {
29
+ return this.options.automationEnabled === true;
30
+ }
31
+
32
+ /** Explicit opt-in only — no background automation started automatically. */
33
+ setAutomationEnabled(enabled) {
34
+ this.options.automationEnabled = Boolean(enabled);
35
+ this.emit("automation", this.options.automationEnabled);
36
+ return this.options.automationEnabled;
37
+ }
38
+
39
+ /** Health snapshot — safe to call anytime. */
40
+ health(api) {
41
+ const mqttClient = api && (api.mqttClient || (api.ctx && api.ctx.mqttClient));
42
+ return {
43
+ version: "1.0.0",
44
+ uptimeMs: Date.now() - this.startedAt,
45
+ automationEnabled: this.isAutomationEnabled(),
46
+ inboxEnabled: true,
47
+ mqtt: mqttClient ? {
48
+ connected: Boolean(mqttClient.connected),
49
+ reconnecting: Boolean(mqttClient.reconnecting)
50
+ } : null,
51
+ queue: { size: this._queue.length, running: this._running },
52
+ stats: Object.assign({}, this._stats)
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Enqueue a task function. Runs sequentially.
58
+ * @param {Function} task async () => result
59
+ * @returns {Promise<any>}
60
+ */
61
+ enqueue(task) {
62
+ if (typeof task !== "function") return Promise.reject(new TypeError("task must be a function"));
63
+ if (this._queue.length >= this.options.maxQueue) {
64
+ return Promise.reject(new Error("AdvancedSystem queue is full (" + this.options.maxQueue + ")"));
65
+ }
66
+ this._stats.enqueued++;
67
+ return new Promise((resolve, reject) => {
68
+ this._queue.push({ task, resolve, reject });
69
+ this._drain();
70
+ });
71
+ }
72
+
73
+ async _drain() {
74
+ if (this._running || this._queue.length === 0) return;
75
+ this._running = true;
76
+ while (this._queue.length > 0) {
77
+ const { task, resolve, reject } = this._queue.shift();
78
+ try {
79
+ const result = await task();
80
+ this._stats.completed++;
81
+ resolve(result);
82
+ } catch (err) {
83
+ this._stats.failed++;
84
+ reject(err);
85
+ }
86
+ // Small throttle between tasks to avoid burst requests
87
+ if (this._queue.length > 0) {
88
+ await new Promise(r => setTimeout(r, this.options.minDelayMs));
89
+ }
90
+ }
91
+ this._running = false;
92
+ }
93
+ }
94
+
95
+ module.exports = AdvancedSystem;
Binary file
Binary file
package/checkUpdate.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ const CURRENT_VERSION = "1.0.0";
4
+
5
+ /**
6
+ * Lightweight, non-blocking update check.
7
+ * Only runs once per process lifetime (guarded by global._alphaFcaUpdateChecked).
8
+ * Never blocks login or throws on failure.
9
+ */
10
+ async function checkForFCAUpdate() {
11
+ try {
12
+ // Try to fetch latest version from npm registry (or GitHub)
13
+ const https = require("https");
14
+ const pkgUrl = "https://registry.npmjs.org/hridoy-ultimate/latest";
15
+ const data = await new Promise((resolve) => {
16
+ const req = https.get(pkgUrl, { timeout: 5000 }, (res) => {
17
+ let body = "";
18
+ res.on("data", (c) => { body += c; });
19
+ res.on("end", () => {
20
+ try { resolve(JSON.parse(body)); }
21
+ catch (_) { resolve(null); }
22
+ });
23
+ });
24
+ req.on("error", () => resolve(null));
25
+ req.on("timeout", () => { req.destroy(); resolve(null); });
26
+ });
27
+ if (data && data.version && data.version !== CURRENT_VERSION) {
28
+ const log = require("npmlog");
29
+ log.warn("alpha-fca", `Update available: v${CURRENT_VERSION} → v${data.version}`);
30
+ log.warn("alpha-fca", "Run: npm update alpha-fca");
31
+ }
32
+ } catch (_) {
33
+ // Silently ignore — update check must never crash the bot
34
+ }
35
+ }
36
+
37
+ module.exports = { checkForFCAUpdate, CURRENT_VERSION };
package/config.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "version": "1.0.0",
3
+
4
+ "automation": {
5
+ "enabled": false,
6
+ "comment": "Keep false. Background automation disabled by default for low-automation stable operation."
7
+ },
8
+
9
+ "inbox": {
10
+ "enabled": true,
11
+ "comment": "Inbox/getThreadList is always active when true."
12
+ },
13
+
14
+ "smooth": {
15
+ "enabled": true,
16
+ "messageDelay": 400,
17
+ "typingDelay": 600,
18
+ "comment": "Smooth mode: shows typing indicator before sending. Keep false to minimize automation."
19
+ },
20
+
21
+ "connection": {
22
+ "minDelayMs": 1000,
23
+ "maxDelayMs": 30000,
24
+ "comment": "Min/max reconnect delay in ms."
25
+ },
26
+
27
+ "e2ee": {
28
+ "enable": true,
29
+ "saveType": "memory",
30
+ "devicePath": "./data/e2ee-device.json",
31
+ "autoReconnect": true,
32
+ "logLevel": "none",
33
+ "comment": "Set enable:true to activate E2EE bridge. saveType: 'memory' (default, keys lost on restart) or 'path' (persistent). devicePath used only when saveType='path'."
34
+ },
35
+
36
+ "imgKeys": {
37
+ "imgbb": null,
38
+ "ik_pub": null,
39
+ "ik_priv": null,
40
+ "comment": "Optional image hosting keys. Leave null to skip image hosting features."
41
+ },
42
+
43
+ "enableTypingIndicator": false,
44
+ "typingDuration": 4000
45
+ }