【Laravel】LINEのMessaging APIを使ってLINE公式アカウントからメッセージを送る
目標
LINEでテキストを送ったら、メッセージが自動で返信される処理を実装する。
主に以下のサイトを参考に実装しました。
LaravelでLINEにチャットボットをつくる(QRコード作成) – console dot log
今回はQRコードは返さずテキストのみ返します。
実装
まず初めにLaravel projectを作成します。
$ laravel new blog
ローカルにあるLaravel projectをサーバーにあげる必要があるので ngrok を使います。
$ cd blog $ php artisan serve $ ngrok http localhost:8000
こんな感じになります。
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 としています)
ルーティング設定
今回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が接続できるか確認します。
成功とでたらWebhook設定がうまく行っています。
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」と自動で送信されると思います。