KOTOFF.NET
  • Главная
  • Пользователи
  • Контакты
  • Статистика
  • Правила
  • О нас
  • Вход / Регистрация

Стейты для бота ВК (последовательный ввод step by step)

Статьи / PHP

Месяц назад я уже писал статью о том, как можно реализовать последовательный ввод данных для бота ВК в формате анкеты. И в тот раз рассматривался вариант с использованием базы данных, где, собственно, и хранились промежуточные ответы пользователей. Сегодня же решил сделать нечто похожее, но уже без БД, а с помощью файлов.



Шаг 1: Принцип

Как ни крути, а промежуточные ответы надо как-то запоминать и в нужный момент доставать, поэтому сейчас будем глядеть в сторону файлового хранения. Ничего заумного тут нет, просто всё будем писать в массив и обновлять его каждый раз при помощи функции file_put_contents().



Шаг 2: Storage

Первым делом нужно сделать хранилище, для этого создаю папку storage, а в ней ещё два файла (CtxStorage.php и storage.php):


Про storage.php я уже чутка выше рассказал, файл будет непосредственно выполнять функцию хранения информации. В него потребуется написать всего одну строку кода:

<?php

return array();


CtxStorage - абстрактный класс со статическими методами, которые будут отвечать за логику наших стейтов. Всего в нём будет 5 методов, больше, думаю, никогда и не понадобится. 

<?php

namespace storage;


abstract class CtxStorage
{

    // Содержимое класса

}


Метод record()

private static function record( $arr )
{
    $str = "<?php\n\nreturn " . var_export( $arr, true ) . ";\n";

    return file_put_contents( 'storage/storage.php', $str, LOCK_EX );
}

На вход метод получает массив (его мы будет формировать в других методах). Далее создаётся переменная $str, в неё записывается интерпретируемое строковое представление массива $arr с помощью функции var_export(). 

На текущий момент в переменной $str содержится строка1 типа "<?php return array ( '*userID*_*peerID*' => array ('status' => 1,'data' => array ( /***/ ) ) );". Ничего непонятно, но пока достаточно увидеть то, как сработала функция var_export(). Если её убрать - то в $str запишутся только значения массива.

Ну, и в конце концов, всё то, что находится в переменной $str (ту самую непонятную строку1), нужно вставить в файл storage.php с помощью file_put_contents().


Метод create()

public static function create( $user_id, $peer_id, $data )
{
    $arr = require 'storage/storage.php';

    $arr[$user_id . '_' . $peer_id] = [
        'status' => 1,
        'data' => $data
    ];

    return self::record( $arr );
}

Метод будет использоваться каждый раз при старте заполнения анкеты. На вход передаётся user_id, peer_id и пустой массив2 с теми полями, которые предполагается заполнить по мере прохождения анкеты. То есть, если мне нужно получить от юзера, к примеру, имя, фамилию и возраст, то сей массив будет выглядеть так (ключи можно придумать любые, главное - в них не запутаться):

[ 'first_name' => '', 'last_name' => '', 'age' => '' ]

Далее в основной массив из файла storage.php мы просто добавляем еще один субмассив. В качестве ключа используем peer_id и user_id. И не стоит забывать, что в общем массиве могут находиться одновременно несколько анкет от разных пользователей. 

Осталось только обновить массив в файле storage.php, используя уже рассмотренный и написанный метод record().

После всех этих манипуляций получаем следующее:

<?php

return array (

    '123_321' => array (
        'status' => 1, // Статус анкеты, будет увеличиваться на едицницу, пока не будут заполнены все поля анкеты
        'data' => array (
            'first_name' => '',
            'last_name' => '',
         ),
     ),

    // Тут могут быть еще какие-то анкеты
);


Метод set()

public static function set( $user_id, $peer_id, $text, $state )
{
    $arr = require 'storage/storage.php';

    $arr[$user_id . '_' . $peer_id]['status']++; // Статус увеличиваем на единицу
    $arr[$user_id . '_' . $peer_id]['data'][$state] = $text; // Записываем ответ пользователя в стейт с соответствующим названием

    return self::record( $arr );
}

Нужен, чтобы записывать полученные от юзера данные. На вход передаётся user_id, peer_id, текст сообщения юзера и название стейта, который нужно обновить. Названия соответствуют ключам массива2, который мы передаём в метод create(). 


Метод get()

public static function get( $user_id, $peer_id )
{
    $arr = require 'storage/storage.php';

    return $arr[$user_id . '_' . $peer_id] ?? null;
}

Возвращает массив с анкетой пользователя. Ключ массива, напомню, имеет вид userID_peerID.


Метод delete()

public static function delete( $user_id, $peer_id )
{
    $arr = require 'storage/storage.php';

    unset( $arr[$user_id . '_' . $peer_id] );

    return self::record( $arr );
}

После того, как юзер полностью заполнил анкету - её можно удалить, а данные перенести на постоянное место хранения (если в этом, конечно, есть нужда). Удалить анкету в общем массиве можно прибегнув к использованию функции unset().


Всё. С хранилищем мы закончили. Отныне его можно подключать в любые свои проекты и использовать как библиотеку.



Шаг 3: Применение хранилища

В индексном файле создаю структуру для дальнейшей работы с сообщениями. Подробно уже не объясняю, поскольку в предыдущей статье писал об этом.

<?php

require 'simplevk-master/autoload.php'; // Подключение SimpleVK
require 'storage/CtxStorage.php'; // Подключение класса CtxStorage




