From f85ec610f267020b66713c09e648ec004b2e26f1 Mon Sep 17 00:00:00 2001 From: bmendonca3 Date: Tue, 3 Mar 2026 16:03:50 -0700 Subject: [PATCH] feishu extension: tighten reply target fallback semantics --- extensions/feishu/src/outbound.test.ts | 28 ++++++++++++++++++++++++++ extensions/feishu/src/outbound.ts | 9 ++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/extensions/feishu/src/outbound.test.ts b/extensions/feishu/src/outbound.test.ts index 5fbe6646490..03d44a79175 100644 --- a/extensions/feishu/src/outbound.test.ts +++ b/extensions/feishu/src/outbound.test.ts @@ -155,6 +155,26 @@ describe("feishuOutbound.sendText local-image auto-convert", () => { }), ); }); + + it("falls back to threadId when replyToId is empty on sendText", async () => { + await sendText({ + cfg: {} as any, + to: "chat_1", + text: "hello", + replyToId: " ", + threadId: "om_thread_2", + accountId: "main", + } as any); + + expect(sendMessageFeishuMock).toHaveBeenCalledWith( + expect.objectContaining({ + to: "chat_1", + text: "hello", + replyToMessageId: "om_thread_2", + accountId: "main", + }), + ); + }); }); describe("feishuOutbound.sendMedia renderMode", () => { @@ -216,5 +236,13 @@ describe("feishuOutbound.sendMedia renderMode", () => { accountId: "main", }), ); + expect(sendMessageFeishuMock).toHaveBeenCalledWith( + expect.objectContaining({ + to: "chat_1", + text: "caption", + replyToMessageId: "om_thread_1", + accountId: "main", + }), + ); }); }); diff --git a/extensions/feishu/src/outbound.ts b/extensions/feishu/src/outbound.ts index 50c7a1fdbda..a7404dd6dce 100644 --- a/extensions/feishu/src/outbound.ts +++ b/extensions/feishu/src/outbound.ts @@ -47,11 +47,14 @@ function resolveReplyToMessageId(params: { replyToId?: string | null; threadId?: string | number | null; }): string | undefined { - const replyTarget = params.replyToId ?? params.threadId; - if (replyTarget == null) { + const replyToId = params.replyToId?.trim(); + if (replyToId) { + return replyToId; + } + if (params.threadId == null) { return undefined; } - const trimmed = String(replyTarget).trim(); + const trimmed = String(params.threadId).trim(); return trimmed || undefined; }