fix(01-05): align matrix confirmation scope with user and room
- carry Matrix room_id through command callbacks - persist pending confirmations by user_id and room_id
This commit is contained in:
parent
97a3dc35ea
commit
35695e043f
4 changed files with 62 additions and 25 deletions
|
|
@ -20,7 +20,7 @@ from adapter.matrix.converter import from_room_event
|
|||
from adapter.matrix.handlers import register_matrix_handlers
|
||||
from adapter.matrix.handlers.auth import handle_invite
|
||||
from adapter.matrix.room_router import resolve_chat_id
|
||||
from adapter.matrix.store import set_pending_confirm
|
||||
from adapter.matrix.store import get_room_meta, set_pending_confirm
|
||||
from core.auth import AuthManager
|
||||
from core.chat import ChatManager
|
||||
from core.handler import EventDispatcher
|
||||
|
|
@ -150,15 +150,19 @@ async def send_outgoing(
|
|||
if event.buttons and store is not None:
|
||||
action_id = event.buttons[0].action
|
||||
payload = event.buttons[0].payload
|
||||
await set_pending_confirm(
|
||||
store,
|
||||
room_id,
|
||||
{
|
||||
"action_id": action_id,
|
||||
"description": event.text,
|
||||
"payload": payload,
|
||||
},
|
||||
)
|
||||
room_meta = await get_room_meta(store, room_id)
|
||||
matrix_user_id = room_meta.get("matrix_user_id") if room_meta else None
|
||||
if matrix_user_id:
|
||||
await set_pending_confirm(
|
||||
store,
|
||||
matrix_user_id,
|
||||
room_id,
|
||||
{
|
||||
"action_id": action_id,
|
||||
"description": event.text,
|
||||
"payload": payload,
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ def extract_attachments(event: Any) -> list[Attachment]:
|
|||
return []
|
||||
|
||||
|
||||
def from_command(body: str, sender: str, chat_id: str) -> IncomingEvent:
|
||||
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 ""
|
||||
|
|
@ -69,7 +69,11 @@ def from_command(body: str, sender: str, chat_id: str) -> IncomingEvent:
|
|||
platform=PLATFORM,
|
||||
chat_id=chat_id,
|
||||
action=action,
|
||||
payload={"source": "command", "command": command},
|
||||
payload={
|
||||
"source": "command",
|
||||
"command": command,
|
||||
**({"room_id": room_id} if room_id is not None else {}),
|
||||
},
|
||||
)
|
||||
|
||||
aliases = {
|
||||
|
|
@ -132,7 +136,7 @@ def from_room_event(event: Any, room_id: str, chat_id: str) -> IncomingEvent | N
|
|||
body = (getattr(event, "body", None) or "").strip()
|
||||
sender = getattr(event, "sender", "")
|
||||
if body.startswith("!"):
|
||||
return from_command(body, sender=sender, chat_id=chat_id)
|
||||
return from_command(body, sender=sender, chat_id=chat_id, room_id=room_id)
|
||||
return IncomingMessage(
|
||||
user_id=sender,
|
||||
platform=PLATFORM,
|
||||
|
|
|
|||
|
|
@ -11,12 +11,20 @@ def make_handle_confirm(store=None):
|
|||
if store is None:
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text="Нет ожидающих подтверждений.")]
|
||||
|
||||
pending = await get_pending_confirm(store, event.chat_id)
|
||||
room_id = event.payload.get("room_id")
|
||||
pending = None
|
||||
if room_id:
|
||||
pending = await get_pending_confirm(store, event.user_id, room_id)
|
||||
if not pending:
|
||||
pending = await get_pending_confirm(store, event.chat_id)
|
||||
if not pending:
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text="Нет ожидающих подтверждений.")]
|
||||
|
||||
description = pending.get("description", "действие")
|
||||
await clear_pending_confirm(store, event.chat_id)
|
||||
if room_id:
|
||||
await clear_pending_confirm(store, event.user_id, room_id)
|
||||
else:
|
||||
await clear_pending_confirm(store, event.chat_id)
|
||||
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text=f"Подтверждено: {description}")]
|
||||
|
||||
|
|
@ -30,11 +38,19 @@ def make_handle_cancel(store=None):
|
|||
if store is None:
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text="Нет ожидающих подтверждений.")]
|
||||
|
||||
pending = await get_pending_confirm(store, event.chat_id)
|
||||
room_id = event.payload.get("room_id")
|
||||
pending = None
|
||||
if room_id:
|
||||
pending = await get_pending_confirm(store, event.user_id, room_id)
|
||||
if not pending:
|
||||
pending = await get_pending_confirm(store, event.chat_id)
|
||||
if not pending:
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text="Нет ожидающих подтверждений.")]
|
||||
|
||||
await clear_pending_confirm(store, event.chat_id)
|
||||
if room_id:
|
||||
await clear_pending_confirm(store, event.user_id, room_id)
|
||||
else:
|
||||
await clear_pending_confirm(store, event.chat_id)
|
||||
return [OutgoingMessage(chat_id=event.chat_id, text="Действие отменено.")]
|
||||
|
||||
return handle_cancel
|
||||
|
|
|
|||
|
|
@ -51,13 +51,26 @@ async def next_chat_id(store: StateStore, matrix_user_id: str) -> str:
|
|||
return f"C{index}"
|
||||
|
||||
|
||||
async def get_pending_confirm(store: StateStore, room_id: str) -> dict | None:
|
||||
return await store.get(f"{PENDING_CONFIRM_PREFIX}{room_id}")
|
||||
def _pending_confirm_key(user_id: str, room_id: str | None = None) -> str:
|
||||
if room_id is None:
|
||||
return f"{PENDING_CONFIRM_PREFIX}{user_id}"
|
||||
return f"{PENDING_CONFIRM_PREFIX}{user_id}:{room_id}"
|
||||
|
||||
async def get_pending_confirm(
|
||||
store: StateStore, user_id: str, room_id: str | None = None
|
||||
) -> dict | None:
|
||||
return await store.get(_pending_confirm_key(user_id, room_id))
|
||||
|
||||
async def set_pending_confirm(
|
||||
store: StateStore, user_id: str, room_id: str | dict, meta: dict | None = None
|
||||
) -> None:
|
||||
if meta is None:
|
||||
await store.set(_pending_confirm_key(user_id), room_id)
|
||||
return
|
||||
await store.set(_pending_confirm_key(user_id, str(room_id)), meta)
|
||||
|
||||
|
||||
async def set_pending_confirm(store: StateStore, room_id: str, meta: dict) -> None:
|
||||
await store.set(f"{PENDING_CONFIRM_PREFIX}{room_id}", meta)
|
||||
|
||||
|
||||
async def clear_pending_confirm(store: StateStore, room_id: str) -> None:
|
||||
await store.delete(f"{PENDING_CONFIRM_PREFIX}{room_id}")
|
||||
async def clear_pending_confirm(
|
||||
store: StateStore, user_id: str, room_id: str | None = None
|
||||
) -> None:
|
||||
await store.delete(_pending_confirm_key(user_id, room_id))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue