diff --git a/nanobot/channels/feishu.py b/nanobot/channels/feishu.py index e57fcef85..7d9c2772b 100644 --- a/nanobot/channels/feishu.py +++ b/nanobot/channels/feishu.py @@ -1014,14 +1014,29 @@ class FeishuChannel(BaseChannel): elif msg_type in ("audio", "file", "media"): file_key = content_json.get("file_key") - if file_key and message_id: - data, filename = await loop.run_in_executor( - None, self._download_file_sync, message_id, file_key, msg_type - ) - if not filename: - filename = file_key[:16] - if msg_type == "audio" and not filename.endswith(".opus"): - filename = f"{filename}.opus" + if not file_key: + logger.warning("Feishu {} message missing file_key: {}", msg_type, content_json) + return None, f"[{msg_type}: missing file_key]" + if not message_id: + logger.warning("Feishu {} message missing message_id", msg_type) + return None, f"[{msg_type}: missing message_id]" + + data, filename = await loop.run_in_executor( + None, self._download_file_sync, message_id, file_key, msg_type + ) + + if not data: + logger.warning("Feishu {} download failed: file_key={}", msg_type, file_key) + return None, f"[{msg_type}: download failed]" + + if not filename: + filename = file_key[:16] + + # Feishu voice messages are opus in OGG container. + # Use .ogg extension for better Whisper compatibility. + if msg_type == "audio": + if not any(filename.endswith(ext) for ext in (".opus", ".ogg", ".oga")): + filename = f"{filename}.ogg" if data and filename: file_path = media_dir / filename