sagor-fca 0.0.4 → 0.0.6

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 (213) hide show
  1. package/README.md +426 -0
  2. package/examples/login-with-cookies.js +38 -0
  3. package/examples/ping.js +36 -0
  4. package/examples/verify.js +69 -0
  5. package/index.js +1 -478
  6. package/package.json +73 -33
  7. package/src/{addExternalModule.js → api/addExternalModule.js} +1 -2
  8. package/src/api/addUserToGroup.js +108 -0
  9. package/src/api/changeAdminStatus.js +148 -0
  10. package/src/api/changeArchivedStatus.js +61 -0
  11. package/src/api/changeAvatar.js +103 -0
  12. package/src/api/changeBio.js +69 -0
  13. package/src/api/changeBlockedStatus.js +54 -0
  14. package/src/api/changeGroupImage.js +136 -0
  15. package/src/api/changeThreadColor.js +116 -0
  16. package/src/{changeThreadEmoji.js → api/changeThreadEmoji.js} +1 -3
  17. package/src/api/comment.js +207 -0
  18. package/src/api/createAITheme.js +129 -0
  19. package/src/api/createNewGroup.js +79 -0
  20. package/src/api/createPoll.js +73 -0
  21. package/src/api/deleteMessage.js +44 -0
  22. package/src/api/deleteThread.js +52 -0
  23. package/src/api/e2ee.js +17 -0
  24. package/src/{editMessage.js → api/editMessage.js} +10 -8
  25. package/src/api/emoji.js +124 -0
  26. package/src/api/fetchThemeData.js +82 -0
  27. package/src/{follow.js → api/follow.js} +15 -8
  28. package/src/api/forwardMessage.js +52 -0
  29. package/src/api/friend.js +243 -0
  30. package/src/api/gcmember.js +122 -0
  31. package/src/api/gcname.js +123 -0
  32. package/src/api/gcrule.js +119 -0
  33. package/src/{getAccess.js → api/getAccess.js} +3 -4
  34. package/src/api/getBotInfo.js +88 -0
  35. package/src/{getBotInitialData.js → api/getBotInitialData.js} +2 -1
  36. package/src/api/getFriendsList.js +79 -0
  37. package/src/api/getMessage.js +423 -0
  38. package/src/api/getTheme.js +95 -0
  39. package/src/api/getThemeInfo.js +116 -0
  40. package/src/api/getThreadHistory.js +239 -0
  41. package/src/api/getThreadInfo.js +267 -0
  42. package/src/api/getThreadList.js +232 -0
  43. package/src/api/getThreadPictures.js +58 -0
  44. package/src/api/getUserID.js +117 -0
  45. package/src/api/getUserInfo.js +513 -0
  46. package/src/api/getUserInfoV2.js +146 -0
  47. package/src/api/handleMessageRequest.js +50 -0
  48. package/src/api/httpGet.js +63 -0
  49. package/src/api/httpPost.js +89 -0
  50. package/src/{httpPostFormData.js → api/httpPostFormData.js} +2 -3
  51. package/src/api/listenMqtt.js +892 -0
  52. package/src/api/listenSpeed.js +179 -0
  53. package/src/api/logout.js +63 -0
  54. package/src/api/markAsDelivered.js +47 -0
  55. package/src/api/markAsRead.js +95 -0
  56. package/src/api/markAsReadAll.js +40 -0
  57. package/src/api/markAsSeen.js +70 -0
  58. package/src/api/mqttDeltaValue.js +278 -0
  59. package/src/api/muteThread.js +45 -0
  60. package/src/api/nickname.js +132 -0
  61. package/src/api/notes.js +163 -0
  62. package/src/api/pinMessage.js +150 -0
  63. package/src/api/produceMetaTheme.js +180 -0
  64. package/src/api/realtime.js +182 -0
  65. package/src/api/removeUserFromGroup.js +117 -0
  66. package/src/api/resolvePhotoUrl.js +58 -0
  67. package/src/api/searchForThread.js +154 -0
  68. package/src/api/sendMessage.js +354 -0
  69. package/src/api/sendMessageMqtt.js +249 -0
  70. package/src/api/sendTypingIndicator.js +48 -0
  71. package/src/api/setMessageReaction.js +27 -0
  72. package/src/api/setMessageReactionMqtt.js +61 -0
  73. package/src/api/setThreadTheme.js +260 -0
  74. package/src/{setThreadTheme.js → api/setThreadThemeMqtt.js} +26 -35
  75. package/src/api/share.js +107 -0
  76. package/src/api/shareContact.js +66 -0
  77. package/src/api/stickers.js +257 -0
  78. package/src/api/story.js +181 -0
  79. package/src/api/theme.js +233 -0
  80. package/src/api/unfriend.js +47 -0
  81. package/src/api/unsendMessage.js +17 -0
  82. package/src/database/appStateBackup.js +189 -0
  83. package/src/database/models/index.js +56 -0
  84. package/src/database/models/s +0 -0
  85. package/src/database/models/thread.js +31 -0
  86. package/src/database/models/user.js +32 -0
  87. package/src/database/threadData.js +101 -0
  88. package/src/database/userData.js +90 -0
  89. package/src/engine/client.js +92 -0
  90. package/src/engine/models/buildAPI.js +113 -0
  91. package/src/engine/models/loginHelper.js +487 -0
  92. package/src/engine/models/s +0 -0
  93. package/src/engine/models/setOptions.js +88 -0
  94. package/src/security/e2ee.js +109 -0
  95. package/src/types/index.d.ts +498 -0
  96. package/src/utils/antiSuspension.js +516 -0
  97. package/src/utils/auth-helpers.js +149 -0
  98. package/src/utils/autoReLogin.js +233 -0
  99. package/src/utils/axios.js +368 -0
  100. package/src/utils/cache.js +54 -0
  101. package/src/utils/clients.js +279 -0
  102. package/src/utils/constants.js +409 -0
  103. package/src/utils/formatters/data/formatAttachment.js +370 -0
  104. package/src/utils/formatters/data/formatDelta.js +109 -0
  105. package/src/utils/formatters/index.js +159 -0
  106. package/src/utils/formatters/value/formatCookie.js +91 -0
  107. package/src/utils/formatters/value/formatDate.js +36 -0
  108. package/src/utils/formatters/value/formatID.js +16 -0
  109. package/src/utils/formatters.js +1369 -0
  110. package/src/utils/headers.js +235 -0
  111. package/src/utils/index.js +153 -0
  112. package/src/utils/monitoring.js +333 -0
  113. package/src/utils/rateLimiter.js +251 -0
  114. package/src/utils/tokenRefresh.js +291 -0
  115. package/src/utils/user-agents.js +238 -0
  116. package/src/utils/validation.js +157 -0
  117. package/src/OldMessage.js +0 -329
  118. package/src/Screenshot.js +0 -83
  119. package/src/addUserToGroup.js +0 -115
  120. package/src/changeAdminStatus.js +0 -103
  121. package/src/changeArchivedStatus.js +0 -55
  122. package/src/changeAvatar.js +0 -136
  123. package/src/changeAvatarV2.js +0 -86
  124. package/src/changeAvt.js +0 -85
  125. package/src/changeBio.js +0 -76
  126. package/src/changeBlockedStatus.js +0 -49
  127. package/src/changeBlockedStatusMqtt.js +0 -80
  128. package/src/changeCover.js +0 -72
  129. package/src/changeGroupImage.js +0 -135
  130. package/src/changeName.js +0 -79
  131. package/src/changeNickname.js +0 -59
  132. package/src/changeThreadColor.js +0 -65
  133. package/src/changeUsername.js +0 -59
  134. package/src/createCommentPost.js +0 -230
  135. package/src/createNewGroup.js +0 -88
  136. package/src/createPoll.js +0 -71
  137. package/src/createPost.js +0 -276
  138. package/src/data/cache/data.json +0 -4
  139. package/src/data/cache/datahandle.js +0 -21
  140. package/src/data/getThreadInfo.json +0 -1
  141. package/src/deleteMessage.js +0 -56
  142. package/src/deleteThread.js +0 -56
  143. package/src/editMessageOld.js +0 -67
  144. package/src/forwardAttachment.js +0 -60
  145. package/src/friendList.js +0 -103
  146. package/src/getAvatarUser.js +0 -78
  147. package/src/getCtx.js +0 -5
  148. package/src/getCurrentUserID.js +0 -7
  149. package/src/getEmojiUrl.js +0 -29
  150. package/src/getFriendsList.js +0 -83
  151. package/src/getMessage.js +0 -847
  152. package/src/getOptions.js +0 -5
  153. package/src/getRegion.js +0 -7
  154. package/src/getThreadHistory.js +0 -680
  155. package/src/getThreadHistoryDeprecated.js +0 -71
  156. package/src/getThreadInfo.js +0 -232
  157. package/src/getThreadInfoDeprecated.js +0 -56
  158. package/src/getThreadList.js +0 -213
  159. package/src/getThreadListDeprecated.js +0 -46
  160. package/src/getThreadPictures.js +0 -59
  161. package/src/getThreadTheme.js +0 -82
  162. package/src/getUID.js +0 -119
  163. package/src/getUserID.js +0 -61
  164. package/src/getUserInfo.js +0 -66
  165. package/src/handleFriendRequest.js +0 -46
  166. package/src/handleMessageRequest.js +0 -47
  167. package/src/httpGet.js +0 -49
  168. package/src/httpPost.js +0 -48
  169. package/src/listenMqtt.js +0 -870
  170. package/src/listenNotification.js +0 -85
  171. package/src/logout.js +0 -75
  172. package/src/markAsDelivered.js +0 -47
  173. package/src/markAsRead.js +0 -70
  174. package/src/markAsReadAll.js +0 -40
  175. package/src/markAsSeen.js +0 -48
  176. package/src/metaTheme.js +0 -190
  177. package/src/muteThread.js +0 -45
  178. package/src/note.js +0 -228
  179. package/src/pinMessage.js +0 -59
  180. package/src/refreshFb_dtsg.js +0 -89
  181. package/src/removeSuspiciousAccount.js +0 -79
  182. package/src/removeUserFromGroup.js +0 -79
  183. package/src/reply.js +0 -442
  184. package/src/resolvePhotoUrl.js +0 -45
  185. package/src/searchForThread.js +0 -53
  186. package/src/searchFriends.js +0 -139
  187. package/src/searchStickers.js +0 -53
  188. package/src/send.js +0 -46
  189. package/src/sendComment.js +0 -159
  190. package/src/sendFriendRequest.js +0 -102
  191. package/src/sendMessage.js +0 -243
  192. package/src/sendMessageMqtt.js +0 -322
  193. package/src/sendTypingIndicator.js +0 -101
  194. package/src/sendTypingIndicatorV2.js +0 -28
  195. package/src/setActiveStatus.js +0 -93
  196. package/src/setMessageReaction.js +0 -122
  197. package/src/setMessageReactionMqtt.js +0 -62
  198. package/src/setPostReaction.js +0 -112
  199. package/src/setProfileGuard.js +0 -44
  200. package/src/setProfileLock.js +0 -98
  201. package/src/setStoryReaction.js +0 -134
  202. package/src/setStorySeen.js +0 -109
  203. package/src/setTitle.js +0 -90
  204. package/src/shareContact.js +0 -110
  205. package/src/shareLink.js +0 -59
  206. package/src/stopListenMqtt.js +0 -23
  207. package/src/storyManager.js +0 -358
  208. package/src/suggestFriend.js +0 -133
  209. package/src/threadColors.js +0 -131
  210. package/src/unfriend.js +0 -52
  211. package/src/unsendMessage.js +0 -45
  212. package/src/uploadAttachment.js +0 -93
  213. package/utils.js +0 -2867
