Hello, World!!

むずかしいことはかけません

【Laravel】LINEのMessaging APIを使ってLINE公式アカウントからメッセージを送る

目標

LINEでテキストを送ったら、メッセージが自動で返信される処理を実装する。
f:id:eeko-amaryllis:20210114162111j:plain:w300

主に以下のサイトを参考に実装しました。
LaravelでLINEにチャットボットをつくる(QRコード作成) – console dot log
今回はQRコードは返さずテキストのみ返します。

実装

まず初めにLaravel projectを作成します。

$ laravel new blog

ローカルにあるLaravel projectをサーバーにあげる必要があるので ngrok を使います。

$ cd blog
$ php artisan serve

$ ngrok http localhost:8000

こんな感じになります。
f:id:eeko-amaryllis:20210114170910p:plain:w600

LINE Developersへのアカウントを登録

次はLINE Developersへのアカウントを登録し、以下を設定する必要があります。

  • プロバイダーを登録する
  • Messaging APIを有効にする

これらの手順は上記に記載されているサイトをみながら行ってください。

Messaging APIに必要な情報を取得する

APIのアクセスに必要な「チャネルシークレット」と「チャネルアクセストークン」を取得します。
これら2つはLaravelの.envに記載しておきましょう。

LINE_CHANNEL_SECRET=XXXXXXXXXXXXXXXXXXXXXX
LINE_ACCESS_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
webhookを有効にする

BOTが自動返信できるようにするには、webhookの設定をしないと使えないため、以下のように「Webhook送信」をオンにし、「Webhook URL」を登録します。
ここでのWebhook URLは先ほどのngrokのURLになります。(今回は参考にしたサイトよりパスは /qr-bot としています)
f:id:eeko-amaryllis:20210114173000p:plain:w600

パッケージをインストール

Messaging API対応のLINE公式SDKをインストールします。

[/blog] $ composer require linecorp/line-bot-sdk
ルーティング設定

今回LINEからアクセスされるURLをhttps://[ngrok-url]/qr-botとします。

Route::post('/qr-bot', 'QrBotController@reply');
CSRF対策を解除

app/Http/Middleware/VerifyCsrfToken.phpの$exceptに先ほどのURLを追加します。

  /**
   * The URIs that should be excluded from CSRF verification.
   *
   * @var array
   */
  protected $except = [
    'qr-bot'  // 追加
  ];
App/Providers/RouteServiceProvider.php の$namespace のコメントアウトを外す

Laravel 8.xから、app/Providers/RouteServiceProvider.phpで定義されていた$namespaceがコメントアウトされているため、上記のようにルーティングを書くなら、以下のようにコメントを外す必要があります。

/**
 * The controller namespace for the application.
 *
 * When present, controller route declarations will automatically be prefixed with this namespace.
 *
 * @var string|null
 */
protected $namespace = 'App\\Http\\Controllers'; // ここのコメントアウトを外す

参考サイト
kawax.biz

ここで登録したチャネルのMessaging API設定から設定したWebhook URLが接続できるか確認します。
f:id:eeko-amaryllis:20210114175216p:plain:w400
成功とでたらWebhook設定がうまく行っています。
f:id:eeko-amaryllis:20210114175014p:plain:w400

Controllerの設定

コントローラーを作成します。

php artisan make:controller QrBotController
<?php

namespace App\Http\Controllers;

use Endroid\QrCode\QrCode;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use LINE\LINEBot;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\MessageBuilder\ImageMessageBuilder;
use LINE\LINEBot\Event\MessageEvent;
use LINE\LINEBot\Event\MessageEvent\TextMessage;
use Illuminate\Support\Facades\Log;

class QrBotController extends Controller
{
    public function reply(Request $request) {
        $channel_secret = env('LINE_CHANNEL_SECRET');
        $access_token = env('LINE_ACCESS_TOKEN');
        $request_body = $request->getContent();
        $hash = hash_hmac('sha256', $request_body, $channel_secret, true);
        $signature = base64_encode($hash);

        if($signature === $request->header('X-Line-Signature')) {   // LINEからの送信を検証

            // アクセストークンを使いCurlHTTPClientをインスタンス化
            $client = new CurlHTTPClient($access_token);
            // CurlHTTPClientとシークレットを使いLINEBotをインスタンス化
            $bot = new LINEBot($client, ['channelSecret' => $channel_secret]);


            try {
                $events = $bot->parseEventRequest($request_body, $signature);
                foreach ($events as $event) {
                    if($event instanceof MessageEvent && $event instanceof TextMessage) {   // テキストメッセージの場合

                        $reply_token = $event->getReplyToken(); // 返信用トークン

                        $textMessageBuilder = new \LINE\LINEBot\MessageBuilder\TextMessageBuilder('hello');
                        $response = $bot->replyMessage($reply_token, $textMessageBuilder);
                        echo $response->getHTTPStatus() . ' ' . $response->getRawBody();
                    }
                }
            } catch (\Exception $e) {}
        }
    }
}

Controller内で何をしているかの解説は別の記事で書こうと思います。

以上で、作成したLINE公式アカウント(TEST)で適当なメッセージを送信すると「hello」と自動で送信されると思います。