surfaces/adapter/telegram/handlers/commands.py
Mikhail Putilovskij d5ab527f5d fix(tg): QA fixes — stream_message, topic_created, archive reply
- sdk/mock.py: stream_message was async def (coroutine), must be async
  generator with yield — caused TypeError on every user message
- topic_events.py: on_topic_created now skips bot-created topics
  (from_user.id == bot.id); cmd_new already registers them under the
  correct human user_id
- commands.py: cmd_archive now sends "Чат архивирован." confirmation
- test_topic_events.py: add bot=SimpleNamespace(id=BOT_ID) to fixture
2026-04-02 14:14:19 +03:00

92 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
import structlog
from aiogram import Router
from aiogram.exceptions import TelegramBadRequest
from aiogram.filters import Command
from aiogram.types import Message
from adapter.telegram import db
from adapter.telegram.keyboards.settings import settings_main_keyboard
logger = structlog.get_logger(__name__)
router = Router(name="commands")
@router.message(Command("new"))
async def cmd_new(message: Message) -> None:
"""Create a new topic and register it as a new chat."""
user_id = message.from_user.id
chat_id = message.chat.id
n = db.count_active_chats(user_id) + 1
new_name = f"Чат #{n}"
try:
topic = await message.bot.create_forum_topic(chat_id=chat_id, name=new_name)
except TelegramBadRequest as e:
if "topics limit" in str(e).lower():
await message.answer("Достигнут лимит топиков (1000). Заархивируй неиспользуемые чаты.")
else:
logger.error("cmd_new_failed", error=str(e))
await message.answer("Не удалось создать чат, попробуй позже.")
return
thread_id = topic.message_thread_id
db.create_chat(user_id=user_id, thread_id=thread_id, chat_name=new_name)
await message.bot.send_message(
chat_id=chat_id,
message_thread_id=thread_id,
text=f"Создан {new_name}. Напиши что-нибудь.",
)
logger.info("cmd_new", user_id=user_id, thread_id=thread_id, name=new_name)
@router.message(Command("archive"))
async def cmd_archive(message: Message) -> None:
"""Archive the current topic."""
user_id = message.from_user.id
thread_id = message.message_thread_id
chat = db.get_chat(user_id=user_id, thread_id=thread_id)
if chat is None or chat["archived_at"] is not None:
await message.answer("Этот чат не найден или уже архивирован.")
return
try:
await message.bot.close_forum_topic(chat_id=message.chat.id, message_thread_id=thread_id)
except TelegramBadRequest as e:
logger.warning("cmd_archive_bot_error", error=str(e))
db.archive_chat(user_id=user_id, thread_id=thread_id)
await message.answer("Чат архивирован.")
logger.info("cmd_archive", user_id=user_id, thread_id=thread_id)
@router.message(Command("rename"))
async def cmd_rename(message: Message) -> None:
"""Rename the current topic. Usage: /rename New Name"""
user_id = message.from_user.id
thread_id = message.message_thread_id
parts = (message.text or "").split(maxsplit=1)
new_name = parts[1].strip() if len(parts) > 1 else ""
if not new_name:
await message.answer("Использование: /rename Новое название")
return
chat = db.get_chat(user_id=user_id, thread_id=thread_id)
if chat is None:
await message.answer("Этот чат не найден.")
return
try:
await message.bot.edit_forum_topic(
chat_id=message.chat.id,
message_thread_id=thread_id,
name=new_name[:128],
)
except TelegramBadRequest as e:
logger.error("cmd_rename_failed", error=str(e))
await message.answer("Не удалось переименовать топик.")
return
db.rename_chat(user_id=user_id, thread_id=thread_id, new_name=new_name[:128])
logger.info("cmd_rename", user_id=user_id, thread_id=thread_id, new_name=new_name)
@router.message(Command("settings"))
async def cmd_settings(message: Message) -> None:
"""Open settings menu."""
await message.answer("⚙️ Настройки", reply_markup=settings_main_keyboard())