From 1afd7030f8e5e9dda682f1de5942a9662ac7dbcf Mon Sep 17 00:00:00 2001 From: Marcus Castro Date: Mon, 23 Feb 2026 23:17:36 -0300 Subject: [PATCH] fix(hooks): decouple message:sent internal hook from mirror param --- src/infra/outbound/deliver.test.ts | 31 +++++++++++++++++++++++++++++- src/infra/outbound/deliver.ts | 4 +++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/infra/outbound/deliver.test.ts b/src/infra/outbound/deliver.test.ts index 0927de7df99..c39d966b804 100644 --- a/src/infra/outbound/deliver.test.ts +++ b/src/infra/outbound/deliver.test.ts @@ -478,7 +478,7 @@ describe("deliverOutboundPayloads", () => { expect(internalHookMocks.triggerInternalHook).toHaveBeenCalledTimes(1); }); - it("does not emit internal message:sent hook when mirror sessionKey is missing", async () => { + it("does not emit internal message:sent hook when neither mirror nor sessionKey is provided", async () => { const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "w1", toJid: "jid" }); await deliverOutboundPayloads({ @@ -493,6 +493,35 @@ describe("deliverOutboundPayloads", () => { expect(internalHookMocks.triggerInternalHook).not.toHaveBeenCalled(); }); + it("emits internal message:sent hook when sessionKey is provided without mirror", async () => { + const sendWhatsApp = vi.fn().mockResolvedValue({ messageId: "w1", toJid: "jid" }); + + await deliverOutboundPayloads({ + cfg: whatsappChunkConfig, + channel: "whatsapp", + to: "+1555", + payloads: [{ text: "hello" }], + deps: { sendWhatsApp }, + sessionKey: "agent:main:main", + }); + + expect(internalHookMocks.createInternalHookEvent).toHaveBeenCalledTimes(1); + expect(internalHookMocks.createInternalHookEvent).toHaveBeenCalledWith( + "message", + "sent", + "agent:main:main", + expect.objectContaining({ + to: "+1555", + content: "hello", + success: true, + channelId: "whatsapp", + conversationId: "+1555", + messageId: "w1", + }), + ); + expect(internalHookMocks.triggerInternalHook).toHaveBeenCalledTimes(1); + }); + it("calls failDelivery instead of ackDelivery on bestEffort partial failure", async () => { const sendWhatsApp = vi .fn() diff --git a/src/infra/outbound/deliver.ts b/src/infra/outbound/deliver.ts index 908b786e5ee..f071a25d048 100644 --- a/src/infra/outbound/deliver.ts +++ b/src/infra/outbound/deliver.ts @@ -216,6 +216,8 @@ type DeliverOutboundPayloadsCoreParams = { mediaUrls?: string[]; }; silent?: boolean; + /** Session key for internal hook dispatch (when `mirror` is not needed). */ + sessionKey?: string; }; type DeliverOutboundPayloadsParams = DeliverOutboundPayloadsCoreParams & { @@ -444,7 +446,7 @@ async function deliverOutboundPayloadsCore( return normalized ? [normalized] : []; }); const hookRunner = getGlobalHookRunner(); - const sessionKeyForInternalHooks = params.mirror?.sessionKey; + const sessionKeyForInternalHooks = params.mirror?.sessionKey ?? params.sessionKey; for (const payload of normalizedPayloads) { const payloadSummary: NormalizedOutboundPayload = { text: payload.text ?? "",