fix: let agents download Feishu message resources

This commit is contained in:
2026-07-10 12:17:07 +08:00
parent 4ca4afb141
commit 1094ebd651
9 changed files with 332 additions and 27 deletions
+41 -2
View File
@@ -1,11 +1,48 @@
import { describe, expect, it, vi } from "vitest";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { resolveSenderName, sendFile, sendLongText, sendTextMessage, type FeishuRuntime } from "../../src/feishu/client.js";
import {
downloadMessageFile,
resolveSenderName,
sendFile,
sendLongText,
sendTextMessage,
type FeishuRuntime,
} from "../../src/feishu/client.js";
import { SenderNameCache } from "../../src/feishu/senderCache.js";
describe("Feishu client helpers", () => {
it("downloads an image message resource through the SDK stream helper", async () => {
const dir = await mkdtemp(join(tmpdir(), "hub-feishu-client-"));
try {
const destination = join(dir, "image.png");
const resourceWriteFile = vi.fn(async (filePath: string) => {
await writeFile(filePath, "image bytes");
});
const messageResourceGet = vi.fn(async () => ({ writeFile: resourceWriteFile }));
const rawRequest = vi.fn(async () => Buffer.from("image bytes"));
const rt = mockRuntime({
fileCreate: vi.fn(),
messageCreate: vi.fn(),
messageResourceGet,
request: rawRequest,
});
await downloadMessageFile(rt, "message-1", "img-key-1", destination, "image");
expect(messageResourceGet).toHaveBeenCalledWith({
params: { type: "image" },
path: { message_id: "message-1", file_key: "img-key-1" },
});
expect(resourceWriteFile).toHaveBeenCalledWith(destination);
await expect(readFile(destination, "utf8")).resolves.toBe("image bytes");
expect(rawRequest).not.toHaveBeenCalled();
} finally {
await rm(dir, { recursive: true, force: true });
}
});
it("accepts top-level file_key from the Lark SDK file upload response", async () => {
const dir = await mkdtemp(join(tmpdir(), "hub-feishu-client-"));
try {
@@ -89,6 +126,7 @@ function mockRuntime(options: {
readonly messageCreate: (payload: unknown) => Promise<unknown>;
readonly messageReply?: (payload: unknown) => Promise<unknown>;
readonly contactBasicBatch?: (payload: unknown) => Promise<unknown>;
readonly messageResourceGet?: (payload: unknown) => Promise<unknown>;
readonly request?: (payload: unknown) => Promise<unknown>;
}): FeishuRuntime {
return {
@@ -104,6 +142,7 @@ function mockRuntime(options: {
im: {
v1: {
file: { create: options.fileCreate },
messageResource: { get: options.messageResourceGet },
message: {
create: options.messageCreate,
reply: options.messageReply ?? vi.fn(async () => ({ data: { message_id: "reply-1" } })),