Assign matrix platform chat ids on creation

This commit is contained in:
Mikhail Putilovskij 2026-04-19 17:31:21 +03:00
parent 0cdee532c4
commit 8270e5821e
4 changed files with 76 additions and 35 deletions

View file

@ -16,16 +16,20 @@ from adapter.matrix.store import (
logger = structlog.get_logger(__name__)
async def handle_invite(client: Any, room: Any, event: Any, platform, store, auth_mgr, chat_mgr) -> None:
matrix_user_id = getattr(event, "sender", "")
display_name = getattr(room, "display_name", None) or matrix_user_id
def _default_room_name(chat_id: str) -> str:
suffix = chat_id[1:] if chat_id.startswith("C") else chat_id
return f"Чат {suffix}"
await client.join(room.room_id)
existing = await get_user_meta(store, matrix_user_id)
if existing and existing.get("space_id"):
return
async def provision_workspace_chat(
client: Any,
matrix_user_id: str,
display_name: str,
platform,
store,
auth_mgr,
chat_mgr,
) -> dict:
user = await platform.get_or_create_user(
external_id=matrix_user_id,
platform="matrix",
@ -34,24 +38,31 @@ async def handle_invite(client: Any, room: Any, event: Any, platform, store, aut
await auth_mgr.confirm(matrix_user_id)
homeserver = matrix_user_id.split(":")[-1]
user_meta = await get_user_meta(store, matrix_user_id) or {}
space_id = user_meta.get("space_id")
space_resp = await client.room_create(
name=f"Lambda — {display_name}",
space=True,
visibility=RoomVisibility.private,
invite=[matrix_user_id],
)
if isinstance(space_resp, RoomCreateError):
logger.error(
"space creation failed",
user=matrix_user_id,
error=getattr(space_resp, "status_code", None),
if not space_id:
space_resp = await client.room_create(
name=f"Lambda — {display_name}",
space=True,
visibility=RoomVisibility.private,
invite=[matrix_user_id],
)
return
space_id = space_resp.room_id
if isinstance(space_resp, RoomCreateError):
logger.error(
"space creation failed",
user=matrix_user_id,
error=getattr(space_resp, "status_code", None),
)
raise RuntimeError("Не удалось создать Space.")
space_id = space_resp.room_id
user_meta["space_id"] = space_id
await set_user_meta(store, matrix_user_id, user_meta)
chat_id = await next_chat_id(store, matrix_user_id)
room_name = _default_room_name(chat_id)
chat_resp = await client.room_create(
name="Чат 1",
name=room_name,
visibility=RoomVisibility.private,
is_direct=False,
invite=[matrix_user_id],
@ -62,7 +73,7 @@ async def handle_invite(client: Any, room: Any, event: Any, platform, store, aut
user=matrix_user_id,
error=getattr(chat_resp, "status_code", None),
)
return
raise RuntimeError("Не удалось создать рабочий чат.")
chat_room_id = chat_resp.room_id
await client.room_put_state(
@ -72,21 +83,16 @@ async def handle_invite(client: Any, room: Any, event: Any, platform, store, aut
state_key=chat_room_id,
)
chat_id = await next_chat_id(store, matrix_user_id)
user_meta = await get_user_meta(store, matrix_user_id) or {}
user_meta["space_id"] = space_id
await set_user_meta(store, matrix_user_id, user_meta)
await set_room_meta(
store,
chat_room_id,
{
"room_type": "chat",
"chat_id": chat_id,
"display_name": "Чат 1",
"display_name": room_name,
"matrix_user_id": matrix_user_id,
"space_id": space_id,
"platform_chat_id": f"matrix:{chat_room_id}",
},
)
await chat_mgr.get_or_create(
@ -94,15 +100,44 @@ async def handle_invite(client: Any, room: Any, event: Any, platform, store, aut
chat_id=chat_id,
platform="matrix",
surface_ref=chat_room_id,
name="Чат 1",
name=room_name,
)
return {
"user": user,
"space_id": space_id,
"chat_room_id": chat_room_id,
"chat_id": chat_id,
"room_name": room_name,
}
async def handle_invite(client: Any, room: Any, event: Any, platform, store, auth_mgr, chat_mgr) -> None:
matrix_user_id = getattr(event, "sender", "")
display_name = getattr(room, "display_name", None) or matrix_user_id
await client.join(room.room_id)
existing = await get_user_meta(store, matrix_user_id)
if existing and existing.get("space_id"):
return
created = await provision_workspace_chat(
client,
matrix_user_id,
display_name,
platform,
store,
auth_mgr,
chat_mgr,
)
welcome = (
f"Привет, {user.display_name or matrix_user_id}! Пиши — я здесь.\n\n"
"Команды: !new · !chats · !rename · !archive · !skills · !soul · !safety · !settings"
f"Привет, {created['user'].display_name or matrix_user_id}! Пиши — я здесь.\n\n"
"Команды: !new · !chats · !rename · !archive · !context · !save · !load · !help"
)
await client.room_send(
chat_room_id,
created["chat_room_id"],
"m.room.message",
{"msgtype": "m.text", "body": welcome},
)

View file

@ -106,6 +106,7 @@ def make_handle_new_chat(
"display_name": room_name,
"matrix_user_id": event.user_id,
"space_id": space_id,
"platform_chat_id": f"matrix:{room_id}",
},
)
ctx = await chat_mgr.get_or_create(

View file

@ -7,7 +7,7 @@ from nio.api import RoomVisibility
from nio.responses import RoomCreateError
from adapter.matrix.handlers.chat import make_handle_archive, make_handle_new_chat, make_handle_rename
from adapter.matrix.store import set_user_meta
from adapter.matrix.store import get_room_meta, set_user_meta
from core.auth import AuthManager
from core.chat import ChatManager
from core.protocol import IncomingCommand, OutgoingMessage
@ -57,6 +57,9 @@ async def test_mat04_new_chat_calls_room_put_state_with_space_id():
assert kwargs.get("room_id") == "!space:ex"
assert kwargs.get("event_type") == "m.space.child"
assert kwargs.get("state_key") == "!newroom:ex"
room_meta = await get_room_meta(store, "!newroom:ex")
assert room_meta is not None
assert room_meta["platform_chat_id"] == "matrix:!newroom:ex"
assert any(isinstance(item, OutgoingMessage) and "Test" in item.text for item in result)

View file

@ -64,6 +64,7 @@ async def test_mat01_invite_creates_space_and_chat1():
assert room_meta is not None
assert room_meta["chat_id"] == "C4"
assert room_meta["space_id"] == "!space:example.org"
assert room_meta["platform_chat_id"] == "matrix:!chat1:example.org"
assert user_meta["next_chat_index"] == 5
chats = await runtime.chat_mgr.list_active("@alice:example.org")
@ -119,6 +120,7 @@ async def test_mat03_no_hardcoded_c1():
room_meta = await get_room_meta(runtime.store, "!chat1:example.org")
assert room_meta is not None
assert room_meta["chat_id"] == "C7"
assert room_meta["platform_chat_id"] == "matrix:!chat1:example.org"
user_meta = await get_user_meta(runtime.store, "@alice:example.org")
assert user_meta is not None