@dongdev/fca-unofficial 3.0.30 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +191 -0
- package/README.md +224 -406
- package/dist/index.d.mts +1241 -0
- package/dist/index.d.ts +1241 -0
- package/dist/index.js +27749 -0
- package/dist/index.mjs +27713 -0
- package/docs/ARCHITECTURE.md +467 -0
- package/docs/DOCS.md +686 -0
- package/fca-config.example.json +33 -0
- package/package.json +33 -22
- package/test/fca.test.cjs +533 -0
- package/CHANGELOG.md +0 -293
- package/DOCS.md +0 -2712
- 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/index.js +0 -8
- 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/addExternalModule.js +0 -25
- 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/markAsRead.js +0 -88
- 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 -52
- package/src/api/messaging/sendMessage.js +0 -270
- package/src/api/messaging/sendTypingIndicator.js +0 -74
- package/src/api/messaging/setMessageReaction.js +0 -91
- 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 -295
- 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 -399
- package/src/api/users/getUserInfoV2.js +0 -134
- package/src/core/sendReqMqtt.js +0 -96
- package/src/database/models/index.js +0 -87
- package/src/database/models/thread.js +0 -50
- package/src/database/models/user.js +0 -46
- package/src/database/threadData.js +0 -98
- package/src/database/userData.js +0 -89
- package/src/remote/remoteClient.js +0 -123
- package/src/utils/broadcast.js +0 -51
- package/src/utils/client.js +0 -10
- package/src/utils/constants.js +0 -23
- package/src/utils/cookies.js +0 -68
- package/src/utils/format.js +0 -1174
- package/src/utils/headers.js +0 -115
- package/src/utils/loginParser.js +0 -365
- package/src/utils/messageFormat.js +0 -1173
- package/src/utils/request.js +0 -332
package/docs/DOCS.md
ADDED
|
@@ -0,0 +1,686 @@
|
|
|
1
|
+
# @dongdev/fca-unofficial — Documentation
|
|
2
|
+
|
|
3
|
+
Comprehensive reference for **version 4.x**. The library is written in TypeScript; the published package ships `dist/` only. Source under `src/` is on [GitHub](https://github.com/dongp06/fca-unofficial).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Installation & Build](#1-installation--build)
|
|
10
|
+
2. [Authentication](#2-authentication)
|
|
11
|
+
3. [The Two API Layers](#3-the-two-api-layers)
|
|
12
|
+
4. [Realtime — MQTT Listener](#4-realtime--mqtt-listener)
|
|
13
|
+
5. [MessengerBot — Event-Driven Interface](#5-messengerbot--event-driven-interface)
|
|
14
|
+
6. [Configuration File (`fca-config.json`)](#6-configuration-file-fca-configjson)
|
|
15
|
+
7. [Thread Cache & Realtime Sync](#7-thread-cache--realtime-sync)
|
|
16
|
+
8. [Database (Optional)](#8-database-optional)
|
|
17
|
+
9. [API Reference — Messages](#9-api-reference--messages)
|
|
18
|
+
10. [API Reference — Threads](#10-api-reference--threads)
|
|
19
|
+
11. [API Reference — Users](#11-api-reference--users)
|
|
20
|
+
12. [API Reference — Account](#12-api-reference--account)
|
|
21
|
+
13. [API Reference — HTTP](#13-api-reference--http)
|
|
22
|
+
14. [API Reference — Scheduler](#14-api-reference--scheduler)
|
|
23
|
+
15. [Events Reference](#15-events-reference)
|
|
24
|
+
16. [Exports Summary](#16-exports-summary)
|
|
25
|
+
17. [Debugging MQTT](#17-debugging-mqtt)
|
|
26
|
+
18. [Security & Ethics](#18-security--ethics)
|
|
27
|
+
19. [License](#19-license)
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 1. Installation & Build
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @dongdev/fca-unofficial@latest
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To work from source:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/dongp06/fca-unofficial.git
|
|
41
|
+
cd fca-unofficial
|
|
42
|
+
npm install
|
|
43
|
+
npm run build
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Build output:
|
|
47
|
+
|
|
48
|
+
| File | Format |
|
|
49
|
+
|-------------------|-------------------|
|
|
50
|
+
| `dist/index.js` | CommonJS (CJS) |
|
|
51
|
+
| `dist/index.mjs` | ES Modules (ESM) |
|
|
52
|
+
| `dist/index.d.ts` | TypeScript types |
|
|
53
|
+
|
|
54
|
+
Additional scripts:
|
|
55
|
+
|
|
56
|
+
| Script | Purpose |
|
|
57
|
+
|-------------------|----------------------------------------|
|
|
58
|
+
| `npm run lint` | Run ESLint on the entire project |
|
|
59
|
+
| `npm run typecheck` | Type-check without emitting files |
|
|
60
|
+
| `npm test` | Run the test suite |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. Authentication
|
|
65
|
+
|
|
66
|
+
### 2.1. `login()` — async, returns `FcaContext`
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { login } from "@dongdev/fca-unofficial";
|
|
70
|
+
|
|
71
|
+
const ctx = await login(
|
|
72
|
+
{ appState: require("./appstate.json") },
|
|
73
|
+
{ listenEvents: true, selfListen: false }
|
|
74
|
+
);
|
|
75
|
+
const api = ctx.api;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 2.2. Credential strategies
|
|
79
|
+
|
|
80
|
+
| Field | Description |
|
|
81
|
+
|--------------------|-----------------------------------------------------------------------------|
|
|
82
|
+
| `appState` | Array of cookie objects `{ key/name, value, domain, path }` exported from a browser extension or tool. **Recommended.** |
|
|
83
|
+
| `Cookie` | Raw cookie header string: `"c_user=...; xs=...; ..."`. |
|
|
84
|
+
| `email` + `password` | Web login credentials. Easily triggers checkpoints; **not recommended** for production bots. |
|
|
85
|
+
|
|
86
|
+
### 2.3. `loginLegacy()` — callback style
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const { loginLegacy } = require("@dongdev/fca-unofficial");
|
|
90
|
+
|
|
91
|
+
loginLegacy({ appState: require("./appstate.json") }, (err, ctx) => {
|
|
92
|
+
if (err) return console.error(err);
|
|
93
|
+
const api = ctx.api;
|
|
94
|
+
// ...
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 2.4. Token-based login
|
|
99
|
+
|
|
100
|
+
`tokensViaAPI` and `loginViaAPI` authenticate through an external API server. Configure the `apiServer` and `credentials` fields in `fca-config.json`. See `src/core/auth.ts` for implementation details.
|
|
101
|
+
|
|
102
|
+
### 2.5. Login options (`FcaOptions`)
|
|
103
|
+
|
|
104
|
+
| Option | Type | Default | Description |
|
|
105
|
+
|-------------------|-----------|-------------|------------------------------------------------|
|
|
106
|
+
| `logLevel` | `string` | `"info"` | `"silly"`, `"info"`, `"warn"`, `"error"`, `"silent"` |
|
|
107
|
+
| `listenEvents` | `boolean` | `false` | Receive thread-level events (not just messages) |
|
|
108
|
+
| `selfListen` | `boolean` | `false` | Receive messages sent by the logged-in user |
|
|
109
|
+
| `selfListenEvent` | `boolean` | `false` | Receive thread events triggered by self |
|
|
110
|
+
| `listenTyping` | `boolean` | `false` | Receive typing indicators |
|
|
111
|
+
| `updatePresence` | `boolean` | `false` | Receive online/offline presence updates |
|
|
112
|
+
| `forceLogin` | `boolean` | `false` | Force re-authentication |
|
|
113
|
+
| `autoMarkRead` | `boolean` | `false` | Automatically mark incoming messages as read |
|
|
114
|
+
| `autoReconnect` | `boolean` | `false` | Reconnect MQTT on disconnect |
|
|
115
|
+
| `online` | `boolean` | `false` | Appear as online to other users |
|
|
116
|
+
| `emitReady` | `boolean` | `false` | Emit `ready` event when MQTT connects |
|
|
117
|
+
| `userAgent` | `string` | Chrome UA | Custom User-Agent for HTTP requests |
|
|
118
|
+
| `proxy` | `string` | — | HTTP or SOCKS proxy URL |
|
|
119
|
+
| `pageID` | `string` | — | Act as a Facebook Page |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 3. The Two API Layers
|
|
124
|
+
|
|
125
|
+
### 3.1. Flat API (legacy-compatible)
|
|
126
|
+
|
|
127
|
+
`ctx.api` exposes all methods as top-level functions, matching the interface of earlier FCA forks:
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
api.sendMessage("Hello!", threadID);
|
|
131
|
+
api.getThreadInfo(threadID, callback);
|
|
132
|
+
api.getUserInfo(userIDs, callback);
|
|
133
|
+
api.setMessageReaction(reaction, messageID, callback);
|
|
134
|
+
api.listenMqtt(callback);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Most methods accept an optional trailing `callback(err, result)`. When the callback is omitted, many methods return a `Promise`.
|
|
138
|
+
|
|
139
|
+
### 3.2. Namespaced client facade
|
|
140
|
+
|
|
141
|
+
`createFcaClient` wraps the flat API into domain-grouped namespaces:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
import { createFcaClient } from "@dongdev/fca-unofficial";
|
|
145
|
+
|
|
146
|
+
const client = createFcaClient(ctx.api);
|
|
147
|
+
|
|
148
|
+
// Messages
|
|
149
|
+
await client.messages.send("Hello!", threadID);
|
|
150
|
+
await client.messages.setReaction(":thumbsup:", messageID);
|
|
151
|
+
|
|
152
|
+
// Threads
|
|
153
|
+
const info = await client.threads.getInfo(threadID);
|
|
154
|
+
const list = await client.threads.getList(10, null, ["INBOX"]);
|
|
155
|
+
|
|
156
|
+
// Users
|
|
157
|
+
const userInfo = await client.users.getInfo(userID);
|
|
158
|
+
|
|
159
|
+
// Realtime
|
|
160
|
+
const emitter = client.realtime.listen();
|
|
161
|
+
emitter.on("message", (ev) => { /* ... */ });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Available namespaces:
|
|
165
|
+
|
|
166
|
+
| Namespace | Flat API equivalents |
|
|
167
|
+
|--------------|-------------------------------------------------------------------------|
|
|
168
|
+
| `messages` | `sendMessage`, `editMessage`, `unsendMessage`, `deleteMessage`, `setMessageReaction`, `sendTypingIndicator`, `markAsRead`, `markAsDelivered`, `markAsSeen`, `markAsReadAll`, `uploadAttachment`, `forwardAttachment`, `shareContact`, `changeThreadColor`, `changeThreadEmoji` |
|
|
169
|
+
| `threads` | `getThreadInfo`, `getThreadList`, `getThreadHistory`, `getThreadPictures`, `searchForThread`, `createNewGroup`, `addUserToGroup`, `removeUserFromGroup`, `changeAdminStatus`, `changeGroupImage`, `changeNickname`, `setTitle`, `createPoll`, `createThemeAI`, `deleteThread`, `changeArchivedStatus`, `muteThread`, `handleMessageRequest`, `getThemePictures` |
|
|
170
|
+
| `users` | `getUserInfo`, `getUserInfoV2`, `getUserID`, `getFriendsList` |
|
|
171
|
+
| `account` | `getCurrentUserID`, `changeAvatar`, `changeBio`, `changeBlockedStatus`, `handleFriendRequest`, `unfriend`, `setPostReaction`, `refreshFb_dtsg`, `logout`, `addExternalModule`, `enableAutoSaveAppState` |
|
|
172
|
+
| `realtime` | `listenMqtt` |
|
|
173
|
+
| `http` | `httpGet`, `httpPost`, `postFormData` |
|
|
174
|
+
| `scheduler` | Scheduling utilities |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 4. Realtime — MQTT Listener
|
|
179
|
+
|
|
180
|
+
The library maintains a persistent WebSocket connection to Facebook's MQTT broker for real-time event delivery.
|
|
181
|
+
|
|
182
|
+
### EventEmitter style (no callback)
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
const mqtt = api.listenMqtt();
|
|
186
|
+
|
|
187
|
+
mqtt.on("message", (event) => {
|
|
188
|
+
// event.type: "message", "message_reply", "message_reaction",
|
|
189
|
+
// "message_unsend", "typ", "read", "presence",
|
|
190
|
+
// "event", "ready", etc.
|
|
191
|
+
console.log(event);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
mqtt.on("error", (err) => {
|
|
195
|
+
console.error("MQTT error:", err);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Stop listening
|
|
199
|
+
await mqtt.stopListeningAsync();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Callback style (legacy)
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
api.listenMqtt((err, event) => {
|
|
206
|
+
if (err) return console.error(err);
|
|
207
|
+
// handle event
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Reconnection
|
|
212
|
+
|
|
213
|
+
When the connection drops, the library schedules a reconnect with debounce and jitter. The old MQTT client is fully cleaned up (`removeAllListeners` + `end`) before a new one is created. Configure the reconnect interval through `fca-config.json` → `mqtt.reconnectInterval`.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 5. MessengerBot — Event-Driven Interface
|
|
218
|
+
|
|
219
|
+
`MessengerBot` provides a Discord.js / Telegraf-style experience with events, middleware, commands, and pattern matching.
|
|
220
|
+
|
|
221
|
+
### 5.1. Creating a bot
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import { createMessengerBot } from "@dongdev/fca-unofficial";
|
|
225
|
+
|
|
226
|
+
const bot = await createMessengerBot(
|
|
227
|
+
{ Cookie: process.env.FCA_COOKIE },
|
|
228
|
+
{
|
|
229
|
+
listenEvents: true,
|
|
230
|
+
stopOnSignals: true,
|
|
231
|
+
commandPrefix: "/",
|
|
232
|
+
maxEventListeners: 64,
|
|
233
|
+
enableComposer: true
|
|
234
|
+
}
|
|
235
|
+
);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### 5.2. Bot options (`MessengerBotOptions`)
|
|
239
|
+
|
|
240
|
+
Extends `FcaOptions` with:
|
|
241
|
+
|
|
242
|
+
| Option | Type | Default | Description |
|
|
243
|
+
|---------------------|-----------|---------|-----------------------------------------------------------|
|
|
244
|
+
| `autoListen` | `boolean` | `true` | Start MQTT automatically after login |
|
|
245
|
+
| `enableComposer` | `boolean` | `true` | Enable the middleware pipeline (`use`, `command`, `hears`) |
|
|
246
|
+
| `commandPrefix` | `string` | `"/"` | Prefix for command matching |
|
|
247
|
+
| `stopOnSignals` | `boolean` | `false` | Auto-stop on `SIGINT` / `SIGTERM` |
|
|
248
|
+
| `maxEventListeners` | `number` | `64` | Max event listeners on the bot emitter (0 = unlimited) |
|
|
249
|
+
|
|
250
|
+
### 5.3. Events
|
|
251
|
+
|
|
252
|
+
| Event name | When it fires |
|
|
253
|
+
|----------------------|-------------------------------------------------|
|
|
254
|
+
| `message` | Any message (including replies) |
|
|
255
|
+
| `messageCreate` | Alias for `message` |
|
|
256
|
+
| `message_reply` | A reply to an existing message |
|
|
257
|
+
| `messageReactionAdd` | A reaction added to a message |
|
|
258
|
+
| `messageDelete` | A message is unsent |
|
|
259
|
+
| `typingStart` | User starts typing |
|
|
260
|
+
| `typingStop` | User stops typing |
|
|
261
|
+
| `threadUpdate` | Thread metadata changed |
|
|
262
|
+
| `ready` / `shardReady` | MQTT connection established |
|
|
263
|
+
| `raw` / `update` | Every incoming MQTT delta (unfiltered) |
|
|
264
|
+
| `error` | Errors from the MQTT layer or composer |
|
|
265
|
+
|
|
266
|
+
Events are only emitted when there is at least one listener registered for that event name (memory optimization).
|
|
267
|
+
|
|
268
|
+
### 5.4. Composer pipeline
|
|
269
|
+
|
|
270
|
+
The composer processes `message` and `message_reply` events through a Koa-style middleware chain.
|
|
271
|
+
|
|
272
|
+
**Global middleware:**
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
bot.use(async (ctx, next) => {
|
|
276
|
+
const start = Date.now();
|
|
277
|
+
await next();
|
|
278
|
+
console.log(`Processed in ${Date.now() - start}ms`);
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**Command handler:**
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
bot.command("help", async (ctx) => {
|
|
286
|
+
await ctx.replyAsync("Available commands: /ping, /help");
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Matches `{prefix}{name}` at the start of the message body (case-insensitive on the command name).
|
|
291
|
+
|
|
292
|
+
**Pattern matching:**
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
bot.hears(/order\s+#\d+/i, async (ctx) => {
|
|
296
|
+
await ctx.replyAsync("Looking up your order...");
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
bot.hears("thank", async (ctx) => {
|
|
300
|
+
await ctx.replyAsync("You're welcome!");
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`hears(string)` checks for a case-insensitive substring match. `hears(RegExp)` tests the full pattern.
|
|
305
|
+
|
|
306
|
+
**Error handler:**
|
|
307
|
+
|
|
308
|
+
```javascript
|
|
309
|
+
bot.catch((err, ctx) => {
|
|
310
|
+
console.error("Middleware error in thread", ctx?.threadID, err);
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 5.5. `MessengerContext`
|
|
315
|
+
|
|
316
|
+
| Property / Method | Type / Return | Description |
|
|
317
|
+
|---------------------------|-----------------------|------------------------------------------|
|
|
318
|
+
| `ctx.text` | `string` | Trimmed message body |
|
|
319
|
+
| `ctx.body` | `string \| undefined` | Raw message body |
|
|
320
|
+
| `ctx.threadID` | `string` | Thread identifier |
|
|
321
|
+
| `ctx.senderID` | `string` | Sender's user ID |
|
|
322
|
+
| `ctx.messageID` | `string` | Message identifier |
|
|
323
|
+
| `ctx.event` | `MessageEvent` | Full event payload |
|
|
324
|
+
| `ctx.bot` | `MessengerBotLike` | Reference to the bot instance |
|
|
325
|
+
| `ctx.reply(payload, cb?)` | varies | Send a reply (callback-style) |
|
|
326
|
+
| `ctx.replyAsync(payload)` | `Promise` | Send a reply (promise-based) |
|
|
327
|
+
|
|
328
|
+
### 5.6. Lifecycle
|
|
329
|
+
|
|
330
|
+
```javascript
|
|
331
|
+
// Start listening + optional signal handling
|
|
332
|
+
await bot.launch({ stopOnSignals: true });
|
|
333
|
+
|
|
334
|
+
// Manual start (without signal handling)
|
|
335
|
+
bot.startListening();
|
|
336
|
+
|
|
337
|
+
// Graceful shutdown: stops MQTT, removes signal handlers, clears listeners
|
|
338
|
+
await bot.stop();
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 5.7. Accessing the client facade
|
|
342
|
+
|
|
343
|
+
```javascript
|
|
344
|
+
const client = bot.client; // FcaClientFacade (lazy-initialized)
|
|
345
|
+
await client.messages.send("Hi from the facade!", threadID);
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## 6. Configuration File (`fca-config.json`)
|
|
351
|
+
|
|
352
|
+
Copy the example and customize:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
cp fca-config.example.json fca-config.json
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### Block reference
|
|
359
|
+
|
|
360
|
+
#### `checkUpdate`
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{
|
|
364
|
+
"checkUpdate": {
|
|
365
|
+
"enabled": true,
|
|
366
|
+
"install": false,
|
|
367
|
+
"notifyIfCurrent": false,
|
|
368
|
+
"packageName": "@dongdev/fca-unofficial",
|
|
369
|
+
"registryUrl": "https://registry.npmjs.org",
|
|
370
|
+
"timeoutMs": 10000
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
| Field | Description |
|
|
376
|
+
|-------------------|---------------------------------------------------------|
|
|
377
|
+
| `enabled` | Check npm for a newer version on startup |
|
|
378
|
+
| `install` | Automatically install the update if found |
|
|
379
|
+
| `notifyIfCurrent` | Show a message even when already on the latest version |
|
|
380
|
+
| `timeoutMs` | Timeout for the registry HTTP request |
|
|
381
|
+
|
|
382
|
+
#### `mqtt`
|
|
383
|
+
|
|
384
|
+
```json
|
|
385
|
+
{
|
|
386
|
+
"mqtt": {
|
|
387
|
+
"enabled": true,
|
|
388
|
+
"reconnectInterval": 3600
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
| Field | Description |
|
|
394
|
+
|---------------------|---------------------------------------------------|
|
|
395
|
+
| `enabled` | Enable the MQTT realtime connection |
|
|
396
|
+
| `reconnectInterval` | Seconds between automatic reconnection cycles |
|
|
397
|
+
|
|
398
|
+
#### `credentials`
|
|
399
|
+
|
|
400
|
+
```json
|
|
401
|
+
{
|
|
402
|
+
"credentials": {
|
|
403
|
+
"email": "",
|
|
404
|
+
"password": "",
|
|
405
|
+
"twofactor": ""
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Used by `autoLogin` and `loginViaAPI` for automatic session recovery.
|
|
411
|
+
|
|
412
|
+
#### `antiGetInfo`
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"antiGetInfo": {
|
|
417
|
+
"AntiGetThreadInfo": false,
|
|
418
|
+
"AntiGetUserInfo": false
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
When enabled, `getThreadInfo` and `getUserInfo` use SQLite-backed caching to reduce repeated GraphQL requests to Facebook.
|
|
424
|
+
|
|
425
|
+
#### `remoteControl`
|
|
426
|
+
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"remoteControl": {
|
|
430
|
+
"enabled": false,
|
|
431
|
+
"url": "",
|
|
432
|
+
"token": "",
|
|
433
|
+
"autoReconnect": true
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Connects to an external WebSocket server for remote management. Emits `remoteConnected`, `remoteDisconnected`, `remoteStop`, `remoteBroadcast`, and `remoteMessage` events on the API emitter.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## 7. Thread Cache & Realtime Sync
|
|
443
|
+
|
|
444
|
+
When Sequelize and the `Thread` model are available, `getThreadInfo` reads from and writes to a local SQLite cache. Cached entries have a freshness window (~10 minutes) before a refetch is triggered.
|
|
445
|
+
|
|
446
|
+
**`attachThreadInfoRealtimeSync`** hooks into MQTT events of type `"event"` and:
|
|
447
|
+
|
|
448
|
+
- Updates or **invalidates** (`data: null`) the cache based on `logMessageType`.
|
|
449
|
+
- On participant subscribe/unsubscribe events, updates `participantIDs` and calls `getUserInfo` to refresh `userInfo` within the cached thread data.
|
|
450
|
+
|
|
451
|
+
This function is called automatically during the standard bootstrap. For custom login flows, you can invoke it manually:
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
import { attachThreadInfoRealtimeSync } from "@dongdev/fca-unofficial";
|
|
455
|
+
|
|
456
|
+
attachThreadInfoRealtimeSync(ctx, models, logger, api);
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## 8. Database (Optional)
|
|
462
|
+
|
|
463
|
+
The library optionally uses **SQLite + Sequelize** for local caching and analytics.
|
|
464
|
+
|
|
465
|
+
### Models
|
|
466
|
+
|
|
467
|
+
| Model | Purpose |
|
|
468
|
+
|----------|-----------------------------------------------------------------|
|
|
469
|
+
| `Thread` | Caches thread info (JSON in `data` column), tracks `messageCount` |
|
|
470
|
+
| `User` | Caches user info |
|
|
471
|
+
|
|
472
|
+
When the database is not configured, cache features fall back to in-memory storage or are skipped entirely. The `Thread.messageCount` field is atomically incremented on each incoming message via `attachThreadUpdater`, enabling analytics like "most active threads" without impacting message processing latency.
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## 9. API Reference — Messages
|
|
477
|
+
|
|
478
|
+
| Method | Description |
|
|
479
|
+
|---------------------------|-------------------------------------------------------|
|
|
480
|
+
| `sendMessage` | Send text, attachments, stickers, or mentions |
|
|
481
|
+
| `editMessage` | Edit an existing message |
|
|
482
|
+
| `unsendMessage` | Unsend (retract) a message |
|
|
483
|
+
| `deleteMessage` | Delete a message |
|
|
484
|
+
| `setMessageReaction` | Add or remove a reaction on a message |
|
|
485
|
+
| `sendTypingIndicator` | Show or hide the typing indicator in a thread |
|
|
486
|
+
| `markAsRead` | Mark specific messages as read |
|
|
487
|
+
| `markAsDelivered` | Mark messages as delivered |
|
|
488
|
+
| `markAsSeen` | Mark messages as seen |
|
|
489
|
+
| `markAsReadAll` | Mark all messages in all threads as read |
|
|
490
|
+
| `uploadAttachment` | Upload a file and get an attachment ID |
|
|
491
|
+
| `forwardAttachment` | Forward an existing attachment to another thread |
|
|
492
|
+
| `shareContact` | Share a contact card |
|
|
493
|
+
| `changeThreadColor` | Change the chat color theme of a thread |
|
|
494
|
+
| `changeThreadEmoji` | Change the quick-reaction emoji of a thread |
|
|
495
|
+
| `getEmojiUrl` | Resolve the image URL for a given emoji |
|
|
496
|
+
| `getMessage` | Fetch a specific message by ID |
|
|
497
|
+
| `resolvePhotoUrl` | Resolve the full-resolution URL of a photo attachment |
|
|
498
|
+
| `getThreadColors` | List all available thread color themes |
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## 10. API Reference — Threads
|
|
503
|
+
|
|
504
|
+
| Method | Description |
|
|
505
|
+
|-------------------------|-------------------------------------------------------------|
|
|
506
|
+
| `getThreadInfo` | Get detailed info about a thread (participants, name, etc.) |
|
|
507
|
+
| `getThreadList` | List threads with pagination and folder filtering |
|
|
508
|
+
| `getThreadHistory` | Retrieve message history for a thread |
|
|
509
|
+
| `getThreadPictures` | Get shared photos in a thread |
|
|
510
|
+
| `getThemePictures` | Get theme-related pictures |
|
|
511
|
+
| `searchForThread` | Search threads by name or keyword |
|
|
512
|
+
| `createNewGroup` | Create a new group conversation |
|
|
513
|
+
| `addUserToGroup` | Add one or more users to a group |
|
|
514
|
+
| `removeUserFromGroup` | Remove a user from a group |
|
|
515
|
+
| `changeAdminStatus` | Promote or demote a group admin |
|
|
516
|
+
| `changeGroupImage` | Update the group's profile image |
|
|
517
|
+
| `changeNickname` | Set a participant's nickname in a thread |
|
|
518
|
+
| `setTitle` | Change the group title |
|
|
519
|
+
| `createPoll` | Create a poll in a thread |
|
|
520
|
+
| `createThemeAI` | Create an AI-generated theme |
|
|
521
|
+
| `deleteThread` | Delete a thread |
|
|
522
|
+
| `changeArchivedStatus` | Archive or unarchive a thread |
|
|
523
|
+
| `muteThread` | Mute or unmute notifications for a thread |
|
|
524
|
+
| `handleMessageRequest` | Accept or decline a message request |
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## 11. API Reference — Users
|
|
529
|
+
|
|
530
|
+
| Method | Description |
|
|
531
|
+
|------------------|--------------------------------------------------------|
|
|
532
|
+
| `getUserInfo` | Get user info by ID(s) — supports batch requests |
|
|
533
|
+
| `getUserInfoV2` | Alternative user info endpoint |
|
|
534
|
+
| `getUserID` | Resolve a vanity URL or username to a user ID |
|
|
535
|
+
| `getFriendsList` | Get the authenticated user's friends list |
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## 12. API Reference — Account
|
|
540
|
+
|
|
541
|
+
| Method | Description |
|
|
542
|
+
|---------------------------|------------------------------------------------------|
|
|
543
|
+
| `getCurrentUserID` | Get the logged-in user's Facebook ID |
|
|
544
|
+
| `changeAvatar` | Update the profile picture |
|
|
545
|
+
| `changeBio` | Update the profile bio |
|
|
546
|
+
| `changeBlockedStatus` | Block or unblock a user |
|
|
547
|
+
| `handleFriendRequest` | Accept, decline, or cancel a friend request |
|
|
548
|
+
| `unfriend` | Remove a user from the friends list |
|
|
549
|
+
| `setPostReaction` | React to a Facebook post |
|
|
550
|
+
| `refreshFb_dtsg` | Refresh the `fb_dtsg` security token |
|
|
551
|
+
| `logout` | End the session and invalidate cookies |
|
|
552
|
+
| `addExternalModule` | Register an external module on the API |
|
|
553
|
+
| `enableAutoSaveAppState` | Toggle automatic appState persistence |
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## 13. API Reference — HTTP
|
|
558
|
+
|
|
559
|
+
Low-level HTTP utilities for making authenticated requests to Facebook's endpoints.
|
|
560
|
+
|
|
561
|
+
| Method | Description |
|
|
562
|
+
|----------------|-----------------------------------------------|
|
|
563
|
+
| `httpGet` | Authenticated GET request |
|
|
564
|
+
| `httpPost` | Authenticated POST request |
|
|
565
|
+
| `postFormData` | Authenticated multipart/form-data POST |
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## 14. API Reference — Scheduler
|
|
570
|
+
|
|
571
|
+
The scheduler domain provides utilities for deferred and periodic task execution within the bot lifecycle.
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## 15. Events Reference
|
|
576
|
+
|
|
577
|
+
### MQTT events (`MqttEvent` union type)
|
|
578
|
+
|
|
579
|
+
| Type | Interface | Key fields |
|
|
580
|
+
|----------------------------|------------------------------|-----------------------------------------------------|
|
|
581
|
+
| `message` | `MessageEvent` | `threadID`, `senderID`, `messageID`, `body`, `attachments` |
|
|
582
|
+
| `message_reply` | `MessageEvent` | Same as `message`, triggered on reply |
|
|
583
|
+
| `message_reaction` | `ReactionEvent` | `messageID`, `reaction`, `userID` |
|
|
584
|
+
| `message_unsend` | `MessageUnsendEvent` | `messageID`, `senderID`, `deletionTimestamp` |
|
|
585
|
+
| `read` / `read_receipt` | `ReadEvent` | `reader` |
|
|
586
|
+
| `presence` | `PresenceEvent` | `userID`, `statuses` |
|
|
587
|
+
| `typ` | `TypingEvent` | `isTyping`, `from` |
|
|
588
|
+
| `friend_request_received` | `FriendRequestReceivedEvent` | `actorFbId` |
|
|
589
|
+
| `friend_request_cancel` | `FriendRequestCancelEvent` | `actorFbId` |
|
|
590
|
+
| `ready` | `ReadyEvent` | `error: null` |
|
|
591
|
+
| `event` | `ThreadEvent` | `logMessageType`, `logMessageData`, `logMessageBody`, `author` |
|
|
592
|
+
| `account_inactive` | `AccountInactiveEvent` | `reason`, `error` |
|
|
593
|
+
| `stop_listen` | `StopListenEvent` | `error` |
|
|
594
|
+
|
|
595
|
+
### API emitter events (lifecycle)
|
|
596
|
+
|
|
597
|
+
| Event | Trigger |
|
|
598
|
+
|---------------------|------------------------------------------------|
|
|
599
|
+
| `sessionExpired` | The session cookie is no longer valid |
|
|
600
|
+
| `autoLoginSuccess` | Automatic re-login succeeded |
|
|
601
|
+
| `autoLoginFailed` | Automatic re-login failed |
|
|
602
|
+
| `checkpoint` | Facebook is requesting a security checkpoint |
|
|
603
|
+
| `checkpoint_282` | Checkpoint type 282 |
|
|
604
|
+
| `checkpoint_956` | Checkpoint type 956 |
|
|
605
|
+
| `loginBlocked` | Login was blocked by Facebook |
|
|
606
|
+
| `rateLimit` | Request was rate-limited |
|
|
607
|
+
| `networkError` | A network-level error occurred |
|
|
608
|
+
| `remoteConnected` | Connected to the remote control WebSocket |
|
|
609
|
+
| `remoteDisconnected`| Disconnected from the remote control WebSocket |
|
|
610
|
+
| `remoteStop` | Remote control issued a stop command |
|
|
611
|
+
| `remoteBroadcast` | Remote control broadcast message received |
|
|
612
|
+
| `remoteMessage` | Incoming remote control message |
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
## 16. Exports Summary
|
|
617
|
+
|
|
618
|
+
All public exports from `@dongdev/fca-unofficial`:
|
|
619
|
+
|
|
620
|
+
| Export | Category | Description |
|
|
621
|
+
|---------------------------------|----------------|---------------------------------------------------|
|
|
622
|
+
| `login` | Auth | Async login, returns `FcaContext` |
|
|
623
|
+
| `loginLegacy` | Auth | Callback-style login |
|
|
624
|
+
| `loginViaAPI` | Auth | Token-based login via external API |
|
|
625
|
+
| `tokensViaAPI` | Auth | Fetch tokens from external API |
|
|
626
|
+
| `normalizeCookieHeaderString` | Auth | Normalize a raw cookie string |
|
|
627
|
+
| `setJarFromPairs` | Auth | Populate a cookie jar from key-value pairs |
|
|
628
|
+
| `createDefaultContext` | Core | Create a blank `FcaContext` |
|
|
629
|
+
| `createFcaState` | Core | Create an initialized state object |
|
|
630
|
+
| `createApiFacade` | Core | Build the base API facade |
|
|
631
|
+
| `createRequestHelper` | Core | HTTP request utilities |
|
|
632
|
+
| `listenMqtt` | Core | MQTT helper function |
|
|
633
|
+
| `createAuthCore` | Core | Auth helper utilities |
|
|
634
|
+
| `defaultConfig` | Config | Default configuration values |
|
|
635
|
+
| `loadConfig` | Config | Load config from `fca-config.json` |
|
|
636
|
+
| `resolveConfig` | Config | Merge defaults with loaded config |
|
|
637
|
+
| `writeConfigTemplate` | Config | Write the example config to disk |
|
|
638
|
+
| `attachThreadInfoRealtimeSync` | Realtime/Cache | Sync thread cache from MQTT events |
|
|
639
|
+
| `checkForPackageUpdate` | Update | Check npm for a newer version |
|
|
640
|
+
| `runConfiguredUpdateCheck` | Update | Run update check based on config |
|
|
641
|
+
| `createFcaClient` | Client | Create the namespaced client facade |
|
|
642
|
+
| `MessengerBot` | Bot | Event-driven bot class |
|
|
643
|
+
| `createMessengerBot` | Bot | Factory function for `MessengerBot` |
|
|
644
|
+
| `MessengerContext` | Bot | Message context for composer handlers |
|
|
645
|
+
| `attachClientFacade` | Compat | Attach the client facade to an existing context |
|
|
646
|
+
| `createMessagesDomain` | Domain | Messages domain factory |
|
|
647
|
+
| `createThreadsDomain` | Domain | Threads domain factory |
|
|
648
|
+
| `createRealtimeDomain` | Domain | Realtime domain factory |
|
|
649
|
+
| `createUsersDomain` | Domain | Users domain factory |
|
|
650
|
+
| `createAccountDomain` | Domain | Account domain factory |
|
|
651
|
+
| `createHttpDomain` | Domain | HTTP domain factory |
|
|
652
|
+
| `createSchedulerDomain` | Domain | Scheduler domain factory |
|
|
653
|
+
| `export * from "./types"` | Types | All TypeScript type definitions |
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## 17. Debugging MQTT
|
|
658
|
+
|
|
659
|
+
### "No subscription existed"
|
|
660
|
+
|
|
661
|
+
This error was resolved internally by ensuring topic subscriptions complete before publishing the sync queue. If you see it, make sure you are using the latest version.
|
|
662
|
+
|
|
663
|
+
### Reconnection issues
|
|
664
|
+
|
|
665
|
+
- `close`, `disconnect`, and `error` events on the MQTT client schedule a reconnect with debounce + jitter.
|
|
666
|
+
- The old client is fully torn down (`removeAllListeners()` + `end()`) before a new client is created, preventing ghost listeners and memory leaks.
|
|
667
|
+
- The `mqtt.reconnectInterval` config controls the periodic reconnection cycle (in seconds).
|
|
668
|
+
|
|
669
|
+
### Logging
|
|
670
|
+
|
|
671
|
+
Set `logLevel: "silly"` in your login options to enable verbose logging of MQTT frames and HTTP requests.
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
## 18. Security & Ethics
|
|
676
|
+
|
|
677
|
+
- **Never commit** `appstate.json`, `cookie.txt`, or `fca-config.json` files containing passwords or tokens.
|
|
678
|
+
- **Rate-limit** your message sending to avoid triggering Facebook's spam detection.
|
|
679
|
+
- **Respect** Facebook / Meta's Terms of Service and applicable laws.
|
|
680
|
+
- **Do not** use this library for spamming, harassment, scraping personal data, or any other activity that harms users.
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## 19. License
|
|
685
|
+
|
|
686
|
+
This project is licensed under the **Apache License, Version 2.0**. See the [LICENSE](../LICENSE) file for the full text.
|