Repl-AIを使ってコードを1行も書かずに対話式チャットボットを作る

#はじめに
FacebookやLINEが自社のメッセージングサービスのプラットフォームを一部開発者に公開したりと、チャットボットがブームの兆しを見せ始めていますが、先日、NTTドコモとIPI社が共同開発した[「Repl-AI」](https://repl-ai.jp/login)という対話式チャットボットのプラットフォームが公開されました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">[ニュース] IPIとドコモ、自然に会話するボットを簡単に作成できる「Repl-AI」 <a href="https://t.co/a2n340V4zH">https://t.co/a2n340V4zH</a> <a href="https://t.co/3rQsGqEHZc">pic.twitter.com/3rQsGqEHZc</a></p>&mdash; ケータイ Watch (@ktai_watch) <a href="https://twitter.com/ktai_watch/status/723374587694616576">2016年4月22日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

上記の記事にもある通り、Repl-AIはプログラミング無しで対話式のチャットボットを作成するためのツールです。『「XX」と話しかけたら「YY」と返す』といったルールベースでの対話フローを、ブラウザ上の操作だけで作ることができます。

現時点でRepl-AIで作成した対話フローにアクセスするにはREST APIを経由するしかないので、実際にチャットボットを作るとなると、何らかのメッセージングサービス（slackやLINEなど）への繋ぎ込み部分を作る必要があります。折角ブラウザだけでボットが作れるのを売りにしているのに、繋ぎ込みでコードを書かなくてはいけないのが勿体ないなと個人的に思ったので、Heroku buttonを使って**コードを1行も書かずに対話式チャットボットを作る仕組みを作ってみました。**

# ノープログラミングで対話式チャットボットを作る手順
## 準備
### 1. docomo developer supportアカウント取得
Repl-AIを使うにはdocomo developer supportのアカウントが必要になります。未取得の場合は、以下のURLにアクセスしてアカウントを作成します。
https://dev.smt.docomo.ne.jp/?p=login

### 2. Herokuアカウント取得
今回作成したチャットボットを動かす環境としてHerokuを使うので、Herokuアカウントを持っていない場合は以下URLより作成します。
https://id.heroku.com/login

### 3. slackへのボット登録
ボットが動くサービスとしてslackを使う場合、salckにボットを登録します。slackを使わない場合、この項目は対応不要です。

slackボットの登録方法は既にたくさん記事があるので以下の記事などを参考にしてください。
[SlackのHubot Integrationが知らぬ間にアップデートされてた](http://qiita.com/KeitaMoromizato/items/0ee11d795d18a49538d8)
今回の例では「repl-bot」という名前でボットを作成します。詳細画面に表示される「API Token」の値を後で使用します。
<img width="1059" alt="slackbot.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/c8b4bebd-ddb3-13fe-e4fd-f2c1505ebc02.png">

## Repl-AI上でシナリオを作成
### 1. プロジェクト作成
準備が整ったら早速Repl-AIでシナリオを組んでいきます。https://repl-ai.jp/ にログインするとまず以下のような画面が開くので「新規作成/インポート」をクリックしてプロジェクトを新規作成します。
<img width="1179" alt="Repl-AI1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/7da0eed4-1c78-1951-cdb5-1d8efc4d94f9.png">
今回は「hubotsample」という名前でプロジェクトを作成します。
<img width="713" alt="Repl-AI2.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/c0ad02d9-8278-1f74-1e58-2ea8464bac62.png">
一覧に追加されました。
<img width="1175" alt="Repl-AI3.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/a7492ff5-79bf-6e23-6d4b-6c9bf03fbbe0.png">

### 2. ボット・シナリオ作成
次にボットとシナリオを作成します。Replでは1つのプロジェクトが複数のボットを持ち、1つのボットが複数のシナリオを持つようになっているようです。
今回のボットIDとボット名はslackbotとします。（なお、このボットID・ボット名は、slackやLINE上で作成するボットID・ボット名などとは一切関係ありません。自由に付けてください。)
<img width="693" alt="newbot.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/f4b59157-493c-c6ae-a3fb-8a2ec1e1c55d.png">
ボットが作成されたら、その下にシナリオを新規作成します。
<img width="1181" alt="newscenario.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/820dfcb8-a31d-ec7b-fcaa-f21560dcf94d.png">
新規シナリオ作成画面では、挨拶シナリオとシンプルシナリオの2種類からテンプレートを選べるので、今回は挨拶を選択します。シナリオIDはaisatsu、シナリオ名は挨拶シナリオとします。
<img width="689" alt="newscenario2.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/ba1b1e81-28ff-9f7c-6a38-fea381b1bf0f.png">
シナリオ一覧に先ほど作成した挨拶シナリオが追加されました。
<img width="1186" alt="scenariolist.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/e68899f8-2709-20b4-6e52-f57e0f755f5c.png">

### 3. 対話フロー作成
作成したシナリオをクリックすると編集画面（オーサリングツール）が開きます。
まずは何も変更も加えずに左下の保存ボタンを押しましょう。
<img width="1181" alt="authoring.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/b57489e5-cde0-d118-b7a3-6321d95e9d88.png">
次に（ここわりと重要なんですが）、フローを実際に反映させるために、デプロイを行う必要があります。デプロイするためのボタンはボット一覧画面にあります。
<img width="1183" alt="deploy1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/ae751282-eaa5-f42d-b91c-97c52dc5368e.png">
デプロイボタンを押して、先ほど作ったaisatsuのチェックボックスにチェックを入れて「適用する」ボタンを押しましょう。
<img width="671" alt="deploy2.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/33c091cc-15ba-bf10-0441-bdf63e38dece.png">
以下のようなダイアログが出ればOKです。
<img width="637" alt="deploy3.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/7d7bdd5a-1e68-59b4-f012-d2b31d9601cb.png">
これでRepl-AI上の作業は最低限終了したことになります。次に、この対話フローをslackボットに反映させるためのアプリケーションを作成します。

## slack用のボットをHerokuにデプロイ
Herokuを使ってslackボットと連携するためのコードをgithubにおきました。
https://github.com/thorikawa/hubot-repl-slack
このページにアクセスして"Deploy to Heroku"のボタンをクリックします。
<img width="1055" alt="herokudeploy.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/85186399-6c2e-462a-57d3-78f9452b5e9a.png">
Herokuの画面が開くので、ログインして処理を進めます。以下のようにHeroku上のアプリケーションを作成するための画面が開くはずです。
<img width="1190" alt="heroku1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/1054bc90-912f-f69f-204f-119e64c162d7.png">
この新規作成画面でSlackやREPLと連携するための環境変数の値も入力します。Config Variableという項目で、それぞれ以下の値を入れていきます。
```
HUBOT_SLACK_TOKEN: Slack botのtokenの値
HUBOT_REPL_API_KEY: Repl-AIのプロジェクト一覧で表示されているAPIキーの値
HUBOT_REPL_BOT_ID: 使用するRepl-AIのボットID(今回の例ではslackbot)
HUBOT_REPL_TOPIC_ID: 使用するRepl-AIのシナリオID(今回の例ではaisatsu)
```
<img width="793" alt="config.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/48ade99f-b1a6-ec87-d902-3ceb5eb6e60e.png">
上記値設定後「Deploy for Free」ボタンを押して、成功すれば完了です！[^1]

## slackボットの動作確認
Deploy後、作成したボットがslack上でオンラインになっていることを確認します。
<img width="770" alt="slack.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/1ae75a77-2ae2-94b7-7bb0-207930aadff0.png">
早速話しかけてみます。
<img width="504" alt="kaiwa1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/ab77c302-3923-5888-1d0d-71aa84967743.png">
ちゃんと動いている！！しかし会話が噛み合っていない…

## Repl-AIでのシナリオを修正
会話が噛み合わないのは理由があって、挨拶のテンプレートから作成されるシナリオをもう一度よく見てみると「システム側の発話から開始」というボックスからのみ矢印がでています。
<img width="545" alt="scenario1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/87772202-2504-1b4f-ab4b-39b5f760d0e1.png">
slack上の会話は、基本的にユーザー開始（ユーザーがボットに何か話しかけて会話が始まる）のはずなので、ユーザーが何を発言しても、「はじめまして」のボックスにフローが来るようにシナリオを修正してみます。
左側メニューから「ユーザー発話」ボックスをドラッグ&ドロップし、青いボックスを追加します。これはデフォルトでは「どんなユーザー発話に対してもマッチするボックス」が作成されます。「ユーザー側の発話から開始」からこの新規作成したボックスの入力に線をつなぎ、さらに出力から「はじめまして」のボックスの入力に線をつなぎます。
<img width="626" alt="scenario2.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/1fc04672-f79a-dd8f-82f2-4e5ee5441efc.png">
これで「最初にユーザーが何を話しても、はじめましての流れでボットとの会話が始まる」というフローができました。
このシナリオを保存しデプロイします。再度試してみましょう。
<img width="621" alt="slack3.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/d478a3f3-2db3-897a-089a-35e4e5c6ffbd.png">
きちんと名前を覚えてくれる会話になりました！ [^2]

## Repl-AIでいろいろ試してみる
せっかくなので色々なパターンを試してみましょう。Repl-AI内にはチュートリアルもあるので、詳細はそちらを確認されるとよいと思います。
再びReplでaisatsuシナリオを開きますが、とりあえず今あるボックスは全部削除（削除ボタンは、各ボックスの左上にマウスをあてると出てきます）した上で、以下ようなシナリオを作ってみます。

### 特定のキーワードに特定のパターンで返す
特定のキーワードに反応して特定のパターンを返す例として、今日のラッキーアイテムなどの情報を教えてくれるボットを作ってみましょう。フロー全体は以下のようになっています。
<img width="705" alt="Repl-AI_シナリオ編集1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/3d3a2d97-da51-f32a-65f0-666a81031209.png">
ユーザー発話のボックスは以下のようになっています。「部分一致」のボックスにチェックを入れることによって、この場合は「ラッキーアイテム」を含む文全体にマッチするようになります。
<img width="930" alt="userbox.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/f0494437-e503-d91a-46f2-4cd38dc0d642.png">
システム発話のボックスは以下のようになっています。
<img width="927" alt="systembox.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/2748df79-2770-da24-8b61-58cbf42908e3.png">
実際に会話してみましょう。（保存とデプロイを忘れずに！）
<img width="619" alt="Slack4.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/56e327f0-c8d1-987e-d1db-b498c2346e08.png">
ちゃんとキーワードにマッチする回答が返ってきます！素敵！

### ランダムで返す
上記の応答にランダム要素を入れてみましょう。システム発話を開いた編集画面で「発話内容」の「+」ボタンをクリックしていくとランダムな応答を追加できます。
<img width="898" alt="Repl-AI_シナリオ編集7.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/2f1e5591-5f84-1103-1cac-fd64d90d5ef8.png">
保存＆デプロイして再び試してみます。
<img width="615" alt="Slack8.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/23d7733f-20eb-eb48-823e-4b60367b628d.png">
ランダム回答できた！かんたん！！

### その他
きりがないのでこの辺にしておきますが、値を記憶する仕組みもあるので、たとえばユーザーの名前を応答に含めることもできますし、条件分岐と記憶されたユーザー名を使って、ユーザーごとに違う応答を返す、といったこともできます。

## LINEボットへの対応

せっかくなのでslackだけではなく、先日ボットが作れるようになったLINEボットも作ってみましょう。こちらもノープログラミングで、対話式のLINEボットが作れます！

### ボット登録
「LINE BUSINESS CENTER」 https://business.line.me/ から登録申請を行うことでボットアカウントを作成できます。

登録後ボットアカウントの詳細画面で以下のような情報が見れるはずです。
この画面上の「Channel ID」「Channel Secret」「MID」の値を後で使用します。

<img width="957" alt="linebot.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/40dafe4a-704b-8476-d59c-5f1498015b4a.png">

### LINE用のボットをherokuにデプロイ
LINEボット用のコードをgithubに置きました。
https://github.com/thorikawa/hubot-repl-line
このページにアクセスして"Deploy to Heroku"のボタンをクリックします。

slackの時と同様、herokuの画面が開くので、ログインして処理を進めます。
Config Variableの項目で、以下の値を入力します。

```
HUBOT_LINE_CHANNEL_ID: LINEボット詳細画面にあるChannel IDの値
HUBOT_LINE_CHANNEL_SECRET: LINEボット詳細画面にあるChannel Secretの値
HUBOT_LINE_CHANNEL_MID: LINEボット詳細画面にあるChannel MIDの値
HUBOT_REPL_API_KEY: Repl-AIのプロジェクト一覧で表示されているAPIキーの値
HUBOT_REPL_BOT_ID: 使用するRepl-AIのボットID(今回の例ではslackbot)
HUBOT_REPL_TOPIC_ID: 使用するRepl-AIのシナリオID(今回の例ではaisatsu)
```
<img width="728" alt="heroku_line.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/899f95f6-052b-3696-3539-792d7b76cf37.png">

上記値設定後「Deploy for Free」ボタンを押して、成功が表示されることを確認します。[^1]

### herokuの情報をLINEボットに反映
herokuへのデプロイが完了したら、今度はその情報をLINEボットの方にも反映させる必要があります。

heroku上のデプロイ完了後、表示される「Manage App」のボタンをクリックします。
<img width="584" alt="mangeapp.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/4e842270-3689-2d64-0ab7-b89a31f36bd0.png">

Add-onsという項目に「Fixie」が表示されているはずなので、クリックします。
<img width="911" alt="fixie1.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/b71c4c7d-6755-310c-a997-a9f676b72e5a.png">

Fixieの画面で「Account」をクリックすると以下のように「Outbound IPs」が表示されるはずです。
<img width="1049" alt="Fixie.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/c0705b32-953a-fb4a-442d-6eba5d2b2cdb.png">

このIPアドレスをLINEボット詳細画面のServer IP Whitelistに追加します。
<img width="1120" alt="whitelist.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/2b18cd2a-3ce6-124e-2060-934385c34039.png">

さらにherokuの管理画面で、Settings->Domainsの項目で新規作成されたherokuアプリケーションのドメインが確認できるはず。このドメイン名を元に `https://ドメイン名:443/hubot/line/callback` というURLをLINEボット詳細画面のCallback URLに登録します。

<img width="812" alt="callback.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/5a7d1365-a764-ddd6-9de1-63d89be02762.png">

### LINEボットの動作確認

これで準備は完了です。QRコードを読み込んでフレンド追加し、実際に動作を確認してみましょう。

<img width="320" alt="test-line-bot.png" src="https://qiita-image-store.s3.amazonaws.com/0/42169/97e74e22-38a2-dc8f-b57e-4707db6f3d91.png">

動いてます！なんと、コードを1行も書かないでLINEボットまで作れました！！

# 仕組み
今回作成した仕組みについての解説です。ざっくり言うと、チャットエンジン部分にはhubotを使っていて、[hubot slack adapter](https://github.com/slackhq/hubot-slack)もしくは[hubot line adapter](https://github.com/umakoz/hubot-line)を使って、それぞれのサービスからメッセージを受け取って、その内容をRepl-AIのAPIに丸投げしています。

Repl-AIのAPIはRegistration（ユーザー登録)とDialogue(会話)の2種類があって、まずRegistration APIでユーザーIDを発行してから、そのIDと入力の文章をDialogue APIに投げる流れになっているんですが、今回作成したコードではhubotのmessageに含まれるuser名をキーにして、まだRepl用のユーザーIDを発行していない場合はRegistration APIにユーザーID発行を依頼しています。

興味有る方は、コードも大して長くないので全文参照されるとよいと思います。
https://github.com/thorikawa/hubot-repl/blob/master/src/repl.coffee

# おわりに
heroku buttonとRepl-AIを使って、slack用ボットとLINE用ボットをノープログラミングで作る仕組みについて解説しました。こういう技術の受け皿を広げてくれるような仕組みはとても素敵だと思います。

エンジニアの方もそうでない方も、面白いチャットボットを作ってみてください！

[^1]: まれに"could not find the source blob"というエラーが表示されてDeployできないことがあるようです。その場合は、githubページで"Deploy to heroku"ボタンを押す所からやり直すとうまくいくようです。
[^2]: ここでは手順を省略しますが、ボットが前回失敗したときの名前を覚えているため、実際に上記の会話にするにはHerokuを再起動してメモリをクリアする（正確にはRepl-AIによって払いだされたUser Idを一旦クリアする）必要があります。