surfaces/adapter/telegram/handlers/confirm.py

81 lines
2.6 KiB
Python

# adapter/telegram/handlers/confirm.py
from __future__ import annotations
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery
from adapter.telegram import db
from adapter.telegram.converter import format_outgoing, is_forum_message, resolve_forum_chat_id
from core.handler import EventDispatcher
from core.protocol import IncomingCallback, OutgoingMessage, OutgoingUI
router = Router(name="confirm")
async def _send_reply(
callback: CallbackQuery,
text: str,
*,
thread_id: int | None = None,
) -> None:
if callback.message is None:
await callback.answer()
return
if thread_id is None:
await callback.message.answer(text)
return
await callback.message.bot.send_message(
callback.message.chat.id,
text,
message_thread_id=thread_id,
)
@router.callback_query(F.data.startswith("confirm:"))
async def handle_confirm(
callback: CallbackQuery,
state: FSMContext,
dispatcher: EventDispatcher,
) -> None:
parts = callback.data.split(":", 2)
_, decision, action_id = parts # "yes" or "no"
data = await state.get_data()
chat_id = data.get("active_chat_id", "")
chat_name = data.get("active_chat_name", "Чат")
thread_id = getattr(callback.message, "message_thread_id", None)
forum_mode = callback.message is not None and is_forum_message(callback.message)
tg_id = callback.from_user.id
tg_user = db.get_or_create_tg_user(tg_id, str(tg_id), callback.from_user.full_name)
platform_user_id = tg_user.get("platform_user_id", str(tg_id))
if forum_mode and callback.message is not None:
resolved_chat_id = resolve_forum_chat_id(callback.message, tg_id)
if resolved_chat_id:
chat_id = resolved_chat_id
chat = db.get_chat_by_id(chat_id)
if chat:
chat_name = chat["name"]
incoming = IncomingCallback(
user_id=platform_user_id,
platform="telegram",
chat_id=chat_id,
action="confirm" if decision == "yes" else "cancel",
payload={"action_id": action_id},
)
events = await dispatcher.dispatch(incoming)
if callback.message is not None:
await callback.message.edit_reply_markup(reply_markup=None)
for event in events:
if isinstance(event, (OutgoingMessage, OutgoingUI)):
rendered = format_outgoing(chat_name, event, prefix=not forum_mode)
await _send_reply(callback, rendered, thread_id=thread_id if forum_mode else None)
await callback.answer()