diff --git a/src/web/active-listener.ts b/src/web/active-listener.ts index 633d03c7d..6f046df07 100644 --- a/src/web/active-listener.ts +++ b/src/web/active-listener.ts @@ -30,6 +30,24 @@ let _currentListener: ActiveWebListener | null = null; const listeners = new Map(); +export function resolveWebAccountId(accountId?: string | null): string { + return (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; +} + +export function requireActiveWebListener(accountId?: string | null): { + accountId: string; + listener: ActiveWebListener; +} { + const id = resolveWebAccountId(accountId); + const listener = listeners.get(id) ?? null; + if (!listener) { + throw new Error( + `No active WhatsApp Web listener (account: ${id}). Start the gateway, then link WhatsApp with: clawdbot providers login --provider whatsapp --account ${id}.`, + ); + } + return { accountId: id, listener }; +} + export function setActiveWebListener(listener: ActiveWebListener | null): void; export function setActiveWebListener( accountId: string | null | undefined, @@ -47,7 +65,7 @@ export function setActiveWebListener( listener: accountIdOrListener ?? null, }; - const id = (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; + const id = resolveWebAccountId(accountId); if (!listener) { listeners.delete(id); } else { @@ -61,6 +79,6 @@ export function setActiveWebListener( export function getActiveWebListener( accountId?: string | null, ): ActiveWebListener | null { - const id = (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; + const id = resolveWebAccountId(accountId); return listeners.get(id) ?? null; } diff --git a/src/web/outbound.ts b/src/web/outbound.ts index 5ae333431..eca4ded5c 100644 --- a/src/web/outbound.ts +++ b/src/web/outbound.ts @@ -5,7 +5,7 @@ import { normalizePollInput, type PollInput } from "../polls.js"; import { toWhatsappJid } from "../utils.js"; import { type ActiveWebSendOptions, - getActiveWebListener, + requireActiveWebListener, } from "./active-listener.js"; import { loadWebMedia } from "./media.js"; @@ -13,15 +13,6 @@ const outboundLog = createSubsystemLogger("gateway/providers/whatsapp").child( "outbound", ); -function requireActiveListener(accountId?: string | null) { - const active = getActiveWebListener(accountId); - if (active) return active; - const id = (accountId ?? "").trim() || "default"; - throw new Error( - `No active WhatsApp Web listener (account: ${id}). Start the gateway, then link WhatsApp with: clawdbot providers login --provider whatsapp --account ${id}.`, - ); -} - export async function sendMessageWhatsApp( to: string, body: string, @@ -35,7 +26,8 @@ export async function sendMessageWhatsApp( let text = body; const correlationId = randomUUID(); const startedAt = Date.now(); - const active = requireActiveListener(options.accountId); + const { listener: active, accountId: resolvedAccountId } = + requireActiveWebListener(options.accountId); const logger = getChildLogger({ module: "web-outbound", correlationId, @@ -71,13 +63,14 @@ export async function sendMessageWhatsApp( { jid, hasMedia: Boolean(options.mediaUrl) }, "sending message", ); - if (!active) throw new Error("Active web listener missing"); await active.sendComposingTo(to); + const hasExplicitAccountId = Boolean(options.accountId?.trim()); + const accountId = hasExplicitAccountId ? resolvedAccountId : undefined; const sendOptions: ActiveWebSendOptions | undefined = - options.gifPlayback || options.accountId + options.gifPlayback || accountId ? { ...(options.gifPlayback ? { gifPlayback: true } : {}), - accountId: options.accountId, + accountId, } : undefined; const result = sendOptions @@ -112,7 +105,7 @@ export async function sendReactionWhatsApp( }, ): Promise { const correlationId = randomUUID(); - const active = requireActiveListener(options.accountId); + const { listener: active } = requireActiveWebListener(options.accountId); const logger = getChildLogger({ module: "web-outbound", correlationId, @@ -148,7 +141,7 @@ export async function sendPollWhatsApp( ): Promise<{ messageId: string; toJid: string }> { const correlationId = randomUUID(); const startedAt = Date.now(); - const active = requireActiveListener(options.accountId); + const { listener: active } = requireActiveWebListener(options.accountId); const logger = getChildLogger({ module: "web-outbound", correlationId,