Thứ năm, 12/12/2019 | 00:00 GMT+7

Cách tạo một Telegram Bot với Laravel và BotMan

Các bot tự động là một cách để cung cấp dữ liệu tùy chỉnh cho user của bạn dựa trên yêu cầu của họ. Laravel và khung công tác Botman cung cấp các công cụ để tạo ra các bot hữu ích. Trong hướng dẫn này, bạn sẽ tạo một bot Telegram cho những người yêu chó bằng cách sử dụng Dog API và nó trông giống như sau:

Gửi một bức ảnh chó ngẫu nhiên theo giống của nó

Cài đặt Laravel & Botman

Bước đầu tiên ta sẽ thực hiện để tạo Bot này là cài đặt LaravelBotman . Nhưng trước khi làm điều đó, trước tiên ta hãy xem nhanh Botman là gì và nó hoạt động như thế nào:

BotMan là một thư viện PHP bất khả tri khung được thiết kế để đơn giản hóa nhiệm vụ phát triển các bot sáng tạo cho nhiều nền tảng nhắn tin, bao gồm Slack, Telegram, Microsoft Bot Framework, Nexmo, HipChat, Facebook Messenger và WeChat.

$botman->hears('Bot, What’s the best Web Development training website?', function (BotMan $bot) {     $bot->reply('DigitalOcean for sure. Give me a harder question!!'); }); 

Cài đặt Botman Studio

Marcel Pociot , người tạo ra Botman, đã giúp ta tiết kiệm thời gian bằng cách tạo ra Botman Studio , một ứng dụng Laravel sẵn sàng sử dụng và cập nhật với Botman và các công cụ kiểm tra khác (được đề cập sau).

Tiếp tục và tạo một dự án mới:

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

Bây giờ ta đã có một bản cài đặt mới của Laravel và Botman, hãy kiểm tra xem mọi thứ có hoạt động tốt không. Mở terminal của bạn và chạy lệnh này:

php artisan botman:tinker 

Nếu bạn nhập “Xin chào” và Bot trả lời bằng “Xin chào” thì bạn đã sẵn sàng.

Botman Tinker

Tạo lệnh

Bot của ta sẽ có thể phản hồi các loại thông báo khác nhau và đây là danh sách các tính năng mà ta sẽ triển khai, nhưng tất nhiên bạn luôn có thể thêm bất kỳ lệnh bổ sung nào mà bạn muốn Bot của bạn nghe:

  • Gửi một bức ảnh chó ngẫu nhiên từ tất cả các giống.
  • Gửi một bức ảnh con chó ngẫu nhiên theo giống của nó.
  • Gửi ảnh con chó ngẫu nhiên theo giống và giống phụ của nó.
  • Có một cuộc trò chuyện và cung cấp trợ giúp.
  • Trả lời các lệnh không được công nhận.

Hãy xóa file routes/botman.php và bắt đầu lại từ đầu.

Gửi ảnh chó ngẫu nhiên từ tất cả các giống

Để nhận được ảnh con chó ngẫu nhiên từ Bot, bạn phải gửi nó /random và đây là cách ta yêu cầu nó phản hồi lại lệnh chính xác đó:

Trong file routes/botman.php của bạn:

<?php  use App\Conversations\StartConversation;  $botman = resolve('botman');  $botman->hears('/random', 'App\Http\Controllers\AllBreedsController@random'); 

Tiếp tục và tạo bộ điều khiển:

php artisan make:controller AllBreedsController 

Đây là những gì nó sẽ giống:

