@Decker

Telegram бот на PHP. Как сохранять состояние ответа пользователя?

Только начинаю знакомиться с Telegram API для ботов (до этого весь опыт разработки ботов сводился к написанию простейших полезняшек для себя, вроде по команде /stat отправить некоторую сводную информацию, собранную PHP скриптом из разных источников) поэтому хотел бы уточнить следующее. Допустим мы пишем простейшего бота на PHP без использования сторонних библиотек и классов. Возможно ли реализовать функционал "опроса" пользователя с сохранением состояний ответов без использования MySQL, сохранения в файлы и т.п. Если утрированно, то постановка задачи такая:

- Имеем хост с установленным Apache + PHP, поддержка SSL настроена, бот запущен и настроен через setWebhook.
- Реализовать простейший опрос пользователя, например, спросить у него имя, год рождения и знак зодиака, после чего вывести ему в ответ какую-нибудь картинку (например его имя на красивом фоне с наложением знака зодиака).

И вот тут, даже на "теоретической стадии", у меня возник следующий вопрос. Фактически мы должны узнать у пользователя три входных параметра param1 (name), param2 (year), param3 (zodiac). "Опрос" пользователя считается завершенным если он корректно ввел все три параметра, только после этого выдается результат - картинка (ну или с введенными данными осуществляются какие-то другие действия). Какие варианты отслеживания текущего состояния пользователя в опросе из скрипта существуют? Сервер Telegram "дергает" скрипт каждый раз, когда пользователь присылает какое-либо сообщение и при этом абсолютно не знает о том что следующее сообщение пользователя относится к какому-либо этапу выполнения сценария скрипта.

Например, пользователь дал команду /poll и тем самым начал участие в опросе. После чего бот задает ему первый вопрос, а-ля введите param1. Если введенные пользователем данные прошли валидацию, то бот переходит к следующему шагу и задает второй вопрос, введите param2 и т.п. Если же параметр введен неверно, например указан 3027 год, то бот должен "переспросить" пользователя, т.е. запросить повторный ввод данных. Так вот, вопрос в следующем - как лучше всего отслеживать состояние (на каком этапе он находится, ввод имени, ввода года, ввод знака зодиака) пользователя в этом опросе?

Если бы у нас была MySQL, то можно было бы хранить id пользователя и некое значение state в БД и исходя из этого строить логику работы бота. Т.е. если значение state=1, например, значит пользователь участвует в опросе и отвечает на первый вопрос, если state=2, то отвечает на второй и т.п. То же самое применимо и к хранению состояний в файлах. По-крайней мере это самое логичное что мне пришло в голову. Но может быть есть какое-то более оптимальное решение (например, можно как-то передать серверу Telegram некий параметр state, который придет вместе со следующим сообщением пользователя) или еще что-нибудь в этом духе?

Как бы вы реализовали подобное в описанных стартовых условиях? (напомню что задача носит "учебный" характер, наверняка есть какие-то библиотеки, классы и т.п. использующие БД и позволяющие реализовать все описанное в одну строчку кода, но мне куда интереснее понять принцип как сохранять "состояние пользователя" и определять на каком шаге "сценария" он находится без их использования, т.е. как это реализуют в большинстве ботов, использующих интерактивные диалоги с пользователем).
  • Вопрос задан
  • 3271 просмотр
Пригласить эксперта
Ответы на вопрос 1
sergiks
@sergiks Куратор тега PHP
♬♬
Метод отправки сообщения sendMessage() не предлагает никакого параметра, который бы «пробрасывался» клиенту для последующих запросов. Кроме клавиатур.

Наверное, можно попробовать давать Inline Keyboard для последующих ответов, содержащих в своих параметрах его предыдущие ответы (до 64 байт).

Например, первым вопросом спрашивать что-то длинное типа имени-фамилии, чтобы он ввёл текстом. А последующие ответы принимать только через заготовленные кнопки.

Но всё это попахивает ржавым велосипедом. Вам лучше подумать, как хранить state на сервере. Пусть во временном in-memory хранилище – Memcached или Redis.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы