💬 Диалоги (Conversations)

Собирать многошаговые диалоги в Telegram-ботах часто неудобно.

Raito даёт лёгкий способ дождаться следующего сообщения пользователя в чистом, линейном стиле.

Предупреждение

Диалоги НЕ работают с Dispatcher.events_isolation, потому что SimpleEventIsolation держит asyncio.Lock на активных хендлерах, и wait_for никогда не получит апдейт.

wait_for также держит хендлер и его middleware-скоуп живыми до прихода следующего сообщения. Не используйте его с request-scoped ресурсами вроде сессии или транзакции SQLAlchemy. Для таких диалогов берите 🎬 Сцены.


Пример

from aiogram import F, Router, filters
from aiogram.fsm.context import FSMContext
from aiogram.types import Message

from raito import Raito

router = Router(name="mute")


@router.message(filters.Command("mute"))
async def mute(message: Message, raito: Raito, state: FSMContext) -> None:
    await message.answer("Enter username:")
    user = await raito.wait_for(state, F.text.regexp(r"@[\w]+"))

    await message.answer("Enter duration (in minutes):")
    duration = await raito.wait_for(state, F.text.isdigit())

    while not duration.number or duration.number < 0:
        await message.answer("⚠️ Duration cannot be negative")
        duration = await duration.retry()

    await message.answer(f"✅ {user.text} will be muted for {duration.number} minutes")

Как это работает

  • Каждый вызов wait_for регистрирует ожидающий диалог во внутреннем реестре Raito

  • Запись диалога хранит:

    • Future (чтобы позже возобновить ваш хендлер)

    • фильтры для проверки входящих сообщений

  • Когда приходит сообщение:

    • Raito ищет активный диалог, привязанный к этому FSMContext.key

    • если фильтры совпали, future завершается и результат возвращается в ваш хендлер