Как сделать анкету по шагам (FSM) в aiogram — спросить имя, потом возраст?
Хочу, чтобы бот задавал вопросы по очереди: сначала спрашивал имя, я отвечаю, потом спрашивал возраст. Но мой бот на любое сообщение отвечает одинаково и не помнит, на каком я шаге. Как сделать пошаговый диалог?
2 ответа
Тебе нужна FSM (машина состояний) — она запоминает, на каком шаге каждый пользователь. В aiogram это делается через StatesGroup и FSMContext:
from aiogram.fsm.state import StatesGroup, State
from aiogram.fsm.context import FSMContext
class Form(StatesGroup):
name = State()
age = State()
@dp.message(Command("start"))
async def start(message: Message, state: FSMContext):
await message.answer("Как тебя зовут?")
await state.set_state(Form.name)
@dp.message(Form.name)
async def get_name(message: Message, state: FSMContext):
await state.update_data(name=message.text) # сохранили имя
await message.answer("Сколько тебе лет?")
await state.set_state(Form.age)
@dp.message(Form.age)
async def get_age(message: Message, state: FSMContext):
data = await state.get_data()
await message.answer(f"{data['name']}, тебе {message.text} лет. Спасибо!")
await state.clear() # анкета закончена
Как это работает: set_state ставит «текущий шаг», и тогда сообщение попадает в хендлер с этим состоянием (@dp.message(Form.name)). update_data копит ответы, get_data достаёт всё в конце, clear сбрасывает состояние.
Не забудь, что для FSM нужно хранилище. В простом боте оно по умолчанию в памяти — этого достаточно для учёбы. Просто создавай диспетчер как обычно: dp = Dispatcher(), и состояния заработают. (Память сбрасывается при перезапуске бота — для серьёзных проектов берут Redis, но на старте это не нужно.)