138 lines
3.8 KiB
Python
138 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from core.protocol import (
|
|
Attachment,
|
|
IncomingCallback,
|
|
IncomingCommand,
|
|
IncomingEvent,
|
|
IncomingMessage,
|
|
)
|
|
|
|
PLATFORM = "matrix"
|
|
|
|
|
|
def extract_attachments(event: Any) -> list[Attachment]:
|
|
source = getattr(event, "source", {}) or {}
|
|
content = source.get("content", {}) or getattr(event, "content", {}) or {}
|
|
msgtype = getattr(event, "msgtype", None)
|
|
if msgtype is None:
|
|
msgtype = content.get("msgtype")
|
|
url = content.get("url") or getattr(event, "url", None)
|
|
filename = content.get("body") or getattr(event, "body", None)
|
|
mime_type = content.get("mimetype") or getattr(event, "mimetype", None)
|
|
if mime_type is None:
|
|
info = content.get("info") or {}
|
|
if isinstance(info, dict):
|
|
mime_type = info.get("mimetype")
|
|
|
|
if msgtype == "m.image":
|
|
return [
|
|
Attachment(
|
|
type="image",
|
|
url=url,
|
|
filename=filename,
|
|
mime_type=mime_type,
|
|
)
|
|
]
|
|
if msgtype == "m.file":
|
|
return [
|
|
Attachment(
|
|
type="document",
|
|
url=url,
|
|
filename=filename,
|
|
mime_type=mime_type,
|
|
)
|
|
]
|
|
if msgtype == "m.audio":
|
|
return [
|
|
Attachment(
|
|
type="audio",
|
|
url=url,
|
|
filename=filename,
|
|
mime_type=mime_type,
|
|
)
|
|
]
|
|
if msgtype == "m.video":
|
|
return [
|
|
Attachment(
|
|
type="video",
|
|
url=url,
|
|
filename=filename,
|
|
mime_type=mime_type,
|
|
)
|
|
]
|
|
return []
|
|
|
|
|
|
def from_command(body: str, sender: str, chat_id: str, room_id: str | None = None) -> IncomingEvent:
|
|
raw = body.lstrip("!").strip()
|
|
parts = raw.split()
|
|
command = parts[0].lower() if parts else ""
|
|
args = parts[1:]
|
|
|
|
if command in {"yes", "no"}:
|
|
action = "confirm" if command == "yes" else "cancel"
|
|
return IncomingCallback(
|
|
user_id=sender,
|
|
platform=PLATFORM,
|
|
chat_id=chat_id,
|
|
action=action,
|
|
payload={
|
|
"source": "command",
|
|
"command": command,
|
|
**({"room_id": room_id} if room_id is not None else {}),
|
|
},
|
|
)
|
|
|
|
if command == "list" and not args:
|
|
return IncomingCommand(
|
|
user_id=sender,
|
|
platform=PLATFORM,
|
|
chat_id=chat_id,
|
|
command="matrix_list_attachments",
|
|
args=[],
|
|
)
|
|
|
|
if command == "remove" and len(args) == 1:
|
|
return IncomingCommand(
|
|
user_id=sender,
|
|
platform=PLATFORM,
|
|
chat_id=chat_id,
|
|
command="matrix_remove_attachment",
|
|
args=[args[0]],
|
|
)
|
|
|
|
aliases = {
|
|
"skills": "settings_skills",
|
|
"connectors": "settings_connectors",
|
|
"soul": "settings_soul",
|
|
"safety": "settings_safety",
|
|
"plan": "settings_plan",
|
|
"status": "settings_status",
|
|
"whoami": "settings_whoami",
|
|
}
|
|
command = aliases.get(command, command)
|
|
return IncomingCommand(
|
|
user_id=sender,
|
|
platform=PLATFORM,
|
|
chat_id=chat_id,
|
|
command=command,
|
|
args=args,
|
|
)
|
|
|
|
|
|
def from_room_event(event: Any, room_id: str, chat_id: str) -> IncomingEvent | None:
|
|
body = (getattr(event, "body", None) or "").strip()
|
|
sender = getattr(event, "sender", "")
|
|
if body.startswith("!"):
|
|
return from_command(body, sender=sender, chat_id=chat_id, room_id=room_id)
|
|
return IncomingMessage(
|
|
user_id=sender,
|
|
platform=PLATFORM,
|
|
chat_id=chat_id,
|
|
text=body,
|
|
attachments=extract_attachments(event),
|
|
reply_to=getattr(event, "replyto_event_id", None),
|
|
)
|