fix(wecom): preserve real filename from SDK when payload omits name (#3737)

This commit is contained in:
04cb 2026-05-12 08:38:11 +08:00 committed by Xubin Ren
parent 6d07aa6059
commit bd0ba745dd
2 changed files with 25 additions and 4 deletions

View File

@ -292,17 +292,18 @@ class WecomChannel(BaseChannel):
file_info = body.get("file", {})
file_url = file_info.get("url", "")
aes_key = file_info.get("aeskey", "")
file_name = file_info.get("name", "unknown")
file_name = file_info.get("name") or None
if file_url and aes_key:
file_path = await self._download_and_save_media(file_url, aes_key, "file", file_name)
if file_path:
content_parts.append(f"[file: {file_name}]")
display_name = os.path.basename(file_path)
content_parts.append(f"[file: {display_name}]")
media_paths.append(file_path)
else:
content_parts.append(f"[file: {file_name}: download failed]")
content_parts.append(f"[file: {file_name or 'unknown'}: download failed]")
else:
content_parts.append(f"[file: {file_name}: download failed]")
content_parts.append(f"[file: {file_name or 'unknown'}: download failed]")
elif msg_type == "mixed":
# Mixed content contains multiple message items

View File

@ -552,6 +552,26 @@ async def test_process_file_message() -> None:
os.unlink(p)
@pytest.mark.asyncio
async def test_process_file_message_uses_sdk_filename_when_name_missing(tmp_path: Path) -> None:
"""Without `file.name`, fall back to SDK fname instead of saving as 'unknown' (#3737)."""
channel = WecomChannel(WecomConfig(bot_id="b", secret="s", allow_from=["user1"]), MessageBus())
client = _FakeWeComClient()
client.download_file.return_value = (b"%PDF-1.4 fake", "real_name.pdf")
channel._client = client
with patch("nanobot.channels.wecom.get_media_dir", return_value=tmp_path):
frame = _FakeFrame(body={
"msgid": "msg_file_2", "chatid": "chat1", "from": {"userid": "user1"},
"file": {"url": "https://example.com/x", "aeskey": "key456"},
})
await channel._process_message(frame, "file")
msg = await channel.bus.consume_inbound()
assert msg.media == [str(tmp_path / "real_name.pdf")]
assert "[file: real_name.pdf]" in msg.content
@pytest.mark.asyncio
async def test_process_voice_message() -> None:
"""Voice message: transcribed text is included in content."""