fix(hub): send Feishu files explicitly

This commit is contained in:
2026-07-08 11:48:25 +08:00
parent c73b41e1da
commit 6178664696
8 changed files with 524 additions and 72 deletions
+32 -7
View File
@@ -60,14 +60,14 @@ export interface CardActionEvent {
export async function sendTextMessage(rt: FeishuRuntime, chatId: string, text: string): Promise<string | null> {
const card = { elements: [{ tag: "div", text: { tag: "lark_md", content: text } }] };
const client = rt.client as unknown as {
im: { v1: { message: { create: (p: unknown) => Promise<{ data?: { message_id?: string } }> } } };
im: { v1: { message: { create: (p: unknown) => Promise<MessageCreateResponse> } } };
};
try {
const res = await client.im.v1.message.create({
params: { receive_id_type: "chat_id" },
data: { receive_id: chatId, msg_type: "interactive", content: JSON.stringify(card) },
});
return res.data?.message_id ?? null;
return messageIdFromResponse(res);
} catch { return null; }
}
@@ -133,8 +133,8 @@ export async function downloadMessageFile(
export async function sendFile(rt: FeishuRuntime, chatId: string, filePath: string, fileName: string): Promise<string | null> {
const client = rt.client as unknown as {
im: { v1: {
file: { create: (p: unknown) => Promise<{ data?: { file_key?: string } }> }
message: { create: (p: unknown) => Promise<{ data?: { message_id?: string } }> }
file: { create: (p: unknown) => Promise<FileCreateResponse> }
message: { create: (p: unknown) => Promise<MessageCreateResponse> }
} };
};
try {
@@ -142,19 +142,44 @@ export async function sendFile(rt: FeishuRuntime, chatId: string, filePath: stri
const ext = fileName.split(".").pop() ?? "";
const fileType = ext === "pdf" ? "pdf" : ext === "doc" ? "doc" : ext === "xls" ? "xls" : ext === "ppt" ? "ppt" : "stream";
const uploadRes = await client.im.v1.file.create({ data: { file_type: fileType, file_name: fileName, file: buf } });
const fileKey = uploadRes.data?.file_key;
if (fileKey === undefined) return null;
const fileKey = fileKeyFromResponse(uploadRes);
if (fileKey === undefined) {
rt.logger.warn({ chatId, filePath }, "sendFile failed: upload response missing file_key");
return null;
}
const msgRes = await client.im.v1.message.create({
params: { receive_id_type: "chat_id" },
data: { receive_id: chatId, msg_type: "file", content: JSON.stringify({ file_key: fileKey }) },
});
return msgRes.data?.message_id ?? null;
const messageId = messageIdFromResponse(msgRes);
if (messageId === null) {
rt.logger.warn({ chatId, filePath }, "sendFile failed: message response missing message_id");
}
return messageId;
} catch (e) {
rt.logger.warn({ chatId, filePath, err: e instanceof Error ? e.message : String(e) }, "sendFile failed");
return null;
}
}
type MessageCreateResponse = {
readonly message_id?: string | undefined;
readonly data?: { readonly message_id?: string | undefined } | undefined;
} | null;
type FileCreateResponse = {
readonly file_key?: string | undefined;
readonly data?: { readonly file_key?: string | undefined } | undefined;
} | null;
function messageIdFromResponse(res: MessageCreateResponse): string | null {
return res?.data?.message_id ?? res?.message_id ?? null;
}
function fileKeyFromResponse(res: FileCreateResponse): string | undefined {
return res?.file_key ?? res?.data?.file_key;
}
// --- Lark client + ws listener ---
export function createLarkClient(config: FeishuConfig): lark.Client {