From 043fdfbbdab1a750cc5c880172f7fb82d643f5aa Mon Sep 17 00:00:00 2001 From: chen Date: Thu, 2 Apr 2026 17:08:19 +0800 Subject: [PATCH] fix: prefer message body fileName over Content-Disposition for non-ASCII filenames (#364) Feishu returns raw UTF-8 bytes in the Content-Disposition header filename field. Node.js HTTP clients decode headers as Latin1 per HTTP/1.1 spec, producing garbled filenames for Chinese/CJK characters. The message body already contains the correct UTF-8 file_name extracted during the converter phase. This fix simply swaps the priority: res.fileName (message body) is now preferred over result.fileName (Content-Disposition header). Fixes larksuite/openclaw-lark#364 --- src/messaging/inbound/media-resolver.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/messaging/inbound/media-resolver.ts b/src/messaging/inbound/media-resolver.ts index 9bcd6743..68a745aa 100644 --- a/src/messaging/inbound/media-resolver.ts +++ b/src/messaging/inbound/media-resolver.ts @@ -53,7 +53,11 @@ export async function downloadResources(params: { contentType = await core.media.detectMime({ buffer: result.buffer }); } - const fileName = result.fileName || res.fileName; + // Prefer the file name from the message body (res.fileName) over + // Content-Disposition (result.fileName), because Feishu may return + // raw UTF-8 bytes in the header that get misinterpreted as Latin1 + // by Node.js HTTP clients, producing garbled non-ASCII filenames. + const fileName = res.fileName || result.fileName; const saved = await core.channel.media.saveMediaBuffer(result.buffer, contentType, 'inbound', maxBytes, fileName); const placeholder = inferPlaceholderFromType(res.type);