Watson APIを使ったSlack BotをBluemix上のNode.jsランタイムで動かす

最近、開発現場でSlackを使うことが一般的になってきました。見た目はチャットツールなのですが、様々なサービスと連携し操作も可能であること、複数の開発者が対話しながら仕事を進めることができること、その場に居なかったメンバーも後から議論を追うことができること等、うまく開発者の心を掴んでいます。

Slackの特徴の一つは、人間の利用者と同じようにメッセージに反応したり、積極的にメッセージを送るbotを簡単に作成できることです。一方、IBM Watson APIは、知識を用いて、人間やビジネスの課題を解決するためのものであり、API化されていることで簡単に他のプログラムに組み込むことが可能です。この2つを使うと、あたかも人間のように開発者を助けることができるのではないかと思っていました。

Waston APIを使ったSlack Botのアイデアは、もちろん私が最初ではなくて、例えば、CTCの原田さんとそのチームは、2015年12月に開催された第1回IBM Watson日本語版ハッカソンにおいて、Watson APIを使って社内コミュニケーションの課題を解決するBotを開発し、見事最優秀賞に輝いています。技術的な説明はこちらにあり、参考になります。原田さんのシステムはNode-REDを使って実現されているようなので、ここではNode-REDを使わずに、Bluemix上のNode.jsランタイムでbotを走らせて、そこからWatson APIを呼ぶことにしました。これがまた思いの外、簡単に実現できるのです。

Slack Botの作成

Slackのアカンウトがすでにあり、ドメインと呼ばれるプロジェクトスペースに加入していることを前提とします。ここまでの作業は、別の情報源を参照してください。

Bot作成ページにアクセスすると、まず加入しているドメイン名を入力する画面、次にユーザ名とパスワードを聞かれる画面に飛びます。これに答えると、botを作成するための画面が表示されます。

スクリーンショット 2016-03-27 20.36.55

Usernameとして、Botの名前を入力します。ここでは、cognitive-bot-hanakoとしましょう。入力して、Add bot integration ボタンを押すと、botが作成されます。

スクリーンショット 2016-03-27 22.25.21

ここで大事なのは、API Tokenです。これを覚えておきましょう。上の図では切れていますが、botのアイイコンの選択や、氏名を入力するする項目があります(これらの設定はオプションです)。Save integrationボタンを押せば終了です。

botの登録
作成したbotをSlackのチャネルに登録します。Slackに自分のIDでログインし、登録したいチャネルを選んだ後、メーセージを入力する代わりに、”/invite @cognitive-bot-hanako”と入力します。下は、登録後の画面です。Botがあたかも人間のユーザーのように登録されます。

スクリーンショット 2016-03-27 22.22.00

ここでは、”integration”チャネルにcognitive-bot-hanakoを登録しています。登録が完了すれば、my-bot-hanakoは、それ以降のこのチャネル上での会話に聞き耳をたてています。利用者は、このbotに直接メッセージを送ることもでできますし、利用者のメッセージに特定の文字列パターンが出現した時に、botがそれに反応することもできます。

さて、Slack側の設定が終わったところで、botに命を吹き込む作業、bot自体をプログラムし実行する作業に移りましょう。

Botの作成

botの作成にあたっては、まずローカルの環境でプログラム構築とテストを行い、その後でBluemixにデプロイすることにします。まずはローカルの環境を構築します。Slackは、botkitと呼ばれるNode.js環境で使えるSDKを公開しており、これを用いることで簡単にbotを作成できるようになっています。botkitと共に、後で使うライブラリをまとめてインストールするため、以下の内容を、package.jsonというファイル名で作成します。

{
  "name": "cognitive-bot-hanako",
  "version": "0.0.1",
  "scripts": {
    "start": "node ./bot.js"
  },
  "dependencies": {
    "botkit": "*",
    "request": "*",
    "mstranslator": "*"
  }
}

このファイルは、以下のことを意味しています。

  • 実行するnode.jsのファイルは、bot.jsである。
  • このプログラムは、botkitとrequest (Watson APIを呼び出すところで使います。

これを置いたディレクトリー上で、以下を実行します。

$ npm install

次に、bot.jsを作成しましょう。Botとしての必要最小限のコード例を以下に示します。

var Botkit = require('botkit');
var controller = Botkit.slackbot();

var bot = controller.spawn({
token: process.env.slack_token
})
bot.startRTM(function(err,bot,payload) {
  if (err) {
    throw new Error('Could not connect to Slack');
}
});

controller.hears(["^Hello","^hi$"],""direct_message","direct_mention","mention","ambient"],function(bot,message) {
  bot.reply(message,'Hello!');
});

});

5行目のprocess.env.slack_tokenには、前述のSlack API Tokenが入ります。プログラム中に埋め込むのではなく、環境変数として外から与えるようにします。botの対話処理を受け持つ部分が13行目あたりです。ここでは、Slack上で誰かが”Hello”や”hi”と発言したら、”Hello!”と返すようにしています。発言に対して、正規表現を使って引っ掛けることができます。Slack APIの詳細については、ここを参照してください。

