feat(feishu): add support for merge_forward message parsing (openclaw#28707) thanks @tsu-builds

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: tsu-builds <264409075+tsu-builds@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
tsu-builds
2026-02-28 10:57:18 +08:00
committed by GitHub
parent 8241145ada
commit f53ef73a2b
3 changed files with 265 additions and 0 deletions

View File

@@ -486,6 +486,131 @@ describe("handleFeishuMessage command authorization", () => {
);
});
it("expands merge_forward content from API sub-messages", async () => {
mockShouldComputeCommandAuthorized.mockReturnValue(false);
const mockGetMerged = vi.fn().mockResolvedValue({
code: 0,
data: {
items: [
{
message_id: "container",
msg_type: "merge_forward",
body: { content: JSON.stringify({ text: "Merged and Forwarded Message" }) },
},
{
message_id: "sub-2",
upper_message_id: "container",
msg_type: "file",
body: { content: JSON.stringify({ file_name: "report.pdf" }) },
create_time: "2000",
},
{
message_id: "sub-1",
upper_message_id: "container",
msg_type: "text",
body: { content: JSON.stringify({ text: "alpha" }) },
create_time: "1000",
},
],
},
});
mockCreateFeishuClient.mockReturnValue({
contact: {
user: {
get: vi.fn().mockResolvedValue({ data: { user: { name: "Sender" } } }),
},
},
im: {
message: {
get: mockGetMerged,
},
},
});
const cfg: ClawdbotConfig = {
channels: {
feishu: {
dmPolicy: "open",
},
},
} as ClawdbotConfig;
const event: FeishuMessageEvent = {
sender: {
sender_id: {
open_id: "ou-merge",
},
},
message: {
message_id: "msg-merge-forward",
chat_id: "oc-dm",
chat_type: "p2p",
message_type: "merge_forward",
content: JSON.stringify({ text: "Merged and Forwarded Message" }),
},
};
await dispatchMessage({ cfg, event });
expect(mockGetMerged).toHaveBeenCalledWith({
path: { message_id: "msg-merge-forward" },
});
expect(mockFinalizeInboundContext).toHaveBeenCalledWith(
expect.objectContaining({
BodyForAgent: expect.stringContaining(
"[Merged and Forwarded Messages]\n- alpha\n- [File: report.pdf]",
),
}),
);
});
it("falls back when merge_forward API returns no sub-messages", async () => {
mockShouldComputeCommandAuthorized.mockReturnValue(false);
mockCreateFeishuClient.mockReturnValue({
contact: {
user: {
get: vi.fn().mockResolvedValue({ data: { user: { name: "Sender" } } }),
},
},
im: {
message: {
get: vi.fn().mockResolvedValue({ code: 0, data: { items: [] } }),
},
},
});
const cfg: ClawdbotConfig = {
channels: {
feishu: {
dmPolicy: "open",
},
},
} as ClawdbotConfig;
const event: FeishuMessageEvent = {
sender: {
sender_id: {
open_id: "ou-merge-empty",
},
},
message: {
message_id: "msg-merge-empty",
chat_id: "oc-dm",
chat_type: "p2p",
message_type: "merge_forward",
content: JSON.stringify({ text: "Merged and Forwarded Message" }),
},
};
await dispatchMessage({ cfg, event });
expect(mockFinalizeInboundContext).toHaveBeenCalledWith(
expect.objectContaining({
BodyForAgent: expect.stringContaining("[Merged and Forwarded Message - could not fetch]"),
}),
);
});
it("dispatches once and appends permission notice to the main agent body", async () => {
mockShouldComputeCommandAuthorized.mockReturnValue(false);
mockCreateFeishuClient.mockReturnValue({