From 8bf18c00b06e6ac2e4b6ce0ca2bef6ea6bfdf745 Mon Sep 17 00:00:00 2001 From: wasrusgen Date: Tue, 12 May 2026 21:49:18 +0300 Subject: [PATCH] bot: add inline keyboard for role choice (Telegram Desktop fix) Telegram Desktop side-panel does NOT forward initData when WebApp is opened via ReplyKeyboardButton.web_app. Resulting in empty initData and falling back to client cabinet for everyone. Inline-keyboard buttons (web_app inside the message) open the MiniApp in modal mode where initData is correctly forwarded. /start now sends two messages: 1. Welcome + reply-keyboard at bottom (works on mobile) 2. Inline-keyboard with role buttons (works on Desktop too) --- bot/handlers/start.py | 45 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/bot/handlers/start.py b/bot/handlers/start.py index a112ee6..f0fa88b 100644 --- a/bot/handlers/start.py +++ b/bot/handlers/start.py @@ -3,6 +3,8 @@ import time from aiogram import F, Router from aiogram.filters import Command, CommandStart from aiogram.types import ( + InlineKeyboardButton, + InlineKeyboardMarkup, KeyboardButton, Message, ReplyKeyboardMarkup, @@ -36,7 +38,27 @@ def _wapp(miniapp_url: str, role: str) -> WebAppInfo: # ============================================================ -# Reply keyboard — выбор роли. Три кнопки, все WebApp. +# Inline keyboard — выбор роли прямо в сообщении /start. +# На Telegram Desktop side-panel reply-keyboard НЕ передаёт initData. +# Inline-кнопки открываются в МОДАЛЬНОМ режиме где initData валидно. +# ============================================================ + +def role_choice_inline(miniapp_url: str) -> InlineKeyboardMarkup: + return InlineKeyboardMarkup( + inline_keyboard=[ + [ + InlineKeyboardButton(text="👤 Я менеджер", web_app=_wapp(miniapp_url, "manager")), + InlineKeyboardButton(text="🏠 Я клиент", web_app=_wapp(miniapp_url, "client")), + ], + [ + InlineKeyboardButton(text="🔧 Я сотрудник", web_app=_wapp(miniapp_url, "staff")), + ], + ] + ) + + +# ============================================================ +# Reply keyboard — постоянная панель снизу (для мобильных). # ============================================================ def role_choice_kb(miniapp_url: str) -> ReplyKeyboardMarkup: @@ -62,17 +84,30 @@ def role_choice_kb(miniapp_url: str) -> ReplyKeyboardMarkup: @router.message(CommandStart()) async def cmd_start(message: Message, config: Config) -> None: + # Сначала отправляем reply-keyboard (постоянная панель снизу для мобильных) await message.answer( - "👋 Здравствуйте, я бот-помощник от Руслана ВАСИЛЬЕВА.\n\n" - "Выберите, кто вы — кабинет откроется одним тапом.\n\n" - "«Сотрудник» — для замерщиков и сборщиков ЗОВ. Если вы менеджер или клиент — выбирайте свою роль.", + "👋 Здравствуйте, я бот-помощник от Руслана ВАСИЛЬЕВА.", reply_markup=role_choice_kb(config.miniapp_url), ) + # Затем inline-keyboard внутри отдельного сообщения — кнопки тут открывают MiniApp + # в МОДАЛЬНОМ режиме (важно для Telegram Desktop) + await message.answer( + "Выберите, кто вы — кабинет откроется одним тапом.\n\n" + "«Сотрудник» — для замерщиков и сборщиков ЗОВ.", + reply_markup=role_choice_inline(config.miniapp_url), + ) @router.message(Command("menu")) async def cmd_menu(message: Message, config: Config) -> None: - await message.answer("Выберите роль:", reply_markup=role_choice_kb(config.miniapp_url)) + await message.answer( + "Выберите роль:", + reply_markup=role_choice_inline(config.miniapp_url), + ) + await message.answer( + "Или используйте панель снизу.", + reply_markup=role_choice_kb(config.miniapp_url), + ) @router.message(Command("hide"))