feat(bot): add Baileys session wrapper

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
yiekheng 2026-05-09 16:18:11 +08:00
parent dd1eb711df
commit fc05a8b459

View File

@ -0,0 +1,74 @@
import { mkdir } from "node:fs/promises";
import { join } from "node:path";
import {
makeWASocket,
useMultiFileAuthState,
type WASocket,
type ConnectionState,
DisconnectReason,
Browsers,
} from "@whiskeysockets/baileys";
import { logger } from "../logger.js";
import { env } from "../env.js";
export type SessionEvent =
| { type: "qr"; payload: string }
| { type: "open"; phoneNumber: string | undefined }
| { type: "close"; reason: number; loggedOut: boolean };
export type SessionEventHandler = (event: SessionEvent) => void | Promise<void>;
export type Session = {
accountId: string;
socket: WASocket;
close: () => Promise<void>;
};
export async function startSession(params: {
accountId: string;
onEvent: SessionEventHandler;
}): Promise<Session> {
const { accountId, onEvent } = params;
const sessionDir = join(env.SESSIONS_DIR, accountId);
await mkdir(sessionDir, { recursive: true });
const { state, saveCreds } = await useMultiFileAuthState(sessionDir);
const socket = makeWASocket({
auth: state,
printQRInTerminal: false,
browser: Browsers.macOS("Safari"),
syncFullHistory: false,
logger: logger.child({ accountId, component: "baileys" }) as never,
});
socket.ev.on("creds.update", () => void saveCreds());
socket.ev.on("connection.update", (update: Partial<ConnectionState>) => {
if (update.qr) {
void onEvent({ type: "qr", payload: update.qr });
}
if (update.connection === "open") {
const phoneNumber = socket.user?.id?.split(":")[0];
void onEvent({ type: "open", phoneNumber });
}
if (update.connection === "close") {
const reason =
(update.lastDisconnect?.error as { output?: { statusCode?: number } } | undefined)?.output?.statusCode ?? 0;
const loggedOut = reason === DisconnectReason.loggedOut;
void onEvent({ type: "close", reason, loggedOut });
}
});
return {
accountId,
socket,
close: async () => {
try {
socket.end(undefined);
} catch (err) {
logger.warn({ err, accountId }, "session.close: error closing socket");
}
},
};
}