diff --git a/src/web/inbound/access-control.test.ts b/src/web/inbound/access-control.test.ts index 61db5a2d2..ac6c447ec 100644 --- a/src/web/inbound/access-control.test.ts +++ b/src/web/inbound/access-control.test.ts @@ -24,6 +24,12 @@ async function checkUnauthorizedWorkDmSender() { }); } +function expectSilentlyBlocked(result: { allowed: boolean }) { + expect(result.allowed).toBe(false); + expect(upsertPairingRequestMock).not.toHaveBeenCalled(); + expect(sendMessageMock).not.toHaveBeenCalled(); +} + describe("checkInboundAccessControl pairing grace", () => { async function runPairingGraceCase(messageTimestampMs: number) { const connectedAtMs = 1_000_000; @@ -80,10 +86,7 @@ describe("WhatsApp dmPolicy precedence", () => { }); const result = await checkUnauthorizedWorkDmSender(); - - expect(result.allowed).toBe(false); - expect(upsertPairingRequestMock).not.toHaveBeenCalled(); - expect(sendMessageMock).not.toHaveBeenCalled(); + expectSilentlyBlocked(result); }); it("inherits channel-level dmPolicy when account-level dmPolicy is unset", async () => { @@ -103,9 +106,6 @@ describe("WhatsApp dmPolicy precedence", () => { }); const result = await checkUnauthorizedWorkDmSender(); - - expect(result.allowed).toBe(false); - expect(upsertPairingRequestMock).not.toHaveBeenCalled(); - expect(sendMessageMock).not.toHaveBeenCalled(); + expectSilentlyBlocked(result); }); }); diff --git a/src/web/inbound/send-api.ts b/src/web/inbound/send-api.ts index 0517dc226..05824536c 100644 --- a/src/web/inbound/send-api.ts +++ b/src/web/inbound/send-api.ts @@ -3,6 +3,20 @@ import type { ActiveWebSendOptions } from "../active-listener.js"; import { recordChannelActivity } from "../../infra/channel-activity.js"; import { toWhatsappJid } from "../../utils.js"; +function recordWhatsAppOutbound(accountId: string) { + recordChannelActivity({ + channel: "whatsapp", + accountId, + direction: "outbound", + }); +} + +function resolveOutboundMessageId(result: unknown): string { + return typeof result === "object" && result && "key" in result + ? String((result as { key?: { id?: string } }).key?.id ?? "unknown") + : "unknown"; +} + export function createWebSendApi(params: { sock: { sendMessage: (jid: string, content: AnyMessageContent) => Promise; @@ -51,15 +65,8 @@ export function createWebSendApi(params: { } const result = await params.sock.sendMessage(jid, payload); const accountId = sendOptions?.accountId ?? params.defaultAccountId; - recordChannelActivity({ - channel: "whatsapp", - accountId, - direction: "outbound", - }); - const messageId = - typeof result === "object" && result && "key" in result - ? String((result as { key?: { id?: string } }).key?.id ?? "unknown") - : "unknown"; + recordWhatsAppOutbound(accountId); + const messageId = resolveOutboundMessageId(result); return { messageId }; }, sendPoll: async ( @@ -74,15 +81,8 @@ export function createWebSendApi(params: { selectableCount: poll.maxSelections ?? 1, }, } as AnyMessageContent); - recordChannelActivity({ - channel: "whatsapp", - accountId: params.defaultAccountId, - direction: "outbound", - }); - const messageId = - typeof result === "object" && result && "key" in result - ? String((result as { key?: { id?: string } }).key?.id ?? "unknown") - : "unknown"; + recordWhatsAppOutbound(params.defaultAccountId); + const messageId = resolveOutboundMessageId(result); return { messageId }; }, sendReaction: async (