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.
- package/README.md +380 -402
- package/examples/login-with-cookies.js +102 -0
- package/examples/ping.js +1 -0
- package/examples/verify.js +70 -0
- package/index.js +2 -8
- package/package.json +82 -56
- package/src/{api/action → apis}/addExternalModule.js +8 -9
- package/src/apis/addUserToGroup.js +108 -0
- package/src/apis/changeAdminStatus.js +148 -0
- package/src/apis/changeArchivedStatus.js +61 -0
- package/src/apis/changeAvatar.js +103 -0
- package/src/apis/changeBio.js +69 -0
- package/src/apis/changeBlockedStatus.js +54 -0
- package/src/apis/changeGroupImage.js +136 -0
- package/src/apis/changeThreadColor.js +116 -0
- package/src/apis/changeThreadEmoji.js +53 -0
- package/src/apis/comment.js +207 -0
- package/src/apis/createAITheme.js +129 -0
- package/src/apis/createNewGroup.js +79 -0
- package/src/apis/createPoll.js +73 -0
- package/src/apis/deleteMessage.js +44 -0
- package/src/apis/deleteThread.js +52 -0
- package/src/apis/e2ee.js +17 -0
- package/src/apis/editMessage.js +70 -0
- package/src/apis/emoji.js +124 -0
- package/src/apis/fetchThemeData.js +82 -0
- package/src/apis/follow.js +81 -0
- package/src/apis/forwardMessage.js +52 -0
- package/src/apis/friend.js +243 -0
- package/src/apis/gcmember.js +122 -0
- package/src/apis/gcname.js +123 -0
- package/src/apis/gcrule.js +119 -0
- package/src/apis/getAccess.js +111 -0
- package/src/apis/getBotInfo.js +88 -0
- package/src/apis/getBotInitialData.js +43 -0
- package/src/apis/getFriendsList.js +79 -0
- package/src/apis/getMessage.js +423 -0
- package/src/apis/getTheme.js +95 -0
- package/src/apis/getThemeInfo.js +116 -0
- package/src/apis/getThreadHistory.js +239 -0
- package/src/apis/getThreadInfo.js +267 -0
- package/src/apis/getThreadList.js +232 -0
- package/src/apis/getThreadPictures.js +58 -0
- package/src/apis/getUserID.js +117 -0
- package/src/apis/getUserInfo.js +513 -0
- package/src/{api/users → apis}/getUserInfoV2.js +26 -14
- package/src/apis/handleMessageRequest.js +50 -0
- package/src/apis/httpGet.js +63 -0
- package/src/apis/httpPost.js +89 -0
- package/src/apis/httpPostFormData.js +69 -0
- package/src/apis/listenMqtt.js +1184 -0
- package/src/apis/listenSpeed.js +179 -0
- package/src/apis/logout.js +63 -0
- package/src/apis/markAsDelivered.js +47 -0
- package/src/{api/messaging → apis}/markAsRead.js +26 -19
- package/src/apis/markAsReadAll.js +40 -0
- package/src/apis/markAsSeen.js +70 -0
- package/src/apis/mqttDeltaValue.js +278 -0
- package/src/apis/muteThread.js +45 -0
- package/src/apis/nickname.js +132 -0
- package/src/apis/notes.js +163 -0
- package/src/apis/pinMessage.js +150 -0
- package/src/apis/produceMetaTheme.js +180 -0
- package/src/apis/realtime.js +182 -0
- package/src/apis/removeUserFromGroup.js +117 -0
- package/src/apis/resolvePhotoUrl.js +58 -0
- package/src/apis/searchForThread.js +154 -0
- package/src/apis/sendMessage.js +354 -0
- package/src/apis/sendMessageMqtt.js +249 -0
- package/src/apis/sendTypingIndicator.js +40 -0
- package/src/apis/setMessageReaction.js +27 -0
- package/src/apis/setMessageReactionMqtt.js +61 -0
- package/src/apis/setThreadTheme.js +260 -0
- package/src/apis/setThreadThemeMqtt.js +94 -0
- package/src/apis/share.js +107 -0
- package/src/apis/shareContact.js +66 -0
- package/src/apis/stickers.js +257 -0
- package/src/apis/story.js +181 -0
- package/src/apis/theme.js +233 -0
- package/src/apis/unfriend.js +47 -0
- package/src/apis/unsendMessage.js +17 -0
- package/src/database/appStateBackup.js +189 -0
- package/src/database/models/index.js +44 -76
- package/src/database/models/thread.js +3 -22
- package/src/database/models/user.js +3 -17
- package/src/database/threadData.js +53 -46
- package/src/database/userData.js +38 -46
- package/src/engine/client.js +92 -0
- package/src/engine/models/buildAPI.js +113 -0
- package/src/engine/models/loginHelper.js +480 -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 +534 -0
- package/src/utils/auth-helpers.js +149 -0
- package/src/utils/autoReLogin.js +240 -0
- package/src/utils/axios.js +369 -0
- package/src/utils/cache.js +54 -0
- package/src/utils/clients.js +279 -0
- package/src/utils/constants.js +402 -15
- 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 +219 -99
- 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 +285 -0
- package/src/utils/user-agents.js +238 -0
- package/src/utils/validation.js +157 -0
- package/.gitattributes +0 -2
- package/.github/workflows/SaGor.yml +0 -22
- package/LICENSE-MIT +0 -21
- package/Sagor_Database/sagor.sqlite +0 -0
- package/docs/ARCHITECTURE.md +0 -142
- package/examples/remote-control.js +0 -85
- package/func/checkUpdate.js +0 -222
- package/func/logAdapter.js +0 -33
- package/func/logger.js +0 -48
- package/index.d.ts +0 -751
- package/module/config.js +0 -40
- package/module/login.js +0 -133
- package/module/loginHelper.js +0 -1296
- package/module/options.js +0 -44
- package/src/api/action/changeAvatar.js +0 -137
- package/src/api/action/changeBio.js +0 -75
- package/src/api/action/enableAutoSaveAppState.js +0 -73
- package/src/api/action/getCurrentUserID.js +0 -7
- package/src/api/action/handleFriendRequest.js +0 -57
- package/src/api/action/logout.js +0 -76
- package/src/api/action/refreshFb_dtsg.js +0 -48
- package/src/api/action/setPostReaction.js +0 -106
- package/src/api/action/unfriend.js +0 -54
- package/src/api/http/httpGet.js +0 -46
- package/src/api/http/httpPost.js +0 -52
- package/src/api/http/postFormData.js +0 -47
- package/src/api/messaging/addUserToGroup.js +0 -68
- package/src/api/messaging/changeAdminStatus.js +0 -126
- package/src/api/messaging/changeArchivedStatus.js +0 -55
- package/src/api/messaging/changeBlockedStatus.js +0 -48
- package/src/api/messaging/changeGroupImage.js +0 -91
- package/src/api/messaging/changeNickname.js +0 -70
- package/src/api/messaging/changeThreadColor.js +0 -79
- package/src/api/messaging/changeThreadEmoji.js +0 -111
- package/src/api/messaging/createNewGroup.js +0 -88
- package/src/api/messaging/createPoll.js +0 -46
- package/src/api/messaging/createThemeAI.js +0 -98
- package/src/api/messaging/deleteMessage.js +0 -136
- package/src/api/messaging/deleteThread.js +0 -56
- package/src/api/messaging/editMessage.js +0 -68
- package/src/api/messaging/forwardAttachment.js +0 -57
- package/src/api/messaging/getEmojiUrl.js +0 -29
- package/src/api/messaging/getFriendsList.js +0 -82
- package/src/api/messaging/getMessage.js +0 -829
- package/src/api/messaging/getThemePictures.js +0 -62
- package/src/api/messaging/handleMessageRequest.js +0 -65
- package/src/api/messaging/markAsDelivered.js +0 -57
- package/src/api/messaging/markAsReadAll.js +0 -49
- package/src/api/messaging/markAsSeen.js +0 -61
- package/src/api/messaging/muteThread.js +0 -50
- package/src/api/messaging/removeUserFromGroup.js +0 -62
- package/src/api/messaging/resolvePhotoUrl.js +0 -43
- package/src/api/messaging/scheduler.js +0 -264
- package/src/api/messaging/searchForThread.js +0 -53
- package/src/api/messaging/sendMessage.js +0 -270
- package/src/api/messaging/sendTypingIndicator.js +0 -74
- package/src/api/messaging/setMessageReaction.js +0 -90
- package/src/api/messaging/setTitle.js +0 -124
- package/src/api/messaging/shareContact.js +0 -49
- package/src/api/messaging/threadColors.js +0 -128
- package/src/api/messaging/unsendMessage.js +0 -81
- package/src/api/messaging/uploadAttachment.js +0 -492
- package/src/api/socket/core/connectMqtt.js +0 -258
- package/src/api/socket/core/emitAuth.js +0 -103
- package/src/api/socket/core/getSeqID.js +0 -320
- package/src/api/socket/core/getTaskResponseData.js +0 -25
- package/src/api/socket/core/parseDelta.js +0 -377
- package/src/api/socket/detail/buildStream.js +0 -215
- package/src/api/socket/detail/constants.js +0 -28
- package/src/api/socket/listenMqtt.js +0 -377
- package/src/api/socket/middleware/index.js +0 -216
- package/src/api/threads/getThreadHistory.js +0 -664
- package/src/api/threads/getThreadInfo.js +0 -296
- package/src/api/threads/getThreadList.js +0 -293
- package/src/api/threads/getThreadPictures.js +0 -78
- package/src/api/users/getUserID.js +0 -65
- package/src/api/users/getUserInfo.js +0 -402
- package/src/core/sendReqMqtt.js +0 -96
- package/src/database/helpers.js +0 -53
- package/src/remote/remoteClient.js +0 -123
- package/src/utils/broadcast.js +0 -51
- package/src/utils/client.js +0 -10
- package/src/utils/cookies.js +0 -68
- package/src/utils/format/attachment.js +0 -357
- package/src/utils/format/cookie.js +0 -9
- package/src/utils/format/date.js +0 -50
- package/src/utils/format/decode.js +0 -44
- package/src/utils/format/delta.js +0 -194
- package/src/utils/format/ids.js +0 -64
- package/src/utils/format/index.js +0 -64
- package/src/utils/format/message.js +0 -88
- package/src/utils/format/presence.js +0 -132
- package/src/utils/format/readTyp.js +0 -44
- package/src/utils/format/thread.js +0 -42
- package/src/utils/format/utils.js +0 -141
- package/src/utils/loginParser/autoLogin.js +0 -125
- package/src/utils/loginParser/helpers.js +0 -43
- package/src/utils/loginParser/index.js +0 -10
- package/src/utils/loginParser/parseAndCheckLogin.js +0 -220
- package/src/utils/loginParser/textUtils.js +0 -28
- package/src/utils/request/client.js +0 -26
- package/src/utils/request/config.js +0 -23
- package/src/utils/request/defaults.js +0 -46
- package/src/utils/request/helpers.js +0 -46
- package/src/utils/request/index.js +0 -17
- package/src/utils/request/methods.js +0 -163
- package/src/utils/request/proxy.js +0 -21
- package/src/utils/request/retry.js +0 -77
- package/src/utils/request/sanitize.js +0 -49
package/README.md
CHANGED
|
@@ -1,524 +1,502 @@
|
|
|
1
|
-
|
|
1
|
+
# sagor-fca
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/sagor-fca)
|
|
4
|
+
[](https://www.npmjs.com/package/sagor-fca)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org)
|
|
4
7
|
|
|
5
|
-
**
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
### Support & Issues
|
|
62
23
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
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
|
-
##
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
|
|
77
|
-
-
|
|
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
|
-
##
|
|
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
|
-
|
|
97
|
+
> **Requirements:** Node.js v18.0.0 or higher
|
|
102
98
|
|
|
103
99
|
```bash
|
|
104
|
-
npm install
|
|
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
|
-
##
|
|
105
|
+
## Quick Start
|
|
115
106
|
|
|
116
|
-
|
|
107
|
+
```js
|
|
108
|
+
const fs = require("fs");
|
|
109
|
+
const { login } = require("sagor-fca");
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
const login = require("@sagor/fca-unofficial");
|
|
111
|
+
const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
|
|
120
112
|
|
|
121
|
-
login({ appState
|
|
122
|
-
|
|
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
|
|
125
|
+
if (err || event.type !== "message" || !event.body) return;
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
160
|
+
### Circuit Breaker
|
|
157
161
|
|
|
158
|
-
|
|
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
|
-
|
|
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
|
-
|
|
171
|
-
|
|
166
|
+
```js
|
|
167
|
+
const { globalAntiSuspension } = require("sagor-fca/src/utils/antiSuspension");
|
|
172
168
|
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
attachment: fs.createReadStream(imagePath),
|
|
182
|
-
};
|
|
172
|
+
// Reset after you've resolved the issue
|
|
173
|
+
globalAntiSuspension.resetCircuitBreaker();
|
|
183
174
|
|
|
184
|
-
|
|
185
|
-
|
|
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
|
-
|
|
181
|
+
Use warmup mode when starting a fresh or recovered session:
|
|
194
182
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
-
##
|
|
190
|
+
## End-to-End Encryption for DMs (Opt-In)
|
|
210
191
|
|
|
211
|
-
|
|
192
|
+
Encrypt and decrypt message bodies in direct chats using X25519 + HKDF + AES-256-GCM.
|
|
212
193
|
|
|
213
|
-
|
|
194
|
+
```js
|
|
195
|
+
api.e2ee.enable();
|
|
214
196
|
|
|
215
|
-
|
|
216
|
-
const
|
|
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
|
-
|
|
222
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
##
|
|
210
|
+
## Security Warning
|
|
262
211
|
|
|
263
|
-
|
|
212
|
+
`appstate.json` contains your Facebook session and must be treated like a password:
|
|
264
213
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
##
|
|
221
|
+
## Getting Started — Generate `appstate.json`
|
|
291
222
|
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
-
|
|
349
|
-
|
|
350
|
-
Configure listening behavior:
|
|
238
|
+
4. Use in your bot:
|
|
351
239
|
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
### 👥 Thread Management
|
|
375
|
-
|
|
376
|
-
`getThreadInfo`, `getThreadList`, `getThreadHistory`, `deleteThread`, `changeThreadColor`, `changeThreadEmoji`, `changeGroupImage`, `setTitle`, `changeNickname`
|
|
377
|
-
|
|
378
|
-
### 👤 User & Group Management
|
|
248
|
+
---
|
|
379
249
|
|
|
380
|
-
|
|
250
|
+
## Bot Example with Commands
|
|
381
251
|
|
|
382
|
-
|
|
252
|
+
```js
|
|
253
|
+
const fs = require("fs");
|
|
254
|
+
const path = require("path");
|
|
255
|
+
const { login } = require("sagor-fca");
|
|
383
256
|
|
|
384
|
-
|
|
257
|
+
const appState = JSON.parse(fs.readFileSync("appstate.json", "utf8"));
|
|
385
258
|
|
|
386
|
-
|
|
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
|
-
|
|
267
|
+
console.log("Logged in as:", api.getCurrentUserID());
|
|
389
268
|
|
|
390
|
-
|
|
391
|
-
|
|
269
|
+
const commandsDir = path.join(__dirname, "commands");
|
|
270
|
+
const commands = new Map();
|
|
392
271
|
|
|
393
|
-
|
|
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
|
-
|
|
396
|
-
|
|
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
|
-
|
|
284
|
+
const prefix = "/";
|
|
285
|
+
if (!event.body.startsWith(prefix)) return;
|
|
406
286
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
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
|
-
|
|
413
|
-
|
|
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
|
-
##
|
|
428
|
-
|
|
429
|
-
- **Proxy support**:
|
|
430
|
-
- You can pass a proxy per‑login:
|
|
304
|
+
## AI Themes
|
|
431
305
|
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
-
|
|
450
|
-
|
|
451
|
-
|
|
313
|
+
// Browse standard themes
|
|
314
|
+
const themes = await api.getTheme(threadID);
|
|
315
|
+
await api.setThreadThemeMqtt(threadID, themes[0].id);
|
|
452
316
|
|
|
453
|
-
|
|
454
|
-
const
|
|
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
|
-
##
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
##
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
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
|
-
##
|
|
481
|
-
|
|
482
|
-
Contributions are welcome! If you want to optimize something or fix a bug:
|
|
463
|
+
## Examples
|
|
483
464
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
##
|
|
472
|
+
## Publishing
|
|
495
473
|
|
|
496
|
-
|
|
474
|
+
```bash
|
|
475
|
+
npm pack --dry-run
|
|
476
|
+
```
|
|
497
477
|
|
|
498
478
|
---
|
|
499
479
|
|
|
500
|
-
##
|
|
480
|
+
## Credits
|
|
501
481
|
|
|
502
|
-
|
|
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
|
-
|
|
486
|
+
> Copyright (c) 2026 SaGor
|
|
505
487
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
### 🛠️ Need Custom Work?
|
|
488
|
+
---
|
|
509
489
|
|
|
510
|
-
|
|
490
|
+
## License
|
|
511
491
|
|
|
512
|
-
|
|
492
|
+
**MIT** — Free to use, modify, and distribute. Attribution appreciated.
|
|
513
493
|
|
|
514
|
-
|
|
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
|
-
|
|
521
|
-
|
|
522
|
-
Made with ❤️ (and a lot of caffeine) for the developer community.
|
|
498
|
+
## Links
|
|
523
499
|
|
|
524
|
-
|
|
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)
|