開発のヒホ

iOSとかAndroidとかのアプリを開発するのに四苦八苦するブログ

Google Apps ScriptでSlackに雑談対話botを導入する

Docomoの雑談対話APIとは

 なんらかの発言テキストを送ると、それっぽい答えを返してくれるDocomo製の無料APIです。
 Slackなどのチャットサービスに癒やし役として活躍してくれるはずです。

f:id:hihokaruta:20150411214133p:plain

 今回はこの雑談会話botを、Google Apps Scriptを通してSlackに導入してみます。

Google Apps Scriptとは

 Slackにbotを導入するにはHubotなどが有名ですが、そのためにサーバーを用意しないといけなかったり、インストールするソフトがいろいろ有ったりと面倒なことが多々あります。
 Google Apps Scriptは文字通りGoogle社が提供していて、サーバーサイドの環境を簡単に入手できます。なので、そこまでプログラムorサーバーの知識ないけどbotを導入してみたい人におすすめです。
 ドットインストールなどで動画を見つつやれば、環境は整うかと思います。

 以下からは、とりあえずGoogle Apps Scriptを実行する環境が整ったという前提で話を進めます。

SlackAppライブラリを導入する

 SlackはAPIを提供しており、これを叩けば良いのですが、URLの指定などが面倒なのでライブラリを使います。
 SlackAppの記事を参考にSlackAppライブラリを導入してください。これでお手軽にAPIを叩けます。

Slackトークンを取ってくる

 SlackのAPIを実行するにはSlackAPIのトークンが必要です。
 SlackAPIのトップページ内の、Web APIページの下の方にTokenと書かれているはずです(要Slackログイン)。
 時期によってトークンを取得できるページが違うようです。見つからない場合は色々探してみてください。
 botを導入したいSlackチームの横に書かれているCreate Tokenボタンを押してトークンを作っておいてください。あとで使います。

f:id:hihokaruta:20150411203649p:plain
トークンが生成される

Docomo APIを使えるようにする

 Docomoの雑談対話APIを使用するためにはユーザー登録が必要です。まずはこちらのサイトなどを参考に登録してください。
 ユーザー登録しただけではDocomoAPIは利用できません。アプリの登録というのが必要になります。「アプリ/APIの申請・管理」から新規アプリケーション作成ボタンを押して、とりあえず形だけ登録します。API機能選択では雑談対話関連のAPIにチェックを入れておきます。
 これでアプリケーション情報の下にAPI keyが表示されているはずです。このAPI keyをあとで使います。

f:id:hihokaruta:20150411210259p:plain

コードを書く

 適当にGoogle Apps Scriptのプロジェクトを作って、botを実装します。とりあえず以下のコードを貼り付ければ動くはずです。

var token = "<<<先ほど取得したSlack tokenをここに入れる>>>";
var apikey = "<<<先ほど取得したDocomo API  keyをここに入れる>>>";

var bot_name = "bot";
var bot_icon = "<<<botのアイコンのURL>>>";

function doPost(e) {
  var app = SlackApp.create(token);
  
  if( e.parameter.user_name == "slackbot" ) {
    return null;
  }
  zatsudanBot(app, e);
}

var dialogueUrl = 'https://api.apigw.smt.docomo.ne.jp/dialogue/v1/dialogue?APIKEY='+apikey;
function zatsudanBot(app, e) {
  if( e.parameter.text.indexOf("@"+bot_name)!=0 ) {
    return false;
  }
  
  var message = getMessage(e.parameter.text);
  var responseMessage = getDialogueMessage(e.parameter.user_name, message);
  var response = app.postMessage(e.parameter.channel_id, responseMessage, {
    username: bot_name,
    icon_url: bot_icon
  });
  return true;
}
 
function getMessage(mes) {
  return mes.replace("@"+bot_name, '').trim();
}
 
function getDialogueMessage(userId, mes) {
  var contextId = 'context' + userId;
  var dialogue_options = {
    'utt': mes
  }
  var props = PropertiesService.getScriptProperties();
  var context = props.getProperty(contextId);
  if (context) {
    dialogue_options.context = context
  }
 
  var options = {
    'method': 'POST',
    'contentType': 'text/json',
    'payload': JSON.stringify(dialogue_options)
  };
  var response = UrlFetchApp.fetch(dialogueUrl, options);
  var content = JSON.parse(response.getContentText());
  props.setProperty(contextId, content.context);
  return content.utt;
}

function init() {
  var e = {
    parameter: {
      text: "@"+bot_name+" こんにちは",
      user_name: "test",
      channel_id: "test"
    }
  };
  doPost(e);
}

認証する

 Google Apps Scriptを正しく実行するには、一度だけいくつかの認証を行う必要があります。
 上の方のツールバーにある下三角を押してinitを選び、実行してください(下図参照)。

f:id:hihokaruta:20150411211331p:plain

公開する

 今回はSlack側からGoogle Apps Scriptにpostが行われるので、コードをだれでも実行できるようにしておきます。
 ツールバー公開ウェブアプリケーションとして導入でダイアログが表示されるはずです。
 そのダイアログ内で新しいバージョンを保存ボタンを押したあと、アプリケーションにアクセスできるユーザー全員(匿名ユーザーを含む)にして、導入ボタンを押します。
 最後にURLが表示されます。後で使うのでコピーしておいてください。
 よくわからなかったらSlackAppの記事が参考になると思います。

SlackのWebhookを設定する

 これで最後です。Slack側の設定をします。今回は@+bot_nameで指定した名前付きで飛んできた発言に返事をするようにします。
 WebhookのIntegrationを使用します。Slack左側の逆三角からConfig Integrationを選び、最後の方にあるOutgoing WebHooks横のAddボタンを押します。
 ChannelAnyに、Trigger Word(s)@+(bot_name)に、URL(s)に先ほどのGoogle Apps Script公開URLを入力します(下図参照)。
 あとはSave Settingボタンを押せば完了です。

f:id:hihokaruta:20150411213618p:plain

試してみる

 どのチャンネルでもいいので、@+(bot_name)のあとに何か言うと反応を返してくれます。
 アイコンを好きなキャラにして、快適な人工知能ライフを!

f:id:hihokaruta:20150411214133p:plain

 うまくいかない場合は以下のことを確認すると良いかもしれません。

  • Docomo APIで雑談対話の使用申請ができているか
  • コード内のtokenapikeyを正しく入力できているか
  • GoogleAppsScript公開URLを正しく入力できているか
  • 認証したか
  • 公開したか
  • bot_name変数とWebhookのTrigger Word(s)の値は一致しているか

コード更新時の穴

 Google Apps Scriptを外部から実行する際、コードをちょっと書き換えても、公開されているものは更新されません。
 コード更新して試すたびに、スクリプト画面左上のファイル版を管理でバージョンを上げてから、公開で上がったバージョンを公開する必要があります。なかなか気づけない落とし穴なので注意してください。

参考にしたサイト

GoogleAppsScript - Slack BotをGASでいい感じで書くためのライブラリを作った - Qiita
Safx: TypetalkのWebhookとNTTドコモの雑談対話APIとGoogle Apps Scriptで雑談ボットをつくる