From ff17dc543a829d883939635a4445094e17c41446 Mon Sep 17 00:00:00 2001 From: "mamonov.ep" Date: Thu, 4 Dec 2025 17:15:49 +0300 Subject: [PATCH] feat(start): add persistent reply keyboard with main commands; add /menu to show it\nchore(bot): register BotCommand list for Telegram menu --- bot/handlers/start.py | 45 ++++++++++++++++++++++++++++++++++++++++--- main.py | 16 +++++++++++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/bot/handlers/start.py b/bot/handlers/start.py index f8ab611..b66045b 100644 --- a/bot/handlers/start.py +++ b/bot/handlers/start.py @@ -1,6 +1,13 @@ from aiogram import Router, F from aiogram.filters import CommandStart, Command -from aiogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery +from aiogram.types import ( + Message, + InlineKeyboardMarkup, + InlineKeyboardButton, + CallbackQuery, + ReplyKeyboardMarkup, + KeyboardButton, +) from aiogram.fsm.context import FSMContext from database.db import async_session_maker @@ -43,7 +50,8 @@ async def cmd_start(message: Message, state: FSMContext): f"• /stats - статистика\n" f"• /settings - настройки\n" f"• /reminder - напоминания\n" - f"• /help - полная справка" + f"• /help - полная справка", + reply_markup=main_menu_keyboard(), ) # Предлагаем пройти тест уровня @@ -70,10 +78,17 @@ async def cmd_start(message: Message, state: FSMContext): f"• /practice - практика диалога\n" f"• /words [тема] - тематическая подборка\n" f"• /stats - статистика\n" - f"• /help - все команды" + f"• /help - все команды", + reply_markup=main_menu_keyboard(), ) +@router.message(Command("menu")) +async def cmd_menu(message: Message): + """Показать клавиатуру с основными командами.""" + await message.answer("Главное меню доступно ниже ⤵️", reply_markup=main_menu_keyboard()) + + @router.message(Command("help")) async def cmd_help(message: Message): """Обработчик команды /help""" @@ -111,6 +126,30 @@ async def skip_level_test_callback(callback: CallbackQuery): """Пропустить тест уровня""" await callback.message.edit_text( "✅ Хорошо!\n\n" +def main_menu_keyboard() -> ReplyKeyboardMarkup: + """Клавиатура с основными командами (кнопки отправляют команды).""" + return ReplyKeyboardMarkup( + resize_keyboard=True, + keyboard=[ + [ + KeyboardButton(text="/add"), + KeyboardButton(text="/vocabulary"), + ], + [ + KeyboardButton(text="/task"), + KeyboardButton(text="/practice"), + ], + [ + KeyboardButton(text="/words travel"), + KeyboardButton(text="/import"), + ], + [ + KeyboardButton(text="/stats"), + KeyboardButton(text="/settings"), + ], + ], + ) + "Ты можешь пройти тест позже командой /level_test\n" "или установить уровень вручную в /settings\n\n" "Давай начнём! Попробуй:\n" diff --git a/main.py b/main.py index 6296477..e265822 100644 --- a/main.py +++ b/main.py @@ -4,6 +4,7 @@ import logging from aiogram import Bot, Dispatcher from aiogram.client.default import DefaultBotProperties from aiogram.enums import ParseMode +from aiogram.types import BotCommand from config.settings import settings from bot.handlers import start, vocabulary, tasks, settings as settings_handler, words, import_text, practice, reminder, level_test @@ -26,6 +27,21 @@ async def main(): ) dp = Dispatcher() + # Команды бота для меню Telegram + await bot.set_my_commands([ + BotCommand(command="start", description="Запустить бота"), + BotCommand(command="add", description="Добавить слово"), + BotCommand(command="words", description="Тематическая подборка слов"), + BotCommand(command="import", description="Импорт слов из текста"), + BotCommand(command="vocabulary", description="Мой словарь"), + BotCommand(command="task", description="Задания"), + BotCommand(command="practice", description="Диалог с AI"), + BotCommand(command="stats", description="Статистика"), + BotCommand(command="settings", description="Настройки"), + BotCommand(command="reminder", description="Напоминания"), + BotCommand(command="help", description="Справка"), + ]) + # Регистрация роутеров dp.include_router(start.router) dp.include_router(level_test.router)