sagor-fca 0.0.10 → 0.0.12

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 (223) hide show
  1. package/README.md +380 -402
  2. package/examples/login-with-cookies.js +102 -0
  3. package/examples/ping.js +1 -0
  4. package/examples/verify.js +70 -0
  5. package/index.js +2 -8
  6. package/package.json +82 -56
  7. package/src/{api/action → apis}/addExternalModule.js +8 -9
  8. package/src/apis/addUserToGroup.js +108 -0
  9. package/src/apis/changeAdminStatus.js +148 -0
  10. package/src/apis/changeArchivedStatus.js +61 -0
  11. package/src/apis/changeAvatar.js +103 -0
  12. package/src/apis/changeBio.js +69 -0
  13. package/src/apis/changeBlockedStatus.js +54 -0
  14. package/src/apis/changeGroupImage.js +136 -0
  15. package/src/apis/changeThreadColor.js +116 -0
  16. package/src/apis/changeThreadEmoji.js +53 -0
  17. package/src/apis/comment.js +207 -0
  18. package/src/apis/createAITheme.js +129 -0
  19. package/src/apis/createNewGroup.js +79 -0
  20. package/src/apis/createPoll.js +73 -0
  21. package/src/apis/deleteMessage.js +44 -0
  22. package/src/apis/deleteThread.js +52 -0
  23. package/src/apis/e2ee.js +17 -0
  24. package/src/apis/editMessage.js +70 -0
  25. package/src/apis/emoji.js +124 -0
  26. package/src/apis/fetchThemeData.js +82 -0
  27. package/src/apis/follow.js +81 -0
  28. package/src/apis/forwardMessage.js +52 -0
  29. package/src/apis/friend.js +243 -0
  30. package/src/apis/gcmember.js +122 -0
  31. package/src/apis/gcname.js +123 -0
  32. package/src/apis/gcrule.js +119 -0
  33. package/src/apis/getAccess.js +111 -0
  34. package/src/apis/getBotInfo.js +88 -0
  35. package/src/apis/getBotInitialData.js +43 -0
  36. package/src/apis/getFriendsList.js +79 -0
  37. package/src/apis/getMessage.js +423 -0
  38. package/src/apis/getTheme.js +95 -0
  39. package/src/apis/getThemeInfo.js +116 -0
  40. package/src/apis/getThreadHistory.js +239 -0
  41. package/src/apis/getThreadInfo.js +267 -0
  42. package/src/apis/getThreadList.js +232 -0
  43. package/src/apis/getThreadPictures.js +58 -0
  44. package/src/apis/getUserID.js +117 -0
  45. package/src/apis/getUserInfo.js +513 -0
  46. package/src/{api/users → apis}/getUserInfoV2.js +26 -14
  47. package/src/apis/handleMessageRequest.js +50 -0
  48. package/src/apis/httpGet.js +63 -0
  49. package/src/apis/httpPost.js +89 -0
  50. package/src/apis/httpPostFormData.js +69 -0
  51. package/src/apis/listenMqtt.js +1184 -0
  52. package/src/apis/listenSpeed.js +179 -0
  53. package/src/apis/logout.js +63 -0
  54. package/src/apis/markAsDelivered.js +47 -0
  55. package/src/{api/messaging → apis}/markAsRead.js +26 -19
  56. package/src/apis/markAsReadAll.js +40 -0
  57. package/src/apis/markAsSeen.js +70 -0
  58. package/src/apis/mqttDeltaValue.js +278 -0
  59. package/src/apis/muteThread.js +45 -0
  60. package/src/apis/nickname.js +132 -0
  61. package/src/apis/notes.js +163 -0
  62. package/src/apis/pinMessage.js +150 -0
  63. package/src/apis/produceMetaTheme.js +180 -0
  64. package/src/apis/realtime.js +182 -0
  65. package/src/apis/removeUserFromGroup.js +117 -0
  66. package/src/apis/resolvePhotoUrl.js +58 -0
  67. package/src/apis/searchForThread.js +154 -0
  68. package/src/apis/sendMessage.js +354 -0
  69. package/src/apis/sendMessageMqtt.js +249 -0
  70. package/src/apis/sendTypingIndicator.js +40 -0
  71. package/src/apis/setMessageReaction.js +27 -0
  72. package/src/apis/setMessageReactionMqtt.js +61 -0
  73. package/src/apis/setThreadTheme.js +260 -0
  74. package/src/apis/setThreadThemeMqtt.js +94 -0
  75. package/src/apis/share.js +107 -0
  76. package/src/apis/shareContact.js +66 -0
  77. package/src/apis/stickers.js +257 -0
  78. package/src/apis/story.js +181 -0
  79. package/src/apis/theme.js +233 -0
  80. package/src/apis/unfriend.js +47 -0
  81. package/src/apis/unsendMessage.js +17 -0
  82. package/src/database/appStateBackup.js +189 -0
  83. package/src/database/models/index.js +44 -76
  84. package/src/database/models/thread.js +3 -22
  85. package/src/database/models/user.js +3 -17
  86. package/src/database/threadData.js +53 -46
  87. package/src/database/userData.js +38 -46
  88. package/src/engine/client.js +92 -0
  89. package/src/engine/models/buildAPI.js +113 -0
  90. package/src/engine/models/loginHelper.js +480 -0
  91. package/src/engine/models/setOptions.js +88 -0
  92. package/src/security/e2ee.js +109 -0
  93. package/src/types/index.d.ts +498 -0
  94. package/src/utils/antiSuspension.js +534 -0
  95. package/src/utils/auth-helpers.js +149 -0
  96. package/src/utils/autoReLogin.js +240 -0
  97. package/src/utils/axios.js +369 -0
  98. package/src/utils/cache.js +54 -0
  99. package/src/utils/clients.js +279 -0
  100. package/src/utils/constants.js +402 -15
  101. package/src/utils/formatters/data/formatAttachment.js +370 -0
  102. package/src/utils/formatters/data/formatDelta.js +109 -0
  103. package/src/utils/formatters/index.js +159 -0
  104. package/src/utils/formatters/value/formatCookie.js +91 -0
  105. package/src/utils/formatters/value/formatDate.js +36 -0
  106. package/src/utils/formatters/value/formatID.js +16 -0
  107. package/src/utils/formatters.js +1369 -0
  108. package/src/utils/headers.js +219 -99
  109. package/src/utils/index.js +153 -0
  110. package/src/utils/monitoring.js +333 -0
  111. package/src/utils/rateLimiter.js +251 -0
  112. package/src/utils/tokenRefresh.js +285 -0
  113. package/src/utils/user-agents.js +238 -0
  114. package/src/utils/validation.js +157 -0
  115. package/.gitattributes +0 -2
  116. package/.github/workflows/SaGor.yml +0 -22
  117. package/LICENSE-MIT +0 -21
  118. package/Sagor_Database/sagor.sqlite +0 -0
  119. package/docs/ARCHITECTURE.md +0 -142
  120. package/examples/remote-control.js +0 -85
  121. package/func/checkUpdate.js +0 -222
  122. package/func/logAdapter.js +0 -33
  123. package/func/logger.js +0 -48
  124. package/index.d.ts +0 -751
  125. package/module/config.js +0 -40
  126. package/module/login.js +0 -133
  127. package/module/loginHelper.js +0 -1296
  128. package/module/options.js +0 -44
  129. package/src/api/action/changeAvatar.js +0 -137
  130. package/src/api/action/changeBio.js +0 -75
  131. package/src/api/action/enableAutoSaveAppState.js +0 -73
  132. package/src/api/action/getCurrentUserID.js +0 -7
  133. package/src/api/action/handleFriendRequest.js +0 -57
  134. package/src/api/action/logout.js +0 -76
  135. package/src/api/action/refreshFb_dtsg.js +0 -48
  136. package/src/api/action/setPostReaction.js +0 -106
  137. package/src/api/action/unfriend.js +0 -54
  138. package/src/api/http/httpGet.js +0 -46
  139. package/src/api/http/httpPost.js +0 -52
  140. package/src/api/http/postFormData.js +0 -47
  141. package/src/api/messaging/addUserToGroup.js +0 -68
  142. package/src/api/messaging/changeAdminStatus.js +0 -126
  143. package/src/api/messaging/changeArchivedStatus.js +0 -55
  144. package/src/api/messaging/changeBlockedStatus.js +0 -48
  145. package/src/api/messaging/changeGroupImage.js +0 -91
  146. package/src/api/messaging/changeNickname.js +0 -70
  147. package/src/api/messaging/changeThreadColor.js +0 -79
  148. package/src/api/messaging/changeThreadEmoji.js +0 -111
  149. package/src/api/messaging/createNewGroup.js +0 -88
  150. package/src/api/messaging/createPoll.js +0 -46
  151. package/src/api/messaging/createThemeAI.js +0 -98
  152. package/src/api/messaging/deleteMessage.js +0 -136
  153. package/src/api/messaging/deleteThread.js +0 -56
  154. package/src/api/messaging/editMessage.js +0 -68
  155. package/src/api/messaging/forwardAttachment.js +0 -57
  156. package/src/api/messaging/getEmojiUrl.js +0 -29
  157. package/src/api/messaging/getFriendsList.js +0 -82
  158. package/src/api/messaging/getMessage.js +0 -829
  159. package/src/api/messaging/getThemePictures.js +0 -62
  160. package/src/api/messaging/handleMessageRequest.js +0 -65
  161. package/src/api/messaging/markAsDelivered.js +0 -57
  162. package/src/api/messaging/markAsReadAll.js +0 -49
  163. package/src/api/messaging/markAsSeen.js +0 -61
  164. package/src/api/messaging/muteThread.js +0 -50
  165. package/src/api/messaging/removeUserFromGroup.js +0 -62
  166. package/src/api/messaging/resolvePhotoUrl.js +0 -43
  167. package/src/api/messaging/scheduler.js +0 -264
  168. package/src/api/messaging/searchForThread.js +0 -53
  169. package/src/api/messaging/sendMessage.js +0 -270
  170. package/src/api/messaging/sendTypingIndicator.js +0 -74
  171. package/src/api/messaging/setMessageReaction.js +0 -90
  172. package/src/api/messaging/setTitle.js +0 -124
  173. package/src/api/messaging/shareContact.js +0 -49
  174. package/src/api/messaging/threadColors.js +0 -128
  175. package/src/api/messaging/unsendMessage.js +0 -81
  176. package/src/api/messaging/uploadAttachment.js +0 -492
  177. package/src/api/socket/core/connectMqtt.js +0 -258
  178. package/src/api/socket/core/emitAuth.js +0 -103
  179. package/src/api/socket/core/getSeqID.js +0 -320
  180. package/src/api/socket/core/getTaskResponseData.js +0 -25
  181. package/src/api/socket/core/parseDelta.js +0 -377
  182. package/src/api/socket/detail/buildStream.js +0 -215
  183. package/src/api/socket/detail/constants.js +0 -28
  184. package/src/api/socket/listenMqtt.js +0 -377
  185. package/src/api/socket/middleware/index.js +0 -216
  186. package/src/api/threads/getThreadHistory.js +0 -664
  187. package/src/api/threads/getThreadInfo.js +0 -296
  188. package/src/api/threads/getThreadList.js +0 -293
  189. package/src/api/threads/getThreadPictures.js +0 -78
  190. package/src/api/users/getUserID.js +0 -65
  191. package/src/api/users/getUserInfo.js +0 -402
  192. package/src/core/sendReqMqtt.js +0 -96
  193. package/src/database/helpers.js +0 -53
  194. package/src/remote/remoteClient.js +0 -123
  195. package/src/utils/broadcast.js +0 -51
  196. package/src/utils/client.js +0 -10
  197. package/src/utils/cookies.js +0 -68
  198. package/src/utils/format/attachment.js +0 -357
  199. package/src/utils/format/cookie.js +0 -9
  200. package/src/utils/format/date.js +0 -50
  201. package/src/utils/format/decode.js +0 -44
  202. package/src/utils/format/delta.js +0 -194
  203. package/src/utils/format/ids.js +0 -64
  204. package/src/utils/format/index.js +0 -64
  205. package/src/utils/format/message.js +0 -88
  206. package/src/utils/format/presence.js +0 -132
  207. package/src/utils/format/readTyp.js +0 -44
  208. package/src/utils/format/thread.js +0 -42
  209. package/src/utils/format/utils.js +0 -141
  210. package/src/utils/loginParser/autoLogin.js +0 -125
  211. package/src/utils/loginParser/helpers.js +0 -43
  212. package/src/utils/loginParser/index.js +0 -10
  213. package/src/utils/loginParser/parseAndCheckLogin.js +0 -220
  214. package/src/utils/loginParser/textUtils.js +0 -28
  215. package/src/utils/request/client.js +0 -26
  216. package/src/utils/request/config.js +0 -23
  217. package/src/utils/request/defaults.js +0 -46
  218. package/src/utils/request/helpers.js +0 -46
  219. package/src/utils/request/index.js +0 -17
  220. package/src/utils/request/methods.js +0 -163
  221. package/src/utils/request/proxy.js +0 -21
  222. package/src/utils/request/retry.js +0 -77
  223. package/src/utils/request/sanitize.js +0 -49