package/README.md ADDED
@@ -0,0 +1,426 @@
1
+ # 💬 sagor-fca
2
+
3
+ <div align="center">
4
+
5
+ **Unofficial Facebook Chat API for Node.js**
6
+
7
+ </div>
8
+
9
+ ---
10
+
11
+ ## 📋 Table of Contents
12
+
13
+ - [⚠️ Disclaimer & Support Policy](#️-disclaimer--support-policy)
14
+ - [✨ Features](#-features)
15
+ - [🚀 Quick Start](#-quick-start)
16
+ - [📚 API Reference](#-api-reference)
17
+ - [💾 AppState Management](#-appstate-management)
18
+ - [🔄 Auto Login](#-auto-login)
19
+ - [🔐 Security & Anti-Ban](#-security--anti-ban)
20
+ - [🤝 Contributing](#-contributing)
21
+ - [📄 License](#-license)
22
+ - [👨‍💻 Author](#-author)
23
+
24
+ ---
25
+
26
+ ## ⚠️ Disclaimer & Support Policy
27
+
28
+ <div align="center">
29
+
30
+ **READ THIS BEFORE USING OR OPENING AN ISSUE.**
31
+
32
+ </div>
33
+
34
+ This repository is provided **"AS IS"** and is entirely open-source. By using this project, you explicitly agree to the following terms:
35
+
36
+ 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).
37
+ 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.
38
+ 3. **No Free Programming Lessons:** The maintainers provide core updates and security patches for the community for free. We do **not** provide free JavaScript/TypeScript tutorials, nor will we tell you exactly which line of code to edit for your specific bot.
39
+ 4. **Custom Features = Paid Service:** Brainpower and time are not free. If you need custom logic, reverse-engineer specific endpoints, or 1-on-1 support for your personal project, **that is a paid service**.
40
+
41
+ If you do not agree with this policy, you are free to fork the repository and maintain it yourself.
42
+
43
+ **Recommendations to minimize ban risks:**
44
+
45
+ - Utilize **AppState** over direct email/password authentication whenever possible.
46
+ - Implement strict **rate limiting** within your bot's operations.
47
+ - Ensure your application adheres to Facebook's platform policies.
48
+
49
+ ---
50
+
51
+ ## ✨ Features
52
+
53
+ This **sagor-fca** extends the base functionality with advanced features for a more robust and versatile Facebook automation experience:
54
+
55
+ **Authentication**
56
+ - Cookie array login (`appState`) — the safest method for long-running bots
57
+ - Email/password login with TOTP/2FA support
58
+ - Session fingerprint locking — User-Agent, Sec-Ch-Ua, locale, timezone locked per session to prevent detection
59
+ - AppState auto-backup and restore on restart
60
+
61
+ **Real-time Messaging**
62
+ - MQTT and HTTP messaging with automatic protocol fallback
63
+ - Send text, attachments, stickers, emoji, mentions, and location
64
+ - Message editing, unsend, forward, and delete
65
+ - Message reactions via HTTP and MQTT
66
+ - Pin/unpin messages, list pinned messages
67
+
68
+ **Anti-Suspension System**
69
+ - Circuit breaker — halts activity after repeated suspension signals, resumes after cooldown
70
+ - 60+ suspension signal patterns: checkpoints, spam flags, rate limits, identity verification, policy violations, session expiry, and more
71
+ - Adaptive per-thread delay that increases with session volume
72
+ - Hourly and daily message volume limits with automatic warning pauses
73
+ - Warmup mode for fresh sessions — gradually increases allowed message rate
74
+ - Humanized typing simulation before every send
75
+ - Randomized request intervals and jitter to avoid periodicity detection
76
+ - Session fingerprint locking to maintain consistent browser identity
77
+ - PostSafe guard: detects auth failures and checkpoint responses in real-time
78
+ - MQTT watchdog: detects stale connections and forces clean reconnect
79
+
80
+ **Stability & Reliability**
81
+ - MQTT auto-reconnect with exponential backoff and jitter
82
+ - Auto re-login using refreshed AppState when session expires
83
+ - TokenRefreshManager with randomized intervals to keep sessions alive
84
+ - Sliding-window rate limiter with per-endpoint tracking
85
+ - SQLite-backed thread and user data cache for fast lookups
86
+
87
+ **Thread & Group Management**
88
+ - Get thread info, history, pictures, and lists
89
+ - Create groups, add/remove members, change admin status
90
+ - Update group image, name, color, emoji
91
+ - Archive, mute, delete threads
92
+ - Create polls, manage notes and rules
93
+ - Search threads by name, handle message requests
94
+
95
+ **User & Friends**
96
+ - Get user info (basic and extended), resolve user IDs
97
+ - Get full friends list, send/cancel friend requests, unfriend, block/unblock
98
+
99
+ **Social**
100
+ - Comment on posts, share posts, follow/unfollow users
101
+
102
+ **Themes & Stickers**
103
+ - Browse 90+ Messenger themes, apply themes via MQTT
104
+ - Generate AI-powered themes with text prompts
105
+ - Search stickers, browse packs, add packs, get AI stickers
106
+
107
+ **E2EE (Opt-In)**
108
+ - Application-layer end-to-end encryption for DMs using X25519 + HKDF + AES-256-GCM
109
+
110
+ **Monitoring**
111
+ - `api.getHealthStatus()` — MQTT status, token refresh stats, rate limiter metrics
112
+ - Built-in `ProductionMonitor` for request/error/performance telemetry
113
+
114
+ **Proxy Support**
115
+ - Full proxy support via the `proxy` login option
116
+
117
+ ---
118
+
119
+ ## 🚀 Quick Start
120
+
121
+ ### Installation
122
+
123
+ To install `sagor-fca`, ensure you have Node.js (version 12.0.0 or higher) installed. Then, use npm:
124
+
125
+ ```bash
126
+ npm install sagor-fca
127
+ ```
128
+
129
+ ### Basic Usage (Echo Bot)
130
+
131
+ Here's a simple example to get started with an echo bot:
132
+
133
+ ```javascript
134
+ const login = require("sagor-fca");
135
+
136
+ login({ appState: [] }, (err, api) => {
137
+ if (err) return console.error(err);
138
+
139
+ api.listenMqtt((err, event) => {
140
+ if (err) return console.error(err);
141
+
142
+ if (event.type === "message") {
143
+ api.sendMessage(event.body, event.threadID);
144
+ }
145
+ });
146
+ });
147
+ ```
148
+
149
+ ### Sending a Text Message
150
+
151
+ ```javascript
152
+ const login = require("sagor-fca");
153
+
154
+ login({ appState: [] }, (err, api) => {
155
+ if (err) {
156
+ console.error("Login Error:", err);
157
+ return;
158
+ }
159
+
160
+ const yourID = "000000000000000"; // Replace with actual Facebook ID
161
+ const msg = "Hello from Sagor-fca! 👋";
162
+
163
+ api.sendMessage(msg, yourID, (err) => {
164
+ if (err) console.error("Message Sending Error:", err);
165
+ else console.log("✅ Message sent successfully!");
166
+ });
167
+ });
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Anti-Suspension Configuration
173
+
174
+ The anti-suspension system is active by default. You can tune it through login options:
175
+
176
+ ```js
177
+ login({ appState }, {
178
+ autoReconnect: true,
179
+ listenEvents: true,
180
+ autoMarkRead: true,
181
+ simulateTyping: true, // humanized typing delays before send
182
+ randomUserAgent: true, // rotate user agent on each session
183
+ persona: "desktop", // "desktop" or "android"
184
+ maxConcurrentRequests: 5, // max parallel HTTP requests
185
+ maxRequestsPerMinute: 50, // sliding-window rate cap
186
+ requestCooldownMs: 60000, // per-endpoint cooldown duration
187
+ errorCacheTtlMs: 300000 // how long to suppress repeated errors
188
+ }, (err, api) => {
189
+ if (err) throw err;
190
+
191
+ console.log(api.getHealthStatus());
192
+ });
193
+ ```
194
+
195
+
196
+ ## API Reference
197
+
198
+ ### Authentication
199
+ | Method | Description |
200
+ |---|---|
201
+ | `login(credentials, options, callback)` | Log in and receive the API object |
202
+ | `api.logout()` | End the session |
203
+ | `api.getAppState()` | Get current session cookies |
204
+ | `api.getCurrentUserID()` | Get logged-in user ID |
205
+
206
+ ### Messaging
207
+ | Method | Description |
208
+ |---|---|
209
+ | `api.sendMessage(msg, threadID)` | Send (HTTP + MQTT fallback) |
210
+ | `api.sendMessageMqtt(msg, threadID)` | Send over MQTT |
211
+ | `api.editMessage(text, messageID)` | Edit a message |
212
+ | `api.unsendMessage(messageID, threadID)` | Retract a message |
213
+ | `api.forwardMessage(messageID, threadID)` | Forward a message |
214
+ | `api.deleteMessage(messageIDs)` | Delete locally |
215
+ | `api.shareContact(senderID, threadID)` | Share a contact card |
216
+
217
+ ### Reactions & Status
218
+ | Method | Description |
219
+ |---|---|
220
+ | `api.setMessageReaction(reaction, messageID)` | React via HTTP |
221
+ | `api.setMessageReactionMqtt(reaction, messageID, threadID)` | React via MQTT |
222
+ | `api.sendTypingIndicator(isTyping, threadID)` | Show/hide typing |
223
+ | `api.markAsRead(threadID)` | Mark thread as read |
224
+ | `api.markAsReadAll()` | Mark all threads as read |
225
+ | `api.markAsSeen()` | Mark as seen |
226
+ | `api.markAsDelivered(threadID, messageID)` | Mark as delivered |
227
+
228
+ ### Threads
229
+ | Method | Description |
230
+ |---|---|
231
+ | `api.getThreadInfo(threadID)` | Thread metadata |
232
+ | `api.getThreadList(limit, timestamp, tags)` | List threads |
233
+ | `api.getThreadHistory(threadID, amount, timestamp)` | Message history |
234
+ | `api.getThreadPictures(threadID, offset, limit)` | Thread images |
235
+ | `api.searchForThread(name)` | Search by name |
236
+ | `api.createNewGroup(participantIDs, name?)` | Create group |
237
+ | `api.deleteThread(threadID)` | Delete thread |
238
+ | `api.muteThread(threadID, muteSeconds)` | Mute thread |
239
+ | `api.changeArchivedStatus(threadID, archive)` | Archive/unarchive |
240
+ | `api.pinMessage(action, threadID, messageID?)` | Pin/unpin/list |
241
+ | `api.createPoll(title, threadID, options?)` | Create poll |
242
+ | `api.handleMessageRequest(threadID, accept)` | Accept/decline |
243
+
244
+ ### Group Admin
245
+ | Method | Description |
246
+ |---|---|
247
+ | `api.addUserToGroup(userID, threadID)` | Add member |
248
+ | `api.removeUserFromGroup(userID, threadID)` | Remove member |
249
+ | `api.changeAdminStatus(threadID, userID, isAdmin)` | Promote/demote |
250
+ | `api.changeGroupImage(image, threadID)` | Group photo |
251
+ | `api.gcname(name, threadID)` | Rename group |
252
+
253
+ ### Users
254
+ | Method | Description |
255
+ |---|---|
256
+ | `api.getUserInfo(id)` | Basic user info |
257
+ | `api.getUserInfoV2(id)` | Extended user info |
258
+ | `api.getUserID(name)` | Resolve name to ID |
259
+ | `api.getFriendsList()` | Friends list |
260
+ | `api.getBotInfo()` | Bot account info |
261
+
262
+ ### Themes & Customization
263
+ | Method | Description |
264
+ |---|---|
265
+ | `api.getTheme(threadID)` | List available themes |
266
+ | `api.getThemeInfo(threadID)` | Current theme |
267
+ | `api.setThreadThemeMqtt(threadID, themeID)` | Apply theme |
268
+ | `api.createAITheme(prompt)` | AI theme |
269
+ | `api.changeThreadColor(color, threadID)` | Thread color |
270
+ | `api.changeThreadEmoji(emoji, threadID)` | Thread emoji |
271
+ | `api.nickname(nickname, threadID, participantID)` | Set nickname |
272
+ | `api.emoji(emoji, threadID)` | Thread emoji shorthand |
273
+
274
+ ### Stickers
275
+ | Method | Description |
276
+ |---|---|
277
+ | `api.stickers.search(query)` | Search stickers |
278
+ | `api.stickers.listPacks()` | Installed packs |
279
+ | `api.stickers.getStorePacks()` | Sticker store |
280
+ | `api.stickers.addPack(packID)` | Add pack |
281
+ | `api.stickers.getStickersInPack(packID)` | Stickers in pack |
282
+ | `api.stickers.getAiStickers(options?)` | AI stickers |
283
+
284
+ ### E2EE
285
+ | Method | Description |
286
+ |---|---|
287
+ | `api.e2ee.enable()` | Enable E2EE |
288
+ | `api.e2ee.disable()` | Disable E2EE |
289
+ | `api.e2ee.getPublicKey()` | Get public key |
290
+ | `api.e2ee.setPeerKey(threadID, key)` | Set peer key |
291
+ | `api.e2ee.hasPeer(threadID)` | Has peer key |
292
+ | `api.e2ee.clearPeerKey(threadID)` | Remove peer key |
293
+
294
+ ### Social
295
+ | Method | Description |
296
+ |---|---|
297
+ | `api.comment(msg, postID)` | Comment on post |
298
+ | `api.share(postID)` | Share post |
299
+ | `api.follow(userID, follow)` | Follow/unfollow |
300
+ | `api.unfriend(userID)` | Unfriend |
301
+ | `api.changeBlockedStatus(userID, block)` | Block/unblock |
302
+
303
+ ### Health
304
+ | Method | Description |
305
+ |---|---|
306
+ | `api.getHealthStatus()` | MQTT, token, rate limiter stats |
307
+
308
+ ---
309
+
310
+ ## Login Options
311
+
312
+ | Option | Type | Default | Description |
313
+ |---|---|---|---|
314
+ | `online` | `boolean` | `true` | Appear online |
315
+ | `selfListen` | `boolean` | `false` | Receive own messages |
316
+ | `listenEvents` | `boolean` | `true` | Receive thread events |
317
+ | `listenTyping` | `boolean` | `false` | Receive typing events |
318
+ | `updatePresence` | `boolean` | `false` | Broadcast presence |
319
+ | `autoMarkDelivery` | `boolean` | `false` | Auto-mark delivered |
320
+ | `autoMarkRead` | `boolean` | `true` | Auto-mark read |
321
+ | `autoReconnect` | `boolean` | `true` | MQTT auto-reconnect |
322
+ | `simulateTyping` | `boolean` | `true` | Humanized typing delays |
323
+ | `randomUserAgent` | `boolean` | `false` | Random User-Agent |
324
+ | `persona` | `"desktop"\|"android"` | `"desktop"` | Browser persona |
325
+ | `proxy` | `string` | — | Proxy URL |
326
+ | `forceLogin` | `boolean` | `false` | Force fresh login |
327
+ | `maxConcurrentRequests` | `number` | `5` | Max parallel requests |
328
+ | `maxRequestsPerMinute` | `number` | `50` | Rate cap per minute |
329
+ | `requestCooldownMs` | `number` | `60000` | Endpoint cooldown |
330
+ | `errorCacheTtlMs` | `number` | `300000` | Error suppression TTL |
331
+ | `stealthMode` | `boolean` | `false` | Extra stealth headers |
332
+
333
+ ---
334
+
335
+
336
+ ## 💾 AppState Management
337
+
338
+ AppState is crucial for maintaining login sessions without re-authenticating with email/password. It helps prevent frequent logouts and reduces the risk of account flags.
339
+
340
+ ### Saving AppState
341
+
342
+ ```javascript
343
+ const fs = require("fs");
344
+ const login = require("sagor-fca");
345
+
346
+ login({ email: "YOUR_EMAIL", password: "YOUR_PASSWORD" }, (err, api) => {
347
+ if (err) {
348
+ console.error("Login Error:", err);
349
+ return;
350
+ }
351
+
352
+ try {
353
+ const appState = JSON.stringify(api.getAppState(), null, 2);
354
+ fs.writeFileSync("appstate.json", appState);
355
+ console.log("✅ AppState saved successfully!");
356
+ } catch (error) {
357
+ console.error("❌ Error saving AppState:", error);
358
+ }
359
+ });
360
+ ```
361
+
362
+ ### Using Saved AppState
363
+
364
+ ```javascript
365
+ const fs = require("fs");
366
+ const login = require("sagor-fca");
367
+
368
+ login(
369
+ { appState: JSON.parse(fs.readFileSync("appstate.json", "utf8")) },
370
+ (err, api) => {
371
+ if (err) {
372
+ console.error("Login Error:", err);
373
+ return;
374
+ }
375
+
376
+ console.log("✅ Logged in successfully using AppState!");
377
+ // Your bot logic here
378
+ },
379
+ );
380
+ ```
381
+
382
+ ---
383
+
384
+ ## 🔄 Auto Login
385
+
386
+ This library supports automatic re-login if your session expires, ensuring continuous operation of your bot. Configure `fca-config.json` in your project root:
387
+
388
+ ```json
389
+ {
390
+ "autoLogin": true,
391
+ "credentials": {
392
+ "email": "YOUR_EMAIL_OR_PHONE",
393
+ "password": "YOUR_PASSWORD",
394
+ "twofactor": "" // Base32 secret for 2FA, leave empty if not used
395
+ }
396
+ }
397
+ ```
398
+
399
+ If `autoLogin` is `true` and credentials are provided, the library will attempt to re-authenticate if the current session becomes invalid.
400
+
401
+ ---
402
+
403
+ ## 🔐 Security & Anti-Ban
404
+
405
+ To enhance the longevity and stability of your bot, `sagor-fca` includes built-in anti-ban measures:
406
+
407
+ - **Request Throttling:** A default delay of 500ms is introduced between API requests. This can be configured in `src/utils/request/config.js` via `requestThrottlingMs`.
408
+ - **User-Agent Rotation:** The library automatically rotates through a list of up-to-date browser User-Agents (as of March 2026) to mimic legitimate browser traffic, reducing the likelihood of detection and blocking by Facebook.
409
+
410
+ ---
411
+
412
+ ## 🤝 Contributing
413
+
414
+ Contributions are welcome! If you have suggestions for improvements, new features, or bug fixes, please feel free to open an issue or submit a pull request to the repository.
415
+
416
+ ---
417
+
418
+ ## 📄 License
419
+
420
+ This project is open-source and available under the [MIT License](LICENSE).
421
+
422
+ ---
423
+
424
+ ## 👨‍💻 Author
425
+
426
+ Developed and maintained by **SAGOR**.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ /**
5
+ * Example: Login with Cookie Array
6
+ *
7
+ * Demonstrates how to authenticate using a browser cookie array
8
+ * instead of email/password credentials.
9
+ *
10
+ * Usage:
11
+ * 1. Export cookies from your browser (c_user, xs, fr, datr)
12
+ * 2. Replace the placeholder values below
13
+ * 3. Run: node examples/login-with-cookies.js
14
+ */
15
+
16
+ const { login } = require("goat-fca");
17
+
18
+ const cookieArray = [
19
+ { name: "c_user", value: "YOUR_USER_ID_HERE" },
20
+ { name: "xs", value: "YOUR_XS_TOKEN_HERE" },
21
+ { name: "fr", value: "YOUR_FR_TOKEN_HERE" },
22
+ { name: "datr", value: "YOUR_DATR_TOKEN_HERE" }
23
+ ];
24
+
25
+ login({ appState: cookieArray }, {
26
+ listenEvents: true,
27
+ autoMarkRead: true,
28
+ selfListen: false
29
+ }, (err, api) => {
30
+ if (err) return console.error("Login failed:", err);
31
+
32
+ console.log("Logged in as:", api.getCurrentUserID());
33
+
34
+ api.listenMqtt((err, event) => {
35
+ if (err || event.type !== "message" || !event.body) return;
36
+ console.log("Message from", event.senderID, ":", event.body);
37
+ });
38
+ });
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ /**
5
+ * Example: Simple Ping Bot
6
+ *
7
+ * Listens for "/ping" in any thread and replies with "pong!".
8
+ *
9
+ * Usage:
10
+ * 1. Save your cookies to appstate.json
11
+ * 2. Run: node examples/ping.js
12
+ */
13
+
14
+ const fs = require("fs");
15
+ const { login } = require("goat-fca");
16
+
17
+ const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
18
+
19
+ login({ appState }, {
20
+ online: true,
21
+ listenEvents: true,
22
+ autoReconnect: true,
23
+ simulateTyping: true
24
+ }, (err, api) => {
25
+ if (err) return console.error("Login error:", err);
26
+
27
+ console.log("Logged in as:", api.getCurrentUserID());
28
+
29
+ api.listenMqtt((err, event) => {
30
+ if (err || event.type !== "message" || !event.body) return;
31
+
32
+ if (event.body.toLowerCase() === "/ping") {
33
+ api.sendMessage("pong!", event.threadID);
34
+ }
35
+ });
36
+ });
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ /**
5
+ * Quick sanity check — verifies the library loads correctly and
6
+ * prints the anti-suspension and rate limiter configuration. Run with:
7
+ * node examples/verify.js
8
+ */
9
+
10
+ const fca = require("goat-fca");
11
+ const { globalAntiSuspension } = require("goat-fca/src/utils/antiSuspension");
12
+ const { globalRateLimiter } = require("goat-fca/src/utils/rateLimiter");
13
+
14
+ console.log("goat-fca Library Verification");
15
+ console.log("==============================\n");
16
+
17
+ console.log("Library entry point:", typeof fca.login === "function" ? "OK" : "FAIL");
18
+
19
+ const config = globalAntiSuspension.getConfig();
20
+ console.log("\nAnti-Suspension Configuration:");
21
+ console.log(` Message Delay : ${config.messageDelayMs}ms`);
22
+ console.log(` Thread Delay : ${config.threadDelayMs}ms`);
23
+ console.log(` Max Login Tries : ${config.maxLoginAttempts}`);
24
+ console.log(` Login Cooldown : ${config.loginCooldownMs}ms`);
25
+ console.log(` Daily Msg Limit : ${config.dailyStats.maxDailyMessages}`);
26
+ console.log(` Hourly Msg Limit : ${config.hourlyStats.maxPerHour}`);
27
+
28
+ console.log("\nEnabled Features:");
29
+ Object.entries(config.features).forEach(([feature, enabled]) => {
30
+ console.log(` ${enabled ? "[x]" : "[ ]"} ${feature}`);
31
+ });
32
+
33
+ const activityPattern = globalAntiSuspension.getRealisticActivityPattern();
34
+ console.log("\nActivity Pattern:");
35
+ console.log(` Current activity : ${activityPattern.messageFrequency}`);
36
+ console.log(` Next action delay : ${activityPattern.nextActionDelayMs.toFixed(0)}ms`);
37
+ console.log(` Is active hours : ${activityPattern.isActiveHours}`);
38
+
39
+ console.log("\nCircuit Breaker:");
40
+ console.log(` Tripped : ${globalAntiSuspension.isCircuitBreakerTripped()}`);
41
+ console.log(` Signal count : ${globalAntiSuspension.suspensionCircuitBreaker.signalCount}`);
42
+
43
+ const rateLimiterStats = globalRateLimiter.getStats();
44
+ console.log("\nRate Limiter:");
45
+ console.log(` Max concurrent : ${rateLimiterStats.maxConcurrentRequests}`);
46
+ console.log(` Max per minute : ${rateLimiterStats.maxRequestsPerMinute}`);
47
+ console.log(` Requests (1 min) : ${rateLimiterStats.requestsInLastMinute}`);
48
+
49
+ const testSignals = [
50
+ { text: "Everything is fine, message sent", expectSuspicion: false },
51
+ { text: "Your account has been suspended due to policy violation", expectSuspicion: true },
52
+ { text: "checkpoint required to verify identity", expectSuspicion: true },
53
+ { text: "Too many requests - rate limited", expectSuspicion: true },
54
+ { text: "Unusual activity detected on your account", expectSuspicion: true },
55
+ ];
56
+ console.log("\nSuspension Signal Detection:");
57
+ testSignals.forEach(({ text, expectSuspicion }) => {
58
+ globalAntiSuspension.resetCircuitBreaker();
59
+ const detected = globalAntiSuspension.detectSuspensionSignal(text);
60
+ const passed = detected === expectSuspicion;
61
+ globalAntiSuspension.resetCircuitBreaker();
62
+ console.log(` ${passed ? "[x]" : "[!]"} "${text.substring(0, 40)}" → ${detected ? "SUSPICIOUS" : "CLEAN"}`);
63
+ });
64
+ globalAntiSuspension.resetCircuitBreaker();
65
+
66
+ console.log("\nAll checks passed. Library is ready to use.");
67
+ console.log("==============================\n");
68
+
69
+ process.exit(0);