Не понимаю почему после 2 уровня кейборд кнопок не работают хэндлеры
Так вот, если нажать на кнопку Astra (это уже второй уровень меню), то ничего не происходит, есть подозрение что это у aiogram ограничение на количество уровней кб кнопок. так вот может быть кто ни будь знает что делать?
from aiogram import types, Bot, Dispatcher, executor
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.types import ReplyKeyboardRemove
import os
bot = Bot('xxx')
dp = Dispatcher(bot)
async def on_startup(_):
print('Все работает')
#######################################HANDLERS########################################
@dp.message_handler(commands=['start', 'help'])
async def command_start(message: types.Message):
await bot.send_message(message.from_user.id, 'Автор бота: @uzjakoweban')
await bot.send_message(message.from_user.id, 'Привет!, это бот который поможет тебе при игре в Valorant!')
await bot.send_message(message.from_user.id, 'Что бы начать нажми: /Button', reply_markup=button)
await message.delete()
@dp.message_handler(commands=['Button'])
async def command_second_start(message: types.Message):
await bot.send_message(message.from_user.id, 'Выбери карту на которой играешь)' ,reply_markup=kb_button)
await message.delete()
#####################################KEYBOARD_HANDLERS#################################
###1УРОВЕНЬ###
@dp.message_handler(content_types='text')
async def first_menu(message: types.Message):
if message.text == 'Split':
await bot.send_message(message.from_user.id, 'Выбрана карта Split', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Heaven':
await bot.send_message(message.from_user.id, 'Выбрана карта Heaven', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Bind':
await bot.send_message(message.from_user.id, 'Выбрана карта Bind', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Accent':
await bot.send_message(message.from_user.id, 'Выбрана карта Accent', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Fracture':
await bot.send_message(message.from_user.id, 'Выбрана карта Fracture', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Breeze':
await bot.send_message(message.from_user.id, 'Выбрана карта Breeze', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Icebox':
await bot.send_message(message.from_user.id, 'Выбрана карта Icebox', reply_markup=kb_button2)
await bot.send_message(message.from_user.id, 'Выбери героя')
await message.delete()
if message.text == 'Вернуться в главное меню':
await bot.send_message(message.from_user.id, 'Автор бота: @uzjakoweban', reply_markup=ReplyKeyboardRemove())
await bot.send_message(message.from_user.id, 'Привет!, это бот который поможет тебе при игре в Valorant!')
await bot.send_message(message.from_user.id, 'Что бы начать нажми: /Button')
await message.delete()
###2УРОВЕНЬ###
@dp.message_handler(content_types='text')
async def second_menu(message: types.Message):
if message.text == 'Astra':
await bot.send_message(message.from_user.id, 'Выбрана карта Astra', reply_markup=kb_button)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Breach':
await bot.send_message(message.from_user.id, 'Выбран герой Breach', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Brimstone':
await bot.send_message(message.from_user.id, 'Выбран герой Brimstone', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Chamber':
await bot.send_message(message.from_user.id, 'Выбран герой Chamber', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Cypher':
await bot.send_message(message.from_user.id, 'Выбран герой Cypher', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Fade':
await bot.send_message(message.from_user.id, 'Выбран герой Fade', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Jett':
await bot.send_message(message.from_user.id, 'Выбран герой Jett', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'KAY/O':
await bot.send_message(message.from_user.id, 'Выбран герой KAY/O', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Killjoy':
await bot.send_message(message.from_user.id, 'Выбран герой Killjoy', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Neon':
await bot.send_message(message.from_user.id, 'Выбран герой Neon', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Omen':
await bot.send_message(message.from_user.id, 'Выбран герой Omen', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Phoenix':
await bot.send_message(message.from_user.id, 'Выбран герой Phoenix', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Raze':
await bot.send_message(message.from_user.id, 'Выбран герой Raze', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Sage':
await bot.send_message(message.from_user.id, 'Выбран герой Sage', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Skye':
await bot.send_message(message.from_user.id, 'Выбран герой Skye', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Sova':
await bot.send_message(message.from_user.id, 'Выбран герой Sova', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Viper':
await bot.send_message(message.from_user.id, 'Выбран герой Viper', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Yoru':
await bot.send_message(message.from_user.id, 'Выбран герой Yoru', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Вернуться в главное меню':
await bot.send_message(message.from_user.id, 'Автор бота: @uzjakoweban', reply_markup=ReplyKeyboardRemove())
await bot.send_message(message.from_user.id, 'Привет!, это бот который поможет тебе при игре в Valorant!')
await bot.send_message(message.from_user.id, 'Что бы начать нажми: /Button')
await message.delete()
###3УРОВЕНЬ###
@dp.message_handler(content_types='text')
async def third_menu(message: types.Message):
if message.text == 'A spot':
await bot.send_message(message.from_user.id, 'Выбрана точка А')
await bot.send_message(message.from_user.id, 'Выбери сторону')
await message.delete()
if message.text == 'B spot':
await bot.send_message(message.from_user.id, 'Выбрана точка B')
await bot.send_message(message.from_user.id, 'Выбери сторону')
await message.delete()
####################################KB_BUTTONS##########################################
# a1 = KeyboardButton('/Button')
# button = ReplyKeyboardMarkup(resize_keyboard=True)
# button.add(a1)
###1УРОВЕНЬ###
a1 = KeyboardButton('Split')
a2 = KeyboardButton('Heaven')
a3 = KeyboardButton('Bind')
a4 = KeyboardButton('Accent')
a5 = KeyboardButton('Fracture')
a6 = KeyboardButton('Breeze')
a7 = KeyboardButton('Icebox')
a8 = KeyboardButton('Вернуться в главное меню')
kb_button = ReplyKeyboardMarkup(resize_keyboard=True)
kb_button.insert(a1).insert(a2).insert(a3).insert(a4).insert(a5).insert(a6).insert(a7).add(a8)
###2УРОВЕНЬ###
b1 = KeyboardButton('Astra')
b2 = KeyboardButton('Breach')
b3 = KeyboardButton('Brimstone')
b4 = KeyboardButton('Chamber')
b5 = KeyboardButton('Cypher')
b6 = KeyboardButton('Fade')
b7 = KeyboardButton('Jett')
b8 = KeyboardButton('KAY/O')
b9 = KeyboardButton('Killjoy')
b10 = KeyboardButton('Neon')
b11 = KeyboardButton('Omen')
b12 = KeyboardButton('Phoenix')
b13 = KeyboardButton('Raze')
b14 = KeyboardButton('Reyna')
b15 = KeyboardButton('Sage')
b16 = KeyboardButton('Skye')
b17 = KeyboardButton('Sova')
b18 = KeyboardButton('Viper')
b19 = KeyboardButton('Yoru')
b20 = KeyboardButton('Вернуться в главное меню')
kb_button2 = ReplyKeyboardMarkup(resize_keyboard=True)
kb_button2.row(b1, b2, b3, b4, b5).row(b6, b7, b8, b9, b10, ).row(b11, b12, b13, b14, b15).row(b16, b17, b18, b19).insert(b20)
###3УРОВЕНЬ###
c1 = KeyboardButton('A spot')
c2 = KeyboardButton('B spot')
kb_button3 = ReplyKeyboardMarkup(resize_keyboard=True)
kb_button3.add(c1).add(c2)
###4УРОВЕНЬ###
executor.start_polling(dp, skip_updates=True, on_startup=on_startup)
Ответы (1 шт):
Таких ограничений в телеграме нет - это раз. Второе вы плохо понимаете работу хендлеров в боте.
Штош. Смотрите, когда юзер присылает сообщение боту оно проходит по, скажем так, списку хендлеров, и по фильтрам в этих самых хендлерах. Если фильтр говорит False то он игнорируется и идет проверка фильтра след хендлера. Когда же фильтр вернет True то перебор хендлеров остановиться и сработает код из этого хендлера.
Вернемся к вам. Итак, я не зная заметили ли вы, но у вас два хендлера с одинаковыми фильтрами content_types='text'(который к слову можно не писать, он стоит по умолчанию). Итак вопрос, что же произойдет если юзер вам что-то отправит? Верно, сработает первый хендлер, фильтр которого вернет True, так как, ну, вы же текст отправили? Вот такие дела.
Ладно. Как фиксить?
Вариант 1 - это юзать FSM.
from aiogram.dispatcher.filters.state import StatesGroup, State
class FSMKbLevels(StatesGroup):
level_1 = State()
level_2 = State()
@dp.message_handler(commands=["start"])
async def start(message: types.Message):
markup=ReplyKeyboardMarkup().add(...)
await message.answer("отправляю клаву 1 лвла", reply_markup=markup)
# там где вы отправляете первую клаву запустите состояние как показано ниже
await FSMKbLevels.level_1.set()
# потом вот тут добавляем фильтр на state
# этот хендлер принимает текст но только если состояние у юзера FSMKbLevels.level_1
@dp.message_handler(state=FSMKbLevels.level_1)
async def first_menu(message: types.Message):
if message.text == 'Split':
await bot.send_message(message.from_user.id, 'Выбрана карта Split', reply_markup=kb_button2)
if message.text == 'Heaven':
await bot.send_message(message.from_user.id, 'Выбрана карта Heaven', reply_markup=kb_button2)
...
await bot.send_message(message.from_user.id, 'Выбери героя')
# тут уже объявляем второй state
await FSMKbLevels.level_2.set()
await message.delete()
# по аналогии с первым хендлером, но другим стейтом
@dp.message_handler(state=FSMKbLevels.level_2)
async def second_menu(message: types.Message):
if message.text == 'Astra':
await bot.send_message(message.from_user.id, 'Выбрана карта Astra', reply_markup=kb_button)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
if message.text == 'Breach':
await bot.send_message(message.from_user.id, 'Выбран герой Breach', reply_markup=kb_button3)
await bot.send_message(message.from_user.id, 'Выбери точку')
await message.delete()
Ну и остальное по тому же алгоритму.
Второй вариант - это поменять ReplyKeyboard на инлайн кнопки, очень рекомендую их изучить, там можно обойтись без стейтов.
Расписывать его не буду так как лень. =) Удачи