Разработка чат-бота (laravel+botman)

  • Tutorial

Welcome! Я, как junior full stack разработчик, при попытке написать бота с использованием laravel и botman’а столкнулся с многими проблемами. Во-первых, я плохо знаю английский, а на русском статей очень мало на эту тему, а те, что есть не помогли мне решить мои проблемы. В статье будет рассказано и показано, как разработать чат-бота на laravel+botman для telegram. Сам я разрабатывал ботов(коммерческих) под viber и telegram. Как разработчику telegram мне нравится больше всего.


image


Я не буду показывать как установить laravel и настроить сервер для его работы. Если вы никогда этого не делали, то проще будет установить openserver, в него встроен composer(пакетный менеджер для php) и уже настроен локальный сервер для laravel’a. Вам останется лишь прописать немного кода в .htaccess. Дома я именно так и работаю. В статье покажу один из способов разработки чат-бота, настроим бота для работы в телеграм, а так же, в конце, оставлю ссылки на полезные статьи о laravel’e и botman’e.


Проектирование/подготовка


Разработку бота предлагаю, как и все нормальные разработчики, начать с проектирования, постановки задачи и объяснения как работает laravel. Перед этим скажу, что я пишу код в phpStrom. Можно писать в любом другом IDE, но я пользуюсь именно им.


В laravel реализован паттерн MVC(Model View Controller). Это не значит, что нужно писать только под mvc, можно и говнокодить, но лучше пользоваться теми преимуществами, которые предоставляет фреймворк. Если вы знакомы с mvc, но не применяли его, как я, то разработка с помощью laravel’a это лучший способ закрепить знания.


Что должен делать наш бот:


  • Спрашивать у пользователя его имя
  • Поинтересоваться, нравится пользователю погода или нет
  • Также записать ответ в БД
  • Попрощаться и отправить картинку

Немного о MVC. При обращение к нашему ПО, посредством команд(url адреса), мы должны принять эти команды и обработать, понять, что требуется пользователю. Для этого есть пути, так называемые routes. Routes определяет какой Controller нужно использовать, в свою очередь controller, если это требуется, обращается к БД через model. Model связывается с базой данных и возвращает нужный нам результат. В боте view не нужен, т.к. вся работа идет через интерфейс мессенджера. Тем самым, после получения данных от model’и, controller отдает эти данные view, в нашем случае это blade шаблон (именно его использует laravel). Данные можно отдать и обычной php странице, но лучше это делать через blade шаблоны. Мы используем интерфейс мессенджера, то отправлять данные будем сразу в него.


Разработка


Чтобы создать проект, достаточно ввести в консоль следующую команду


composer create-project --prefer-dist botman/studio botelegram


Входной точкой будет rout "/start". В botman’e есть несколько реализаций routes. Т.к. мы будем обращаться к routes через бота в телеграме, то нам нужен "botman.php".


image


В нем нам нужно записать следующую строчку


$botman->hears('/start', function ( $bot ) { $bot->startConversation ( new mainConversation ); } );

telegram сам предлагает начинать работу с ботом через команду "start", а раз так, то мы можем облегчить взаимодействие с ботом, задав начальную точку входа как "/start" и сразу перейти к работе с ним.


С помощью $bot->startConversation ( new mainConversation ); мы указываем какой контроллер будет отвечать за работу. Так же, пропишем использование нашего контроллера, для этого нам нужно в файле с путями добавить этот код:


use App\Conversations\mainConversation;

Продолжим. Нам нужно создать базу данных и сам контроллер. Я подразумеваю, что вы используете openserver. БД можно создать через консоль или с помощью phpMyAdmin, который встроен в openserver.


Теперь немного конфигураций. Нам нужно внести данные БД в конфигурационный файл laravel. Он лежит в корневом каталоге проекта и называется .env


image


Найдите строчки связанные с БД


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=botelegram
DB_USERNAME=root
DB_PASSWORD=

Здесь нас интересует лишь название базы, имя юзера и пароль. Если вы используете openserver, то можно написать в имя-root, а пароль оставить пустым, название БД зависит уже от вас.


Теперь наше приложение имеет доступ к БД. Следующее, что нам потребуется, это создать model и migration. Прописываем в консоле:


php artisan make:model messengerUser -m


Флаг -m создаст миграцию для БД и свяжет ее с нашей моделью. Давайте сразу и настроим нашу миграцию, чтобы больше к ней не возвращаться.


Лучше так не делать, но чтобы не создавать кучу файлов, запишем все данные в одну таблицу.
Нам нужно:


  • id чата
  • Имя пользователя
  • Хорошая погода или нет

Этого достаточно, чтобы продемонстрировать основные возможности botman’a. Откройте только что созданную миграцию, которая находится в database/migrations/дата_создания_create_messanger_users_table.php


image


Дополните метод up в данной миграции, она должна иметь следующий вид:


public function up() { 
    Schema::create('messenger_users', function (Blueprint $table) { 
        $table->increments('id'); 
        $table->string("id_chat"); 
        $table->string("name"); 
        $table->string('response'); 
        $table->timestamps(); 
    }); 
}