$vk = \DigitalStar\vk_api\vk_api::create( 'ключ', 'версия api' )->setConfirm( 'возвращаемая сервером строка' );
$vk->initVars( $peer_id, $message, $payload, $vk_id, $type, $data ); // Инициализация переменных



if ( $type == 'message_new' )
{


    // Тут продолжим кодить


}


В переменную $ctx запишем методом CtxStorage::get() анкету юзера (если, конечно, она есть). Если нет, то запишется null:

$ctx = \storage\CtxStorage::get( $vk_id, $peer_id );


Теперь приступаем к обработке команд и ответов пользователя. Начинаем с команды для старта (у меня это будет /заполнить), которая создаст новую анкету (метод CtxStorage::create()), а далее бот попросит пользователя ввести имя:

if ( $message == '/заполнить' )
{
    \storage\CtxStorage::create( $vk_id, $peer_id, [ 'name' => '', 'age' => -1, 'city' => '' ] );

    $vk->sendMessage( $peer_id, 'Укажите имя' );
}


Через elseif проверим, существует ли анкета у этого пользователя. Если да, то значит будем определять по статусу, что дальше спрашивать у него:

else if ( isset( $ctx ) and $ctx )
{


    switch ( $ctx['status'] )
    {

        // Тут будет проверка по статусам

    }


}


В моём случае проверки по статусам будет 3, так как будет 3 поля в анкете (имя, возраст и город проживания). В первых двух шагах просто получаем и записываем данные собесдника:

case 1:
{
    \storage\CtxStorage::set( $vk_id, $peer_id, $message, 'name' );

    $vk->sendMessage( $peer_id, 'Укажите возраст' );


    break;
}

case 2:
{
    \storage\CtxStorage::set( $vk_id, $peer_id, $message, 'age' );

    $vk->sendMessage( $peer_id, 'Укажите город проживания' );


    break;
}


На третьем шаге можно сохранить, например, в БД полученные данные (если есть необходимость). Я же просто отправлю оформленную анкету для просмотра пользователю и удалю её из временного хранилища с помощью CtxStorage::delete()

case 3:
{
    \storage\CtxStorage::set( $vk_id, $peer_id, $message, 'city' );

    $name = $ctx['data']['name'];
    $age = $ctx['data']['age'];
    $city = $message;

    $vk->sendMessage( $peer_id, "Имя: $name\nВозраст: $age\nГород: $city" );


    \storage\CtxStorage::delete( $vk_id, $peer_id );


    break;
}



Шаг 4: Проверяем

Всё работает в точности так же, как и при использовании базы данных в кач-ве временного хранилища :)


Архив с исходниками:

storage.zip

  • 5id15
  • 20.07.2022
  • 2 664
  • 0
Как сделать цепочку сообщений (анкету) для бота ВК на PHP
Как сделать цепочку сообщений (анкету) для бота ВК на PHP
23-06-2022, 16:32, PHP
Movie

Нет комментариев. Не желаешь оставить первый комментарий?

Перед публикацией, советую ознакомится с правилами!

{login}

Твой комментарий..

Заказывай!
Разработка ботов на заказ, любой сложности, обращаться:
 VK KOTOFF.net - Сообщество, в личные сообщения или по контактам указанным там 
 mail: [email protected]

Рекламный блок
  • Новости
  • Платная категория
  • Блог
  • Игры
  • Обновления
  • Программы
  • Статьи
    • PHP
    • Python
    • JS
  • Дизайн
    • PSD исходники
  • DLE
    • Шаблоны
    • Модули
    • Хаки
  • Магазин
    • Скрипты
Комментарии
Создание простого Telegram-бота с клавиатурой и inline-кнопками [Часть 2]
Класс, хорошая тема
Динамическая обложка для группы ВК, последний подписчик, топ комментатор и прочее
Как отключить вывод результата cron в папку modules/cron в Open Server? Крон запускает несколько
Динамическая обложка для группы ВК, последний подписчик, топ комментатор и прочее
Планируете ли вернуться к динамической обложке?
Скрипт для скачивания видео с YouTube на PHP
Уже не работает.
Авторизация на сайте с помощью ВК, простой и понятный способ на PHP!
Страница для авторизации http://oauth.vk.com/authorize - не существует. Метод не актуален
Все комментарии..
Полный список последних комментариев
Лучшие новости
Всего публикаций: 111
Добавлено за сутки: +0
Записей в блоге: 1
Добавлено за сутки: +0
Комментариев: 935
Добавлено за сутки: +0
Пользователей: 4124
Добавлено за сутки: +0
Полная статистика..
Подробная статистика сайта
Loading...

Нашли ошибку?
Вы можете сообщить об этом администрации.
Выделив текст нажмите CTRL+Enter

Полезные ссылки
  • О проекте
  • Наши контакты
  • Администрация
  • Рекламные материалы
  • Идеи и предложения
  • Ответы на вопросы
Информация
  • Условия сделки
  • Способы оплаты
  • Поддержка / F.A.Q
  • Онлайн документация
  • Статистика сайта
  • Список пользователей
Услуги/Работа
  • Разработка ботов ВК
  • Обновление проекта
  • Консультация/поддержка
KOTOFF.net

Copyright © Footer 2019-2023. All right reserved.
KOTOFF.net - Уроки по PHP, SQL, IT новости
Быстрый вход

Используйте социальные сети для быстрой регистрации и авторизации.

Google
ВКонтакте
Яндекс
Mail.ru
Создать аккаунт / Регистрация
Авторизация

Я забыл свой пароль