docs: fix matrix adapter spec — attachments, returning user, get_or_create_user

This commit is contained in:
Mikhail Putilovskij 2026-03-31 21:34:54 +03:00
parent 09919b2463
commit c979f96c3c

View file

@ -20,12 +20,17 @@ Matrix-адаптер — внутренняя поверхность для к
**Решение:** DM-комната с ботом = Чат #1. Space создаётся только при первом `!new`. **Решение:** DM-комната с ботом = Чат #1. Space создаётся только при первом `!new`.
### Флоу ### Флоу — новый пользователь
1. Пользователь инвайтит бота в личные сообщения 1. Пользователь инвайтит бота в личные сообщения
2. Бот принимает инвайт, регистрирует DM-комнату как `chat_room` с `chat_id = C1` 2. Бот принимает инвайт, вызывает `platform.get_or_create_user(matrix_user_id, "matrix", display_name)`
3. Бот пишет приветствие в DM — пользователь сразу пишет 3. Бот регистрирует DM-комнату как `chat_room` с `chat_id = C1` в SQLite
4. При первом `!new` — бот создаёт Space `Lambda — {display_name}`, добавляет DM-комнату в Space через `m.space.child`, создаёт новую комнату-чат 4. Бот пишет приветствие в DM — пользователь сразу пишет
5. При первом `!new` — бот создаёт Space `Lambda — {display_name}`, добавляет DM-комнату в Space через `m.space.child`, создаёт новую комнату-чат
### Флоу — возвращающийся пользователь
Если `matrix_user_id` уже есть в БД (бот перезапустился, или пользователь пишет повторно) — `get_or_create_user` возвращает `is_new=False`. Бот не создаёт ничего заново, просто обрабатывает сообщение в контексте существующей комнаты.
### Почему не Space сразу ### Почему не Space сразу
@ -181,10 +186,25 @@ def from_room_message(event: RoomMessageText, room_id: str, chat_id: str) -> Inc
platform="matrix", platform="matrix",
chat_id=chat_id, # C1, C2... из rooms таблицы chat_id=chat_id, # C1, C2... из rooms таблицы
text=event.body, text=event.body,
attachments=[], attachments=extract_attachments(event),
reply_to=event.replyto_event_id, reply_to=event.replyto_event_id,
) )
def extract_attachments(event: RoomMessageText) -> list[Attachment]:
# m.image → Attachment(type="image", url=mxc_url, mime_type=...)
# m.file → Attachment(type="document", url=mxc_url, filename=..., mime_type=...)
# m.audio → Attachment(type="audio", url=mxc_url, mime_type=...)
# m.text → []
msgtype = getattr(event, "msgtype", "m.text")
if msgtype == "m.image":
return [Attachment(type="image", url=event.url, mime_type=event.mimetype)]
elif msgtype == "m.file":
return [Attachment(type="document", url=event.url,
filename=event.body, mime_type=event.mimetype)]
elif msgtype == "m.audio":
return [Attachment(type="audio", url=event.url, mime_type=event.mimetype)]
return []
def from_reaction(event: ReactionEvent, room_id: str) -> IncomingCallback | None: def from_reaction(event: ReactionEvent, room_id: str) -> IncomingCallback | None:
# Парсит m.reaction → IncomingCallback(action="toggle_skill" | "confirm" | "cancel") # Парсит m.reaction → IncomingCallback(action="toggle_skill" | "confirm" | "cancel")
... ...