その他

Laravelでチャットボットを作ってみた

その他
この記事は約12分で読めます。

こんにちは、宮﨑です。
突然ですが、みなさんは『匿名ラジオ』というラジオ番組をご存じでしょうか。

(それっぽいイメージ画像)

オモコロのライターであるARuFaさんダ・ヴィンチ・恐山さんの2人が放送している番組です。
僕は3ヶ月ほど前からこのラジオを聴き始め……
ラジオCDを買うくらいまでどハマりしました!!!!!

(もっといい写真の撮り方があっただろうに)

通勤時の退屈な時間をオモロなトークで楽しませて頂いています。いえーーーーーい!!毎日がたのしーーーーーーー

しかし、1点だけ大変なことがあります。それは……

匿名ラジオの回数多すぎるーーーーーー!!

2021年12月13日現在、匿名ラジオは全284話あります(番外編除く)朝の忙しい時間に流す回を選ぶだけでめっちゃ悩みますし、結構時間もかかります。

そこで……

毎朝LINEを送れば適当な回数を返してくるBOTを作れば、もっと朝を早く・楽しく過ごすことができるんじゃないの〜〜〜!!


ということでチャットボットを作成していこうと思います。

※こちらはファンボットです。非公式のものであるため、匿名ラジオとは関係がありません。

ここまで茶番に付き合っていただきありがとうございます。一度やってみたかったんです。
ここからは真面目に書いていきます。

今回の目標と使用したもの

今回作成するチャットボットの目標としましては
・適当なメッセージを送信したら、ランダムにURLが返ってくる
・数字を入力すると、その回のURLが返ってくる
・「おすすめ」と入力すると公式チャンネルにあるオススメ回への再生リンクURLが返ってくる
と非常にシンプルな作りになっております。

使用するものは以下の通りです
・Laravel (8.64.0)
・LINE messaging API
・SQlite
・DBeaver
・ngrok

そもそもチャットボットって何?

チャットボット(ChatBot)とは「チャット(chat)」と「ボット(bot)」を組み合わせた言葉で、自動的に会話を行うプログラムのことを指します。有名な例としましては、LINEにて自動で返信を行う公式アカウントであったり、カスタマーサポートセンターにてユーザーからのお問合せに対応するツールとして用いられたりしています。

ということで作りました。

完成品

おすすめと入力するとおすすめ回のURLが、回数を入力すると対応した回のURLが返ってくる。
さらに適当な言葉を入力するとランダムに回が返ってくるという目標通りの使用となっております。

これらの設定方法やコードについて紹介していきます。

LINEの設定

今回のチャットボットではLINEを使用します。そのため、まず最初にLINEの設定をしていきます。こちらの資料をもとに進めさせていただきました。この通りに進めれば問題ないと思います。

私の場合、登録設定は下記のようになりました。

ちなみに業種はかなりの種類があり、どんな事業にも対応できそうだなと思いました。

【参考資料】
LaravelとLINE連携:LINE Messaging APIで自動返信やメッセージ送信する

ngrok(エングロック)の設定

チャットボットを作るにあたり、Webhookの設定が必須となります。

Webhookの設定にはHTTPS URLが必要になります。その際に私が使用したのがngrokです。

こちらの資料をもとに作成させていただきました。

流れとしましては

ユーザ登録を行い

コマンドをインストール

ngrokでWebサイトを公開

となります。そしてできたものが

こちらになります。

HTTPSのForwardingをWebhookに入力することで設定できます。ちなみにForwardingの内容は起動するたびに変わります。
これでLINEの設定が完了です。

【参考資料】
ローカルで HTTPS テスト環境を構築できるNGROKの使い方【Windows編】

コードの設定

ルーティング

admin/routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\LineApiController;
use App\Http\Controllers\LineMessengerControllers;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

// /************************ LINE *************************/

Route::post('/line/webhook',[LineMessengerControllers::class, 'webhook'])->name('line.webhook');

Route::post('/entry',[EntryController::class,'entry'])->name('entry');

こちらはルーティングの設定となります。
コメントにも記載しているように

Route::post('/line/webhook',[LineMessengerControllers::class, 'webhook'])->name('line.webhook');

この部分がメッセージ送受信に関する部分となり、こちらのパスをWebhookに設定します。

トークン等の設定

.env

LINE_MESSENGER_SECRET="各々のチャンネルシークレットを入力"
LINE_CHANNEL_TOKEN="各々のチャンネルアクセストークン(長期)を入力"

また、メッセージの送受信のためにチャンネルシークレットとトークンをenv.ファイルに追加します。

チャンネルシークレットはチャンネル基本設定ページに
チャネルアクセストークン(長期)はMessaging API設定ページに記載しています。

機能部分

admin/app/Http/Controllers/LineMessengerControllers.php

<?php