<?php  namespace App\Http\Controllers;  use App\Services\DogService; use App\Http\Controllers\Controller;  class AllBreedsController extends Controller {     /**      * Controller constructor      *       * @return void      */     public function __construct()     {         $this->photos = new DogService;     }      /**      * Return a random dog image from all breeds.      *      * @return void      */     public function random($bot)     {         // $this->photos->random() is basically the photo URL returned from the service.         // $bot->reply is what we will use to send a message back to the user.         $bot->reply($this->photos->random());     }  } 

Đầu tiên, ta tạo một version DogService của ta ( app//services/DogService.php ), nó sẽ chịu trách nhiệm thực hiện các lệnh gọi API đến các điểm cuối của ta và tìm nạp hình ảnh và đây là hình ảnh trông như thế nào:

<?php  namespace App\Services;  use Exception; use GuzzleHttp\Client;  class DogService {     // The endpoint we will be getting a random image from.     const RANDOM_ENDPOINT = 'https://dog.ceo/api/breeds/image/random';      /**      * Guzzle client.      *      * @var GuzzleHttp\Client      */     protected $client;      /**      * DogService constructor      *       * @return void      */     public function __construct()     {         $this->client = new Client;     }      /**      * Fetch and return a random image from all breeds.      *      * @return string      */     public function random()     {         try {             // Decode the json response.             $response = json_decode(                 // Make an API call an return the response body.                 $this->client->get(self::RANDOM_ENDPOINT)->getBody()             );              // Return the image URL.             return $response->message;         } catch (Exception $e) {             // If anything goes wrong, we will be sending the user this error message.             return 'An unexpected error occurred. Please try again later.';         }     } } 

Gửi ảnh con chó ngẫu nhiên theo giống của nó

Đối với cái này, ta sẽ sử dụng lệnh /b {breed} và tương tự như trên, ta mở file routes/botman.php và yêu cầu Bot lắng nghe lệnh đó bằng cách thêm dòng này:

$botman->hears('/b {breed}', 'App\Http\Controllers\AllBreedsController@byBreed'); 

Ta sẽ sử dụng cùng một bộ điều khiển mà ta đã sử dụng trước đây. Mở AllBreedsController và thêm phương thức này vào nó:

/**  * Return a random dog image from a given breed.  *  * @return void  */ public function byBreed($bot, $name) {     // Because we used a wildcard in the command definition, Botman will pass it to our method.     // Again, we let the service class handle the API call and we reply with the result we get back.     $bot->reply($this->photos->byBreed($name)); } 

Hãy xác định phương thức byBreed trong lớp dịch vụ của ta bằng cách mở lớp DogService và thêm phương thức này vào nó:

/**  * Fetch and return a random image from a given breed.  *  * @param string $breed  * @return string  */ public function byBreed($breed) {     try {         // We replace %s    in our endpoint with the given breed name.         $endpoint = sprintf(self::BREED_ENDPOINT, $breed);          $response = json_decode(             $this->client->get($endpoint)->getBody()         );          return $response->message;     } catch (Exception $e) {         return "Sorry I couldn\"t get you any photos from $breed. Please try with a different breed.";     } } 

Và đừng quên thêm const điểm cuối được sử dụng ở trên vào cùng một file :

// The endpoint we will hit to get a random image by a given breed name. const BREED_ENDPOINT = 'https://dog.ceo/api/breed/%s/images/random'; 

Gửi ảnh chó ngẫu nhiên theo giống và giống phụ của nó

Để có ảnh giống con, hãy sử dụng lệnh /s {breed}:{subBreed}

$botman->hears('/s {breed}:{subBreed}', 'App\Http\Controllers\SubBreedController@random'); 

Tạo bộ điều khiển:

php artisan make:controller SubBreedController 

Và ta sẽ xác định phương pháp random như được hiển thị bên dưới:

<?php  namespace App\Conversations;  use App\Services\DogService; use App\Http\Controllers\Controller;  class SubBreedController extends Controller {     /**      * Controller constructor      *       * @return void      */     public function __construct()     {         $this->photos = new DogService;     }      /**      * Return a random dog image from all breeds.      *      * @return void      */     public function random($bot, $breed, $subBreed)     {         $bot->reply($this->photos->bySubBreed($breed, $subBreed));     } } 

Và ta thêm điểm cuối và phương thức cần thiết vào lớp DogService của ta :

// The endpoint we will hit to get a random image by a given breed name and its sub-breed. const SUB_BREED_ENDPOINT = 'https://dog.ceo/api/breed/%s/%s/images/random'; 
/**  * Fetch and return a random image from a given breed and its sub-breed.  *  * @param string $breed  * @param string $subBreed  * @return string  */ public function bySubBreed($breed, $subBreed) {     try {         $endpoint = sprintf(self::SUB_BREED_ENDPOINT, $breed, $subBreed);          $response = json_decode(             $this->client->get($endpoint)->getBody()         );          return $response->message;     } catch (Exception $e) {         return "Sorry I couldn\"t get you any photos from $breed. Please try with a different breed.";     } } 

Trò chuyện và cung cấp trợ giúp

Một cuộc trò chuyện là những gì bạn thường sử dụng khi xây dựng Bots của bạn và các tài liệu mô tả nó là:

Khi nói đến bot trò chuyện, có thể bạn không muốn phản ứng đơn giản với các từ khóa đơn lẻ, mà thay vào đó, bạn có thể cần thu thập thông tin từ user bằng cách sử dụng một cuộc trò chuyện. Giả sử rằng bạn muốn bot trò chuyện của bạn cung cấp trải nghiệm gia nhập user thanh lịch cho user ứng dụng của bạn.

Hãy tạo cuộc trò chuyện của ta bằng cách thêm dòng này vào file routes/botman.php của ta :

$botman->hears('Start conversation', 'App\Http\Controllers\ConversationController@index'); 

Tạo bộ điều khiển:

php artisan make:controller ConversationController 

Và xác định một phương thức index bên trong lớp đó:

<?php  namespace App\Http\Controllers;  use App\Http\Controllers\Controller; use App\Conversations\DefaultConversation;  class ConversationController extends Controller {     /**      * Create a new conversation.      *      * @return void      */     public function index($bot)     {         // We use the startConversation method provided by botman to start a new conversation and pass         // our conversation class as a param to it.          $bot->startConversation(new DefaultConversation);     } } 

Nếu bạn đang sử dụng Botman Studio, bạn nên có một folder Conversations bên trong folder App, vì vậy hãy tiếp tục và tạo một lớp mới bên trong folder đó và đặt tên là DefaultConversation.php :

<?php  namespace App\Conversations;  use BotMan\BotMan\Messages\Incoming\Answer; use BotMan\BotMan\Messages\Outgoing\Question; use BotMan\BotMan\Messages\Outgoing\Actions\Button; use BotMan\BotMan\Messages\Conversations\Conversation;  class DefaultConversation extends Conversation {     /**      * First question to start the conversation.      *      * @return void      */     public function defaultQuestion()     {         // We first create our question and set the options and their values.         $question = Question::create('Huh - you woke me up. What do you need?')             ->addButtons([                 Button::create('Random dog photo')->value('random'),                 Button::create('A photo by breed')->value('breed'),                 Button::create('A photo by sub-breed')->value('sub-breed'),             ]);          // We ask our user the question.         return $this->ask($question, function (Answer $answer) {             // Did the user click on an option or entered a text?             if ($answer->isInteractiveMessageReply()) {                 // We compare the answer to our pre-defined ones and respond accordingly.                 switch ($answer->getValue()) {                 case 'random':                     $this->say((new App\Services\DogService)->random());                     break;                     case 'breed':                         $this->askForBreedName();                         break;                     case 'sub-breed':                         $this->askForSubBreed();                         break;                 }             }         });     }      /**      * Ask for the breed name and send the image.      *      * @return void      */     public function askForBreedName()     {         $this->ask('What\'s the breed name?', function (Answer $answer) {             $name = $answer->getText();              $this->say((new App\Services\DogService)->byBreed($name));         });     }      /**      * Ask for the breed name and send the image.      *      * @return void      */     public function askForSubBreed()     {         $this->ask('What\'s the breed and sub-breed names? ex:hound:afghan', function (Answer $answer) {             $answer = explode(':', $answer->getText());              $this->say((new App\Services\DogService)->bySubBreed($answer[0], $answer[1]));         });     }      /**      * Start the conversation      *      * @return void      */     public function run()     {         // This is the boot method, it's what will be excuted first.         $this->defaultQuestion();     } } 

Trả lời các lệnh không được công nhận:

Cuối cùng, ta cần cho user biết khi họ gửi tin nhắn mà Bot của ta không nhận ra và ta có thể làm điều đó bằng cách sử dụng phương pháp dự phòng. Mở các routes/botman.php của bạn routes/botman.php và dòng này:

$botman->fallback('App\Http\Controllers\FallbackController@index'); 

Tạo bộ điều khiển:

php artisan make:controller FallbackController 

Và ta chỉ gửi lại thông báo mà ta muốn user thấy:

<?php  namespace App\Http\Controllers;  use App\Http\Controllers\Controller;  class FallbackController extends Controller {     /**      * Respond with a generic message.      *      * @param Botman $bot      * @return void      */     public function index($bot)     {         $bot->reply('Sorry, I did not understand these commands. Try: \'Start Conversation\'');     } } 

Thử nghiệm Bot

  • Gửi ảnh chó ngẫu nhiên từ tất cả các giống:

Gửi ảnh chó ngẫu nhiên từ tất cả các giống

  • Gửi ảnh con chó ngẫu nhiên theo giống của nó:

Gửi một bức ảnh chó ngẫu nhiên theo giống của nó

  • Gửi ảnh con chó ngẫu nhiên theo giống và giống phụ của nó:

Gửi ảnh con chó ngẫu nhiên theo giống và giống phụ của nó

  • Trò chuyện và cung cấp trợ giúp:

Trò chuyện và giúp đỡ

  • Trả lời các lệnh không được công nhận:

Trả lời các lệnh không được công nhận

Cài đặt trình điều khiển Telegram

Sau khi tạo và thử nghiệm thành công các lệnh của ta , giờ là lúc tích hợp nó với Telegram. Để làm điều đó, ta cần phải kéo trình điều khiển Telegram do Botman cung cấp:

composer require botman/driver-telegram 

Tạo một Bot Telegram

Ta đã tạo thành công Bot của bạn , xác định các lệnh và thử nghiệm nó, bây giờ đã đến lúc tạo một Telegram Bot. Mở ứng dụng và tìm kiếm BotFather , nhập / newbot , nhập tên user cho bot của bạn và bạn đã sẵn sàng.

Tạo một Bot Telegram

Thêm mã này vào file .env của bạn và thay thế YOUR_TOKEN bằng mã thông báo mà Telegram đã cung cấp cho bạn:

TELEGRAM_TOKEN=YOUR_TOKEN 

Cài đặt và chạy ngrok

Bởi vì Telegram yêu cầu một URL hợp lệ và an toàn để cài đặt webhook và nhận tin nhắn từ user của bạn, ta sẽ sử dụng ngrok hoặc bạn có thể triển khai ứng dụng của bạn trên server và cài đặt certificate SSL, nhưng đối với bản demo, ta sẽ sử dụng ngrok. Cung cấp cho Trang download của họ và nhấp vào nút download phù hợp với hệ điều hành của bạn.

Bây giờ cd vào folder ứng dụng của bạn và chạy php artisan serve

nghệ nhân php phục vụ

Đã đến lúc chạy ngrok, cd vào folder có ngrok và chạy ./ngrok http 8000

ngrok http 8000

Bước cuối cùng là liên kết ứng dụng của ta với Telegram Bot mà ta đã tạo trước đó và để thực hiện điều đó, ta sẽ thực hiện yêu cầu ĐĂNG tới URL này và chuyển URL ngrok đã tạo cho ta :

 https://api.telegram.org/bot{TOKEN}/setWebhook 

Bạn có thể thực hiện việc này với Postman hoặc CURL bằng cách chạy lệnh sau:

curl -X POST -F 'url=https://{YOU_URL}/botman' https://api.telegram.org/bot{TOKEN}/setWebhook 

Nếu bạn đã làm đúng, bạn sẽ nhận được phản hồi JSON chính xác này:

{     "ok": true,     "result": true,     "description": "Webhook was set" } 

Thử nghiệm nó trên Telegram

  • Gửi ảnh chó ngẫu nhiên từ tất cả các giống:
    Gửi ảnh chó ngẫu nhiên từ tất cả các giống

  • Gửi ảnh con chó ngẫu nhiên theo giống của nó:
    Gửi một bức ảnh chó ngẫu nhiên theo giống của nó

  • Gửi ảnh con chó ngẫu nhiên theo giống và giống phụ của nó:
    Gửi ảnh con chó ngẫu nhiên theo giống và giống phụ của nó

  • Trò chuyện và cung cấp trợ giúp:
    Trò chuyện và giúp đỡ

  • Trả lời các lệnh không được công nhận:
    Trả lời các lệnh không được công nhận

Kết luận

Tôi hy vọng bạn thấy hướng dẫn này hữu ích, nếu bạn đang làm theo và bạn đã tạo Bot của riêng mình.


Tags:

Các tin liên quan