Hubot on BluemixでWatsonボット

# **【注意】Watson QAサービスは2015年12月16日をもって提供終了となりました。**

Bluemix上に公開されているWatson Question and Answer (Watson QA)サービスのユーザインタフェースとしてHubotによるtwitterボットを実装してみました。

##前提

* [IBM idの登録とBluemixへのサインアップ](https://apps.admin.ibmcloud.com/manage/trial/bluemix.html])
* ローカル環境への[CloudFoundry CLI](https://github.com/cloudfoundry/cli)のインストール
* ローカル環境へのnode.js、npm、express、express-generatorのインストール
* ボット用Twitterアカウント(ここでは@travelqabot)取得および[Twitter APIコンソール](https://apps.twitter.com/)でのアプリケーション登録と権限設定(Read and write)

##ローカルでのhubot-twitterアプリ作成

```shell-session:ローカルhubot作成
$ sudo npm install -g yo grunt-cli bower
$ sudo npm install -g coffee-script
$ sudo npm install -g generator-hubot
$ mkdir travelqabot
$ cd travelqabot
$ yo hubot:app --owner=travelqabot@gmail.com --name=travelqabot --description=travelqabot --adapter=twitter
```

* ローカル起動用スクリプトの作成

```bash:./local_run.sh
#!/bin/sh

HUBOT_TWITTER_KEY="[Consumer Key (API Key)]の値" \
HUBOT_TWITTER_SECRET="[Consumer Secret (API Secret)]の値" \
HUBOT_TWITTER_TOKEN="[Access Token]の値" \
HUBOT_TWITTER_TOKEN_SECRET="[Access Token Secret]の値" \
PORT=3000 \
bin/hubot -a twitter -n travelqabot
```

* ローカル実行テスト

```shell-session:hubotテスト実行
$ chmod +x local_run.sh 
$ ./local_run.sh 
```

この状態で、任意のtwitterアカウントから"travelqabot ping"とツイートすると、ボットが"PONG"と返してきます。

##Bluemixへのアップロードとテスト

manifest.ymlを準備します。メモリが128MB以下ではメモリ不足になるかもしれません。

```yaml:manifest.yml
applications:
- name: travelqabot
  path: .
  memory: 256M
```

Hubot generatorが自動生成したpackage.jsonに実行スクリプトを追加します。

```json:package.json(追加部分)
  "scripts": {
    "start": "bin/hubot -a twitter -n travelqabot"
  }
```

以上の修正を行ったあと、Bluemixにアプリケーションを作成し、環境変数設定をしたうえでプッシュ起動します。

```
$ cf app travelqabot
$ cf set-env travelqabot HUBOT_TWITTER_KEY "[Consumer Key (API Key)]の値"
$ cf set-env travelqabot HUBOT_TWITTER_SECRET "[Consumer Secret (API Secret)]の値"
$ cf set-env travelqabot HUBOT_TWITTER_TOKEN "[Access Token]の値"
$ cf set-env travelqabot HUBOT_TWITTER_TOKEN_SECRET "[Access Token Secret]の値"
$ cf env travelqabot # Confirm
$ cf push travelqabot
```

ここでアプリケーション起動に成功すれば、ローカル実行と同様、"ping"に対して"PONG"が返ってきます。

以上でBlumix上でhubotを動かすことができました。

##Watsonクエリ機能の実装

Watsonクエリはいろいろなところで紹介されているとおりですが、今回はcoffeescriptで実装してみました。対象はtravelドメインです。

今回はインタフェースがtwitterであるため、全文を返すことができません。そこで、全文をredisに登録し、別途参照できるようにしています。(メンションしてきたアカウント名が長かったなどのエラー処理は省略)もちろん、redisはBluemixのサービスを使用しています。

今回のサンプルアプリケーションでは、Watso Q&Aとredis以外にサービス状態監視のMonitoringAndAnalyticsサービスも利用しています。したがって、それぞれ、manifest.ymlへの登録、サービスの作成とバインドが必要です。

|サービス名|サービス|プラン|
|----------|-------------|------|
|travelqabot-service|question_and_answer|question_and_answer_free_plan|
|travelqabot-redis|redis|100|
|travelqabot-monitor|MonitoringAndAnalytics|Free|

詳細は、ソースのscripts/にある各スクリプトをご覧ください。

* https://github.com/blackaplysia/travelqabot.git

最後にサンプルアプリケーションの実行イメージを貼り付けておきます。

  * Twitterボットとの会話例

    ![travelqabot-conversation.png](https://qiita-image-store.s3.amazonaws.com/0/21963/84c32e44-08ef-0ae8-4082-add0a67460be.png)

  * Watsonへのクエリのログ (/d/short-urlで参照)

    ![travelqabot-watson-query-log.png](https://qiita-image-store.s3.amazonaws.com/0/21963/a21f6a2c-c568-66eb-4e59-8d8118e0f89a.png) 

##まとめ

* Bluemixでhubotを動作させることは何の工夫も必要としませんでした。もともとhubotはherokuを考慮してあるため当然かとは思われますが。
* Watson Q&A(QAAPI)のログは階層が深いため、coffeescriptを使うとjsの場合よりもかなり読みやすくなりました。
* Bluemix上のredisは非常に簡単に使うことができますが、いくつか難点があります。
  * RedisはBluemixの外から接続することができないため、ローカル環境では別途redisを立てておかなければなりません。
  * 上記ともからみますが、Bluemixの外から接続できないということは、redis-cliでの操作を行うことができないため、データの削除などをする方法がありません。データを削除するためには、自前で実装するか、サービスを削除し再作成することになります。後者ではもちろん全データが削除されます。
* MonitoringAndAnalyticsサービスは以下の状態の統計をとることができます。起動スクリプトがnode/npmの場合は自動でライブラリを呼び出すとのことですが、hubotの場合は手動で呼び出す必要があるようです。(scripts/monitor_conf.coffee)
  * 可用性: アプリケーションの可用性と応答時間
  * 性能モニタリング: 最低速要求、スループットと応答時間、CPU使用率、メモリー使用量
  * ログ分析: 実行ログ(node_logsなど)の検索