feat(bot): add Baileys session wrapper
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
dd1eb711df
commit
fc05a8b459
74
apps/bot/src/whatsapp/session.ts
Normal file
74
apps/bot/src/whatsapp/session.ts
Normal 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");
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user