aiogram, telegram bot, проблема с inline клавиатурами, не получается добавить многоуровневую клавиатуру
я хотел добавить второй уровень инлайн клавиатуры, чтобы при нажатии на первую инлайн клавиатуру пользователю приходила вторая клавиатура
import aiogram
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from config import TOKEN
from aiogram import Bot, types
from aiogram.utils import executor
from aiogram.utils.markdown import text
from aiogram.dispatcher import Dispatcher
bot = aiogram.Bot(token=TOKEN)
dp = aiogram.Dispatcher(bot)
genres_keyboard = InlineKeyboardMarkup(row_width=3)
genres_keyboard.add(
InlineKeyboardButton('Action', callback_data='action'),
InlineKeyboardButton('MMO', callback_data='mmo'),
InlineKeyboardButton('RPG', callback_data='rpg')
)
delivery_keyboard = InlineKeyboardMarkup(row_width=2)
delivery_keyboard.add(
InlineKeyboardButton('Доставка курьером', callback_data='courier'),
InlineKeyboardButton('Самовывоз', callback_data='pickup')
)
@dp.callback_query_handler(lambda c: c.data in ['action'])
async def process_genre(callback_query: aiogram.types.CallbackQuery):
await bot.send_message(
chat_id=message.from_user.id,
reply_markup=delivery_keyboard,
text='Вы успешно выбрали жанр "MMO", теперь необходимо выбрать вариант доставки!')
@dp.callback_query_handler(lambda c: c.data in [ 'mmo'])
async def process_genre(callback_query: aiogram.types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, 'Вы успешно выбрали жанр "MMO", теперь необходимо выбрать вариант доставки!')
genre = callback_query.data
@dp.callback_query_handler(lambda c: c.data in ['rpg'])
async def process_genre(callback_query: aiogram.types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, 'Вы успешно выбрали жанр "RPG", теперь необходимо выбрать вариант доставки!')
@dp.callback_query_handler(lambda c: c.data in ['courier', 'pickup'])
async def process_delivery(callback_query: aiogram.types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
delivery = callback_query.data
@dp.message_handler(commands=['start'])
async def process_start_command(message: aiogram.types.Message):
await message.reply('Здравствуйте!\nВы находитесь в магизине игр\nВыберите жанр игры :', reply_markup=genres_keyboard)
if __name__ == '__main__':
aiogram.executor.start_polling(dp)
Ответы (1 шт):
Автор решения: ZxNuClear
→ Ссылка
Как-то мудрено вы хотели это реализовать. Все делается намного проще - когда вы планируете собирать и обрабатывать данные, которые вводит пользователь, то почти всегда можно использовать FSM, если вводимых данных больше единицы. Я бы сделал это вот так:
from aiogram import Bot, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import Dispatcher, FSMContext
from aiogram.dispatcher.filters.state import StatesGroup, State
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils import executor
bot = Bot(token='ТВОЙ ТОКЕН')
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)
class Games(StatesGroup):
game = State()
delivery = State()
genres_keyboard = InlineKeyboardMarkup(row_width=3)
genres_keyboard.add(
InlineKeyboardButton('Action', callback_data='Action'),
InlineKeyboardButton('MMO', callback_data='MMO'),
InlineKeyboardButton('RPG', callback_data='RPG')
)
delivery_keyboard = InlineKeyboardMarkup(row_width=2)
delivery_keyboard.add(
InlineKeyboardButton('Доставка курьером', callback_data='courier'),
InlineKeyboardButton('Самовывоз', callback_data='pickup')
)
@dp.message_handler(commands=['start'])
async def process_start_command(message: types.Message):
await message.delete()
await message.answer('Здравствуйте!\nВы находитесь в магазине игр\nВыберите жанр игры:', reply_markup=genres_keyboard)
await Games.game.set()
@dp.callback_query_handler(state=Games.game)
async def get_games(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['game'] = call.data
await call.message.edit_text(text=f'Вы успешно выбрали жанр "{call.data}", теперь необходимо выбрать вариант доставки!', reply_markup=delivery_keyboard)
await Games.next()
@dp.callback_query_handler(state=Games.delivery)
async def process_delivery(call: types.CallbackQuery, state: FSMContext):
async with state.proxy() as data:
data['delivery'] = 'Доставка курьером' if call.data == 'courier' else 'Самовывоз'
await call.message.edit_text(text=f'Вы выбрали жанр "{data["game"]}" и вариант доставки "{data["delivery"]}"')
await state.finish()
if __name__ == '__main__':
executor.start_polling(dp)
ну а дальше делайте с данными пользователя что хотите, они находятся в data['game'] и data['delivery']