Иногда бывает необходимо получить от пользователя несколько ответов в определённой последовательности, то бишь поэтапно принимать информацию от него в формате анкеты (к примеру, как на Дайвинчике). Для этого боту необходимо как-то запоминать сообщения юзера, а также понимать, на какой стадии находится беседа. О реализации подобной системы в этой статье и пойдёт речь.
Для решения этой задачи обозначим каждый вопрос анкеты уникальным номером (айдишником). Первый пункт анкеты - id1, второй пункт- id2, ну, и так далее. Соответственно, после того, как пользователь ответит нашему боту - id будет увеличиваться на единицу, а ответ записываться в базу данных.
Ну, а теперь поподробнее...
Шаг 1: Создаём группу ВКонтакте
На текущем этапе нужно создать сообщество в ВК и правильным образом его настроить. И первым делом переходим во вкладку "Сообщения", дабы включить их:
В подвкладке "Настройки для бота" включаем возможности ботов:
Далее идём во вкладку "Настройки" -> "Работа с API". Жмём на кнопку "Создать ключ" и даём доступ приложению к сообщениям сообщества. Ключ для удобства стоит сразу скопировать и сохранить где-нибудь под рукой. Я оставлю его на рабочем столе. Также не стоит забывать о том, что ключ конфиденциален, передавать кому-либо и показывать его в публичном доступе запрещено.
Осталось указать путь до нашего бота и в типах событий поставить галочку напротив входящих сообщений. Конкретно для наших задач никаких других галочек ставить не потребуется:
Шаг 2: Подготавливаем базу данных
С базой данных долго мучаться не придётся. Я создал вот такую небольшую таблицу с шестью полями:
Поле id - идентификатор анкеты;
Поле user_id - айди пользователя (автора анкеты);
Поле status - статус беседы с ботом (всего статутов будет 4);
Поле name - имя пользователя (то, которое он сам введёт);
Поле sex - пол пользователя;
Поле city - город пользователя.
Шаг 3: Начинаем кодить
Я буду использовать две библиотеки для работы, более подробно о применении которых рассказывалось в этих статьях: Статья 1, Статья 2
Начинаю с подключения этих библиотек и создания экземпляров класса VK_api и класса Mysql:
В этот раз я создам простенькую анкету, где будет всего 3 пункта (вопроса). Бот у пользователей будет спрашивать имя, пол и город проживания. Для удобства потребителей сделаем несколько кнопок. Первые две кнопки будут отвечать за создание и удаление анкет, а третья и четвёртая будут отправляться пользователям при выборе пола:
Далее нужно инициализировать некоторые переменные, а также получить payload для работоспособности кнопок:
Нам осталось на самом-то деле не очень много работы. Сейчас будем приступать к обработке полученных от пользователей сообщений и отправке ответов на них. Для удобства я перенёс все комментарии непосредственно в сам код:
if ( $type == 'message_new' ) // Проверка на тип события, в нашем случае нужны входящие сообщения (message_new)
{
$result = $db->query( "SELECT * FROM `anketa` WHERE `user_id` = ?i", $peer_id )->fetchAssoc(); // Поиск в БД по айди пользователя
if ( $message == '/заполнить' or $payload == 'Заполнить' ) // Проверка на текст сообщения (если пользователь прислал команду /заполнить, то условие истинно)
{
if ( isset( $result['id'] ) and $result['id'] ) // Выше есть запрос к БД по айдишнику юзера. Если поиск был удачным, значит у человека уже есть анкета
{
$vk->sendButton( $peer_id, 'У тебя уже есть анкета, но ты можешь её удалить с помощью команды /удалить и потом заполнить заново.', [ [ $btn_del ] ] ); // Посылаем текст с кнопкой для удаления анкеты
}
else // А если у него анкеты всё-таки нет, значит можно продолжать создавать новую
{
$db->query( "INSERT INTO `anketa` SET `user_id` = ?i, `status` = ?i", $peer_id, 1 ); // Добавляем анкету в БД, указываем ID юезера и устанавливаем статус 1
$vk->sendButton( $peer_id, 'Привет! Для начала тебе нужно указать своё имя.', [ [ $btn_del ] ] );
}
exit; // Завершаем работу скрипта, проверка по статусам (та, что ниже) нам уже не нужна
}
else if ( $message == '/удалить' or $payload == 'Удалить' ) // Проверка на наличие в тексте пользователя команды /удалить
{
$db->query( "DELETE FROM `anketa` WHERE `user_id` = ?i", $peer_id ); // Удаление анкеты из БД
$vk->sendButton( $peer_id, 'Анкета удалена, но ты всегда можешь заполнить её повторно', [ [ $btn_start ] ] ); // Отправляем пользователю текст и кнопку создания новой анкеты
exit; // завершаем работу скрипта
}
if ( $result['status'] == 1 ) // Если статус равен 1
{
$db->query( "UPDATE `anketa` SET `status` = ?i, `name` = '?s' WHERE `user_id` = ?i", 2, $message, $peer_id ); // Обновляем анкету в БД, записываем имя и увеличиваем на единицу статус
$vk->sendButton( $peer_id, 'Хорошо, ' . $message . '. Теперь, пожалуйста, укажи свой пол.', [ [ $btn_male, $btn_woman ], [ $btn_del ] ] ); // Даем юзеру кнопки для выбора пола
}
else if ( $result['status'] == 2 ) // Если статус равен 2
{
$db->query( "UPDATE `anketa` SET `status` = ?i, `sex` = '?s' WHERE `user_id` = ?i", 3, $payload, $peer_id ); // Записываем пол в базу, увеличиваем статус
$vk->sendButton( $peer_id, 'Отлично, анкета почти заполнена. Тебе осталось указать город проживания.', [ [ $btn_del ] ] );
}
else if ( $result['status'] == 3 ) // если статус равен 3
{
$db->query( "UPDATE `anketa` SET `status` = ?i, `city` = '?s' WHERE `user_id` = ?i", 4, $message, $peer_id ); // Добавляем город в БД, статус 4
$vk->sendButton( $peer_id, "Мы закончили :) Вот твои данные:\nИмя: " . $result['name'] . "\nПол: " . $result['sex'] . "\nГород: " . $message, [ [ $btn_del ] ] ); // Показываем юзеру его анкету
}
}
По итогу мы сделали две команды (/заполнить и /удалить), а также 3 вопроса в нашу анкету. Кстати, ссылка на скачку полной версии бота будет в конце статьи :)
Шаг 4: Проверяем
С написанием скрипта закончили. Давайте теперь проверим, как работает бот. Прописываю команду /заполнить, после чего создаётся пустая анкета, которую мне предстоит пройти:
Бот поздоровался и спросил имя. Окей, продолжим:
Имя указано, теперь мне предложено указать пол. Указываю:
Всё! Последний пункт формы - город проживания. После заполнения бот прислал конечный вид анкеты.
Перед публикацией, советую ознакомится с правилами!
Нашли ошибку?
Вы можете сообщить об этом администрации.
Выделив текст нажмите CTRL+Enter