Одна из главных функций Telegram-бота — это общение с пользователями. Состояния помогают организовать диалог между ботом и пользователем, обеспечивая ветвление диалогов в зависимости от ответов пользователя и позволяя боту запоминать необходимую информацию.
Рассмотрим процесс регистрации, где пользователю предлагается ввести имя и отправить фотографию. Без состояний невозможно было бы определить, что именно прислал пользователь. Поэтому мы присваиваем пользователю определённое состояние, которое определяет его текущий этап взаимодействия с ботом. В зависимости от этого состояния бот может понять, какое действие выполнил пользователь: ввёл имя или отправил фотографию.
Это лишь один из примеров использования состояний в Telegram-боте. Они позволяют ботам быть более гибкими и адаптивными к различным сценариям взаимодействия с пользователями.
В процессе общения с пользователями Telegram-бот может выполнять различные функции: поддерживать диалог, предоставлять информацию и т. д. Для организации эффективного взаимодействия с пользователем применяются состояния. Они позволяют боту «запоминать» предыдущие действия пользователя и в зависимости от них выбирать следующий шаг.
В качестве примера рассмотрим процесс регистрации. Чтобы бот мог корректно обработать запрос пользователя, необходимо создать набор состояний. Эти состояния будут определять этапы процесса регистрации и возможные варианты действий пользователя на каждом из них.
Для реализации этой логики создаётся класс в файле handlers, который будет содержать поля для каждого состояния. Каждое поле будет соответствовать определённому этапу процесса регистрации или действию пользователя.
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
...
class Reg(StatesGroup):
name = State()
number = State()
photo = State()
Чтобы собрать необходимую информацию от пользователя (имя, номер телефона и аватар), создаётся дочерний класс Reg по отношению к StatesGroup. В этом классе определяются поля, которые являются объектами класса State. Таким образом, мы определяем состояния или этапы, через которые должен пройти пользователь в процессе регистрации.
Для применения этих состояний можно использовать класс FSMContext и его методы set_state и clear.
@router.message(CommandStart())
async def cmd_start(message: Message, state: FSMContext):
await state.set_state(Reg.name) # Установка состояния Reg.name
await message.answer(f'Привет! Введит своё имя')
С помощью метода set_state устанавливается состояние name, что означает начало процесса регистрации. Пользователю предлагается ввести своё имя. После того как пользователь введёт и отправит своё имя, мы должны «поймать» это имя по установленному состоянию и сразу же сохранить его.
@router.message(Reg.name)
async def reg_name(message: Message, state: FSMContext):
await state.update_data(name=message.text)
await state.set_state(Reg.number)
await message.answer('Отправьте свой номер телефона')
@router.message(Reg.number)
async def reg_number(message: Message, state: FSMContext):
await state.update_data(number=message.text)
await state.set_state(Reg.photo)
await message.answer('Отправьте фото')
@router.message(Reg.photo, F.photo)
async def reg_photo(message: Message, state: FSMContext):
await state.update_data(photo=message.photo[-1].file_id)
data = await state.get_data()
await message.answer_photo(photo=data['photo'],
caption=f'Информация о Вас:
{data['name']}, {data['number']}')
await state.clear()
Все данные, которые присылает пользователь, сохраняются в методе state.update_data с использованием определённого ключа. В результате получается словарь (dictionary).
В конце процесса мы можем получить сохранённые данные с помощью метода get_data по указанному ключу-индексу. При этом состояние очищается через метод clear.
Рекомендуется самостоятельно попробовать работу этих методов.
P.S. Даже, если эта статья будет неактуальна, она всё равно станет отличным блокнотом для меня, чтобы не потерять некоторые команды и не гуглить их повторно. Может через пару лет я вернусь сюда, чтобы вспомнить некоторые моменты. А дочитавшим до конца желаю, чтобы ваши работы, проекты и поделки были актуальными всегда!=)