From c690226d8ab28e98773efb4b9a02a1992a0263ca Mon Sep 17 00:00:00 2001 From: geekiot Date: Fri, 24 Oct 2025 17:06:24 +0500 Subject: [PATCH] Add [messages & callbacks]: add the bot menu keyboard & update register router --- src/bot/handlers/callbacks/menu.py | 21 ++++++++++++++++++++ src/bot/handlers/callbacks/test.py | 0 src/bot/handlers/commands/help.py | 6 +++--- src/bot/handlers/commands/menu.py | 10 +++++++--- src/bot/handlers/commands/test.py | 13 ------------ src/bot/handlers/utils/keyboards/__init__.py | 19 ++++++++++++++++-- src/bot/handlers/utils/registry/__init__.py | 18 +++++++++++------ 7 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 src/bot/handlers/callbacks/menu.py delete mode 100644 src/bot/handlers/callbacks/test.py delete mode 100644 src/bot/handlers/commands/test.py diff --git a/src/bot/handlers/callbacks/menu.py b/src/bot/handlers/callbacks/menu.py new file mode 100644 index 0000000..ac8ca01 --- /dev/null +++ b/src/bot/handlers/callbacks/menu.py @@ -0,0 +1,21 @@ +from aiogram.types import CallbackQuery, Message + +from bot.handlers import registry +from bot.handlers.utils.keyboards import get_menu_markup +from bot.handlers.utils.types import ChatType + + +@registry.register( + commands="menu", + chat_types=ChatType.PRIVATE, + description="Menu Callback Function Description", + is_callback=True, +) +async def cmd_menu(call: CallbackQuery) -> None: + if not isinstance(call.message, Message): + return + + await call.message.edit_text( + "Menu Callback Function Answer Text", + reply_markup=get_menu_markup(), + ) diff --git a/src/bot/handlers/callbacks/test.py b/src/bot/handlers/callbacks/test.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/bot/handlers/commands/help.py b/src/bot/handlers/commands/help.py index 3ccbb61..ce56a3b 100644 --- a/src/bot/handlers/commands/help.py +++ b/src/bot/handlers/commands/help.py @@ -5,9 +5,9 @@ from bot.handlers.utils.types import ChatType @registry.register( - command="help", + commands="help", chat_types=ChatType.PRIVATE, - description="Test Help Function Description", + description="Help Command Function Description", ) async def cmd_help(message: Message) -> None: - await message.answer("Test Help Function Answer Text") + await message.answer("Help Command Function Answer Text") diff --git a/src/bot/handlers/commands/menu.py b/src/bot/handlers/commands/menu.py index 2639ae6..3df72e9 100644 --- a/src/bot/handlers/commands/menu.py +++ b/src/bot/handlers/commands/menu.py @@ -1,13 +1,17 @@ from aiogram.types import Message from bot.handlers import registry +from bot.handlers.utils.keyboards import get_menu_markup from bot.handlers.utils.types import ChatType @registry.register( - command="start", + commands=["menu", "start"], chat_types=ChatType.PRIVATE, - description="Test Start Function Description", + description="Menu Command Function Description", ) async def cmd_menu(message: Message) -> None: - await message.answer("Test Start Function Answer Text") + await message.answer( + "Menu Command Function Answer Text", + reply_markup=get_menu_markup(), + ) diff --git a/src/bot/handlers/commands/test.py b/src/bot/handlers/commands/test.py deleted file mode 100644 index ab4bfc7..0000000 --- a/src/bot/handlers/commands/test.py +++ /dev/null @@ -1,13 +0,0 @@ -from aiogram.types import Message - -from bot.handlers import registry -from bot.handlers.utils.types import ChatType - - -@registry.register( - command="group", - chat_types=ChatType.GROUP, - description="Test Group Function Description", -) -async def cmd_group(message: Message) -> None: - await message.answer("Test Group Function Answer Text") diff --git a/src/bot/handlers/utils/keyboards/__init__.py b/src/bot/handlers/utils/keyboards/__init__.py index f25d66d..6bb3ee2 100644 --- a/src/bot/handlers/utils/keyboards/__init__.py +++ b/src/bot/handlers/utils/keyboards/__init__.py @@ -1,4 +1,19 @@ -__all__ = [] +__all__ = ["get_menu_markup"] -# TODO: Add reply keyboard markups for bot here. +from aiogram.utils.keyboard import ( + InlineKeyboardBuilder, + InlineKeyboardButton, + InlineKeyboardMarkup, +) + + +def get_menu_markup() -> InlineKeyboardMarkup: + """ + Reply markup for the bot callback menu & message menu. + """ + builder = InlineKeyboardBuilder() + builder.add( + InlineKeyboardButton(text="Test Menu", callback_data="menu"), + ) + return builder.as_markup() diff --git a/src/bot/handlers/utils/registry/__init__.py b/src/bot/handlers/utils/registry/__init__.py index c66c19e..9e899ec 100644 --- a/src/bot/handlers/utils/registry/__init__.py +++ b/src/bot/handlers/utils/registry/__init__.py @@ -54,7 +54,7 @@ class RouterRegistry: description: str, chat_types: Union[ChatType, list[ChatType]], filters: Union[BaseFilter, list[BaseFilter]] = [], - command: str, + commands: str | list[str], is_callback: bool = False, ) -> Callable[[Any], HandlerType]: """ @@ -84,8 +84,10 @@ class RouterRegistry: handler description for Telegram bot menu. chat_types (Union[ChatType, list[ChatType]]): list of Telegram chat types. - command (str): + commands (str | list[str]): specifying handler command trigger (data for callback). + It can be a list of str for callbacks & messages. + Use first command as main command for bot menu. filters (Union[BaseFilter, list[BaseFilter]], optional): List of a handler's filters. Defaults to []. @@ -99,12 +101,16 @@ class RouterRegistry: if isinstance(filters, BaseFilter): filters = [filters] + if isinstance(commands, str): + commands = [commands] + def decorator(func: HandlerType) -> HandlerType: meta = HandlerMeta( func=func, description=description, chat_types=chat_types, - command=command, + command=commands[0], + is_callback=is_callback, ) self._handlers.append(meta) @@ -113,14 +119,14 @@ class RouterRegistry: func, *filters, ChatTypeFilter(chat_types=chat_types), - F.data == command, + F.data.in_(commands), ) else: self._router.message.register( func, *filters, ChatTypeFilter(chat_types=chat_types), - Command(commands=[command]), + Command(commands=commands), ) return func @@ -140,7 +146,7 @@ class RouterRegistry: description=meta.description, ) for meta in self._handlers - if meta.command is not None + if meta.is_callback is False and ChatType.PRIVATE in meta.chat_types ], scope=BotCommandScopeAllPrivateChats(),