Делаю бота, часть задачи - сделать меню, где бот задает вопросы, а пользователь отвечает. Всего условно 4 этапа:
Этап 1 - бот спрашивает, какую активность пользователь выбирает.
Этап 2 - бот спрашивает ФИО пользователя.
Этап 3 - бот спрашивает телефон пользователя.
Этап 4 - бот выводит всю информацию с этапов 1-3 на экран.
Когда я делаю все без кнопок, использую FSM (Finite State Machine), то все работает. Но я хочу, чтобы этап 1 был в виде инлайн клавиатуры - пользователь кликает на вариант, информация об этом варианте фиксируется (вместо того, чтобы пользователь писал вручную). Когда пытаюсь реализовать, кнопки добавить получилось, но вот информация с клика так и не передается, остается "разрыв", пользователю все равно вручную приходится вводить текст и только после этого идет переход на следующий этап.
Подскажите, пожалуйста, что мне нужно изменить в коде? Где ошибка? Код прилагаю:
from aiogram import Bot, Dispatcher, types, executor
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.dispatcher.filters import Command
from aiogram.dispatcher.filters.state import StatesGroup, State
from aiogram.dispatcher import FSMContext
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from API_KEY_1196494 import API_KEY
# making a class for a state to move from one state to another later and tie commands to a current state
class reg_state (StatesGroup):
activity = State()
full_name = State()
phone = State()
# button names content
button1_text = 'Activity 1'
button2_text = 'Activity 2'
# buttons
button1 = InlineKeyboardButton (text = button1_text, callback_data='activity1')
button2 = InlineKeyboardButton (text = button2_text, callback_data='activity2')
#keyboard
keyboard_inline = InlineKeyboardMarkup().add(button1).add(button2)
# answers
enter_your_name_details = 'Enter your full name'
enter_your_phone = "Enter your phone number"
bot = Bot(API_KEY)
storage = MemoryStorage()
dp = Dispatcher(bot, storage = storage)
# job initiated, asking to choose activity
@dp.message_handler(commands=['start'])
async def activity_reg (message: types.Message):
user_name_greeting = message.from_user.first_name
await message.answer (text = f"{user_name_greeting}, Which activity do you want to choose?", reply_markup=keyboard_inline)
# reading button info
async def inline_buttons_handler(call: types.CallbackQuery):
match call.data:
case 'activity1':
await call.message.answer (f"You chose {button1_text}")
await bot.answer_callback_query(callback_query_id=call.id)
await reg_state.activity.set()
case 'activity2':
await call.message.answer (f"You chose {button2_text}")
await bot.answer_callback_query(callback_query_id=call.id)
await reg_state.activity.set()
await call.answer()
@dp.callback_query_handler(inline_buttons_handler)
# grabbing the info about activity provided by the user and asking for name
@dp.message_handler(state=reg_state.activity)
async def grab_activity (message: types.Message, state: FSMContext):
await state.update_data(activity = message.text)
await message.answer (enter_your_name_details)
await reg_state.full_name.set()
# grabbing the info about the user's name and asking for phone
@dp.message_handler(state=reg_state.full_name)
async def grab_full_name (message: types.Message, state: FSMContext):
await state.update_data(full_name = message.text)
await message.answer (enter_your_phone)
await reg_state.phone.set()
# grabbing user's phone info and wrapping it up
@dp.message_handler (state = reg_state.phone)
async def grab_phone (message: types.Message, state: FSMContext):
await state.update_data (phone = message.text)
data_full = await state.get_data()
await message.answer(f"Activity: {data_full['activity']}'\n"
f"Full name: {data_full['full_name']}\n"
f"Phone: {data_full['phone']}")
await state.finish()
if __name__ == '__main__':
executor.start_polling(dp)