@dongdev/fca-unofficial
Version:
Unofficial Facebook Chat API for Node.js - Interact with Facebook Messenger programmatically
367 lines (265 loc) • 14.2 kB
Markdown
# @dongdev/fca-unofficial
An **unofficial** Node.js library for interacting with **Facebook Messenger** through user-session emulation. It speaks the same HTTP/GraphQL and MQTT protocols the browser client uses, giving you programmatic access to messages, threads, reactions, typing indicators, and more — all in TypeScript with full type definitions.
> **Disclaimer:** This library operates by emulating a logged-in browser session. Using it may violate Facebook / Meta's Terms of Service and could result in account restrictions or bans. The author assumes **no responsibility** for how you use this software. Use it only for lawful purposes and at your own risk.
---
## Table of Contents
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Authentication](#authentication)
- [API Styles](#api-styles)
- [MessengerBot (Event-Driven)](#messengerbot-event-driven)
- [Configuration](#configuration)
- [Features Overview](#features-overview)
- [Project Documentation](#project-documentation)
- [Requirements](#requirements)
- [License](#license)
- [Links](#links)
---
## Installation
```bash
npm install @dongdev/fca-unofficial@latest
```
If you clone the repository and want to work with the source directly:
```bash
git clone https://github.com/dongp06/fca-unofficial.git
cd fca-unofficial
npm install
npm run build
```
The build produces these artifacts in `dist/`:
| File | Format / role |
|-------------------|----------------------------------------------------|
| `dist/cjs.cjs` | **CommonJS entry** — `require()` resolves here; the export **is** the `login` function (Mirai / classic FCA). |
| `dist/index.js` | Internal CJS bundle (required by `cjs.cjs`) |
| `dist/index.mjs` | ES Modules (ESM) |
| `dist/index.d.ts` | TypeScript typings |
---
## Quick Start
### Event-driven bot (recommended)
```javascript
const { createMessengerBot } = require("@dongdev/fca-unofficial");
async function main() {
const bot = await createMessengerBot(
{ appState: require("./appstate.json") },
{
listenEvents: true,
stopOnSignals: true,
commandPrefix: "/"
}
);
bot.on("error", (err) => console.error("Bot error:", err));
bot.on("messageCreate", (event) => {
if (event.body) {
console.log(`[${event.threadID}] ${event.body}`);
}
});
bot.command("ping", async (ctx) => {
await ctx.replyAsync("pong");
});
}
main();
```
### Classic `require` (default export = `login`)
Same pattern as older FCA forks: the required module **is** `login`. Callback gets **`api`**, not `ctx`.
```javascript
const login = require("@dongdev/fca-unofficial");
login({ appState: require("./appstate.json") }, (err, api) => {
if (err) return console.error(err);
api.setOptions({ listenEvents: true });
api.listenMqtt((e, ev) => {
if (e) return console.error(e);
if (ev.type === "message") api.sendMessage(ev.body, ev.threadID);
});
});
```
Optional FCA options before the callback: `login(credentials, { listenEvents: true }, (err, api) => { ... })`.
### Async / Promise style
```javascript
const { login } = require("@dongdev/fca-unofficial");
async function main() {
const ctx = await login({ appState: require("./appstate.json") });
const api = ctx.api;
api.listenMqtt((err, event) => {
if (err) return console.error(err);
if (event.type === "message") {
api.sendMessage(`Echo: ${event.body}`, event.threadID);
}
});
}
main();
```
---
## Authentication
With **`require("@dongdev/fca-unofficial")`**, you get the **`login`** function directly (see [Quick Start](#quick-start)). With **named** imports / ESM, use `import { login } from "..."` or `import login from "..."`.
The library supports multiple credential strategies. Pass **one** of the following to `login()` or `createMessengerBot()`:
| Credential | Description |
|----------------|-------------------------------------------------------------------------------------------------------------|
| `appState` | An array of cookie objects (`{ key, value, domain, path, ... }`) exported from a browser extension or tool. **Recommended for bots.** |
| `Cookie` | A raw cookie header string, e.g. `"c_user=...; xs=...; ..."`. |
| `email` + `password` | Web login credentials. Prone to checkpoints and CAPTCHAs; **not recommended** for long-running bots. |
You can also use `loginViaAPI` / `tokensViaAPI` for token-based authentication through an external API server (see `fca-config.json` → `apiServer`).
---
## API Styles
After authentication, you get an `FcaContext` object. The library offers two ways to call Messenger functions:
### 1. Flat API (legacy-compatible)
Every method lives directly on `ctx.api`:
```javascript
api.sendMessage("Hello!", threadID);
api.getThreadInfo(threadID, (err, info) => { ... });
api.setMessageReaction(":heart:", messageID);
```
### 2. Namespaced client facade
Group related methods under domain namespaces for cleaner code:
```typescript
import { createFcaClient } from "@dongdev/fca-unofficial";
const client = createFcaClient(ctx.api);
await client.messages.send("Hello!", threadID);
await client.threads.getInfo(threadID);
await client.users.getInfo(userID);
```
Available namespaces: `messages`, `threads`, `users`, `account`, `realtime`, `http`, `scheduler`.
---
## MessengerBot (Event-Driven)
`MessengerBot` provides a high-level, event-driven interface inspired by Discord.js and Telegraf.
### Creating a bot
```typescript
import { createMessengerBot } from "@dongdev/fca-unofficial";
const bot = await createMessengerBot(
{ appState: require("./appstate.json") },
{
listenEvents: true,
stopOnSignals: true,
commandPrefix: "/",
maxEventListeners: 64,
enableComposer: true
}
);
```
### Events
| Event | Trigger |
|----------------------|----------------------------------------------|
| `message` | Any incoming message (including replies) |
| `messageCreate` | Alias for `message` |
| `message_reply` | A reply to an existing message |
| `messageReactionAdd` | A reaction is added to a message |
| `messageDelete` | A message is unsent/deleted |
| `typingStart` | A user starts typing |
| `typingStop` | A user stops typing |
| `threadUpdate` | Thread metadata changes (title, participants) |
| `ready` | MQTT connection established |
| `raw` / `update` | Every MQTT delta (unfiltered) |
| `error` | Any error during listening |
### Composer middleware
The composer pipeline processes `message` and `message_reply` events through a chain of middleware functions:
```javascript
// Global middleware
bot.use(async (ctx, next) => {
console.log(`[${ctx.threadID}] ${ctx.text}`);
await next();
});
// Command handler — matches "/ping" at the start of a message
bot.command("ping", async (ctx) => {
await ctx.replyAsync("pong");
});
// Pattern matching — regex or substring
bot.hears(/hello/i, async (ctx) => {
await ctx.replyAsync("Hi there!");
});
bot.hears("goodbye", async (ctx) => {
ctx.reply("See you later!");
});
// Error handler for the composer chain
bot.catch((err, ctx) => {
console.error("Composer error:", err);
});
```
### MessengerContext
Each composer handler receives a `MessengerContext` with:
| Property / Method | Description |
|-----------------------|-----------------------------------------------|
| `ctx.text` | Trimmed message body |
| `ctx.body` | Raw message body |
| `ctx.threadID` | Thread the message belongs to |
| `ctx.senderID` | User who sent the message |
| `ctx.messageID` | Unique message identifier |
| `ctx.event` | Full `MessageEvent` object |
| `ctx.reply(payload)` | Send a reply (callback-style) |
| `ctx.replyAsync(payload)` | Send a reply (returns a `Promise`) |
### Lifecycle
```javascript
await bot.launch({ stopOnSignals: true });
// Graceful shutdown
await bot.stop();
```
When `stopOnSignals` is `true`, the bot automatically calls `stop()` on `SIGINT` / `SIGTERM`.
---
## Configuration
If `fca-config.json` is missing in the process working directory, it is **created automatically** with defaults on first load (or in-memory defaults only if the file cannot be written).
You can also copy the example and edit it:
```bash
cp fca-config.example.json fca-config.json
```
### Configuration blocks
| Block | Purpose |
|-----------------|-------------------------------------------------------------------------------|
| `checkUpdate` | Automatic npm version check on startup |
| `mqtt` | MQTT reconnect interval, enable/disable realtime |
| `autoLogin` | Re-authenticate automatically when the session expires |
| `credentials` | Email / password / 2FA secret for auto-login |
| `antiGetInfo` | Toggle SQLite-backed caching for `getThreadInfo` / `getUserInfo` |
| `remoteControl` | WebSocket-based remote control for external dashboards |
| `apiServer` | External API server URL for token-based login |
### Login options (`FcaOptions`)
| Option | Type | Default | Description |
|-------------------|-----------|-----------|--------------------------------------------------|
| `listenEvents` | `boolean` | `false` | Receive thread events (not just messages) |
| `selfListen` | `boolean` | `false` | Receive your own messages |
| `selfListenEvent` | `boolean` | `false` | Receive your own thread events |
| `listenTyping` | `boolean` | `false` | Receive typing indicators |
| `updatePresence` | `boolean` | `false` | Receive presence/online status updates |
| `forceLogin` | `boolean` | `false` | Force login even if already logged in |
| `autoMarkRead` | `boolean` | `false` | Automatically mark messages as read |
| `autoReconnect` | `boolean` | `false` | Reconnect MQTT automatically on disconnect |
| `online` | `boolean` | `false` | Appear online to other users |
| `emitReady` | `boolean` | `false` | Emit a `ready` event when MQTT connects |
| `userAgent` | `string` | Chrome UA | Custom User-Agent header |
| `proxy` | `string` | — | HTTP/SOCKS proxy URL |
| `pageID` | `string` | — | Act as a Facebook Page instead of a user |
| `logLevel` | `string` | `"info"` | Logging verbosity (`silly`, `info`, `warn`, `error`, `silent`) |
---
## Features Overview
### Messaging
Send text, attachments, stickers; edit, unsend, delete messages; forward attachments; upload files; set reactions; share contacts; send typing indicators; mark as read/delivered/seen.
### Threads
Get thread info and history; list threads; search threads; create groups; add/remove participants; change admin status; change group name, image, color, emoji; create polls; archive/mute/delete threads; handle message requests.
### Users
Look up user info (single and batch); resolve user IDs from vanity URLs; get friends list.
### Account
Change avatar, bio, blocked status; handle friend requests; unfriend; set post reactions; refresh `fb_dtsg`; logout; manage external modules; auto-save app state.
### Realtime (MQTT)
Persistent WebSocket connection to Facebook's MQTT broker. Receives messages, reactions, typing indicators, presence, thread events, read receipts, and more in real time. Automatic reconnection with debounce and jitter.
### Database (optional)
SQLite-backed caching via Sequelize. Thread and user data are cached locally to reduce API calls. Thread cache is kept in sync with realtime events through `attachThreadInfoRealtimeSync`.
### Scheduler
Built-in scheduling domain for deferred or periodic tasks.
---
## Project Documentation
| Document | Contents |
|------------------------------------------------|---------------------------------------------------------|
| [docs/DOCS.md](./docs/DOCS.md) | Full API reference: login, facade, MessengerBot, MQTT, caching |
| [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md) | Source tree layout, bootstrap flow, module design |
| [CHANGELOG](https://github.com/dongp06/fca-unofficial/blob/main/CHANGELOG.md) | Version history (repository only; not in the npm package) |
| [fca-config.example.json](./fca-config.example.json) | Sample configuration file |
---
## Requirements
- **Node.js** >= 14.0.0 (LTS recommended)
- **npm** or any compatible package manager
---
## License
This project is licensed under the **Apache License, Version 2.0**. See the [LICENSE](./LICENSE) file for the full text.
---
## Links
- **npm:** [@dongdev/fca-unofficial](https://www.npmjs.com/package/@dongdev/fca-unofficial)
- **GitHub:** [dongp06/fca-unofficial](https://github.com/dongp06/fca-unofficial)
- **Issues:** [GitHub Issues](https://github.com/dongp06/fca-unofficial/issues)
- **Author:** DongDev — [GitHub](https://github.com/dongp06)