Теперь нам нужно запустить миграцию, чтобы наша таблица существовала в БД. В консоли нужно прописать:


php artisan migrate


Подсказка: если в процессе разработки вам потребуется изменить поля в таблице, а в таблице есть данные, и если вам они не нужны, то с помощью команды php artisan migrate:refresh можно обновить таблицы.


Результат:


image


laravel провел 3 миграции, но нас интересует лишь 3-я миграция т.к. именно туда мы будем записывать наши данные.


Настало время создать controller, подключить к нему нашу model и написать логику.


Вообще, лучше все файлы создавать через консоль, но так как мы пользуемся botman’ом, да и я уже так привык, создадим controller вручную. В botman контроллер носит название conversation, возможно, между ними есть существенные отличия, но в этом я не разбирался — не было нужды. В папке app/Conversations создаем файл с именем mainConversation.php .


На экране вы видите минимальную комплектацию conversation’а


namespace App\Conversations;
use BotMan\BotMan\Messages\Conversations\Conversation;
class mainConversation extends conversation
{
   public function run () {      
   }
}

В вашем классе обязательно должен быть публичный метод run, он является входной точкой для controller’а.


Подключим нашу модель к котроллеру:


use app\messengerUser;
Пропишем начальную логику. Метод run будет запускать приватный метод, который спросит, как зовут пользователя, запишет его id и имя в id_chat и name нашей таблицы.


Для начала пропишем:


use App\messengerUser as database;
use BotMan\BotMan\Messages\Attachments\Image;
use BotMan\BotMan\Messages\Conversations\Conversation;

use BotMan\BotMan\Messages\Incoming\Answer as BotManAnswer;
use BotMan\BotMan\Messages\Outgoing\Actions\Button;
use BotMan\BotMan\Messages\Outgoing\OutgoingMessage;
use BotMan\BotMan\Messages\Outgoing\Question as BotManQuestion;

что позволит нам использовать методы botman’a


А теперь внесем изменения в наш контроллер:


class mainConversation extends conversation
{

   public $response = [];

   public function run () {
       $this->setName();
   }

   private function setName() {
       $question = BotManQuestion::create("Привет! Как тебя зовут?");

       $this->ask( $question, function ( BotManAnswer $answer ) {
           if( $answer->getText () != '' ){
               array_push ($this->response, $answer->getText());

               $this->askWeather ();
          }
      });
   }
}

run() запускает нужный нам метод, это setName(). Уже в setName() мы спрашивает имя пользователя, записываем имя в массив, после запускаем следующий метод, который спросит пользователя о погоде.


private function askWeather () {
   $question = BotManQuestion::create("Тебе нравится погода на улице?");

   $question->addButtons( [
       Button::create('Да')->value(1),
       Button::create('Нет')->value(2)
   ]);

   $this->ask($question, function (BotManAnswer $answer) {
       // здесь можно указать какие либо условия, но нам это не нужно сейчас

       array_push ($this->response, $answer);

       $this->exit();
   });
}

askWeather() имеет схожую структуру, но здесь мы используем кнопки чтобы ограничить выбор пользователя и облегчить себе жизнь т.к. кнопки убирают очень много ошибок, которые может создать пользователь. Здесь мы также создаем вопрос, с помощью addButtons() привязываем к вопросу кнопки, а позже вызываем данный вопрос и обрабатываем ответ, а также переходим к последнему методу.


Метод exit() будет записывать все данные в БД(можно вынести в отдельный метод), прощаться с пользователем, а также отправит ему картинку.


private function exit() {
   $db = new database();
   $db->id_chat    = $this->bot->getUser()->getId();
   $db->name       = $this->response[0];
   $db->response   = $this->response[1];
   $db->save();

   $attachment = new Image('https://gykov.ru/projects/botelegram.png');

   $message = OutgoingMessage::create('До новых встреч!')
       ->withAttachment($attachment);
   $this->bot->reply($message);

   return true;
}

С помощью OutgoingMessage::create('До новых встреч!')->withAttachment($attachment) мы создаем новое сообщение и привязываем к нему картинку. Вообще, все публичные файлы, которые должен видеть пользователь, размещаются в папке public, но в последнем моем боте с этим случилась проблема и мне пришлось разместить их в отдельной папке на сервере(не связанной с проектом). Здесь я сделал тоже самое.


Логика нашего бота готова. Чтобы протестировать его достаточно открыть сайт через openserver, но перед этим, нужно создать файл .htiaccess со следующим содержимым


<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^(.*)$ public/$1 [L]
</IfModule>

Файл должен находиться в корне сайта. Теперь все запросы будут передаваться в папку public. Так работает laravel. Открываем сайт и тестируем бота, не забываем, что для начала нужно ввести "/start".


Убедившись, что все работает можно и присоединить его к телеграмм. Для этого необходимо создать нового бота у @botfather, скопировать key бота в конец .env файла. Выглядит это вот так:


