from __future__ import annotations import structlog from aiogram import Router from aiogram.exceptions import TelegramBadRequest from aiogram.filters import CommandStart from aiogram.types import Message from adapter.telegram import db logger = structlog.get_logger(__name__) router = Router(name="start") @router.message(CommandStart()) async def cmd_start(message: Message) -> None: """ Bootstrap the user's forum. First visit: create Чат #1, hide General topic. Returning visit: health-check all active topics, archive stale ones. """ user_id = message.from_user.id chat_id = message.chat.id try: await _check_and_prune_stale_topics(message, user_id, chat_id) except Exception: logger.exception("prune_stale_topics_error", user_id=user_id) active = db.get_active_chats(user_id) if not active: try: topic = await message.bot.create_forum_topic(chat_id=chat_id, name="Чат #1") thread_id = topic.message_thread_id db.create_chat(user_id=user_id, thread_id=thread_id, chat_name="Чат #1") logger.info("start_created_first_topic", user_id=user_id, thread_id=thread_id) except TelegramBadRequest as e: logger.warning("start_create_topic_failed", error=str(e)) await message.answer( "Не удалось создать топик. Убедись, что в @BotFather включён " "Threaded Mode для этого бота." ) return try: await message.bot.hide_general_forum_topic(chat_id=chat_id) except TelegramBadRequest: pass # Not critical await message.answer( "Привет! Это твоё личное пространство с AI-агентом Lambda. " "Каждый топик — отдельный контекст. Напиши что-нибудь." ) else: await message.answer( f"Снова привет! У тебя {len(active)} активных чатов. " "Напиши /new чтобы создать новый." ) async def _check_and_prune_stale_topics( message: Message, user_id: int, chat_id: int ) -> None: """Send typing action to each active topic; archive any that no longer exist.""" for chat in db.get_active_chats(user_id): thread_id = chat["thread_id"] try: await message.bot.send_chat_action( chat_id=chat_id, action="typing", message_thread_id=thread_id, ) except TelegramBadRequest: db.archive_chat(user_id=user_id, thread_id=thread_id) logger.info("pruned_stale_topic", user_id=user_id, thread_id=thread_id)