refactor(web): centralize active web listener resolution

This commit is contained in:
Peter Steinberger
2026-01-09 23:03:41 +00:00
parent 6f6acd94cc
commit 6016a63162
2 changed files with 29 additions and 18 deletions

View File

@@ -30,6 +30,24 @@ let _currentListener: ActiveWebListener | null = null;
const listeners = new Map<string, ActiveWebListener>(); const listeners = new Map<string, ActiveWebListener>();
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(listener: ActiveWebListener | null): void;
export function setActiveWebListener( export function setActiveWebListener(
accountId: string | null | undefined, accountId: string | null | undefined,
@@ -47,7 +65,7 @@ export function setActiveWebListener(
listener: accountIdOrListener ?? null, listener: accountIdOrListener ?? null,
}; };
const id = (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; const id = resolveWebAccountId(accountId);
if (!listener) { if (!listener) {
listeners.delete(id); listeners.delete(id);
} else { } else {
@@ -61,6 +79,6 @@ export function setActiveWebListener(
export function getActiveWebListener( export function getActiveWebListener(
accountId?: string | null, accountId?: string | null,
): ActiveWebListener | null { ): ActiveWebListener | null {
const id = (accountId ?? "").trim() || DEFAULT_ACCOUNT_ID; const id = resolveWebAccountId(accountId);
return listeners.get(id) ?? null; return listeners.get(id) ?? null;
} }

View File

@@ -5,7 +5,7 @@ import { normalizePollInput, type PollInput } from "../polls.js";
import { toWhatsappJid } from "../utils.js"; import { toWhatsappJid } from "../utils.js";
import { import {
type ActiveWebSendOptions, type ActiveWebSendOptions,
getActiveWebListener, requireActiveWebListener,
} from "./active-listener.js"; } from "./active-listener.js";
import { loadWebMedia } from "./media.js"; import { loadWebMedia } from "./media.js";
@@ -13,15 +13,6 @@ const outboundLog = createSubsystemLogger("gateway/providers/whatsapp").child(
"outbound", "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( export async function sendMessageWhatsApp(
to: string, to: string,
body: string, body: string,
@@ -35,7 +26,8 @@ export async function sendMessageWhatsApp(
let text = body; let text = body;
const correlationId = randomUUID(); const correlationId = randomUUID();
const startedAt = Date.now(); const startedAt = Date.now();
const active = requireActiveListener(options.accountId); const { listener: active, accountId: resolvedAccountId } =
requireActiveWebListener(options.accountId);
const logger = getChildLogger({ const logger = getChildLogger({
module: "web-outbound", module: "web-outbound",
correlationId, correlationId,
@@ -71,13 +63,14 @@ export async function sendMessageWhatsApp(
{ jid, hasMedia: Boolean(options.mediaUrl) }, { jid, hasMedia: Boolean(options.mediaUrl) },
"sending message", "sending message",
); );
if (!active) throw new Error("Active web listener missing");
await active.sendComposingTo(to); await active.sendComposingTo(to);
const hasExplicitAccountId = Boolean(options.accountId?.trim());
const accountId = hasExplicitAccountId ? resolvedAccountId : undefined;
const sendOptions: ActiveWebSendOptions | undefined = const sendOptions: ActiveWebSendOptions | undefined =
options.gifPlayback || options.accountId options.gifPlayback || accountId
? { ? {
...(options.gifPlayback ? { gifPlayback: true } : {}), ...(options.gifPlayback ? { gifPlayback: true } : {}),
accountId: options.accountId, accountId,
} }
: undefined; : undefined;
const result = sendOptions const result = sendOptions
@@ -112,7 +105,7 @@ export async function sendReactionWhatsApp(
}, },
): Promise<void> { ): Promise<void> {
const correlationId = randomUUID(); const correlationId = randomUUID();
const active = requireActiveListener(options.accountId); const { listener: active } = requireActiveWebListener(options.accountId);
const logger = getChildLogger({ const logger = getChildLogger({
module: "web-outbound", module: "web-outbound",
correlationId, correlationId,
@@ -148,7 +141,7 @@ export async function sendPollWhatsApp(
): Promise<{ messageId: string; toJid: string }> { ): Promise<{ messageId: string; toJid: string }> {
const correlationId = randomUUID(); const correlationId = randomUUID();
const startedAt = Date.now(); const startedAt = Date.now();
const active = requireActiveListener(options.accountId); const { listener: active } = requireActiveWebListener(options.accountId);
const logger = getChildLogger({ const logger = getChildLogger({
module: "web-outbound", module: "web-outbound",
correlationId, correlationId,