LINE Bot で雑談 Bot 作ってみた
LINE Bot が楽しそうだったので触って見ました。せっかくなので何かしら雑談エンジン的なものと連携させて雑談 Bot にしてみました。
環境
- macOS Sierra 10.12.3
- Python 3.6.1 (サーバ上の Python はバージョン 3.5.1 )
全体構成
今回作るモノ。登場人物が多いので図示してみました。
- ユーザはおなじみの LINE で LINE Bot とメッセージをやりとり
- LINE Bot は Bluemix 上に立てたサーバプログラムと HTTP/1.1 で通信
- Bluemix 上に立てたサーバは HTTP/1.1 で Talk API の対話サービスと通信
という感じです。
Bluemix は Python 含めて様々な言語の Webサービスを手軽に構築できるIBMのサービスです。使用メモリ量を抑えれば24時間365日起動しても無料枠に収まるので、この手の実験する時によく使ってます。
Talk API は先日プレスリリースがあった Recruit社の持つビッグデータを利用したサービス A3RT(アート)の一つ。手軽に雑談Botが組めそうだったので使ってみました。
LINE Bot もTalk API もHTTP/1.1 で通信しますが、形式が違うので直接は接続できません。
そこで、Python の中継サーバを挟んで、そこで両者の形式の差異を吸収するような形にします。
ちなみに、サーバをPython にしたのは対話と言えば機械学習、機械学習と言えば Python というノリです。(実際にはPython である必要は無かったです。PHPとかでもできるかと)
ここで作成したプログラムは githubに置いていますので良かったら参照してください。
Talk API を使ってみる
上図の右から順番に、まず雑談エンジンのTalk API を使える状態にします。
Talk API のページ下部にある「API KEY発行」をクリックします。メールアドレスを入力すると、そのアドレスにTalk API を利用するのに必要な API KEY を記載したメールが届きます。
なんとこれだけで登録は終了です。完全に無料らしいので、アカウント登録とか無いんですかね。
試しに使ってみます。Talk API は HTTP/1.1 で入力文を投げると、それに応じた応答分をレスポンスで投げ返してきます。curl で下記のようなコマンドを叩いて試してみます。
1 2 3 4 |
$ curl -X POST https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk \ -F "apikey=<メールに記載されていたAPI KEY>" \ -F "query=おはよう" |
以下のような出力になるかと思います。
1 2 |
{"status": 0, "message": "ok", "results": [{"perplexity": 0.07743213382788067, "reply": "\u304a\u306f\u3088\u3046\u3054\u3056\u3044\u307e\u3059"}]} |
JSON形式でレスポンスが返ってきました。reply が応答文っぽいですが、Unicode がエスケープされて通知されてくるようですね。デコードしてあげましょう。Python でワンライナーつけて以下のようにします。
1 2 3 4 |
$ curl -X POST https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk \ -F "apikey=<メールに記載されていたAPI KEY>" \ -F "query=おはよう" | python3 -c 'from sys import stdin; print(bytes(stdin.readline(), "utf-8").decode("unicode_escape"))' |
出力
1 2 |
{"status": 0, "message": "ok", "results": [{"perplexity": 0.07743213382788067, "reply": "おはようございます"}]} |
OKですね。Talk API は簡単に使えそうです。
Bluemix 上に Python のサーバを立てる
予めcf
コマンドが使えるようにしておいてください。(brew install cloudfoundry/tap/cf-cli
)
Bluemix にサインインしてアプリを作成します。
Cloud Foundary より、「Python」を選択します。
アプリ名(ホスト名)は「linedialogue」としました。
アプリ作成が完了すると、チュートリアル画面になります。一度チュートリアルに従って Python サーバをデプロイして手順を押さえておきましょう。
git clone でプログラムをダウンロード
1 2 |
$ git clone https://github.com/IBM-Bluemix/get-started-python |
ダウンロードしたディレクトリのルートに移動します。
今回は Python3系前提なので、下記コマンドで必要なモジュールをインストール
1 2 |
$ python3 -m pip install -r requirements.txt |
ひとまずローカルで動かしてみます。
1 2 |
$ python3 hello.py |
ブラウザから http://localhost:8080/ にアクセスして Welcome ページが開ければとりあえずOKです。
チュートリアルには http://localhost:8000/
と記載されていましたが、8080 番ポートで待ち受けているみたいなので http://localhost:8080/が正しいと思われます。
次にデプロイ用の設定です。manifest.yml を編集して、applications の name を設定します。
1 2 3 4 5 6 |
--- applications: - name: linedialogue random-route: true memory: 128M |
API のエンドポイントを設定します。リージョンが US South, United Kingdom, Sydney があり、リージョン毎にURLがありますが、アカウントに紐付いているリージョンのURLを指定してあげれば良いかと思います。私は US South なので下記コマンド
1 2 |
$ cf api https://api.ng.bluemix.net |
ログインします。
1 2 |
$ cf login |
ログイン成功したらデプロイ
1 2 |
$ cf push |
成功すると, ターミナル上で下記のように URL が表示されるので、ブラウザからアクセス。 さきほどと同じような結果が見れるはずです。
1 2 |
URL: linedialogue.mybluemix.net |
ここまでで、とりあえず Python サーバは動かせて、外部からもアクセスできる状態にまで行きました。
LINE Bot を使えるようにする
LINE Business Center の Messaging API のページから登録を行い、LINE Bot が使えるようにします。
続いてメールアドレスを登録すると、認証用のページを記載したメールが届きます。基本的にはフォームを埋めていけば良いですが、ここで登録する「会社/事業者名」はBot を友達として登録する際に表示されますので、その点だけ留意しましょう。
登録が完了すると、LINE@ Manager という管理ページに行きます。ここでアカウント設定 -> Bot設定と進み、「APIを利用する」をクリックします。(1:1トークとかが利用できなくなるなどの注意書きがありますが、私は特に気にせず進みました)
とりあえずここまでで Bot 自体が動くか確認してみましょう。
アカウント設定 -> 基本設定に QRコードが有りますので、それをLINE で読み込んで友達になります。試しにメッセージを送ると、応答できない旨の自動返信が表示されるかと思います。
LINE Bot、中継サーバ、Talk API をつなぎ合わせる
LINE Bot の会話を中継サーバに送信する
上記まで単品で動かしてきた3者を繋いでいきます。まずは LINE Bot の設定を変更します。先程の Bot 設定で「Webhook送信」を「利用する」に、「自動応答メッセージ」を「利用しない」に設定します。
続いて、同じページの上部にある「LINE Developersで設定する」をクリック。
開いたページ下部にある「EDIT」をクリックし、Webhook URL を Bluemix上の中継サーバの URL にします。
1 2 |
https://linedialogue.mybluemix.net/callback |
ここのURLは HTTPS 必須ですが、Bluemix でサーバ立てると何もしなくてもHTTPSアクセスできました。最後に callback とついていますが、これは後ほど記載しますのでとりあえず気にしないでください。
また、このページの「Channel Secret」と「Channel Access Token」は後ほど使いますので控えておいてください。
この設定で、LINE Bot の会話が HTTP/1.1 で中継サーバに送信されてくる状態になりました。
中継サーバ編集
作業的にはこれが最後です。Python中継サーバを編集してLINE Bot と Talk API を連携させます。
LINE Bot から中継サーバへの通信は HTTP/1.1 なので、そのままでも扱えなくはないですが、さらに簡単に扱えるSDK line-bot-sdk-python がありますのでそちらを使います。
line-bot-sdk-python のREADMEに従い、SDKをインストールします。Python3 なので下記コマンドとなります。
1 2 |
$ pythone3 -m pip install line-bot-sdk |
Bluemix 上でも使えるよう、requirements.txt にも下記一文をつけ加えておきます。
1 2 |
line-bot-sdk==1.1.0 |
line-bot-sdk-pythonのページにサンプルがあるので、それを変更して中継サーバを作っていきます。ここのサンプルが https://ホスト名/callback
で待ち受けていたので上記の Webhook URL もこの設定にしました。
まずは先程控えたChannel Access Token と Channel Secret を設定する箇所があるので設定します。
1 2 3 |
line_bot_api = LineBotApi('YOUR_CHANNEL_ACCESS_TOKEN') handler = WebhookHandler('YOUR_CHANNEL_SECRET') |
このサンプルでは入力されたメッセージと同じものを出力する、いわゆるオウム返しの実装になっています。実装しているのは下記の部分
1 2 3 4 5 6 |
@handler.add(MessageEvent, message=TextMessage) def handle_message(event): line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text)) |
これを書き換えて、Talk API と連携する形にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@handler.add(MessageEvent, message=TextMessage) def handle_message(event): data = { "apikey": talk_api_key, "query": event.message.text } data = urllib.parse.urlencode(data).encode("utf-8") with urllib.request.urlopen("https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk", data=data) as res: #response = res.read().decode("utf-8") reply_json = json.loads(res.read().decode("unicode_escape")) if reply_json['status'] == 0: reply = reply_json['results'][0]['reply'] line_bot_api.reply_message( event.reply_token, TextSendMessage(text=reply)) |
あとはできたサーバを cf push
でデプロイし直せば完了となります。
プログラムの全文は githubに置いています。
細かい部分はそちらを参照ください。
ちなみに、ここで request というモジュールが無いというようなエラーが出力されてサーバが起動できなかった場合、Bluemix 上のPython が 2系で動いている可能性があります。その場合は requirements.txt などあるディレクトリと同じディレクトリに runtime.txt というファイル名で以下のように Python の動作バージョンを指定してください。
1 2 |
python-3.5.1 |
所感
github 見てもらえばわかりますが、システムの枠組みを作るのに少し手間がいるだけで、サーバプログラム自体は大したことはしていません。
やはり重要なのは対話の実処理をするサービスにあると思います。今回は雑談ということで Talk API を使いましたが、Wit.ai や api.ai といった対話サービスと連携すれば、もっと本格的な(ビジネスロジックを持った)対話Botを作れると思います。最近はそれらのサービスも HTTP/1.1 経由でサービス(いわゆるWeb API) が提供されているので、今回の枠組みを応用すればいろいろできそうで夢が膨らみます。
最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。
Follow @ryuta461
この記事をシェアする
GitHub のコードを fork して Watson Retrieve And Rank に問い合わせるように改造してみました。
Qiita: http://qiita.com/6onoda/items/4151752b49ee2b6d8911
GitHub: https://github.com/6onoda/linebotRnR
ご迷惑なら削除しますので、教えてください。
引用、fork などなどありがとうございます。
Qiita の記事の方も見させていただきました。
同じような構成で接続先変えれば色々なサービスに連携できそうで、夢が拡がりますよね。
使えそうな記述やコードなどあれば、じゃんじゃん使ってください。
すみません。初心者なのでまねしながらしましたけど、最期のcf pushで「[APP/PROC/WEB/0] ERR bash: server.py: command not found」というメッセージが出て失敗しますけど、何が原因でしょうか・・
cf push コマンド自体がエラーで終了するということでしょうか?
「[APP/PROC/WEB/0] ERR bash: server.py: command not found」のエラーの出方はサーバ側のエラーメッセージを見ているように見えるのですが、前後になにかメッセージがメッセージが出ていたりしないでしょうか。今の情報だけだと何が原因なのかは良くわからないですね・・・