Установка Botman
Предполагаю, что вы уже зарегистрировали бот через BotFather..
Botman — это по инстрмент для удобной и быстрой разработки ботов под любые платформы. Представляет из себя компонент для фреймворка Laravel. Однако если вы не знакомы с Laravel, то это не будет большой проблемой, так как экосистема Botman достаточно изолирована и самодостаточна. Вам хватит знаний PHP.
Установить Botman starter kit командой
composer create-project --prefer-dist botman/studio <directory>
После этого возможно появится ошибка, если установлен Composer 2. Тогда нужно выполнить команду
composer update
Еще одна необходимая команда после установки
php artisan key:generate
Затем нужно подгрузить модуль для работы с Телеграм
composer require botman/driver-telegram
Запустить сервер
php artisan serve
Как вести разработку чат-бота Telegram на локальном домене? Использовать Ngrok!
Если вы ведете разработку на локальной машине без внешнего IP, то возникнет трудность с регистрацией вэб Хука для обработки сообщений телеграм. Но проблема эта легко решается сервисом ngrok.com, от даст возможность связать локальный домен с доменом вида https://99328bcc9109.ngrok.io/, доступным в интернете. Еще очень удобно, что этот сервис сам генерирует https, даже если исходный домен без SSL.
Настройки Ngrok (бесплатный аккаунт)
Для начала нужно скачать эту программу себе на компьютер, разархивировать, запустить и ввести команду
authtoken [Ваш токен]
php artisan serve + Ngrok
Если вы используете команду php artisan serve для реализации веб-сервера, то скорее всего вам будет достаточно будет ввести команду (запустите ngrok.exe и там введите эту команду)
ngrok http 127.0.0.1:8000
Увидите примерно это:

