この記事では、質問すると答えを教えてくれるボットをIBM Watsonで実装し、Slack、Twitterに組み込んで使ってみたという記事(チュートリアル)の前編となります。
尚、今回の記事にて採用したボットはHubotとなります。

Hubot

Hubotはadapter, robot,script の3つの機能から構成され、ボットの処理はCoffee Scriptを使い記述します。ボットが動作するチャットシステムに依存する部分は、全てAdapterが吸収するため、例えばSlackで動かしてたボットを明日からTwitterで動かします。と言われても、Adapterを変更することで対応できるため開発したscriptはそのまま活用する事ができます。この点は、とてもいいですね。

図のrobotの下にあるredisはデータを永続化して保存する場合に使用します。(今回は使わない)

では、実装、実装。
Slackへのボット追加、ボットの実装、herokuへのデプロイの順に説明し、後編でTwitterへの追加について触れます。
尚、チャット環境のSlack、twitter、ボットの実行環境として利用したheroku、Watsonの準備については説明しませんので、各自で準備をお願いします。Watsonは下記を参考にしてください。その他はネットで調べれば分かると思います。

TwitterとSlackでチャットするWatson

【Twitterボット】
下の画像はTwitterからWatsonに質問し、回答を得ているところです。

【Slack ボット】
Slackでチャットを行うHubotのscript部分は、Twitterと同じものになっています。違いはAdapterのみ。
SlackのHubotに対して言い回しの違う質問を与えていますが、さすがWatson、質問文のゆらぎを理解しTwitterと同じ回答をしてくれています。

今回Watsonに与えた知識

横手市がオープンデータとして公開している、”横手市のごみ収集QA”を使わせて頂きました。
横手市オープンデータ
http://www.city.yokote.lg.jp/joho/page000006.html
(横手市とオープンデータに感謝)

システムの構成

システムは以下の構成となり、ボットはhubotを使いました。
Slack、Twitterから入力したチャットメッセージをheroku上のHubot scriptで受け、バックエンドのWatsonへ送信し、受信した応答メッセージをチャットメッセージとしてHubotから返します。

SlackにHubotを追加

①チーム名の所をクリックしメニューを開く
②App&integrationをクリック

③次の画面にてHubotとタイプ
④リスト表示された中からHubotを選択する

⑤Add Configurationをクリック

➅ボットの名づけ
ココは全て英小文字で入れた方がいいでしょう。理由は、この後の手順で改めてボット名を指定する事になるのですが、その際に使用できる文字種とココで使用できる文字種が違うためです。ハマりますので注意が必要です。

⑦HUBOT_SLACK_TOKEN
herokuに設定する環境変数となりますので、HUBOT_SLACK_TOKENの値を控えておきます。

Slackで動かすHubotを構築

構築はローカルPC上で行い、herokuへデプロイします。

①heroku Toolbeltの導入
ToolbeltはPC側からリモートでheroku環境を操作するためのコマンドが含まれています。
使っているOSに合わせてインストールを行います。下図はMac OSでの様子。

②ターミナル(コマンドプロンプト)にて構築
まずherokuへのログインし、ボット名でフォルダを作りカレントディレクトリを変えておきます。

$ heloku login
$ mkdir ボットの名前
$ cd ボットの名前

③yoコマンドを使いHubotを構築する
Owner, Bot name, Description, Bod Adaptorについて入力を行います。最後のBod AdaptorはSlackを指定します。
この指定をTwitterとするとツイッターに接続するBotを構築する事ができます。

                     _____________________________  
                    /                             \ 
   //\              |      Extracting input for    |
  ////\    _____    |   self-replication process   |
 //////\  /_____\   \                             / 
 ======= |[^_/\_]|   /----------------------------  
  |   | _|___@@__|__                                
  +===+/  ///     \_\                               
   | |_\ /// HUBOT/\\                             
   |___/\//      /  \\                            
         \      /   +---+                            
          \____/    |   |                            
           | //|    +===+                            
            \//      |xx|                            