namespace App\Http\Controllers;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot;
use App\Models\User;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use Illuminate\Support\Facades\DB;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class LineMessengerControllers extends Controller
{
    public function webhook(Request $request) {
        
    $input = $request->all();
    //送られてきたメッセージを確認
    $episode = $input["events"][0]['message']['text'];
    //数字に変換(文字列の場合は0に)
    $episode_num = (int)$input["events"][0]['message']['text'];

    if ($episode_num == 0){
        //数字以外が入力されている時
        if($episode == "おすすめ"){
            $reply_message = 'https://www.youtube.com/playlist?list=PLwL8OTDdmtk1CpllAwXsRx1CO8eIk_fcI';
        }else{
        $reply_message = DB::table('tokumeis')->inRandomOrder()->limit(1)->value('URL');
        }
    }else{
        //数字が入力された時
        $reply_message   =DB::table('tokumeis')->where('episode','=',$episode_num)->value('URL');
    }

    $reply_token = $input["events"][0]['replyToken'];
    // LINEBOTSDKの設定
    $http_client = new CurlHTTPClient(config('services.line.channel_token'));
    $bot = new LINEBot($http_client, ['channelSecret' => config('services.line.messenger_secret')]);

    $reply=$bot->replyText($reply_token, $reply_message);

        return 'ok';
    }
}

こちらの部分が実際にメッセージを受けて送信する機能部分になります。

ここで

メッセージの受信

メッセージ内容を判定し返信するメッセージを決定

メッセージ返信

が行われます。

    $input = $request->all();
    //送られてきたメッセージを確認
    $episode = $input["events"][0]['message']['text'];
    //数字に変換(文字列の場合は0に)
    $episode_num = (int)$input["events"][0]['message']['text'];

メッセージの受信部分がここで行われています。episodeにTextで受信したメッセージを、episode_numで受信したメッセージをInt型に変換して格納します。

    if ($episode_num == 0){
        //数字以外が入力されている時
        if($episode == "おすすめ"){
            $reply_message = 'https://www.youtube.com/playlist?list=PLwL8OTDdmtk1CpllAwXsRx1CO8eIk_fcI';
        }else{
        $reply_message = DB::table('tokumeis')->inRandomOrder()->limit(1)->value('URL');
        }
    }else{
        //数字が入力された時
        $reply_message   =DB::table('tokumeis')->where('episode','=',$episode_num)->value('URL');
    }

メッセージ内容を判定し返信するメッセージを決定する部分がここで行われます。
episode_numが0の場合は受信メッセージが0か数字以外の場合であるため、こちらで受信メッセージが数字が文字列かを判定します。ちなみにスタンプが来た場合は何も返ってきません。
数字以外が入力されている場合は、その文字列が”おすすめ”の場合はおすすめ再生リストのURLを返信しそれ以外の場合はDBからランダムでURLが返ってくるようになっています。
数字が入力された場合は、episode_numと同じ話数の回をDBから引っ張ってくるように設定しています。

    $reply_token = $input["events"][0]['replyToken'];
    // LINEBOTSDKの設定
    $http_client = new CurlHTTPClient(config('services.line.channel_token'));
    $bot = new LINEBot($http_client, ['channelSecret' => config('services.line.messenger_secret')]);

    $reply=$bot->replyText($reply_token, $reply_message);

メッセージ返信がこの部分で行われます。
メッセージの返信にはtokenとメッセージが必要になります。
こちらは参考資料をそのまま利用させていただきました。

これでメッセージの受信と送信ができるようになります。

【参考資料】
疑似彼氏、作りました。
Laravelとの出会い
LaravelとLINE連携:LINE Messaging APIで自動返信やメッセージ送信する

DB (データベース)の設定

匿名ラジオは現段階で250話以上あるため、IF構文で繋げると非常に長いコードとなってしまいます。そのため、今回はDBを作成してそこから必要な回を呼び出す仕組みを採用し、コードを簡単に書くこととしました。

データベースに入れる情報はエクセルでcssを作り、それをDBにインストールする方式で作成していきます。

データベースに入れる情報を……手入力で作り……ました……

(ちゃんと284話まで作成しています)

単純作業の連続で一番疲れたかもしれません。もう二度とやりたくない。
YoutubeAPIを利用する方法など考えたのですが、データベース作成よりも時間がかかりそうだったため見送りました。

DBに関しては本当に初めての作成だったためかなり簡単に作成しています。
episodeで話数がURLで該当URLが対応しています。

ということでDBeaverで接続して、インポートしました。DBeaverの使い方に関してはこちらのサイトを参考にさせていただきました。

ということでインポート完了!!疲れた!! !!

無事に接続もでき、これでメッセージを送ると返ってくるようになります!!
やったぜ!!

【参考資料】
DBeaver使い方メモ

最後に

ということで以上になります。


作成した正直な感想としましては、もっと作り込みたかった!!です。
ちゃんとドメインを獲得すれば普段使いすることが可能になり、毎朝の送信も可能になります。
また、YouTubeAPIを利用することでDBへの最新話追加や最新話が追加された際に通知を送信も自動化できたのではないかとも思います。スタンプを押した時の反応で色々なパターンを作るのもやってみたいですね。

また、チャットボット自体も色々な使い方ができそうな予感がしているので、色々と可能性を模索してさらに面白いものを作っていければなと思っています。

匿名ラジオ
https://www.youtube.com/channel/UClSsb_e0HDQ-w7XuwNPgGqQ