A lightweight TypeScript wrapper around
@dongdev/fca-unofficialwith a clean, middleware-based event system.
import { ConduitClient } from "@theophilusdev/conduit";
const client = new ConduitClient({ listenEvents: true });
await client.login({ appstate });
client.on("message:create", async (ctx) => {
await ctx.reply(`hey, you said: ${ctx.body}`);
});npm install @theophilusdev/conduitimport { ConduitClient } from "@theophilusdev/conduit";
import fs from "fs";
const appstate = fs.readFileSync("./appstate.json", "utf-8");
const client = new ConduitClient({ listenEvents: true });
await client.login({ appstate });
client.on("message:create", async (ctx, next) => {
if (ctx.body === "ping") {
await ctx.reply("pong");
return;
}
await next();
});Pass one of the following to .login():
| Strategy | Field | Notes |
|---|---|---|
| App state | appstate |
Recommended |
| Raw cookies | cookies |
Cookie header string |
| Email + password | account.email / account.password |
Triggers checkpoints easily — avoid in production |
// appstate (recommended)
await client.login({ appstate: [...] });
// raw cookies
await client.login({ cookies: "c_user=...; xs=..." });
// email/password (not recommended)
await client.login({
account: { email: "...", password: "..." },
});Register handlers with .on(event, ...middlewares).
Handlers receive a context object and an optional next() function for middleware chaining.
All events include:
send(body)— send a message to the same thread
Message events additionally include:
reply(body)— quoted reply to the triggering messagereact(emoji)— react to the triggering message
Both send() and reply() accept a plain string or a ConduitMessageBody object for rich messages with attachments and mentions.
| Event | Description |
|---|---|
message:create |
New message received |
message:respond |
Reply to an existing message |
message:remove |
Message unsent by sender |
message:react |
Reaction added or removed |
message:writing |
Typing indicator (requires listenTyping: true) |
message:read |
Thread or message marked as read |
| Event | Description |
|---|---|
user:create |
User added to a group thread |
user:remove |
User left or was removed from a group thread |
| Event | Description |
|---|---|
thread:update |
Catch-all for thread updates |
thread:title_change |
Group title updated |
thread:photo_replaced |
Group photo changed |
thread:theme_changed |
Chat theme changed |
thread:nickname_changed |
Participant nickname updated |
thread:admin_changed |
Admin role changed |
.on() accepts multiple handlers. Each must call next() to continue the chain.
client.on(
"message:create",
async (ctx, next) => {
console.log("middleware 1");
await next();
},
async (ctx, next) => {
console.log("middleware 2");
await next();
},
);Drop down to FCA when needed:
// raw FCA event
client.onFca("presence", async (data) => {
console.log(data);
});
// raw FCA API (no type safety)
client.api.getThreadList(10, null, ["INBOX"]);See docs/DOCS.md or TypeDoc Documentation for full API details:
client.messagesclient.threadsclient.usersclient.account
GNU GPL v3 © theophilusdev
Official GitHub repository: TheophilusWorks/conduit
NPM Package: @theophilusdev/conduit
Built on top of @dongdev/fca-unofficial FCA.