package/README.md CHANGED
@@ -1,524 +1,502 @@
1
- <div align="center">
1
+ # sagor-fca
2
2
 
3
- # sagor-nx-fca
3
+ [![npm version](https://img.shields.io/npm/v/sagor-fca.svg)](https://www.npmjs.com/package/sagor-fca)
4
+ [![npm downloads](https://img.shields.io/npm/dm/sagor-fca.svg)](https://www.npmjs.com/package/sagor-fca)
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/sagor-fca.svg)](https://nodejs.org)
4
7
 
5
- **Unofficial Facebook Chat API for Node.js** - Interact with Facebook Messenger programmatically
8
+ **sagor-fca** is an advanced Facebook Chat API (FCA) client built for **reliable**, **real-time**, and **modular** interaction with Facebook Messenger.
6
9
 
7
- [Features](#-features) [Installation](#-installation) [Quick Start](#-quick-start) • [Documentation](#-documentation) • [Support](#-author--support)
8
-
9
- </div>
10
-
11
- ---
12
-
13
- ## 📋 Table of Contents
14
-
15
- - [⚠️ Disclaimer & Support Policy](#️-disclaimer--support-policy)
16
- - [⚡ Why this fork?](#-why-this-fork)
17
- - [✨ Features](#-features)
18
- - [🔍 Introduction](#-introduction)
19
- - [📦 Installation](#-installation)
20
- - [🚀 Quick Start](#-quick-start)
21
- - [📝 Message Types](#-message-types)
22
- - [💾 AppState Management](#-appstate-management)
23
- - [🔄 Auto Login](#-auto-login)
24
- - [👂 Listening for Messages](#-listening-for-messages)
25
- - [🎯 API Quick Reference](#-api-quick-reference)
26
- - [📚 Documentation](#-documentation)
27
- - [🛠️ Projects Using This API](#️-projects-using-this-api)
28
- - [🤝 Contributing](#-contributing)
29
- - [📄 License](#-license)
30
- - [👨‍💻 Author & Support](#-author--support)
10
+ Developed and maintained by **[SaGor](https://github.com/SAGOR-KINGx)**.
11
+ Inspired by **ws3-fca** and **@dongdev/fca-unofficial**
31
12
 
32
13
  ---
33
14
 
34
- ## ⚠️ Disclaimer & Support Policy
35
-
36
- <div align="center">
37
-
38
- **READ THIS BEFORE USING OR OPENING AN ISSUE.**
39
-
40
- </div>
41
-
42
- This repository is provided **"AS IS"** and is entirely open-source. By using this project, you explicitly agree to the following terms:
43
-
44
- 1. **Use at your own risk:** We are NOT responsible if your account gets banned for spammy activities (sending messages too fast, unsolicited mass messaging, suspicious URLs, or rapid login/logout).
45
- 2. **No Spoon-Feeding:** This is a tool for developers. If you cannot read source code, navigate directories, or use basic search tools (`Ctrl + Shift + F`), you should not be using this library.
46
- 3. **No Free Programming Lessons:** I maintain the core updates and security patches for the community for free. I do **not** provide free JavaScript/TypeScript tutorials, nor will I tell you exactly which line of code to edit for your specific bot.
47
- 4. **Custom Features = Paid Service:** Brainpower and time are not free. If you need me to write custom logic, reverse-engineer specific endpoints, or provide 1-on-1 support for your personal project, **that is a paid service**.
48
-
49
- If you don't like this policy, feel free to fork the repository and maintain it yourself.
50
-
51
- **Recommendations to avoid bans:**
52
-
53
- - Use **Firefox** or the [fca.dongdev.id.vn](https://fca.dongdev.id.vn) flow to reduce logout issues (especially on iOS).
54
- - Prefer **AppState** over email/password when possible.
55
- - Use strict **rate limiting** in your bots.
56
-
57
- ---
15
+ ## Documentation
58
16
 
59
- ## Why this fork?
17
+ - **[Cookie Login Guide](COOKIE_LOGIN.md)** — Authenticate using browser cookies
18
+ - **[Theme Features](THEME_FEATURES.md)** — Comprehensive guide to theme management
19
+ - **[Changelog](CHANGELOG.md)** — Version history and updates
20
+ - **[Examples](examples/)** — Code examples and usage patterns
60
21
 
61
- Unlike other outdated forks, `@sagor/fca-unofficial` is built with a focus on **real-world practicality and performance**:
22
+ ### Support & Issues
62
23
 
63
- - **Performance First:** Stripped out legacy, redundant code that causes technical debt.
64
- - **Modernized Architecture:** Adapted to the latest Facebook backend structure.
65
- - **Clean Logic:** No messy wrappers. The codebase is straightforward and easy to navigate if you actually open the files.
24
+ - GitHub: [https://github.com/SAGOR-KINGx](https://github.com/SAGOR-KINGx)
25
+ - Issues: [https://github.com/SAGOR-KINGx/sagor-fca/issues](https://github.com/SAGOR-KINGx/sagor-fca/issues)
66
26
 
67
27
  ---
68
28
 
69
- ## Features
70
-
71
- - ✅ **Full Messenger API** - Send messages, files, stickers, and more
72
- - **Real-time Events** - Listen to messages, reactions, and thread events
73
- - **User Account Support** - Works with personal Facebook accounts (not just Pages)
74
- - **AppState Support** - Save login state to avoid re-authentication
75
- - **MQTT Protocol** - Real-time messaging via MQTT
76
- - ✅ **TypeScript Support** - Includes TypeScript definitions
77
- - **Active Development** - Regularly updated and maintained
29
+ ## Features
30
+
31
+ **Authentication**
32
+ - Cookie array login (`appState`) the safest method for long-running bots
33
+ - Email/password login with TOTP/2FA support
34
+ - Session fingerprint locking — User-Agent, Sec-Ch-Ua, locale, timezone locked per session to prevent detection
35
+ - AppState auto-backup and restore on restart
36
+
37
+ **Real-time Messaging**
38
+ - MQTT and HTTP messaging with automatic protocol fallback
39
+ - Send text, attachments, stickers, emoji, mentions, and location
40
+ - Message editing, unsend, forward, and delete
41
+ - Message reactions via HTTP and MQTT
42
+ - Pin/unpin messages, list pinned messages
43
+
44
+ **Anti-Suspension System**
45
+ - Circuit breaker — halts activity after repeated suspension signals, resumes after cooldown
46
+ - 60+ suspension signal patterns: checkpoints, spam flags, rate limits, identity verification, policy violations, session expiry, and more
47
+ - Adaptive per-thread delay that increases with session volume
48
+ - Hourly and daily message volume limits with automatic warning pauses
49
+ - Warmup mode for fresh sessions — gradually increases allowed message rate
50
+ - Humanized typing simulation before every send
51
+ - Randomized request intervals and jitter to avoid periodicity detection
52
+ - Session fingerprint locking to maintain consistent browser identity
53
+ - PostSafe guard: detects auth failures and checkpoint responses in real-time
54
+ - MQTT watchdog: detects stale connections and forces clean reconnect
55
+
56
+ **Stability & Reliability**
57
+ - MQTT auto-reconnect with exponential backoff and jitter
58
+ - Auto re-login using refreshed AppState when session expires
59
+ - TokenRefreshManager with randomized intervals to keep sessions alive
60
+ - Sliding-window rate limiter with per-endpoint tracking
61
+ - SQLite-backed thread and user data cache for fast lookups
62
+
63
+ **Thread & Group Management**
64
+ - Get thread info, history, pictures, and lists
65
+ - Create groups, add/remove members, change admin status
66
+ - Update group image, name, color, emoji
67
+ - Archive, mute, delete threads
68
+ - Create polls, manage notes and rules
69
+ - Search threads by name, handle message requests
70
+
71
+ **User & Friends**
72
+ - Get user info (basic and extended), resolve user IDs
73
+ - Get full friends list, send/cancel friend requests, unfriend, block/unblock
74
+
75
+ **Social**
76
+ - Comment on posts, share posts, follow/unfollow users
77
+
78
+ **Themes & Stickers**
79
+ - Browse 90+ Messenger themes, apply themes via MQTT
80
+ - Generate AI-powered themes with text prompts
81
+ - Search stickers, browse packs, add packs, get AI stickers
82
+
83
+ **E2EE (Opt-In)**
84
+ - Application-layer end-to-end encryption for DMs using X25519 + HKDF + AES-256-GCM
85
+
86
+ **Monitoring**
87
+ - `api.getHealthStatus()` — MQTT status, token refresh stats, rate limiter metrics
88
+ - Built-in `ProductionMonitor` for request/error/performance telemetry
89
+
90
+ **Proxy Support**
91
+ - Full proxy support via the `proxy` login option
78
92
 
79
93
  ---
80
94
 
81
- ## 🔍 Introduction
82
-
83
- Facebook provides an [official API for chat bots](https://developers.facebook.com/docs/messenger-platform), but it's **only available for Facebook Pages**.
84
-
85
- `@sagor/fca-unofficial` is the API that allows you to automate chat functionalities on a **user account** by emulating the browser. This means:
86
-
87
- - 🔄 Making the exact same GET/POST requests as a browser
88
- - 🔐 Does not work with auth tokens
89
- - 📝 Requires Facebook account credentials (email/password) or AppState
90
-
91
- **Perfect for:**
92
-
93
- - 🤖 Building chatbots
94
- - 📱 Automating message responses
95
- - 🔔 Creating notification systems
96
- - 🎮 Building interactive games
97
- - 📊 Analytics and monitoring
98
-
99
- ---
95
+ ## Installation
100
96
 
101
- ## 📦 Installation
97
+ > **Requirements:** Node.js v18.0.0 or higher
102
98
 
103
99
  ```bash
104
- npm install @sagor/fca-unofficial@latest
100
+ npm install sagor-fca
105
101
  ```
106
102
 
107
- **Requirements:**
108
-
109
- - Node.js >= 12.0.0
110
- - Active Facebook account
111
-
112
103
  ---
113
104
 
114
- ## 🚀 Quick Start
105
+ ## Quick Start
115
106
 
116
- ### 1️⃣ Login and Simple Echo Bot
107
+ ```js
108
+ const fs = require("fs");
109
+ const { login } = require("sagor-fca");
117
110
 
118
- ```javascript
119
- const login = require("@sagor/fca-unofficial");
111
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
120
112
 
121
- login({ appState: [] }, (err, api) => {
122
- if (err) return console.error(err);
113
+ login({ appState }, {
114
+ online: true,
115
+ listenEvents: true,
116
+ autoMarkRead: true,
117
+ autoReconnect: true,
118
+ simulateTyping: true
119
+ }, (err, api) => {
120
+ if (err) return console.error("Login error:", err);
121
+
122
+ console.log("Logged in as:", api.getCurrentUserID());
123
123
 
124
124
  api.listenMqtt((err, event) => {
125
- if (err) return console.error(err);
125
+ if (err || event.type !== "message" || !event.body) return;
126
126
 
127
- // Echo back the received message
128
- if (event.type === "message") {
129
- api.sendMessage(event.body, event.threadID);
127
+ if (event.body === "/ping") {
128
+ api.sendMessage("pong!", event.threadID);
130
129
  }
131
130
  });
132
131
  });
133
132
  ```
134
133
 
135
- ### 2️⃣ Send Text Message
136
-
137
- ```javascript
138
- const login = require("@sagor/fca-unofficial");
139
-
140
- login({ appState: [] }, (err, api) => {
141
- if (err) {
142
- console.error("Login Error:", err);
143
- return;
144
- }
145
-
146
- const yourID = "000000000000000"; // Replace with actual Facebook ID
147
- const msg = "Hey! 👋";
134
+ ---
148
135
 
149
- api.sendMessage(msg, yourID, (err) => {
150
- if (err) console.error("Message Sending Error:", err);
151
- else console.log("✅ Message sent successfully!");
152
- });
136
+ ## Anti-Suspension Configuration
137
+
138
+ The anti-suspension system is active by default. You can tune it through login options:
139
+
140
+ ```js
141
+ login({ appState }, {
142
+ autoReconnect: true,
143
+ listenEvents: true,
144
+ autoMarkRead: true,
145
+ simulateTyping: true, // humanized typing delays before send
146
+ randomUserAgent: true, // rotate user agent on each session
147
+ persona: "desktop", // "desktop" or "android"
148
+ maxConcurrentRequests: 5, // max parallel HTTP requests
149
+ maxRequestsPerMinute: 50, // sliding-window rate cap
150
+ requestCooldownMs: 60000, // per-endpoint cooldown duration
151
+ errorCacheTtlMs: 300000 // how long to suppress repeated errors
152
+ }, (err, api) => {
153
+ if (err) throw err;
154
+
155
+ // Check anti-suspension and rate limiter status
156
+ console.log(api.getHealthStatus());
153
157
  });
154
158
  ```
155
159
 
156
- > **💡 Tip:** To find your Facebook ID, look inside the cookies under the name `c_user`
160
+ ### Circuit Breaker
157
161
 
158
- ### 3️⃣ Send File/Image
162
+ 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.
159
163
 
160
- ```javascript
161
- const login = require("@sagor/fca-unofficial");
162
- const fs = require("fs");
163
-
164
- login({ appState: [] }, (err, api) => {
165
- if (err) {
166
- console.error("Login Error:", err);
167
- return;
168
- }
164
+ You can also trip or reset it manually:
169
165
 
170
- const yourID = "000000000000000";
171
- const imagePath = __dirname + "/image.jpg";
166
+ ```js
167
+ const { globalAntiSuspension } = require("sagor-fca/src/utils/antiSuspension");
172
168
 
173
- // Check if file exists
174
- if (!fs.existsSync(imagePath)) {
175
- console.error("❌ Error: Image file not found!");
176
- return;
177
- }
169
+ // Manually trip (e.g. after you detect a warning in a response)
170
+ globalAntiSuspension.tripCircuitBreaker("manual_pause", 30 * 60 * 1000); // 30 min
178
171
 
179
- const msg = {
180
- body: "Check out this image! 📷",
181
- attachment: fs.createReadStream(imagePath),
182
- };
172
+ // Reset after you've resolved the issue
173
+ globalAntiSuspension.resetCircuitBreaker();
183
174
 
184
- api.sendMessage(msg, yourID, (err) => {
185
- if (err) console.error("Message Sending Error:", err);
186
- else console.log("✅ Image sent successfully!");
187
- });
188
- });
175
+ // Check status
176
+ console.log(globalAntiSuspension.getConfig());
189
177
  ```
190
178
 
191
- ---
179
+ ### Warmup Mode
192
180
 
193
- ## 📝 Message Types
181
+ Use warmup mode when starting a fresh or recovered session:
194
182
 
195
- | Type | Usage | Example |
196
- | ---------------- | ------------------------------------------- | -------------------------------------------------- |
197
- | **Regular text** | `{ body: "message text" }` | `{ body: "Hello!" }` |
198
- | **Sticker** | `{ sticker: "sticker_id" }` | `{ sticker: "369239263222822" }` |
199
- | **File/Image** | `{ attachment: fs.createReadStream(path) }` | `{ attachment: fs.createReadStream("image.jpg") }` |
200
- | **URL** | `{ url: "https://example.com" }` | `{ url: "https://github.com" }` |
201
- | **Large emoji** | `{ emoji: "👍", emojiSize: "large" }` | `{ emoji: "👍", emojiSize: "large" }` |
202
-
203
- > **📌 Note:** A message can only be a regular message (which can be empty) and optionally **one of the following**: a sticker, an attachment, or a URL.
204
-
205
- **Emoji sizes:** `small` | `medium` | `large`
183
+ ```js
184
+ const { globalAntiSuspension } = require("sagor-fca/src/utils/antiSuspension");
185
+ globalAntiSuspension.enableWarmup(); // limits to 25 msg/hour for 20 minutes
186
+ ```
206
187
 
207
188
  ---
208
189
 
209
- ## 💾 AppState Management
190
+ ## End-to-End Encryption for DMs (Opt-In)
210
191
 
211
- ### Save AppState
192
+ Encrypt and decrypt message bodies in direct chats using X25519 + HKDF + AES-256-GCM.
212
193
 
213
- Save your login session to avoid re-authentication:
194
+ ```js
195
+ api.e2ee.enable();
214
196
 
215
- ```javascript
216
- const fs = require("fs");
217
- const login = require("@sagor/fca-unofficial");
218
-
219
- const credentials = { email: "YOUR_EMAIL", password: "YOUR_PASSWORD" }; // Or use existing appState
197
+ // Share your bot's public key with the peer
198
+ const botPubKey = api.e2ee.getPublicKey();
220
199
 
221
- login(credentials, (err, api) => {
222
- if (err) {
223
- console.error("Login Error:", err);
224
- return;
225
- }
200
+ // Register the peer's public key for a DM thread
201
+ api.e2ee.setPeerKey(threadID, peerPublicKeyBase64);
226
202
 
227
- try {
228
- const appState = JSON.stringify(api.getAppState(), null, 2);
229
- fs.writeFileSync("appstate.json", appState);
230
- console.log("✅ AppState saved successfully!");
231
- } catch (error) {
232
- console.error("❌ Error saving AppState:", error);
233
- }
234
- });
235
- ```
236
-
237
- ### Use Saved AppState
238
-
239
- Load your saved AppState for faster login:
240
-
241
- ```javascript
242
- const fs = require("fs");
243
- const login = require("@sagor/fca-unofficial");
244
-
245
- login(
246
- { appState: JSON.parse(fs.readFileSync("appstate.json", "utf8")) },
247
- (err, api) => {
248
- if (err) {
249
- console.error("Login Error:", err);
250
- return;
251
- }
252
-
253
- console.log("✅ Logged in successfully!");
254
- // Your code here
255
- },
256
- );
203
+ // Messages to that thread are now auto-encrypted on send
204
+ // and auto-decrypted on receive
205
+ api.sendMessage("Top secret message", threadID);
257
206
  ```
258
207
 
259
208
  ---
260
209
 
261
- ## 🔄 Auto Login
210
+ ## Security Warning
262
211
 
263
- When your session (AppState) expires, the library can **automatically re-login** using credentials from a config file, so your bot can keep running without manual intervention.
212
+ `appstate.json` contains your Facebook session and must be treated like a password:
264
213
 
265
- 1. Create **`fca-config.json`** in your project root (same folder as where you run `node`):
266
-
267
- ```json
268
- {
269
- "autoLogin": true,
270
- "apiServer": "https://minhdong.site",
271
- "apiKey": "",
272
- "credentials": {
273
- "email": "YOUR_EMAIL_OR_PHONE",
274
- "password": "YOUR_PASSWORD",
275
- "twofactor": ""
276
- }
277
- }
278
- ```
279
-
280
- 2. **Log in with AppState** as usual. If the session later expires (e.g. Facebook invalidates cookies), the library will use `credentials` (and optionally the external `apiServer`) to log in again and retry the request.
281
-
282
- - Set **`autoLogin`** to `false` to disable automatic re-login.
283
- - **`twofactor`**: Base32 secret for 2FA (not the 6-digit code). Leave empty if you do not use 2FA.
284
- - **`apiServer`** / **`apiKey`**: Optional; used for external iOS-style login. Default server is `https://minhdong.site`.
285
-
286
- Keep **`fca-config.json`** out of version control (add it to `.gitignore`) since it contains credentials.
214
+ - **Never commit `appstate.json` to version control**
215
+ - **Never share your `appstate.json` publicly**
216
+ - Add it to `.gitignore`
217
+ - Use environment variables or a secrets manager in production
287
218
 
288
219
  ---
289
220
 
290
- ## 🔐 Security, Trust & Supply Chain
221
+ ## Getting Started Generate `appstate.json`
291
222
 
292
- - Published via **GitHub Actions** using `npm publish --provenance`, so the tarball on npm can be cryptographically tied back to this repo.
293
- - Core runtime code in `module/` and `src/` is **readable JavaScript** with no obfuscated logic.
294
- - Legacy forks (such as Horizon) are kept only for reference and are **not** shipped in the npm package.
295
- - No telemetry or hidden network calls:
296
- - All HTTP traffic is implemented in `src/utils/request.js` and `module/loginHelper.js`.
297
- - External URLs (such as `apiServer` or proxies) are fully user‑configurable.
298
- - The npm publish account uses **2FA** and dedicated automation tokens.
223
+ 1. Install a cookie export extension:
224
+ - Chrome/Edge: **C3C FbState** or **CookieEditor**
225
+ - Firefox: **Cookie-Editor**
299
226
 
300
- See `SECURITY.md` for more details.
227
+ 2. Log in to Facebook in your browser
301
228
 
302
- ---
303
-
304
- ## 👂 Listening for Messages
229
+ 3. Export cookies as JSON and save as `appstate.json`:
305
230
 
306
- ### Echo Bot with Stop Command
307
-
308
- ```javascript
309
- const fs = require("fs");
310
- const login = require("@sagor/fca-unofficial");
311
-
312
- login(
313
- { appState: JSON.parse(fs.readFileSync("appstate.json", "utf8")) },
314
- (err, api) => {
315
- if (err) return console.error("Login Error:", err);
316
-
317
- // Enable listening to events (join/leave, title change, etc.)
318
- api.setOptions({ listenEvents: true });
319
-
320
- const stopListening = api.listenMqtt((err, event) => {
321
- if (err) return console.error("Listen Error:", err);
322
-
323
- // Mark as read
324
- api.markAsRead(event.threadID, (err) => {
325
- if (err) console.error("Mark as read error:", err);
326
- });
327
-
328
- // Handle different event types
329
- switch (event.type) {
330
- case "message":
331
- if (event.body && event.body.trim().toLowerCase() === "/stop") {
332
- api.sendMessage("Goodbye… 👋", event.threadID);
333
- stopListening();
334
- return;
335
- }
336
- api.sendMessage(`🤖 BOT: ${event.body}`, event.threadID);
337
- break;
338
-
339
- case "event":
340
- console.log("📢 Event Received:", event);
341
- break;
342
- }
343
- });
344
- },
345
- );
231
+ ```json
232
+ [
233
+ { "key": "c_user", "value": "your-user-id" },
234
+ { "key": "xs", "value": "your-xs-value" }
235
+ ]
346
236
  ```
347
237
 
348
- ### Listen Options
349
-
350
- Configure listening behavior:
238
+ 4. Use in your bot:
351
239
 
352
- ```javascript
353
- api.setOptions({
354
- listenEvents: true, // Receive events (join/leave, rename, etc.)
355
- selfListen: true, // Receive messages from yourself
356
- logLevel: "silent", // Disable logs (silent/error/warn/info/verbose)
357
- });
240
+ ```js
241
+ const { login } = require("sagor-fca");
242
+ const appState = require("./appstate.json");
243
+ login({ appState }, {}, (err, api) => { ... });
358
244
  ```
359
245
 
360
- ---
361
-
362
- ## 🎯 API Quick Reference
363
-
364
- _(For full details, please read the source code or `DOCS.md`)_
365
-
366
- ### 📨 Messaging
367
-
368
- `sendMessage`, `sendTypingIndicator`, `getMessage`, `editMessage`, `deleteMessage`, `unsendMessage`, `setMessageReaction`, `forwardAttachment`, `uploadAttachment`, `createPoll`
369
-
370
- ### 📬 Read Receipt & Delivery
246
+ See **[COOKIE_LOGIN.md](COOKIE_LOGIN.md)** for more formats and troubleshooting.
371
247
 
372
- `markAsRead`, `markAsReadAll`, `markAsDelivered`, `markAsSeen`
373
-
374
- ### 👥 Thread Management
375
-
376
- `getThreadInfo`, `getThreadList`, `getThreadHistory`, `deleteThread`, `changeThreadColor`, `changeThreadEmoji`, `changeGroupImage`, `setTitle`, `changeNickname`
377
-
378
- ### 👤 User & Group Management
248
+ ---
379
249
 
380
- `getUserInfo`, `getFriendsList`, `getCurrentUserID`, `createNewGroup`, `addUserToGroup`, `removeUserFromGroup`, `changeAdminStatus`
250
+ ## Bot Example with Commands
381
251
 
382
- ### ⚙️ Thread Settings & Actions
252
+ ```js
253
+ const fs = require("fs");
254
+ const path = require("path");
255
+ const { login } = require("sagor-fca");
383
256
 
384
- `muteThread`, `changeArchivedStatus`, `changeBlockedStatus`, `handleMessageRequest`, `changeAvatar`, `changeBio`, `handleFriendRequest`, `unfriend`
257
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
385
258
 
386
- ### 🔐 Auth & Listening
259
+ login({ appState }, {
260
+ online: true,
261
+ selfListen: false,
262
+ simulateTyping: true,
263
+ autoReconnect: true
264
+ }, async (err, api) => {
265
+ if (err) return console.error("Login error:", err);
387
266
 
388
- `logout`, `getAppState`, `setOptions`, `listenMqtt`
267
+ console.log("Logged in as:", api.getCurrentUserID());
389
268
 
390
- ---
391
- ## 🎛 Event Hooks & Remote Control (Advanced)
269
+ const commandsDir = path.join(__dirname, "commands");
270
+ const commands = new Map();
392
271
 
393
- Starting from `3.x`, the API instance also behaves like an **EventEmitter** for lifecycle and remote‑control events:
272
+ if (fs.existsSync(commandsDir)) {
273
+ for (const file of fs.readdirSync(commandsDir).filter(f => f.endsWith(".js"))) {
274
+ const cmd = require(path.join(commandsDir, file));
275
+ if (cmd.name && typeof cmd.execute === "function") {
276
+ commands.set(cmd.name, cmd);
277
+ }
278
+ }
279
+ }
394
280
 
395
- - **Lifecycle events**:
396
- - `sessionExpired` login session is no longer valid, auto‑login will be attempted (if configured).
397
- - `autoLoginSuccess` — auto‑login succeeded and the failed request will be retried.
398
- - `autoLoginFailed` — auto‑login could not recover the session.
399
- - `checkpoint` — generic checkpoint, with subtype in `{ type: "282" | "956" | "scraping_warning" }`.
400
- - `checkpoint_282`, `checkpoint_956` — more specific checkpoint events.
401
- - `loginBlocked` — Facebook actively blocked the login (error `1357001`).
402
- - `rateLimit` — HTTP 429 detected on Facebook endpoints.
403
- - `networkError` — network‑level failure (timeouts, DNS, connection reset, etc.).
281
+ api.listenMqtt(async (err, event) => {
282
+ if (err || event.type !== "message" || !event.body) return;
404
283
 
405
- Usage:
284
+ const prefix = "/";
285
+ if (!event.body.startsWith(prefix)) return;
406
286
 
407
- ```javascript
408
- api.on("checkpoint_956", ({ res }) => {
409
- console.error("Checkpoint 956 detected, manual action required.");
410
- });
287
+ const args = event.body.slice(prefix.length).trim().split(/ +/);
288
+ const name = args.shift().toLowerCase();
289
+ const cmd = commands.get(name);
290
+ if (!cmd) return;
411
291
 
412
- api.on("rateLimit", ({ url, method }) => {
413
- console.warn("Rate limit hit on", method, url);
292
+ try {
293
+ await cmd.execute({ api, event, args });
294
+ } catch (e) {
295
+ console.error(`Error in /${name}:`, e.message);
296
+ api.sendMessage("An error occurred.", event.threadID);
297
+ }
298
+ });
414
299
  });
415
300
  ```
416
301
 
417
- - **Remote control events** (when `remoteControl.enabled` is `true` in `fca-config.json`):
418
- - `remoteConnected` / `remoteDisconnected`
419
- - `remoteStop`
420
- - `remoteBroadcast`
421
- - `remoteMessage` (raw messages from your WS backend)
422
-
423
- See `examples/remote-control.js` for a concrete integration example.
424
-
425
302
  ---
426
303
 
427
- ## 🌐 Proxy Configuration & Broadcast Helper
428
-
429
- - **Proxy support**:
430
- - You can pass a proxy per‑login:
304
+ ## AI Themes
431
305
 
432
- ```javascript
433
- login({ appState }, (err, api) => {
434
- if (err) return console.error(err);
435
- api.setOptions({ proxy: "http://user:pass@host:port" });
436
- });
437
- ```
438
-
439
- - Or define a default in `fca-config.json`:
440
-
441
- ```json
442
- {
443
- "proxy": "http://user:pass@host:port"
306
+ ```js
307
+ // Generate an AI theme from a text prompt
308
+ const aiThemes = await api.createAITheme("vibrant ocean sunset purple");
309
+ if (aiThemes && aiThemes.length > 0) {
310
+ await api.setThreadThemeMqtt(threadID, aiThemes[0].id);
444
311
  }
445
- ```
446
-
447
- - All HTTP calls go through this proxy using `https-proxy-agent`.
448
312
 
449
- - **Broadcast helper** (optional util):
450
- - Not part of the public API surface on purpose (to avoid encouraging spam).
451
- - You can use it manually:
313
+ // Browse standard themes
314
+ const themes = await api.getTheme(threadID);
315
+ await api.setThreadThemeMqtt(threadID, themes[0].id);
452
316
 
453
- ```javascript
454
- const broadcast = require("@sagor/fca-unofficial/src/utils/broadcast");
455
-
456
- const threads = ["1000...", "2000..."];
457
- await broadcast(api, threads, { body: "Hello!" }, {
458
- delayMs: 1200,
459
- skipBlocked: true
460
- });
317
+ // Check current theme
318
+ const info = await api.getThemeInfo(threadID);
319
+ console.log(info.color, info.emoji);
461
320
  ```
462
321
 
463
322
  ---
464
323
 
465
- ## 📚 Documentation
466
-
467
- - **[DOCS.md](./DOCS.md)** — Full API reference, examples, and best practices.
468
- - **[docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)** Codebase structure and modules (for contributors).
469
- - For implementation details, the `src/` folder is the authoritative reference.
324
+ ## API Reference
325
+
326
+ ### Authentication
327
+ | Method | Description |
328
+ |---|---|
329
+ | `login(credentials, options, callback)` | Log in and receive the API object |
330
+ | `api.logout()` | End the session |
331
+ | `api.getAppState()` | Get current session cookies |
332
+ | `api.getCurrentUserID()` | Get logged-in user ID |
333
+
334
+ ### Messaging
335
+ | Method | Description |
336
+ |---|---|
337
+ | `api.sendMessage(msg, threadID)` | Send (HTTP + MQTT fallback) |
338
+ | `api.sendMessageMqtt(msg, threadID)` | Send over MQTT |
339
+ | `api.editMessage(text, messageID)` | Edit a message |
340
+ | `api.unsendMessage(messageID, threadID)` | Retract a message |
341
+ | `api.forwardMessage(messageID, threadID)` | Forward a message |
342
+ | `api.deleteMessage(messageIDs)` | Delete locally |
343
+ | `api.shareContact(senderID, threadID)` | Share a contact card |
344
+
345
+ ### Reactions & Status
346
+ | Method | Description |
347
+ |---|---|
348
+ | `api.setMessageReaction(reaction, messageID)` | React via HTTP |
349
+ | `api.setMessageReactionMqtt(reaction, messageID, threadID)` | React via MQTT |
350
+ | `api.sendTypingIndicator(isTyping, threadID)` | Show/hide typing |
351
+ | `api.markAsRead(threadID)` | Mark thread as read |
352
+ | `api.markAsReadAll()` | Mark all threads as read |
353
+ | `api.markAsSeen()` | Mark as seen |
354
+ | `api.markAsDelivered(threadID, messageID)` | Mark as delivered |
355
+
356
+ ### Threads
357
+ | Method | Description |
358
+ |---|---|
359
+ | `api.getThreadInfo(threadID)` | Thread metadata |
360
+ | `api.getThreadList(limit, timestamp, tags)` | List threads |
361
+ | `api.getThreadHistory(threadID, amount, timestamp)` | Message history |
362
+ | `api.getThreadPictures(threadID, offset, limit)` | Thread images |
363
+ | `api.searchForThread(name)` | Search by name |
364
+ | `api.createNewGroup(participantIDs, name?)` | Create group |
365
+ | `api.deleteThread(threadID)` | Delete thread |
366
+ | `api.muteThread(threadID, muteSeconds)` | Mute thread |
367
+ | `api.changeArchivedStatus(threadID, archive)` | Archive/unarchive |
368
+ | `api.pinMessage(action, threadID, messageID?)` | Pin/unpin/list |
369
+ | `api.createPoll(title, threadID, options?)` | Create poll |
370
+ | `api.handleMessageRequest(threadID, accept)` | Accept/decline |
371
+
372
+ ### Group Admin
373
+ | Method | Description |
374
+ |---|---|
375
+ | `api.addUserToGroup(userID, threadID)` | Add member |
376
+ | `api.removeUserFromGroup(userID, threadID)` | Remove member |
377
+ | `api.changeAdminStatus(threadID, userID, isAdmin)` | Promote/demote |
378
+ | `api.changeGroupImage(image, threadID)` | Group photo |
379
+ | `api.gcname(name, threadID)` | Rename group |
380
+
381
+ ### Users
382
+ | Method | Description |
383
+ |---|---|
384
+ | `api.getUserInfo(id)` | Basic user info |
385
+ | `api.getUserInfoV2(id)` | Extended user info |
386
+ | `api.getUserID(name)` | Resolve name to ID |
387
+ | `api.getFriendsList()` | Friends list |
388
+ | `api.getBotInfo()` | Bot account info |
389
+
390
+ ### Themes & Customization
391
+ | Method | Description |
392
+ |---|---|
393
+ | `api.getTheme(threadID)` | List available themes |
394
+ | `api.getThemeInfo(threadID)` | Current theme |
395
+ | `api.setThreadThemeMqtt(threadID, themeID)` | Apply theme |
396
+ | `api.createAITheme(prompt)` | AI theme |
397
+ | `api.changeThreadColor(color, threadID)` | Thread color |
398
+ | `api.changeThreadEmoji(emoji, threadID)` | Thread emoji |
399
+ | `api.nickname(nickname, threadID, participantID)` | Set nickname |
400
+ | `api.emoji(emoji, threadID)` | Thread emoji shorthand |
401
+
402
+ ### Stickers
403
+ | Method | Description |
404
+ |---|---|
405
+ | `api.stickers.search(query)` | Search stickers |
406
+ | `api.stickers.listPacks()` | Installed packs |
407
+ | `api.stickers.getStorePacks()` | Sticker store |
408
+ | `api.stickers.addPack(packID)` | Add pack |
409
+ | `api.stickers.getStickersInPack(packID)` | Stickers in pack |
410
+ | `api.stickers.getAiStickers(options?)` | AI stickers |
411
+
412
+ ### E2EE
413
+ | Method | Description |
414
+ |---|---|
415
+ | `api.e2ee.enable()` | Enable E2EE |
416
+ | `api.e2ee.disable()` | Disable E2EE |
417
+ | `api.e2ee.getPublicKey()` | Get public key |
418
+ | `api.e2ee.setPeerKey(threadID, key)` | Set peer key |
419
+ | `api.e2ee.hasPeer(threadID)` | Has peer key |
420
+ | `api.e2ee.clearPeerKey(threadID)` | Remove peer key |
421
+
422
+ ### Social
423
+ | Method | Description |
424
+ |---|---|
425
+ | `api.comment(msg, postID)` | Comment on post |
426
+ | `api.share(postID)` | Share post |
427
+ | `api.follow(userID, follow)` | Follow/unfollow |
428
+ | `api.unfriend(userID)` | Unfriend |
429
+ | `api.changeBlockedStatus(userID, block)` | Block/unblock |
430
+
431
+ ### Health
432
+ | Method | Description |
433
+ |---|---|
434
+ | `api.getHealthStatus()` | MQTT, token, rate limiter stats |
470
435
 
471
436
  ---
472
437
 
473
- ## 🛠️ Projects Using This API
474
-
475
- Here are some awesome projects built with `@sagor/fca-unofficial`:
476
- _(See [GitHub Repository](https://github.com/SAGOR-KINGx/fca-unofficial) for the full list)._
438
+ ## Login Options
439
+
440
+ | Option | Type | Default | Description |
441
+ |---|---|---|---|
442
+ | `online` | `boolean` | `true` | Appear online |
443
+ | `selfListen` | `boolean` | `false` | Receive own messages |
444
+ | `listenEvents` | `boolean` | `true` | Receive thread events |
445
+ | `listenTyping` | `boolean` | `false` | Receive typing events |
446
+ | `updatePresence` | `boolean` | `false` | Broadcast presence |
447
+ | `autoMarkDelivery` | `boolean` | `false` | Auto-mark delivered |
448
+ | `autoMarkRead` | `boolean` | `true` | Auto-mark read |
449
+ | `autoReconnect` | `boolean` | `true` | MQTT auto-reconnect |
450
+ | `simulateTyping` | `boolean` | `true` | Humanized typing delays |
451
+ | `randomUserAgent` | `boolean` | `false` | Random User-Agent |
452
+ | `persona` | `"desktop"\|"android"` | `"desktop"` | Browser persona |
453
+ | `proxy` | `string` | — | Proxy URL |
454
+ | `forceLogin` | `boolean` | `false` | Force fresh login |
455
+ | `maxConcurrentRequests` | `number` | `5` | Max parallel requests |
456
+ | `maxRequestsPerMinute` | `number` | `50` | Rate cap per minute |
457
+ | `requestCooldownMs` | `number` | `60000` | Endpoint cooldown |
458
+ | `errorCacheTtlMs` | `number` | `300000` | Error suppression TTL |
459
+ | `stealthMode` | `boolean` | `false` | Extra stealth headers |
477
460
 
478
461
  ---
479
462
 
480
- ## 🤝 Contributing
481
-
482
- Contributions are welcome! If you want to optimize something or fix a bug:
463
+ ## Examples
483
464
 
484
- 1. 🍴 Fork the repository
485
- 2. 🌿 Create a new branch
486
- 3. 💾 Commit your changes
487
- 4. 📤 Push to the branch
488
- 5. 🔄 Open a Pull Request
489
-
490
- **Rule:** Keep it clean, minimal, and performant. No bloated dependencies.
465
+ See the **[examples/](examples/)** directory:
466
+ - `simple-bot.js` Basic bot setup and message handling
467
+ - `theme-usage-example.js` Theme management
468
+ - `test-bot.js` Full-featured test bot
491
469
 
492
470
  ---
493
471
 
494
- ## 📄 License
472
+ ## Publishing
495
473
 
496
- This project is licensed under the **MIT License** - see the [LICENSE-MIT](./LICENSE-MIT) file for details.
474
+ ```bash
475
+ npm pack --dry-run
476
+ ```
497
477
 
498
478
  ---
499
479
 
500
- ## 👨‍💻 Author & Support
480
+ ## Credits
501
481
 
502
- <div align="center">
482
+ - **Developed and maintained by [SaGor](https://github.com/SAGOR-KINGx)**
483
+ - **SaGor Team** — development, maintenance, and feature contributions
484
+ - **Inspired by ws3-fca** — by @NethWs3Dev and @CommunityExocore
503
485
 
504
- **Maintained by SaGor**
486
+ > Copyright (c) 2026 SaGor
505
487
 
506
- </div>
507
-
508
- ### 🛠️ Need Custom Work?
488
+ ---
509
489
 
510
- If you have the budget and need specialized features, API reverse-engineering, or private bot development, reach out to me directly via Facebook. **Do not contact me for free coding lessons.**
490
+ ## License
511
491
 
512
- ### 🔗 Links
492
+ **MIT** Free to use, modify, and distribute. Attribution appreciated.
513
493
 
514
- - 📦 [NPM Package](https://www.npmjs.com/package/@sagor/fca-unofficial)
515
- - 🐙 [GitHub Repository](https://github.com/SAGOR- KINGx/fca-unofficial)
516
- - 🐛 [Issue Tracker](https://github.com/SAGOR-KINGx/fca-unofficial/issues)
494
+ See [LICENSE](LICENSE) for full license text.
517
495
 
518
496
  ---
519
497
 
520
- <div align="center">
521
-
522
- Made with ❤️ (and a lot of caffeine) for the developer community.
498
+ ## Links
523
499
 
524
- </div>
500
+ - **npm:** [https://www.npmjs.com/package/sagor-fca](https://www.npmjs.com/package/sagor-fca)
501
+ - **GitHub:** [https://github.com/SAGOR-KINGx](https://github.com/SAGOR-KINGx)
502
+ - **Issues:** [https://github.com/SAGOR-KINGx/sagor-fca/issues](https://github.com/SAGOR-KINGx/sagor-fca/issues)