* feat(feishu): add parentId and rootId to inbound context Add ParentMessageId and RootMessageId fields to Feishu inbound message context, enabling agents to: - Identify quoted/replied messages - Fetch original message content via Feishu API - Build proper message thread context The parent_id and root_id fields already exist in FeishuMessageContext but were not being passed to the agent's inbound context. Fixes: Allows proper handling of quoted card messages and message thread reconstruction. * feat(feishu): parse interactive card content in quoted messages Add support for extracting readable text from interactive card messages when fetching quoted/replied message content. Previously, only text messages were parsed. Now interactive cards (with div and markdown elements) are also converted to readable text. * 更新 bot.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(types): add RootMessageId to MsgContext type definition * style: fix formatting in bot.ts * ci: trigger rebuild * ci: retry flaky tests * Feishu: add reply-context and interactive-quote regressions --------- Co-authored-by: qiangu <qiangu@qq.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> Co-authored-by: 牛牛 <niuniu@openclaw.ai> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
72 lines
1.7 KiB
TypeScript
72 lines
1.7 KiB
TypeScript
import type { ClawdbotConfig } from "openclaw/plugin-sdk";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { getMessageFeishu } from "./send.js";
|
|
|
|
const { mockClientGet, mockCreateFeishuClient, mockResolveFeishuAccount } = vi.hoisted(() => ({
|
|
mockClientGet: vi.fn(),
|
|
mockCreateFeishuClient: vi.fn(),
|
|
mockResolveFeishuAccount: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("./client.js", () => ({
|
|
createFeishuClient: mockCreateFeishuClient,
|
|
}));
|
|
|
|
vi.mock("./accounts.js", () => ({
|
|
resolveFeishuAccount: mockResolveFeishuAccount,
|
|
}));
|
|
|
|
describe("getMessageFeishu", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
mockResolveFeishuAccount.mockReturnValue({
|
|
accountId: "default",
|
|
configured: true,
|
|
});
|
|
mockCreateFeishuClient.mockReturnValue({
|
|
im: {
|
|
message: {
|
|
get: mockClientGet,
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("extracts text content from interactive card elements", async () => {
|
|
mockClientGet.mockResolvedValueOnce({
|
|
code: 0,
|
|
data: {
|
|
items: [
|
|
{
|
|
message_id: "om_1",
|
|
chat_id: "oc_1",
|
|
msg_type: "interactive",
|
|
body: {
|
|
content: JSON.stringify({
|
|
elements: [
|
|
{ tag: "markdown", content: "hello markdown" },
|
|
{ tag: "div", text: { content: "hello div" } },
|
|
],
|
|
}),
|
|
},
|
|
},
|
|
],
|
|
},
|
|
});
|
|
|
|
const result = await getMessageFeishu({
|
|
cfg: {} as ClawdbotConfig,
|
|
messageId: "om_1",
|
|
});
|
|
|
|
expect(result).toEqual(
|
|
expect.objectContaining({
|
|
messageId: "om_1",
|
|
chatId: "oc_1",
|
|
contentType: "interactive",
|
|
content: "hello markdown\nhello div",
|
|
}),
|
|
);
|
|
});
|
|
});
|