Upstream AgentApi responses can return attachment objects that don't implement the Attachment dataclass. _to_core_attachments coerces them via duck-typing so OutgoingMessage always carries typed Attachment instances regardless of the upstream response shape.
71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
# core/handlers/message.py
|
|
from __future__ import annotations
|
|
|
|
from core.protocol import Attachment, IncomingMessage, OutgoingMessage, OutgoingTyping
|
|
|
|
|
|
def _infer_attachment_type(mime_type: str | None) -> str:
|
|
if not mime_type:
|
|
return "document"
|
|
if mime_type.startswith("image/"):
|
|
return "image"
|
|
if mime_type.startswith("audio/"):
|
|
return "audio"
|
|
if mime_type.startswith("video/"):
|
|
return "video"
|
|
return "document"
|
|
|
|
|
|
def _to_core_attachments(raw: list) -> list[Attachment]:
|
|
result = []
|
|
for a in raw:
|
|
if isinstance(a, Attachment):
|
|
result.append(a)
|
|
else:
|
|
result.append(Attachment(
|
|
type=getattr(a, "type", None) or _infer_attachment_type(getattr(a, "mime_type", None)),
|
|
url=getattr(a, "url", None),
|
|
filename=getattr(a, "filename", None),
|
|
mime_type=getattr(a, "mime_type", None),
|
|
workspace_path=getattr(a, "workspace_path", None),
|
|
))
|
|
return result
|
|
|
|
|
|
def _start_command(platform: str) -> str:
|
|
return "!start" if platform == "matrix" else "/start"
|
|
|
|
|
|
async def handle_message(event: IncomingMessage, auth_mgr, platform, chat_mgr, settings_mgr) -> list:
|
|
if not await auth_mgr.is_authenticated(event.user_id):
|
|
return [
|
|
OutgoingMessage(
|
|
chat_id=event.chat_id,
|
|
text=f"Введите {_start_command(event.platform)} чтобы начать.",
|
|
)
|
|
]
|
|
|
|
# Voice slot fallback: audio attachment without registered voice_handler
|
|
if event.attachments and event.attachments[0].type == "audio":
|
|
return [OutgoingMessage(
|
|
chat_id=event.chat_id,
|
|
text="Голосовые сообщения скоро поддержим.",
|
|
parse_mode="plain",
|
|
)]
|
|
|
|
response = await platform.send_message(
|
|
user_id=event.user_id,
|
|
chat_id=event.chat_id,
|
|
text=event.text,
|
|
attachments=event.attachments,
|
|
)
|
|
|
|
return [
|
|
OutgoingTyping(chat_id=event.chat_id, is_typing=False),
|
|
OutgoingMessage(
|
|
chat_id=event.chat_id,
|
|
text=response.response,
|
|
parse_mode="markdown",
|
|
attachments=_to_core_attachments(getattr(response, "attachments", [])),
|
|
),
|
|
]
|