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.
- package/README.md +426 -0
- package/examples/login-with-cookies.js +38 -0
- package/examples/ping.js +36 -0
- package/examples/verify.js +69 -0
- package/index.js +1 -478
- package/package.json +73 -33
- package/src/{addExternalModule.js → api/addExternalModule.js} +1 -2
- package/src/api/addUserToGroup.js +108 -0
- package/src/api/changeAdminStatus.js +148 -0
- package/src/api/changeArchivedStatus.js +61 -0
- package/src/api/changeAvatar.js +103 -0
- package/src/api/changeBio.js +69 -0
- package/src/api/changeBlockedStatus.js +54 -0
- package/src/api/changeGroupImage.js +136 -0
- package/src/api/changeThreadColor.js +116 -0
- package/src/{changeThreadEmoji.js → api/changeThreadEmoji.js} +1 -3
- package/src/api/comment.js +207 -0
- package/src/api/createAITheme.js +129 -0
- package/src/api/createNewGroup.js +79 -0
- package/src/api/createPoll.js +73 -0
- package/src/api/deleteMessage.js +44 -0
- package/src/api/deleteThread.js +52 -0
- package/src/api/e2ee.js +17 -0
- package/src/{editMessage.js → api/editMessage.js} +10 -8
- package/src/api/emoji.js +124 -0
- package/src/api/fetchThemeData.js +82 -0
- package/src/{follow.js → api/follow.js} +15 -8
- package/src/api/forwardMessage.js +52 -0
- package/src/api/friend.js +243 -0
- package/src/api/gcmember.js +122 -0
- package/src/api/gcname.js +123 -0
- package/src/api/gcrule.js +119 -0
- package/src/{getAccess.js → api/getAccess.js} +3 -4
- package/src/api/getBotInfo.js +88 -0
- package/src/{getBotInitialData.js → api/getBotInitialData.js} +2 -1
- package/src/api/getFriendsList.js +79 -0
- package/src/api/getMessage.js +423 -0
- package/src/api/getTheme.js +95 -0
- package/src/api/getThemeInfo.js +116 -0
- package/src/api/getThreadHistory.js +239 -0
- package/src/api/getThreadInfo.js +267 -0
- package/src/api/getThreadList.js +232 -0
- package/src/api/getThreadPictures.js +58 -0
- package/src/api/getUserID.js +117 -0
- package/src/api/getUserInfo.js +513 -0
- package/src/api/getUserInfoV2.js +146 -0
- package/src/api/handleMessageRequest.js +50 -0
- package/src/api/httpGet.js +63 -0
- package/src/api/httpPost.js +89 -0
- package/src/{httpPostFormData.js → api/httpPostFormData.js} +2 -3
- package/src/api/listenMqtt.js +892 -0
- package/src/api/listenSpeed.js +179 -0
- package/src/api/logout.js +63 -0
- package/src/api/markAsDelivered.js +47 -0
- package/src/api/markAsRead.js +95 -0
- package/src/api/markAsReadAll.js +40 -0
- package/src/api/markAsSeen.js +70 -0
- package/src/api/mqttDeltaValue.js +278 -0
- package/src/api/muteThread.js +45 -0
- package/src/api/nickname.js +132 -0
- package/src/api/notes.js +163 -0
- package/src/api/pinMessage.js +150 -0
- package/src/api/produceMetaTheme.js +180 -0
- package/src/api/realtime.js +182 -0
- package/src/api/removeUserFromGroup.js +117 -0
- package/src/api/resolvePhotoUrl.js +58 -0
- package/src/api/searchForThread.js +154 -0
- package/src/api/sendMessage.js +354 -0
- package/src/api/sendMessageMqtt.js +249 -0
- package/src/api/sendTypingIndicator.js +48 -0
- package/src/api/setMessageReaction.js +27 -0
- package/src/api/setMessageReactionMqtt.js +61 -0
- package/src/api/setThreadTheme.js +260 -0
- package/src/{setThreadTheme.js → api/setThreadThemeMqtt.js} +26 -35
- package/src/api/share.js +107 -0
- package/src/api/shareContact.js +66 -0
- package/src/api/stickers.js +257 -0
- package/src/api/story.js +181 -0
- package/src/api/theme.js +233 -0
- package/src/api/unfriend.js +47 -0
- package/src/api/unsendMessage.js +17 -0
- package/src/database/appStateBackup.js +189 -0
- package/src/database/models/index.js +56 -0
- package/src/database/models/s +0 -0
- package/src/database/models/thread.js +31 -0
- package/src/database/models/user.js +32 -0
- package/src/database/threadData.js +101 -0
- package/src/database/userData.js +90 -0
- package/src/engine/client.js +92 -0
- package/src/engine/models/buildAPI.js +113 -0
- package/src/engine/models/loginHelper.js +487 -0
- package/src/engine/models/s +0 -0
- package/src/engine/models/setOptions.js +88 -0
- package/src/security/e2ee.js +109 -0
- package/src/types/index.d.ts +498 -0
- package/src/utils/antiSuspension.js +516 -0
- package/src/utils/auth-helpers.js +149 -0
- package/src/utils/autoReLogin.js +233 -0
- package/src/utils/axios.js +368 -0
- package/src/utils/cache.js +54 -0
- package/src/utils/clients.js +279 -0
- package/src/utils/constants.js +409 -0
- package/src/utils/formatters/data/formatAttachment.js +370 -0
- package/src/utils/formatters/data/formatDelta.js +109 -0
- package/src/utils/formatters/index.js +159 -0
- package/src/utils/formatters/value/formatCookie.js +91 -0
- package/src/utils/formatters/value/formatDate.js +36 -0
- package/src/utils/formatters/value/formatID.js +16 -0
- package/src/utils/formatters.js +1369 -0
- package/src/utils/headers.js +235 -0
- package/src/utils/index.js +153 -0
- package/src/utils/monitoring.js +333 -0
- package/src/utils/rateLimiter.js +251 -0
- package/src/utils/tokenRefresh.js +291 -0
- package/src/utils/user-agents.js +238 -0
- package/src/utils/validation.js +157 -0
- package/src/OldMessage.js +0 -329
- package/src/Screenshot.js +0 -83
- package/src/addUserToGroup.js +0 -115
- package/src/changeAdminStatus.js +0 -103
- package/src/changeArchivedStatus.js +0 -55
- package/src/changeAvatar.js +0 -136
- package/src/changeAvatarV2.js +0 -86
- package/src/changeAvt.js +0 -85
- package/src/changeBio.js +0 -76
- package/src/changeBlockedStatus.js +0 -49
- package/src/changeBlockedStatusMqtt.js +0 -80
- package/src/changeCover.js +0 -72
- package/src/changeGroupImage.js +0 -135
- package/src/changeName.js +0 -79
- package/src/changeNickname.js +0 -59
- package/src/changeThreadColor.js +0 -65
- package/src/changeUsername.js +0 -59
- package/src/createCommentPost.js +0 -230
- package/src/createNewGroup.js +0 -88
- package/src/createPoll.js +0 -71
- package/src/createPost.js +0 -276
- package/src/data/cache/data.json +0 -4
- package/src/data/cache/datahandle.js +0 -21
- package/src/data/getThreadInfo.json +0 -1
- package/src/deleteMessage.js +0 -56
- package/src/deleteThread.js +0 -56
- package/src/editMessageOld.js +0 -67
- package/src/forwardAttachment.js +0 -60
- package/src/friendList.js +0 -103
- package/src/getAvatarUser.js +0 -78
- package/src/getCtx.js +0 -5
- package/src/getCurrentUserID.js +0 -7
- package/src/getEmojiUrl.js +0 -29
- package/src/getFriendsList.js +0 -83
- package/src/getMessage.js +0 -847
- package/src/getOptions.js +0 -5
- package/src/getRegion.js +0 -7
- package/src/getThreadHistory.js +0 -680
- package/src/getThreadHistoryDeprecated.js +0 -71
- package/src/getThreadInfo.js +0 -232
- package/src/getThreadInfoDeprecated.js +0 -56
- package/src/getThreadList.js +0 -213
- package/src/getThreadListDeprecated.js +0 -46
- package/src/getThreadPictures.js +0 -59
- package/src/getThreadTheme.js +0 -82
- package/src/getUID.js +0 -119
- package/src/getUserID.js +0 -61
- package/src/getUserInfo.js +0 -66
- package/src/handleFriendRequest.js +0 -46
- package/src/handleMessageRequest.js +0 -47
- package/src/httpGet.js +0 -49
- package/src/httpPost.js +0 -48
- package/src/listenMqtt.js +0 -870
- package/src/listenNotification.js +0 -85
- package/src/logout.js +0 -75
- package/src/markAsDelivered.js +0 -47
- package/src/markAsRead.js +0 -70
- package/src/markAsReadAll.js +0 -40
- package/src/markAsSeen.js +0 -48
- package/src/metaTheme.js +0 -190
- package/src/muteThread.js +0 -45
- package/src/note.js +0 -228
- package/src/pinMessage.js +0 -59
- package/src/refreshFb_dtsg.js +0 -89
- package/src/removeSuspiciousAccount.js +0 -79
- package/src/removeUserFromGroup.js +0 -79
- package/src/reply.js +0 -442
- package/src/resolvePhotoUrl.js +0 -45
- package/src/searchForThread.js +0 -53
- package/src/searchFriends.js +0 -139
- package/src/searchStickers.js +0 -53
- package/src/send.js +0 -46
- package/src/sendComment.js +0 -159
- package/src/sendFriendRequest.js +0 -102
- package/src/sendMessage.js +0 -243
- package/src/sendMessageMqtt.js +0 -322
- package/src/sendTypingIndicator.js +0 -101
- package/src/sendTypingIndicatorV2.js +0 -28
- package/src/setActiveStatus.js +0 -93
- package/src/setMessageReaction.js +0 -122
- package/src/setMessageReactionMqtt.js +0 -62
- package/src/setPostReaction.js +0 -112
- package/src/setProfileGuard.js +0 -44
- package/src/setProfileLock.js +0 -98
- package/src/setStoryReaction.js +0 -134
- package/src/setStorySeen.js +0 -109
- package/src/setTitle.js +0 -90
- package/src/shareContact.js +0 -110
- package/src/shareLink.js +0 -59
- package/src/stopListenMqtt.js +0 -23
- package/src/storyManager.js +0 -358
- package/src/suggestFriend.js +0 -133
- package/src/threadColors.js +0 -131
- package/src/unfriend.js +0 -52
- package/src/unsendMessage.js +0 -45
- package/src/uploadAttachment.js +0 -93
- 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
|
+
});
|
package/examples/ping.js
ADDED
|
@@ -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);
|