bot.jsが完成したら、以下のように実行します。Node.jsはすでにインストールされているとします。

$ slack_token=xoxb-29777007188-wC1QQKl9IbN.... node ./bot.js

slack_tohen=”…”のところには、登録したbotのtokenが入ります。ここで指定した値は、
環境変数process.env.slack_tokenにセットされbot.jsに渡されます。
bot.jsを実行した後で、botを登録したチャネルで、”Hello”と言ってみてください。
あなたのbotが応えてくれるはずです。

スクリーンショット 2016-03-27 22.16.37

Watson APIとの連携
それでは、Watson APIと連携させてみましょう。ここではBluemix上で定義されているWatson APIのうち、翻訳を行うLanguage Translationサービスを使ってみます。Watson APIを連携するには、インスタンスを作成し、クレデンシャル情報を入手する必要があるので、先にBluemix上でNode.jsランタイムとそれにバインドするサービスを先に作っておきましょう。

Bluemixにログインし”cognitive-bot-hanako”という名前でnode.jsランタイムインスタンスを作成します。ランタイムの名前は、適切に読み替えてください (Bluemixはグローバル空間において一意でないといけません)。さらに、Watson Language Translationサービスをバインドします。

スクリーンショット 2016-03-27 22.45.23

バインド後、Watson APIにアクセスする際の環境変数をチェックします。
スクリーンショット 2016-03-27 22.51.30

重要なのは、usernameとpasswordです。もう一つ重要なのが、Bluemix上でbot (Node.jsランタイム)を動かす時には、Slack API Tokenを教えておく必要があります。そのために、”ユーザ定義”タブから、slack_token環境変数とその値を追加しておきます。

スクリーンショット 2016-03-27 22.57.29

ここまで終わったところで、bot.jsにWatson APIを組み込む作業に戻りましょう。Watson APIを組み込んだbot.jsはこんな感じです。

var Botkit = require('botkit');
var request = require('request');
var controller = Botkit.slackbot();
var bot = controller.spawn({
  token: process.env.slack_token
})

var WatsonLTCredentials = {
  name: "Watson_LT";
};

if (process.env.VCAP_SERVICES) {
  var vcapServices = JSON.parse(process.env.VCAP_SERVICES);
  if (vcapServices.language_translation[0].credentials) {
    // WatsonLTCredentials.url      = vcapServices.language_translation[0].credentials.url;
    // 何故かWatson APIのendpoint URLが違っているので陽にセット
    WatsonLTCredentials.url = "https://gateway.watsonplatform.net/language-translation/api/v2/translate";
    WatsonLTCredentials.username = vcapServices.language_translation[0].credentials.username;
    WatsonLTCredentials.password = vcapServices.language_translation[0].credentials.password;
  }
}

bot.startRTM(function(err,bot,payload) {
  if (err) {
    throw new Error('Could not connect to Slack');
  }
});
controller.hears(["^Hello","^hi$"],["direct_message","direct_mention","mention","ambient"],function(bot,message) {
bot.reply(message,'Hello!');
});

controller.hears(["^translate*","^Translate*"],["direct_message","direct_mention","mention","ambient"],function(bot,message) {
  var matches  = message.text.match(/^[tT]ranslate (.*)/i);
  var sentence = matches[1];
  var options = {
    url: WatsonLTCredentials.url,
    method:"POST",
    auth: {
      user: WatsonLTCredentials.username,
      password: WatsonLTCredentials.password
    },
    form: {
      "source":"en",
      "target":"fr",
      "text":sentence
    }
  }
  request(options, function (error, response, body) {
    var translated = "In French "+body;
    bot.reply(message, translated);
  });
});

12行目あたりで、Watson APIのクレデンシャル情報を環境変数経由で読みこんでいます。32行目から、英語で書かれたメッセージをフランス語に翻訳するためのコードが続きます。やっていることは

  • メッセージは、”translate <翻訳したい英文>”の形式であると仮定し、英文のところだけを取り出す。
  • Watson APIをPOSTで呼び出すための準備。認証情報として、Watson APIのusernameとpasswordをセット。翻訳は、英語->フランス語とする (日本語に訳したかったのですが、Watson Language Translation APIでは日本語がサポートされていない..)
  • リクエストを送り、結果をbot側に送り返す

最後に、プログラムファイルを、Bluemixにpushします。この際に、以下に示すmanifest.ymlファイルが必要です。

applications:
- name: cognitive-bot-hanako
command: node ./bot.js
path: .
domain: mybluemix.net
host: cognitive-bot-hanako
memory: 512M
instances: 1

bot.js, package.json, manifest.ymlが揃っていることを確認して、ファイル群をBluemixにpushします。–no-routeを付け忘れないように。

$ ch push --no-route

うまくpushできたら。チャネル上で、”translate I love you” などと言ってみましょう。あなたのbotがフランス語でささやいてくれます。
スクリーンショット 2016-03-27 23.38.26.jpg

 

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中