Longman Telegram bot пример

В интернет-коммерции сейчас активно развивается автоматизация мессенджеров. Полезные боты растут, как грибы после дождя. Тут вам и магазины, и онлайн-помощники, инструменты для аналитики, и прочие важные и полезные решения. Современный бот в телеграмме может полноценно заменить целый сайт и вывести бизнес на новый уровень.

Даже криптовалютный кошелек можно создать с помощью бота. Этим и займемся.

Для быстрого создания сервиса будем использовать PHP, возьмем одну из библиотек с core.telegram.org (https://core.telegram.org/bots/samples) php-telegram-bot (https://github.com/php-telegram-bot/core/). Эта библиотека часто обновляется и подходит для дальнейшего масштабирования бота.

В свободном доступе есть несколько API-сервисов для работы с криптовалютами:

Во всех перечисленных сервисах нет проверки KYC и свободная регистрация. Blockchain.info требует получение токена для работы, он условно без проверки, но его получение может занять несколько дней или даже недель.

Как создать телеграм бота с автопостингом в каналы ⚡️ Telegram bot на языке Python ⚡️

Выбор пал на сервис Apirone, потому что тут нет ограничений на создание кошельков и адресов.

Итак, наш бот будет уметь:

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

Вся обработка колбэков от телеграма уже реализована в php-telegram-bot .

< «require»: < «longman/telegram-bot»: «^0.74.0», «monolog/monolog»: «^2.2» >, «autoload»: < «classmap»: [«Classes»] >>

Запускаем composer update для создания базовой структуры. Создаем ее и добавляем туда папку Apirone и в нее файл ApironeWallet.php, в котором реализуем класс взаимодействия с криптопроцессингом.

В нем реализованы следующие функции:

getWallets($user_id, $currencyId = null) //получить кошельки для telegram Пользователя addWallet($user_id, $wallet, $address) //add generated wallet into DB postWallet($user_id, $currency) //get wallet from Apirone createWallets($user_id) //create all available wallets getCurrencyId($currency,$units = null) //get currency id from DB getAddress($chat_id, $user_id, $currency) //outputs wallet from DB getAvailableCurrencies() //collect available currencies from DB getCurrencyById($id, $units = null) // return currency by Id getBalance($chat_id, $user_id, $wallet_id = null) // get wallet or wallets balance checkAddress($currency, $address) // validate crypto address estimate($user_id, $currencyName, $address, $amount) // pre-calculation of crypto transaction transfer($user_id, $currencyName, $address, $amount) // transfer funds explorerUrl($currency, $tx) // get explorer link

Подробно работу этих функций смотрим в примере. Создадим MySQL базу данных, она будет нужна для работы интерактивных диалогов. В нее требуется добавить три таблицы: apirone_currencies, apirone_transactions и apirone_users.

Телеграм бот и гугл таблица: создание, webhook, логгирование

С телеграмом будем общаться с помощью вебхуков (Webhook). Для этого set.php и unset.php — включение и отключение колбэков. hook.php принимает сами колбэки из телеграма:

$telegram->handle();

Установка и удаление вебхука выполняются в две функции:

$result = $telegram->setWebhook($config[‘webhook’][‘url’]); $result = $telegram->deleteWebhook();

В корне проекта нужна папка Commands, в нее запишем наши кастомные команды и изменим существующие. Из изменений в базовых классах нас интересует взаимодействие с меню не только через команды, начинающихся со слэша, но и просто текстовые команды. Для этого в папке Commands добавляем папку ServiceMessages и в ней создаем GenericmessageCommand.php , в который путем перечисления вносим нужные команды и реакции на них:

// Fetch conversation command if it exists and execute it. if ($conversation->exists() $command = $conversation->getCommand()) < return $this->telegram->executeCommand($command); > if($type === «text») < $text = $message->getText(true); if (stripos($text, ‘Receive’) === 0) < return $this->telegram->executeCommand(‘receive’); > if (stripos($text, ‘Menu’) === 0) < return $this->telegram->executeCommand(‘menu’); > if (stripos($text, ‘Balance’) === 0) < return $this->telegram->executeCommand(‘balance’); > if (stripos($text, ‘Send’) === 0) < return $this->telegram->executeCommand(‘send’); > return $this->replyToChat( ‘Command not found’ ); >

Также добавляем наши четыре кастомные команды BalanceCommand.php , MenuCommand.php , ReceiveCommand.php и SendCommand.php.

Каждой команде делаем описание, использование по умолчанию, присваиваем версию.

protected $name = ‘balance’; protected $description = ‘Show balance of wallet’; protected $usage = ‘/balance’; protected $version = ‘1.2.0’;

Сам код команды закладывается в функцию execute(). В ней происходит выполнение операций. Например, вот команда, которая смотрит баланс

$message = $this->getMessage(); $text = $message->getText(true); $chat = $message->getChat(); $user = $message->getFrom(); $chat_id = $chat->getId(); $user_id = $user->getId(); $sql = ‘ SELECT * FROM `apirone_currencies` ‘; $pdo = DB::getPdo(); $sth = $pdo->prepare($sql); $sth->execute(); $result = $sth->fetchAll(PDO::FETCH_ASSOC); foreach ($result as $currency) < if (stripos($text, $currency[‘name’]) === 8) < $response = new ApironeWallet; $response->getAddress($chat_id,$user_id,$currency[‘name’]); return Request::emptyResponse(); > > if ($text === ‘Balance’ || $text ===») < $response = new ApironeWallet; $response->getBalance($chat_id, $user_id); > return Request::emptyResponse();

SendCommand.php будет интерактивным. В нем бот спросит криптовалюту, адрес для перевода средств и сумму платежа.

$this->conversation = new Conversation($user_id, $chat_id, $this->getName()); // Load any existing notes from this conversation $notes = conversation->notes; … // Every time a step is achieved the state is updated if($text === ‘Cancel’) < $state = 4; $notes[‘answer’] = ‘Cancel’; >if($text === ‘Send’) < $text = »; >switch ($state) < case 0: $currencies = $apirone->getAvailableCurrencies(); if ($text === » || !in_array(strtoupper($text), $currencies, true)) < . $data[‘reply_markup’] = (new Keyboard( [$currencies[0],$currencies[1]], [$currencies[2],$currencies[3],$currencies[4]], [‘Cancel’])) ->setResizeKeyboard(true) ->setOneTimeKeyboard(true) ->setSelective(true); $result = Request::sendMessage($data); break; > $notes[‘currency’] = strtolower($text); $text = »; case 1: if ($text === »|| !$apirone->checkAddress($notes[‘currency’], $text)) < $notes[‘state’] = 1; $this->conversation->update(); $data[‘text’] = ‘Type address for transfer:’; if ($text !== ») < . break; >$notes[‘address’] = $text; $text = »; // No break! case 2: … case 3: if ($text === » || !in_array($text, [‘Ok’, ‘Cancel’], true)) < $notes[‘state’] = 3; $this->conversation->update(); $currency = $apirone->getCurrencyId($notes[‘currency’], true); $estimate = $apirone->estimate($user_id, $notes[‘currency’], $notes[‘address’], $notes[‘amount’]); if(isset($estimate[‘message’])) < $data[‘text’] = ‘Message from Apirone:’. PHP_EOL. ‘*’.$estimate[‘message’].’*’ .PHP_EOL. ‘Operation cancelled.’; $data[‘parse_mode’] = ‘markdown’; $data[‘reply_markup’] = (new Keyboard([‘Receive’, ‘Send’], [‘Balance’])) ->setResizeKeyboard(true) ->setOneTimeKeyboard(true) ->setSelective(true); $this->conversation->stop(); > else < $data[‘reply_markup’] = (new Keyboard([‘Ok’, ‘Cancel’])) ->setResizeKeyboard(true) ->setOneTimeKeyboard(true) ->setSelective(true); $data[‘text’] = ‘Please double check that all data correct.

Еще по теме:  Как отправить пресет из лайтрума в Телеграм

Send «Ok» message in answer. If you want to stop sending type «Cancel»‘. PHP_EOL; . if ($text !== ») < $data[‘text’] = ‘Simply type Ok or Cancel.’; >> $result = Request::sendMessage($data); break; > $notes[‘answer’] = $text; // No break! case 4: $this->conversation->update(); unset($notes[‘state’]); if($notes[‘answer’] === ‘Ok’) < $transfer = $apirone->transfer($user_id, $notes[‘currency’], $notes[‘address’], $notes[‘amount’]); if(isset($transfer[‘message’])) < $data[‘text’] = ‘Message from Apirone:’. PHP_EOL. ‘*’.$transfer[‘message’].’*’ .PHP_EOL. ‘Operation cancelled.’; . $this->conversation->stop(); > else < $data[‘text’] = ‘Transfer successfully complete.’.PHP_EOL. ‘Transactions:’. PHP_EOL ; foreach ($transfer[‘txs’] as $tx) < $data[‘text’].= $tx .PHP_EOL. $apirone->explorerUrl($notes[‘currency’], $tx).PHP_EOL; >; > > . $result = Request::sendMessage($data); $this->conversation->stop(); break; > return $result;

Создаем StartCommand.php И в нем при первом обращении генерируем данные для нашей базы данных

$message = $this->getMessage(); $user_id = $message->getFrom()->getId(); $apirone = new ApironeWallet; $apirone->createWallets($user_id); return $this->replyToChat( ‘Welcome to Apirone wallet bot! You are ready to use BTC,BCH,DOGE and LTC wallets right now’ . PHP_EOL . ‘Type /menu to start using it now!’ );

В корне проекта создаем callback.php . Здесь будет приниматься колбэк от процессинга:

require_once __DIR__ . ‘/vendor/autoload.php’; use LongmanTelegramBotRequest; use ClassesApironeApironeWallet; $config = require __DIR__ . ‘/config.php’; $telegram = new LongmanTelegramBotTelegram($config[‘api_key’], $config[‘bot_username’]); $apirone = new ApironeWallet; $telegram->enableMySql($config[‘mysql’]);; $apironeData = file_get_contents(‘php://input’); if ($apironeData) < $params = json_decode($apironeData, true); // check your secret code if ($params[«data»][«secret»] !== $config[‘apirone_secret’]) die(); $user_id = $params[«data»][«user_id»]; $input_address = $params[«input_address»]; $input_transaction_hash = $params[«input_transaction_hash»]; $value_in_satoshi = $params[«value»]; $wallets = $apirone->getWallets($user_id); foreach ($wallets as $wallet) < if($wallet[‘wallet_id’] === $params[‘wallet’]) < $currency = $apirone->getCurrencyById($wallet[‘currency’], true); > > //Save unconfirmed transactions and data to your Database. $data[‘chat_id’] = $user_id; $data[‘parse_mode’] = ‘markdown’; if ($params[«confirmations»] < 2 ) < $data[‘text’] = ‘*’.strtoupper($currency[‘name’]) .’ wallet*: ‘. PHP_EOL . «Transaction «. $input_transaction_hash . PHP_EOL. ‘Waiting *’. number_format($value_in_satoshi/pow(10, $currency[‘units-factor’]), 8, ‘.’, »). strtoupper($currency[‘name’]) .’*’. PHP_EOL . $params[«confirmations»].’ of 2 confirmations received’.

PHP_EOL . $apirone->explorerUrl($currency[‘name’], $input_transaction_hash); > if ($params[«confirmations»] >= 2) < $balance = $apirone->getBalance($user_id, $user_id, $params[‘wallet’]); $data[‘text’] = ‘*’.strtoupper($currency[‘name’]) .’ wallet*: ‘. PHP_EOL . «Transaction «. $input_transaction_hash . PHP_EOL. ‘Payment successfully received!’. PHP_EOL .’Amount: *’. number_format($value_in_satoshi/pow(10, $currency[‘units-factor’]), 8, ‘.’, »). strtoupper($currency[‘name’]) .’*’. PHP_EOL. ‘Current balance:’. PHP_EOL . $balance . PHP_EOL. $apirone->explorerUrl($currency[‘name’], $input_transaction_hash); echo «*ok*»; > return Request::sendMessage($data);

В итоговом результате имеем простого бота, который в дальнейшем можно будет трансформировать и дорабатывать, т.к. заложена серьезная база в виде php-telegram-bot.

При написании бота было изучено достаточно источников. И как оказалось, готовых примеров реализаций ботов на просторах интернета очень мало. Данный бот будет полезен тем, кто хочет дорабатывать свои сервисы для приема криптовалюты или хочет получить свой собственный криптовалютный кошелек в телеграме.

Источник: tproger.ru

Простой Telegram бот, который задаёт 1 вопрос

gimp творчество

Основная идея бота — это противодействие спам — регистрациям в группе Telegram.

Ниже расскажу о процессе создания Telegram бота который выполняет простую функцию — задаёт новому пользователю группы вопрос и предоставляет возможностью выбрать ответ на него.

Для всех желающих увидеть код сразу и целиком — добро пожаловать в конец статьи ( там есть ссылки)

Инструменты

Всё началось с того что одна из моих групп доросла до некоторого количество пользователей и стала интересна для различных спам сервисов. Удаление спам сообщений не составляет труда, но постоянно мониторить группы на предмет таких сообщений не самый лучший способ провести время. При этом давно хотел попробовать указанные выше инструменты для реализации хоть сколько полезного бота Telegram.

Идея с тем что бы задавать вопрос пользователю при помощи бота, далеко не новая и успешно была реализована в таких сервисах — ботах как Combot, Terminator (не помню точное название, там ещё мужик похожий на Арнольда в куртке был на логотипе) и другие.

Как это должно работать в теории

  1. Пользователь (человек, авто-спам, злой бот) вступает в сообщество
  2. Бот (добрый бот) — администратор сообщества реагирует на каждое новое вступление и задаёт простой вопрос. (Кто ты?). При этом есть только два варианта ответов — «Я человек» и «Я робот». Так же бот забирает все права и разрешения у пользователя в этой группе.
  3. По сути можно оставить только одну кнопку — «Я человек» и предположить, то что ответить, не ткнув на кнопку пальцем не представляется возможным.
  4. После нажатия на кнопку с ответом, backend этого бота обрабатывает ответ и принимает дальнейшее решение.
  5. Если ответ принадлежит пользователю вступившему в группу — и ответ «Я человек», пользователю возвращаются права и разрешения в группе в которую он вступил.
  6. Бот что-нибудь пишет, например, «добро пожаловать»

Для понимания того что происходит в группе необходимо обрабатывать json-ы которые сервис Telegram будет присылать на URL адрес (webhook) закреплённый за созданным вами ботом.

Достаточно вольное изображение схемы

Наш backend обрабатывает все сообщения приходящие от сервиса Telegram, и по мере необходимости наступления некоторых событий формирует запросы к сервису Telegram. В свою очередь последний — через вашего бота доводит эти команды до группы (где вы можете видеть результат).

Для реализации взаимодействия с сервисом Telegram есть несколько API библиотек на языке PHP

  1. danog/MadelineProto — Мощная, гибкая, с асинхронными «фичами».
  2. php-telegram-bot/core — Выбрал её, так как захотелось попробовать что то новое. Как оказалась она достаточно простая для понимания, достаточно пробежаться по ней xdebug-ом

Немного о php-telegram-bot/core

Вся «сила» библиотеки крутится возле одного крупного класса class LongmanTelegramBotTelegram. При этом есть возможность создавать отдельные обработчики поступающих json-ов через создание файлов-классов команд.

При инициализации объекта класса LongmanTelegramBotTelegram необходимо указать путь к папке с вашими обработчиками команд, что бы затем в этих обработчиках описать всю необходимую логику реагирования на события происходящие в вашей группе (события обновления группы).

Еще по теме:  Как вручается Телеграмма почтой России

Так же что бы лаконично внедриться в этот механизм взаимодействия с библиотекой, потребовалось расширить базовый класс библиотеки своим собственным, добавить новый метод для встраивания InteropContainerContainerInterface от Laminas и организовать фабрику для удовлетворения всех зависимостей.

Немного кода — реализации

Код сильно упрощён (В конце будут ссылки на репозитарий с модулем и отдельно приложением Laminas)

Пример обработчика поступающих команд

getMessage(); // Здесь какие либо действия или обработки return Request::emptyResponse(); > >

В момент поступления сообщения от сервиса Telegram — библиотека вызовет необходимый обработчик из указанной вами папки. Внутри этого обработчика можно получить данные о сообщение, отправителе, получателе, а так же сформировать новое сообщение для отправки — в группу от имени бота.

Так образом, мы можем получить уведомление о новом событие в группе. В данном случае нас интересует событие связанное с вступлением в группу нового пользователя.

Теперь необходимо сформировать сообщение которое будет иметь вопрос и две кнопки с ответом.

Ниже код, формирующий две кнопки. Поле callback_data — содержит значение ответа. В нашем случае это некоторая строка к которой добавлен (методом конкатенации) id вступившего в группу пользователя. Значение id пользователя добавляется в объект при его создании в вызывающем коде.

InlineKeyboard] */ public function getQuestion() < $keyboard = new InlineKeyboard([ [‘text’ =>’Я бот!’, ‘callback_data’ => QuestionKeyboardMap::CALLBACK_ANSWER_BOT.$this->curentUserId], [‘text’ => ‘Я человек!’, ‘callback_data’ => QuestionKeyboardMap::CALLBACK_ANSWER_HUMAN.$this->curentUserId], ]); return [‘reply_markup’ => $keyboard]; > public function setCurentUserId(string $curentUserId) < $this->curentUserId = $curentUserId; return $this; > >

Пример обработки события о вступлении нового пользователя в группу. В данном случае используется триггер события framework-а Laminas, что бы выполнить всю логику обработки этого кода в другой части модуля.

Подписываемся на событие при инициализации модуля и обрабатываем его в методе processRequestToJoinGroup класса Events

getApplication()->getServiceManager()->get(Events::class); $eventManager = $e->getApplication()->getServiceManager()->get(EventManager::class); $eventManager->attach(EventsMap::NEW_USER_SENT_REQUEST_TO_JOIN_GROUP,[$eventsService,’processRequestToJoinGroup’]); > >

Теперь необходимо отправить приветственное сообщение новому пользователю и добавить к сообщению наши кнопки с ответами. А так же лишить пользователя всех прав в группе до того момента пока он не предоставит ответ на вопрос.

Дальше, нужно обработать ответ от пользователя, снять ограничения и написать ему что нибудь в ответ, например «Добро пожаловать»

Опять большой код

Это метод так же вызывается как триггер на событие созданное при инициализации модуля Laminas. (В рамках статьи этот код здесь не указан)

Так же в этом методе есть триггер успешного прохождения проверки пользователя (здесь пример реализации не приводится) — его можно использовать для записи каких-либо данных о пользователе в базу данных.

Как это работает на самом деле, и какие есть оправданные сомнения

  • «Хороший» пользователь вступает в группу, получает вопрос и отвечает «Я человек». У него есть все возможности для общения в группе и за ним больше ни кто не наблюдает и его действия ни как не обрабатываются. Хотя при желании можно и дальше отслеживать, сервис Telegram будет отправлять изменения в группе на webhook.
  • «Плохой бот» вступает в группу (именно бот в понятии Telegram), эта «единица» пользователей отмечены специальным полем. Такие по задумке блокируются на «подлёте» без дополнительных вопросов.
  • «Плохой» пользователь (чаще всего автоматизированный) — вступает в группу и кидает сообщение с здоровенной картинкой (сейчас модно почему то про Биткоин спамить таким способом). Вот тут возникает предположение, что наш «добрый» бот не успеет сделать всё как надо, потому — что ему потребуется время на отправку команды для лишения пользователя всех прав в группе и отправка команды с приветствием и вопросом. (два запроса, в обоих случаях это вызов LongmanTelegramBotRequest). И с большей долей вероятности «Плохой» пользователь сможет выполнить свой корыстный спам-запрос и нагадить в нашу группу между Request.
  • Если групп очень крупная, популярная, тогда есть вероятность что сообщения по линии webhook от сервиса Telegram на наш backend встанут в очередь и часть пользователей не сможет дать ответ на вопрос (тупо запрос повиснет в воздухе) или по достижению 100-а запросов в единицу времени, 101-й будет проходить мимо «доброго» бота. От части можно снизить очередь сообщений об обновлениях в группе, указав при создании webhook-а какие обновления от сервиса Телеграм отправлять (через параметр allowed_updates)

Какие ещё были мысли перед реализацией и что остаётся за рамками сейчас

Для проверки отправителя ответа нужно записывать информацию в базу данных. Т.е с начало сохранить данные о попытке вступления, потом сверить эти данные с теми что придут после ответа на вопрос (если они придут).

Показалось что это слишком сложно, и как указал выше, можно просто «приплюсовать» конкатенировать id пользователя к значению ответа перед формированием кнопок с ответами. Потом сопоставить ответ с тем значением от кого пришёл ответ.

Пример Json от сервиса Telegram c полем конкатенации строки и ИД пользователя

Удалять все сервисные сообщения от бота. Группа может быть просто завален вопросами от бота без ответа. Так как при нормальной логике (после верного ответа), вопрос удаляется. Для очистки нужно подключать cron, а так же вести лог с номерами сервисных сообщений в базе данных.

Что делать если бот не доступен, тогда новые пользователи в чат не попадут без ручного модерирования.

Пользователя после ответа на вопрос можно наделить «избыточными» разрешениями. Но как оказалось во время исследования, наделить пользователя полномочиями выше тех что установлены на группу глобально — не получится.

Это не будет работать. Да, действительно, решение достаточно спорное и пока оно тестируется в весьма «тепличных» условиях.

Перед вступлениемПользователь собрался вступить в группуПользователь ответил - Я человек

Ссылки

  • Библиотека для запросов а API Telegram php-telegram-bot/core здесь
  • Весь код модуля бота для Laminas здесь
  • Скелетон приложения Laminas с модулем для развёртывания здесь
Еще по теме:  Отличие Телеграмма от ВК

P.S.: Весь код в примерах на PHP, выбрать язык не позволил новый редактор, отправил баг в специальный раздел

Источник: habr.com

Начало проекта

Это первая заметка из небольшого цикла по реальному применению Vesp. В качестве примера мы напишем и запустим Telegram бота, который будет делать что-то несложное.

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

Я буду предполагать, что у вас уже есть своё рабочее окружение, и вы можете запускать на своей машине PHP с NodeJS.

Лично я использую последнюю MacOS с Homebrew, Laravel Valet, MySQL 8, PHP 7.4 и Node 17.5. Если нужна отдельная заметка по их установке и настройке — напишите в комментариях.

Подготовка

Если вы тоже используете Valet, то установите мой драйвер для работы с Vesp.

Итак, создаём новый проект в директории ExampleBot :

composer create-project vesp/vesp ExampleBot

Эта команда скачает и установит все нужные зависимости для PHP и Node.

Создаём локальный домен example-bot.test для работы:

cd ExampleBot valet link example-bot

Переименовываем .env в .env.local , чтобы избежать возможных конфликтов при будущем деплое на рабочий сервер

mv .env .env.local

И редактируем файл, примерно так:

APP_NAME=»Example Bot» SITE_URL=http://example-bot.test/ API_URL=http://example-bot.test/api/ CORS=1 # Разрешаем кросс-доменные запросы к API DB_DRIVER=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_PREFIX=app_ DB_DATABASE=ExampleBot DB_USERNAME=root DB_PASSWORD=root DB_CHARSET=utf8mb4 DB_COLLATION=utf8mb4_general_ci DB_FOREIGN_KEYS=1 JWT_SECRET=secret JWT_EXPIRE=2592000 JWT_MAX=3 UPLOAD_DIR=/Users/developer/Projects/ExampleBot/upload/ CACHE_DIR=/Users/developer/Projects/ExampleBot/tmp/

Теперь можно собрать фронтенд и проверить работу проекта:

composer node:generate

Открываем ваш локальный http://example-bot.test , и видим стандартную заглушку.

Фронтенд нам пока не нужен, но пусть будет. Интересует нас работа API, которую тоже легко проверить.

Открываем http://example-bot.test/api/user/profile , и в ответ мы должны получить «Authentication required» и код 401.

Если вы это видите, значит всё в порядке, API работает и можно продолжать работу.

Создаём бота

Я сделал VespExampleBot, и получил токен для HTTP запросов к нему.

Cоздаём новые переменные в .env.local , чтобы затем использовать их в своём коде

BOT_USERNAME=ВашеИмяБота BOT_API_KEY=ВашСекретныйТокен

Если в будущем нужно будет заменить токен, то поменять его придётся только в файле настроек.

Всё, телеграм-бот уже работает, только ничего не делает, потому что мы не написали программу, которая будет с ним дружить.

Логика работы API Vesp

Для получения и обработки запросов Vesp использует Slim 4.

  • Все запросы прилетают в www/api.php
  • Там Slim инициализируется через PHP-DI, что сразу даёт нам поддержку контейнера зависимостей в контроллерах
  • Затем добавлятся маршруты с контроллерами из core/routes.php
  • Slim сверяет запрос с указанными маршрутами и передаёт его подходящему контроллеру
  • Контроллер обрабатывает запрос и возвращает ответ через $this->success() или $this->failure() в формате JSON.

Согласно спецификации HTTP, запросы могут быть отправлены разными методами: GET , POST , PUT , PATCH , DELETE и OPTIONS .

Ответы должны соответствовать PSR-7, за что также отвечает Slim 4.

Нам остаётся только добавить в котроллер публичную функцию для нужного запроса с его именем, например для GET :

public function get( ): PsrHttpMessageResponseInterface < return $this->success(‘Hello World!’); >

Как следуюет из сигнатуры функции, ответ обязательно должен быть экземпляром PsrHttpMessageResponseInterface .

Для POST и PATCH это будут соответственно:

public function post( ): PsrHttpMessageResponseInterface < // . > public function patch( ): PsrHttpMessageResponseInterface < // . >

Если кто-то запросит метод, которого в котроллере нет, то получит ошибку 405 Method Not Allowed .

Итого, для поддержки любых запросов в API, нам нужно:

  1. Создать контроллер в core/src/Controllers , который будет расширять VespControllersController или его наследника.
  2. Прописать в нём нужные публичные методы.
  3. Указать этот контроллер для маршрута в core/routes.php
  4. Ну и присылать запросы на этот адрес.

Проверяем связь с ботом

Устанавливаем библиотеку для работы с API Телеграм:

composer require longman/telegram-bot

Создаём сервис для работы с API, чтобы его можно было легко использовать в контроллерах Vesp.

Создаём файл core/src/Services/Telegram.php :

namespace AppServices; class Telegram extends LongmanTelegramBotTelegram < public function __construct( ) < parent::__construct(getenv(‘BOT_API_KEY’), getenv(‘BOT_USERNAME’)); > >

Как видно, наш класс расширяет основной класс библиотеки, всего с одним изменением — он сразу указывает наши переменные для бота. То есть, когда мы будем вызывать наш сервис, он всегда будет инициализировать именно нашего бота, без лишних вопросов.

Теперь пишем простенький контроллер для теста core/src/Controllers/Web/Test.php . Он не будет требовать никакой авторизации, поэтому кладём его в раздел Web :

namespace AppControllersWeb; use AppServicesTelegram; use LongmanTelegramBotRequest; use PsrHttpMessageResponseInterface; use VespControllersController; use VespServicesEloquent; class Test extends Controller < protected Telegram $telegram; public function __construct(Eloquent $eloquent, Telegram $telegram) < parent::__construct($eloquent); $this->telegram = $telegram; > public function get( ): ResponseInterface < $response = Request::getMe(); if ($response->isOk()) < return $this->success($response->getResult()); > return $this->failure($response->getDescription(), $response->getErrorCode()); > >

Тут нужно обратить внимание, что мы расширили конструктор контроллера и помимо стандартной загрузки Eloquent для работы с базой данных, добавили еще и наш новый сервис Telegram .

Так как Vesp использует контейнер зависимостей, при обращении к такому контроллеру в него автоматически передаются требуемые классы.

Таким образом можно загружать любые свои сервисы в контроллеры и там их использовать.

Осталось только указать новый маршрут с нашим контроллером в core/routes.php внутри группы api , сразу после подгруппы admin :

$group->group( ‘/web’, static function (RouteCollectorProxy $group) < $group->get(‘/test’, AppControllersWebTest::class); > );

Теперь можно делать запрос по адресу http://example-bot.test/api/web/test и, если вы всё сделали верно, то получите ответ с данными бота.

У меня он вот такой:

Это значит, что наша система не только работает, но и связана с ботом, и может им управлять.

Полный код проекта в текущем виде находится на GitHub.

Источник: bezumkin.ru

Рейтинг
( Пока оценок нет )
Загрузка ...