? Owner herokuのアカウント
? Bot name ボットの名前(今回はgarbageqabot)
? Description 何か説明 
? Bot adapter (campfire) adapterの指定(<span style="color: #ff0000;">slack</span>)

yoコマンドにより作成されたボットをローカル環境で動作させ、ここまで問題が無いか確認します。

$ bin/hubot
ボット名prompt> ボット名 ping
ボット名prompt> PONG
ボット名prompt> exit

こんな感じでpingに対して、PONGが返されれば問題ありません。

④スクリプトの記述
続いてチャットメッセージを受けた時に行う処理をcoffee scriptで記述します。ファイル名は任意の名前を指定します。尚、Hubotは起動時にscriptsフォルダ以下にあるファイルを読み込みますので、不要なスクリプトはフォルダからファイルを取り出し、Hubotの再起動を行うだけで挙動を変える事ができます。

今回は質問を受け付けWatsonに送信を行い、その応答をチャットに送り返します。
以下がそのスクリプトとなります。

$ cd scripts

スクリプトは任意のファイル名(xxxx.coffee)を付けてscriptsフォルダ以下に保管します。

# System:
# ごみに関する質問応答システム
# IBM Watson 自然言語分類器に問い合わせ、得られた応答(top class)を返す
# Module:
# garbagebot.coffee
# Version:
# 1.0.0
# Last Update:
# 2015/8/15
# Author:
# coffeeが初心者なウエサマ
# Commands:
# hubot - 質問(Watson API)
# Copyright (c) 2016 CRESCO,LTD. All Rights Reserved.
#------------------------------------------------------------------------------
module.exports = (robot) -&gt;
status = {}
robot.respond /(.*)/i, (res) -&gt;
message = res.match[1]
return if message is ''
res
.http('https://(ユーザ名):(パスワード)
@gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/(分類器のID)/classify')
.headers('Content-Type': 'application/json')
.post(JSON.stringify({ text: message})) (err, response, body) -&gt;
if err?
console.log "Encountered an error #{err}"
else
data = JSON.parse(body);
res.send data["top_class"]

ボットとのチャットに必要となるスクリプトについて、少し触れておきます。
記述例にある通りrespondでボットがメッセージを受け取り、replyで応答します。
respondにはボットに反応させたいメッセージを指定します。(正規表現による指定も可能)
ボットに行わせたい処理はreturnの前に記述します。

respondはボットを指定して送られたメッセージ、hearはタイムラインに投稿されたメッセージに反応します。
応答も発信者に対するreplyとタイムラインに応答するsendがあります。

コードサンプル

module.exports = (robot) -&gt;
  robot.hear /お腹すいたなぁ/i, (msg) -&gt;
    msg.send '気のせいですよ'
    return
  robot.respond /今日は疲れちゃったよ/i, (msg) -&gt;
    msg.reply 'それは大変、早く寝ましょう'
    return

会話だけではなく、httpdによる呼出しを受け付けるなど他にもコマンドがありますが、ここでの説明は割愛します。
では、構築ステップに戻りたいと思います。

⑤herokuにデプロイします。

$ cd ~/ボット名
$ git init
$ git add -A
$ git commit -am “make it better”
$ heroku create ボット名
$ git push heroku master

➅環境変数の設定
前の手順で控えておいたHUBOT_SLACK_TOKENを環境変数として設定します。
他にURL、slackチーム名、ボット名についても設定を行います。

$ heroku config:set HUBOT_SLACK_TOKEN=控えていた値
$ heroku config:set HEROKU_URL=’https://ボット名.herokuapp.com’
$ heroku config:set HUBOT_SLACK_TEAM=‘slackのチーム名’
$ heroku config:set HUBOT_SLACK_BOTNAME=‘ボット名’

⑦Hubotのリスタート

設定した環境変数を反映させるためHubotを再起動します。

$ heroku restart -app ボット名

手順は以上となり、slackにおいてWatsonの頭脳を持つボットに対し、自然言語による質問が行えるようになります。
後編はScriptはそのままで、AdapterをTwitterに変えて行った構築手順について記述します。