Исходный код raito.plugins.conversations.registry

import asyncio
from collections.abc import Sequence

from aiogram.dispatcher.event.handler import CallbackType
from aiogram.fsm.storage.base import StorageKey
from aiogram.types import Message
from typing_extensions import NamedTuple

__all__ = ("ConversationRegistry",)


[документация] class ConversationData(NamedTuple): """Container for an active conversation. Stores the Future object awaiting a message and the filters to apply. :param future: asyncio.Future that will hold the incoming Message :param filters: Sequence of CallbackType filters to validate the message """ future: asyncio.Future[Message] filters: Sequence[CallbackType]
[документация] class ConversationRegistry: """Registry for managing active conversations with users. This class allows setting up a "wait for message" scenario where a handler can pause and wait for a specific message from a user, optionally filtered by aiogram filters. """ STATE = "raito__conversation" def __init__(self) -> None: """Initialize the conversation registry.""" self._conversations: dict[StorageKey, ConversationData] = {}
[документация] def listen(self, key: StorageKey, *filters: CallbackType) -> asyncio.Future[Message]: """Start listening for a message with a specific StorageKey. :param key: StorageKey identifying the conversation (user/chat/bot) :param filters: Optional filters to apply when the message arrives :return: Future that will resolve with the Message when received """ existing = self._conversations.get(key) if existing and not existing.future.done(): existing.future.cancel() future = asyncio.get_running_loop().create_future() self._conversations[key] = ConversationData(future, filters) return future
[документация] def get_filters(self, key: StorageKey) -> Sequence[CallbackType] | None: """Get the filters associated with an active conversation. :param key: StorageKey identifying the conversation :return: Sequence of CallbackType filters or None if no conversation exists """ data = self._conversations.get(key) return data.filters if data else None
[документация] def resolve(self, key: StorageKey, message: Message) -> None: """Complete the conversation with a received message. :param key: StorageKey identifying the conversation :param message: Message object that satisfies the filters """ data = self._conversations.pop(key, None) if data and not data.future.done(): data.future.set_result(message)
[документация] def cancel(self, key: StorageKey) -> None: """Cancel an active conversation. Cancels the Future and removes the conversation from the registry. :param key: StorageKey identifying the conversation """ data = self._conversations.pop(key, None) if data and not data.future.done(): data.future.cancel()