Теперь ваш локальный http://127.0.0.1:8000 доступен по адресу https://df4c2ff466f6.ngrok.io. Класс!
OpenServer + Ngrok
OpenServer — это комплект утилит для реализации локального сервера, в том числе локальных доменов.
Если просто ввести команду ngrok http cb.test (cb.test — локальный домен), почему-то при заходе на поддомен Ngrok возникает синий экран с надписью "Как вы здесь оказались? Для перенаправления IP на нужный домен создайте алиас в настройках."
Поэтому следует указывать немного другую команду чтобы Ngrok работал корректно в связке с OpenServer:
ngrok http --host-header=loc-team.test 80
Или
ngrok http loc-team.test --host-header=loc-team.test
Установка Вэб-хука для бота Telegram в Botman
Перед установкой вэб-хука нужно
Создать бота через BotFather
Добавить в ваш .env файл строчку с токеном из BotFather
TELEGRAM_TOKEN='Ваш_токен'
Установка Вэб-хука для бота Telegram в Botman
Вводим команду
php artisan botman:telegram:register --output
В ответ на вопрос What is the target url for the telegram bot? Вводим https адрес, полученный из Ngrok, с прибавленным путем /botman, например вот такой:
https://df4c2ff466f6.ngrok.io/botman
Настройка завершена! Ваш локальный домен теперь используется в качестве веб-кука для бота!
Построение бота в Botman
Обработка входящих сообщений
В файле routes\botman.php прописываются команды, на которые будет реагировать ваш бот
Обработать входящее сообщение можно прямо тут же, хотя лучше использовать контроллер
$botman->hears('Hi', function ($bot) {
$bot->reply("Hello! @" . $bot->getUser()->getUsername());
});
Данные пользователя
$botman->hears('Кто я', function ($bot) {
$bot->reply("@" . $bot->getUser()->getUsername() . " - твой Username");
$bot->reply($bot->getUser()->getId() . " - твой Id");
});
Разные варианты вопроса
$botman->hears(['yo', 'oy'], function ($bot) {
$bot->reply("@" . $bot->getUser()->getUsername()." - твой Username");
});
Пример с использованием контроллера
$botman->hears('/start', BotManController::class . '@start');
Означает, что команда /start будет обработана методом start в контроллере BotManController. В этот метод будет передан объект класса BotMan
namespace App\Http\Controllers;
use BotMan\BotMan\BotMan;
class BotManController extends Controller {
public function start(BotMan $bot){
$bot->reply("Bot started");
}
}
Составить диалог
По-настоящему раскрывает свой потенциал Botman именно в обслуживании диалогов. Вы можете создавать достаточно сложные диалоги, при этом их структура будет упорядоченной и лаконичной. Документация на английском
Для создания файла с диалогом введите команду. Появится новый файл в app\Conversations.
php artisan botman:make:conversation SimpleConversation
В этом методе сначала есть только метод run(). Но давайте постепенно добавим туда пару вопросов.
Пример диалога (Conversation) в Botman
В файле routes\botman.php добавляем строчку с активацией диалога:
$botman->hears('/simple', function($bot){
$bot->startConversation(new \App\Conversations\SimpleConversation());
});
И заполним диалог. Пока все очень просто. Сначала бот спросит имя, затем email. Ответы на вопросы будут сохраняться.
namespace App\Conversations;
use BotMan\BotMan\Messages\Conversations\Conversation;
use BotMan\BotMan\Messages\Incoming\Answer;
class SimpleConversation extends Conversation {
public $user = [];
public function askEmail() {
$this->ask('Напиши свой E-mail, плз', function (Answer $answer) {
$this->user['email'] = $answer->getText();
$this->say('Спасибо '.$this->user['name'].', теперь оправлю тебе тонну спама на ' . $this->user['email']);
//return $this->askGender();
});
}
public function askName() {
$this->ask('Привет, как тебя зовут?', function (Answer $answer) {
// Сохраняем результат, и он будет доступен и в других вопросах/ответах
$this->user['name'] = $answer->getText();
$this->say('Приятно познакомиться, ' . $this->user['name']);
// переход к следующему вопросу
$this->askEmail();
});
}
// Этот метод запускается при создании диалога
public function run() {
return $this->askName();
}
}
Добавим кнопки в диалог
добавьте метод askGender(), и раскомментируйте return $this->askGender(); в методе askEmail().
public function askGender() {
$question = Question::create('Ваш гендер')
->addButtons([
Button::create('Женский')->value('woman'),
Button::create('Мужской')->value('man'),
Button::create('Другое')->value('other'),
]);
$this->ask($question, function (Answer $answer) {
// Если кликнули по кнопке
if ($answer->isInteractiveMessageReply()) {
switch($answer->getValue()){
case "woman":
$this->bot->reply($this->user['name'].", ты прекрасна!");
break;
case "man":
$this->bot->reply($this->user['name'].", твой дух силен!");
break;
case "other":
$this->bot->reply($this->user['name'].", ты загадка!");
break;
}
}else{
// Если ввели тект, то задаем вопрос заново
$this->bot->reply("Вы ввели текстом ". $answer->getText(). ", но надо нажать на кнопку..");
return $this->askGender();
}
});
}
Дебаг в Botman
Первое, что нужно знать - это сброс кэша во время диалогов. Чтобы заново начать общение выполните команду
php artisan cache:clear
Логирование и дебаг вашего приложение по-умолчанию достаточно скудный. Если ошибка на сервере, то вы просто получаете 500 ошибку в своем Ngrok.exe. Неприятным дополнением является то, что ошибка зацикливается, так как Telegram повторяет запросы к серверу. Чтобы их остановить нужно чтобы ваше приложение дало хоть какой-то ответ. А потом уже ищите в чем проблема по коду. В Laravel (Botman — это пакет/расширение для Laravel) ошибки записываются в файл storage\logs\laravel.log.
Функция для логирования в Laravel:
info('some string', $some_array);
Чтобы избежать зацикливания ошибки можно настроить приложение чтобы оно возвращало JSON при 500 ошибке. Telegram не будет опрашивать ваш сервер в надежде получить какой-то ответ. Он увидит, что какая-то "шляпа", и успокоится.
Для этого в файле app\Exceptions\Handler.php метод render()
Теперь вы можете отслеживать ошибки тут http://127.0.0.1:4040, если пользуетесь Ngrok.
public function render($request, Exception $exception) {
return response()->json([
'type' => get_class($exception),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTrace(),
'previous' => $exception->getPrevious(),
]);
}
Хорошо бы еще отслеживать исходящие данные. Для этого я использовал костыль. Наверняка есть способы лучше, но...
В файле vendor\botman\driver-telegram\src\TelegramDriver.php
В методе sendPayload перед return добавляем:
info('TG p', $payload);
В методе sendRequest перед return добавляем:
info('TG r', $parameters);
Теперь в файл логирования storage\logs\laravel.log будут попадать дынные ответа
Как отправить свой запрос, используя API Телеграма в обход оберток Botman
Пример из routes\botman.php
Документация Telegram - https://core.telegram.org/bots/api#sendmessage
$botman->hears('yo', function (BotMan $bot) {
$bot->sendRequest('sendMessage', ['text' => 'text..', 'reply_markup' => json_encode([
'inline_keyboard' => [
[ ['text' => '11', 'callback_data' => "1-1"], ['text' => 'yo', 'callback_data' => "YO"] ],
[ ['text' => 'yo', 'callback_data' => "YO"] ],
[ ['text' => 'yo', 'callback_data' => "YO"] ],
]
], 256)]);
});
Обновление текста и кнопок во время диалога
Подробное описание в отдельной статье — Добавить в botman editMessageText для Telegram
Комментарии (0)
Не писать ответ