SotaでBotと連携させた賢い対話を実現してみる

# Botを使って対話をしてみよう
この記事では、対話Botを使ってSotaと対話する方法を解説します。Sotaと対話Botが連携することにより、Sota単独では実現できないより賢い対話を実現することができます。

ここで使うBotは以下の二つです。

- おうむ返し対話Bot
    - 人がSotaにしゃべった言葉をそのままおうむ返しする入門向けBotです。
- レストラン検索Bot
    - ぐるなびAPIをつかって、希望の場所や金額に応じてレストランをおすすめしてくれるBotです。 
    - このBotは記事[初心者に捧げる対話システムの作り方](http://qiita.com/Hironsan/items/0373339388f460cebb08)のハンズオン内容を使いますので、まずはそちらを読んでください。

##おうむ返しBotを使った対話
ここからは、対話Botの一番簡単な例として、**おうむ返しをする対話Bot**を使う方法を解説します。

構成を下図に示します。

Sotaは①ユーザからの発言を認識し、②認識した文字列を対話Botサーバに送ります。
次に、③Botサーバは単純に同じ内容をSotaに返します。
最後に、④SotaはBotサーバから返ってきた返答を喋ります。

![sota_bot_local.png](https://qiita-image-store.s3.amazonaws.com/0/60470/402b4847-a663-c4d4-741f-e77c87e8a7aa.png)

##環境設定・ビルド
では、プロジェクトをダウンロードして、環境設定、ビルドまでしてみましょう。

①プロジェクトのダウンロード
ターミナルにうつって、プロジェクトをダウンロードしましょう。

```bash
# 今回使うSotaのプロジェクトをブラウザ開いてforkする
# こちら　→ 　https://github.com/tech-sketch/SotaMessengerSample

# forkしたプロジェクトをclone
git clone https://github.com/自分のユーザ名/SotaMessengerSample.git

cd SotaMessengerSample

# developブランチにチェックアウト
git checkout develop
```

②プロジェクトを開く
次に、cloneしたSotaMessengerSampleフォルダの下の、client/sotaimple/SotaWebsocketTalker/SotaWebsocketTalker.VWSファイルをダブルクリックしてプロジェクトを開きます。

開くときに以下のように聞かれるので、必ず**「いいえ」を選択**します。
![sota_template_confirm.png](https://qiita-image-store.s3.amazonaws.com/0/60470/8e6c43f1-01ee-ad1d-068b-99e56b7c02fc.png)

もし他のエラーが出たら、最後の「補足」を参考にしてください。

③依存jarの追加
VstoneMagic右部のエクスプローラウィンドウの、jarフォルダにjarファイルを追加します。
「jarフォルダ右クリック」→「追加」→「参照jar」からSotaMessengerSample/libフォルダ内にある”tyrus-standalone-client-1.13.jar”を選択し、「開く」をクリックします。（下図）
![sota_add_jar.png](https://qiita-image-store.s3.amazonaws.com/0/60470/2deb698c-2548-b2b3-65a4-5a42876bd390.png)

④Sotaへの接続とビルド
最後に、「接続設定」でSotaのIPを指定してSotaに接続し、ビルドボタンを押してビルドが正常に通るか確認してください。

##ファイルの説明
VstoneMagicの右部のエクスプローラウィンドウ内の各ファイルの機能は以下のとおりです。

- mymain.java    
中身が空のプログラム。今回は無視してください。
- TalkChecker.java    
Sotaが音声認識、サーバへの認識結果送信、発話などのメイン処理を行うクラスです。このクラスのtalkCheck()メソッドがメインメソッドとして設定されています。
- WebsocketMessenger.java    
WebSocketをつかってサーバと接続・通信するためのWebsocketクライアントクラスです。

##処理の解説
処理の中身を見るために、右のエクスプローラウィンドウからTalkChecker.javaをダブルクリックし、下図のように表示されることを確認します。
![talk_cheker_overview.png](https://qiita-image-store.s3.amazonaws.com/0/60470/970b611e-a2a3-3f37-ed62-5fcda80ae845.png)

このクラスでは、ユーザとの対話に必要なSota上での処理を行っています。

具体的な処理について解説します。このクラスの中で、talkCheck()というメソッドを定義しています。そしてその中で大きく三つの処理を行います。

① WebSocketでBotサーバに接続
② 音声認識
③ 認識した文字列をWebSocketをつかってBotサーバに送信し、返答結果を喋る

②、③は無限ループ内で実行されています。それぞれに対応する処理を下図に示します。

![sota_method.png](https://qiita-image-store.s3.amazonaws.com/0/60470/a27d16b6-98fa-85db-3556-9c887bd5b05e.png)

BotサーバのIPアドレスを指定するには、下図のようにクリックし、プロパティウィンドウでargumentsの[0]に下図のように入力します。IPアドレスを調べるには、CMDではipconfigで表示されます。

![sota_prop.png](https://qiita-image-store.s3.amazonaws.com/0/60470/14bbc6a3-bc6a-d61d-4f4a-c87000e960d9.png)


##おうむ返しBotサーバの起動
Botサーバの起動には、ターミナルを使います。
SotaMessengerSampleフォルダ下で以下のようにして起動します。

```bash:おうむ返しBotサーバの起動手順
# sota_env環境を作成
conda create -n sota_env --file server/requirements.txt

# sota_env環境を有効化
source activate sota_env

cd SotaMessengerSampleフォルダへのパス/server

# おうむBotサーバ起動
python message_server.py
```

##Sota起動
ではVstoneMagicにうつって、実行ボタンを押し起動しましょう。
起動後、サーバと接続が成功すればSotaが「セッションが開いたよ」と言います。
その後、Sotaに向かって「こんにちは」などと話かけて、同じ言葉をSotaが喋れば成功です！

止めるには中断ボタンを押してください。

#レストラン検索Botを使った対話
では２番目のBotである[レストラン検索Bot](http://qiita.com/Hironsan/items/0373339388f460cebb08)をつかって、Sotaとの対話によってレストランをお勧めしてくれるようにしましょう。

おうむがえしBotからの変更点は以下のとおりです。

（Botサーバ側）

- おうむ返しBotではなくレストラン検索Botを起動する
    - レストラン検索Botの起動手順とほとんど同じです
    -  Tornadoを追加でインストールします

（Sota側）

- IPアドレスをレストラン検索Botが起動しているIPに変更する

たったこれだけです。ではBotサーバの起動から行いましょう。


```bash:Botサーバの起動手順
cd レストラン検索Bot記事でcloneしてきたHotPepperGourmetDialogueフォルダのパス

# （activateしていない場合は有効化）
source activate env

# tornadoインストール
pip install tornado

#ここで事前に必要な環境変数をセットすること
export SLACK_API_KEY=
export DOCOMO_DIALOGUE_API_KEY=
export HOTPEPPER_API_KEY=

# モジュールのインポート
export PYTHONPATH=`pwd`

cd application/

# レストラン検索botサーバ起動（起動後、何も表示されないがOK）
python server.py
```

以上です。

もしサーバ起動時にエラーが出る場合は、ページの最後の「補足」を参照してください。


次に、Sotaを起動しましょう。VstoneMagicを開いて、TalkChecker.javaをダブルクリックし、connect()のargments[0]引数に上のサーバが起動しているマシンのIPに変更して、起動してください。

起動すると、「料理のジャンルや場所をおっしゃってください。」と聞かれるので、たとえば「ラーメンが食べたい」と言えばSotaが返事をしてくれ、その後の対話が続きます。

例）「ラーメンが食べたい」といったときのSotaの反応
![ramen.png](https://qiita-image-store.s3.amazonaws.com/0/60470/a03bac0c-fb0f-286e-db6e-5767262c6b27.png)

レストラン検索Botには雑談機能もあるので、Sotaに色々話しかけて対話を楽しんでください！

#まとめ
この記事では、おうむ返しBotやレストラン検索BotとSotaを連携することにより、Sotaだけでは実現できない賢い対話を実現する方法を説明しました。Botを様々に工夫することで、Sotaとの対話をより面白くできそうですね！

#補足
##Websocketクラスの再利用
この後自分で新しくプロジェクトを作る場合もBotサーバとのWebsocket通信のために、WebsocketMessenger.javaを再利用します。

そのためには、新しいプロジェクトを新規作成後、右のエクスプローラウィンドウのjp.co.sotaパッケージを右クリック→「追加」→「クラスのインポート」で、SotaMessengerSampleフォルダ下の、client\sotaimple\SotaWebsocketTalker\src\jp\co\mysota\WebsocketMessenger.javaを選択してください。（下図）

![add_class.png](https://qiita-image-store.s3.amazonaws.com/0/60470/5835b085-c230-af2b-af7a-a7fe5b071bd1.png)
　　　　　　　　　　　　　　　　↓

![select_file.png](https://qiita-image-store.s3.amazonaws.com/0/60470/bfcfcaeb-6337-3d9b-88f1-bcd285d1fdfc.png)


#レストラン検索Botのサーバ起動時にエラーが出る場合
前のワークショップでやった、[レストラン検索Bot](http://qiita.com/Hironsan/items/0373339388f460cebb08)で正しい設定が行えていない場合があります。まずは下記のように入力して、Slack上で正しく返事が返ってくるかを確認してください。

```bash
# 下記実行後、Slack上で動作確認
python slack_bot.py
```

もしエラーが出た場合は、上記レストラン検索Bot記事の手順を見直してください。