SlackのWebHookとNTTドコモの雑談対話APIとApigeeで雑談ボットをつくる #apijp
Web API Advent Calendar 2014、最終日のエントリは、最近一部で流行中のチームコミュニケーションツールSlackのネタです。
Slackネタはid:i2keyさんの12/13の素敵なエントリ:
ZapierでSlackを佐野ひなこちゃんで埋め尽くす #apijp - @i2key のBlog
ですでに使われてしまいましたが、ここではSlackが提供する別のインテグレーション方法を使って雑談ボットを作ってみます。
Slackには外部プログラムとのさまざまなインテグレーション方法が用意されています。この中のOutgoing WebHooksの機能は、Slackに新しいメッセージが入力されるたびに設定した外部URLを呼び出してくれるというものです。これに、先日のAPI Meetup Tokyo #4でドコモさんが紹介していた雑談対話APIを組み合わせます。
SlackのWebHook呼び出しと雑談対話APIの呼び出し形式は異なるため、間でその調整や変換を行う何かが必要になります。通常なら何らかのスクリプトなどを書くところですが、ここではさりげない(?)宣伝を兼ねてApigee EdgeのAPI Proxyの機能を使ってこの接続を実現してみました。
おおまかな処理の流れ
- 指定された条件に合致するメッセージが入力されると、設定しておいたApigee ProxyのURLにSlackがメッセージテキストなどをPOSTする
- Apigeeがフォームデータを受け取り、メッセージテキスト(text)やユーザ名(user_name)などを取り出す
- ユーザ名が"slackbot"の場合、発言者は(自分を含む)ボットなので何もせず200で空のレスポンスを返して処理を終える。これを行わないと自分の発言に対してもWebHook呼び出しが起こるため無限ループが発生する(1回やらかしました)
- 以前の会話のコンテキストIDがキャッシュにあれば読み出す
- 必要なデータをJSON形式にしてドコモAPIにPOSTする
- ドコモAPIが返すJSONデータを受け取り、ボットの発言(utt)やコンテキストID(context)を取り出す
- コンテキストIDはSlackのchannel_idをキーとしてキャッシュに保存しておく
- ボットの発言をWebHookの返信形式のJSONにまとめ直してSlackに返す
Apigeeでの実装
これらはクラウド型のApigee無償版ですべて実現できます。
Apigeeでの実装上のポイントは以下の通り:
- SlackからPOSTされるフォームデータや、ドコモAPIから返されるJSON内データからのパラメタの取得にはExtractVariablesポリシーを使う
- ドコモAPIへのリクエストや、Slackへのレスポンスの作成にはAssignMessageポリシーを使う
- contextの保存・読み出しにはPopulateCacheポリシーとLookupCacheポリシーを使う
- ボット発言による無限ループを防ぐためにはConditional FlowとRaiseFaultポリシーを使う
(「ポリシー」というのはApigee用語であらかじめ用意された処理部品のこと)
まとめ
Slackに限らず、最近はさまざまなサービスでWebHookが提供されるようになってきています。Apigeeの持つインタフェース変換機能を使えば、自分でPOSTを受けるサーバやスクリプトを用意することなく、さまざまな別のAPIに接続することができます。(ここでは扱いませんでしたが複数APIのマッシュアップも可能)
Apigeeは本来API提供者にAPI管理レイヤを提供するもので、ここに書いたツール的な用法は本質的な使い方ではありません。しかしWebHook用の接続ツールとしては特に有用性が高いかもしれないと感じました。
ちなみに書いている途中で、非常によく似た内容のブログ記事を見つけたので、本エントリのタイトルは敬意を表してこちらにあわせてみました。:-)
Safx: TypetalkのWebhookとNTTドコモの雑談対話APIとGoogle Apps Scriptで雑談ボットをつくる
SlackではなくnulabさんのTypetalk、ApigeeではなくGoogle Apps Scriptを使われていますが、仕組み的にはほとんど同じです。一部参考にさせていただきました、感謝!