TELEGRAM_KEY=key_bot


Теперь нужно поставить в наш проект драйвер для совместной работы нашей логики и телеграм бота. Делается это всего лишь одной командой в консоли:


composer require botman/driver-telegram


Также потребуется зарегистрировать бота в laravel.


php artisan botman:telegram:register


Нам будет предложено ввести адрес по которому будет доступен наш бот.


image


Если вы разрабатываете бота на сервере, то достаточно добавить https://url_site/botman после этого бота можно протестировать и в самом мессенджере. Но знайте, для laravel’а нужны особые настройки сервера и вам, скорей всего, придется самим его настраивать. Ссылку о том, как настроить сервер я оставлю в конце статьи.


Пожалуй, на этом все. Если вы дочитали до конца, то поздравляю, теперь вы можете разрабатывать чат-ботов под laravel с использованием botman. Если есть вопросы, то с радостью отвечу в комментариях, а также обещанные ссылки:


Исходники на github
Документация botman
Настройка сервера
Статья по которой я создавал своего первого бота
Ру статья по botman

Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 14

    0
    Это не значит, что нужно писать только под mvc, можно и...

    Можно и не стрелять из пушки по воробьям.
      0
      вот тоже это хотел сказать. Пишу ботов для вк на чистом php + самописная библиотека для работы с vkapi. Среднее количество строк кода — 170-200 у каждого бота. И ради этого устанавливать фреймворк, создавать миграции и прочее??? Ну нафиг.
        0
        Боты могут быть куда сложнее. Это пример. С фреймворком работать гораздо легче + один интерфейс для большинства месенджеров. Если нужно написать бот для telegram, viber'a и whatsapp, то мне придется писать кучу лишнего кода. Это пример из реального таска.
          0
          Что должен делать наш бот:

          • Спрашивать у пользователя его имя
          • Поинтересоваться, нравится пользователю погода или нет
          • Также записать ответ в БД
          • Попрощаться и отправить картинку



          40 минут работы на PHP+mysqli(или PDO) для вк. Ещё +30 минут для телеграма. Сам фреймворк устанавливать будете столько же, если не дольше.

          Да и полно уже гайдов по созданию ботов и в телеграме, и вайбере и пр. Обучающих материалов по Laravel тоже достаточно (в т.ч. и на русском). Зачем ещё статьи?
            –1
            Я нашел 3-4 стать на русском о botman'е. Никто из них не использует БД. Там показано как подключить botman и отправить сообщение через $this->say(); сомневаюсь, что это поможет новичку понять, что это за инструментарий. Я посчитал нужным написать об этом, возможно я ошибся, но сомневаюсь в этом.
              +2

              В корне с вами не согласен. Здесь должен был быть аргумент о скорости работы, но никак не о скорости установки. Развертка нового laravel приложения занимает минут 5, из которых 4 — скачивание пакетов из сети.


              1) composer create-project laravel/laravel project_name
              2) правка .env для подключения к базе
              3) все.


              Остальные действия ты делаешь так или иначе, когда работаешь с чистым php.


              Правда я согласен с тем, что использование фреймворка для такой простой задачи — стрельба из пушки по воробьям.

        –2
        Спрашивать у пользователя его имя
        Поинтересоваться, нравится пользователю погода или нет
        Также записать ответ в БД
        Попрощаться и отправить картинку

        Что называется «вот и поговорили...»
        Зачем писать таких роботов? — Это же «программирование ради программирования» в чистом виде. А под «лаварель» оно («лаваш» + «акварель» — кто у них там названия выдумывает!) или под «ес ит из» — какая разница?
        Стоит подумать о том, как научить его более интересным вещам, чтобы не было как в «Терминаторе 2»: «А ты можешь немного походить на людей, а не быть всё время полным болваном...»
          0

          Но это полный набор требований для организации соединения, далее идет разработка логики, что может делать другой человек. Ему достаточно использовать простой апи для отправки/получения сообщений и чтения истории из бд.

          –1
          Для начинающих неплохой материал. Часто встречаю на практике, что люди даже не знают как подступиться к написанию ботов. А тут прямо говориться что можно взять Laravel.

          Я тоже сначала подумал «Зачем?», но для новичков-студентов самое то.

          Даже было бы интересно проследить на «ростом» бота в функциональном плане)
            0
            Хотел показать, что разработка с «новым» инструментарием легче, чем кажется. Мне на работе хватает ботов. =)
            Но есть исходники на гитхабе, если есть желание, то можете добавить что-то свое.
            +2
            class mainConversation extends conversation

            Имейте ввиду, что в винде такое прокатит, но в unix файловая система регистрозависима и ваш класс conversation не будет найден. Соблюдайте PSR, и будет вам счастье
            –1
            Спасибо! Вовремя опубликованная для меня. Много, конечно, технических нюансов, но это не мешает взять из статьи самое главное.
              0
              Очень рад, что статья пригодилась.=)

            Only users with full accounts can post comments. Log in, please.