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.
- Installation
- Quick Start
- Authentication
- API Styles
- MessengerBot (Event-Driven)
- Configuration
- Features Overview
- Project Documentation
- Requirements
- License
- Links
npm install @dongdev/fca-unofficial@latestIf you clone the repository and want to work with the source directly:
git clone https://github.com/dongp06/fca-unofficial.git
cd fca-unofficial
npm install
npm run buildThe 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 |
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();Same pattern as older FCA forks: the required module is login. Callback gets api, not ctx.
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) => { ... }).
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();With require("@dongdev/fca-unofficial"), you get the login function directly (see 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).
After authentication, you get an FcaContext object. The library offers two ways to call Messenger functions:
Every method lives directly on ctx.api:
api.sendMessage("Hello!", threadID);
api.getThreadInfo(threadID, (err, info) => { ... });
api.setMessageReaction(":heart:", messageID);Group related methods under domain namespaces for cleaner code:
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 provides a high-level, event-driven interface inspired by Discord.js and Telegraf.
import { createMessengerBot } from "@dongdev/fca-unofficial";
const bot = await createMessengerBot(
{ appState: require("./appstate.json") },
{
listenEvents: true,
stopOnSignals: true,
commandPrefix: "/",
maxEventListeners: 64,
enableComposer: true
}
);| 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 |
The composer pipeline processes message and message_reply events through a chain of middleware functions:
// 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);
});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) |
await bot.launch({ stopOnSignals: true });
// Graceful shutdown
await bot.stop();When stopOnSignals is true, the bot automatically calls stop() on SIGINT / SIGTERM.
Copy the example config and edit it:
cp fca-config.example.json fca-config.json| 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 |
| 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) |
Send text, attachments, stickers; edit, unsend, delete messages; forward attachments; upload files; set reactions; share contacts; send typing indicators; mark as read/delivered/seen.
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.
Look up user info (single and batch); resolve user IDs from vanity URLs; get friends list.
Change avatar, bio, blocked status; handle friend requests; unfriend; set post reactions; refresh fb_dtsg; logout; manage external modules; auto-save app state.
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.
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.
Built-in scheduling domain for deferred or periodic tasks.
| Document | Contents |
|---|---|
| docs/DOCS.md | Full API reference: login, facade, MessengerBot, MQTT, caching |
| docs/ARCHITECTURE.md | Source tree layout, bootstrap flow, module design |
| CHANGELOG | Version history (repository only; not in the npm package) |
| fca-config.example.json | Sample configuration file |
- Node.js >= 14.0.0 (LTS recommended)
- npm or any compatible package manager
This project is licensed under the Apache License, Version 2.0. See the LICENSE file for the full text.
- npm: @dongdev/fca-unofficial
- GitHub: dongp06/fca-unofficial
- Issues: GitHub Issues
- Author: DongDev — GitHub