DroidKaigi2018 Dialogflow for Android

#DroidKaigi2018 Dialogflow for Android
**Dialogflow for Android** は DroidKaigi 2018 2日目 Room5 で行われたセッションです。Dialogflowの基本的な使い方と、Androidアプリにチャットボットを導入する方法をご紹介しました。そのセッションのまとめを書きたいと思います。セッション内容を全て書くと記事が肥大化するため要点を絞ってご紹介したいと思います。全スライドを見たい方は下記のリンクをご参照ください。

##対象者
- Dialogflow初心者
- Androidアプリにサクッとチャットボットを導入したい方

##リンク
- [イベント内容はこちら](https://droidkaigi.jp/2018/timetable?session=15883)
- [スライドはこちら](https://www.slideshare.net/tsudakyohei/droidkaigi-2018-dialogflow-for-android)

##自己紹介

- 普段はサーバーサイドのエンジニアをしている
- 元々Androidアプリのエンジニア＋趣味でAndroidアプリを作成している
- Dialogflowは1年くらい触っていてQiitaに記事などを書いてる

##Dialogflowとは？

- 自然言語処理を提供しているサービス
- チャットボットを簡単に作成することが出来るサービス
    - 「OK Google...」なアプリが実装可能
    - Facebook, LINEなどにすぐ連携可能

##Dialogflowのすごいところ
- コードを書かずに自然言語処理の実装ができる
- 対応言語が豊富！
    - 英語や日本語を始め、中国語、ロシア語、イタリア語など対応
- チャットボットサービスに簡単に連携することができる
    - Facebook, LINE, Slack...
- SDKが豊富
    - Android, iOS, Python, NodeJS...
- アナリティクス機能
    - Dialogflowを通じた会話は全てログに残る

##Dialogflowで出来ること
- 発言からユーザーが何をしたいのかを分析
    - ユーザーは挨拶をしたいのか
    - ユーザーは航空券を検索したいのか
    - ユーザーは音楽を聞きたいのか
- ユーザーの発言にどんなパラメータが入っているか分析
    - メールアドレス、身長、体重、日時、通貨...
- BOTに必須パラメータがあれば発言するまで聞き返す
    - BMIを計算するBOTの場合、身長と体重を言うまで聞き返す
- 答えが決まっている会話
    - 「こんにちは」ときたら「こんにちは」と返す

##Dialogflowで出来ないこと
- 計算などの動的な処理（サーバーで実装する）
    - BMIの計算
    - 航空券の検索や予約処理

##Dialogflowの使い方
- [Googleアカウントでログイン](https://console.dialogflow.com)
- Dialogflowのアカウントとプロジェクトを作成
- 基本機能3つを抑える
- キャンセル待ちを登録するBotを作成してみる

##Agentの作成
AgentはDialogflowのプロジェクトです。

- 名前
- 言語・ロケール
    - 後から言語の追加可能

※注意: DialogflowはGCPプロジェクトを利用します。GCPのプロジェクトを新規作成したくない人は、Agentの作成画面で「GCPプロジェクトをImportする」を選択してください。

##Dialogflow基本機能３つ
###Intent

- 会話の設計をする場所
- 会話を開始するトリガーを決める
    - 「こんにちは！」、「BMIを知りたい」など
- 会話を成立させるための条件を決める
    - 身長と体重の入力を必須にする
- レスポンスを決める
    - 答えが既に決まっている場合
        - Intentのレスポンスに内容を入力
    - 答えが決まっていない場合
        - BMIの計算、航空券の検索など
        - バックエンドを設定してあげる

####Intentは1つの目的につき、1つのIntentを作成する
- 挨拶Intent
- BMI計算Intent
- レシピIntent

<img width="400" alt="Screen Shot 0030-02-09 at 8.49.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/2183d3a3-5443-0dc4-baa7-ff085fda7ebb.png">

####発言に応じて適切なIntentに案内してくれる

<img width="400" alt="Screen Shot 0030-02-09 at 8.49.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/8c00063f-0a6b-338e-6e79-ae9da69ca3d1.png">

####おはようIntentを作成してみる
- User Saysに会話のトリガーをいれる
    - おはようございます
- Responseに会話の返答をいれる
    - おはよう！

<img width="400" alt="Screen Shot 0030-02-09 at 8.52.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/32ac9407-7f69-7f63-3aea-33e589b72c2a.png">

作成が完了したら右側のシミュレーターでテストします。「おはようございます」と発言すると「おはよう！」が返ってくることが分かります。

####Dialogflowは学習する
いくつかの「おはようパターン」を入れておけば、その中に無いパターンでも良い感じに解釈してくれるようになる。下記画像の例では「おはよ」というのはUser Says に登録されていないが、ちゃんと解釈してくれている。

<img width="400" alt="Screen Shot 0030-02-09 at 8.57.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/77904256-d81f-3f5e-e304-55a0a23b129f.png">

####最初から入っている2つの特殊なIntent
- Default Welcome Intent
    - Google アシスタントなどでアプリを起動した時に返答する挨拶文
        - 今回は使用しない
- Default Fallback Intent
    - ユーザーの発言がどのIntentにも当てはまらない時に呼ばれる
    - 「すみません、分かりませんでした」のような文言を返す
        - 「サーバーエラーです」のような文言を返すのはNG
            - 会話にエラーは存在しない

###Entity
- 文章から特定の単語を取り出すための辞書
- 通貨、時間、メールアドレスなどの標準的なものは既に用意されている
- ユニークなワードも自分で作成可能

※正規表現やMeCabの品詞分解が不要になる

###Fulfillment
- サーバーの情報を登録する場所
- HTTPS POST 通信
    - Google好きならfunctionsやappengineを使おう
- 登録できる情報
   - URL
   - BASIC 認証
   - HEADER
   - DOMAINS

##キャンセル待ちを登録するBotを作成してみる
題材:DroidKaigiにはキャンセル待ちを提供していました。その機能をWebフォームではなくチャットボットで実装したいと思います。実際のキャンセル待ちに必要な情報はメールアドレスのみでしたが、よりDialogflowを理解するために興味のあるトピックも必要な情報にしました。

###完成予定の会話フロー
- キャンセル待ちに登録したい
- メールアドレスを教えてください
- hogehoge@test.com 
- 興味のあるトピックを教えてください
- Kotlinとテスト
- キャンセル待ちに登録しました

###Entityの作成
興味あるトピックというのはユニークな単語のため新しく作成します。
EntityはKey-Valuesの関係で作成します。最終的に取得したい変数名をKeyにし、そのKeyを取得するための単語を知る限り入力します。

<img width="400" alt="Screen Shot 0030-02-09 at 10.24.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/fffde6ca-733e-00ee-cb31-58cadfcd9dce.png">

###Intentの作成
- User says: 「キャンセル待ちに登録したい」
- 必須Entity: メールアドレスと興味あるトピック
- Response: 「キャンセル待ちに登録しました」

<img width="400" alt="Screen Shot 0030-02-09 at 10.24.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/20d11d5a-3611-477a-9c65-a7515e6d801c.png">

###結果

<img width="209" alt="Screen Shot 0030-02-09 at 10.26.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/1a481013-fca2-148f-3ba0-c12dee959af7.png">

###取得できた情報
ちゃんとメールアドレスと興味のあるトピックが取得できました。あとはこれらの情報をサーバーに送信し、キャンセル待ちの登録処理をすれば完成です。

<img width="500" alt="Screen Shot 0030-02-09 at 10.29.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/9f439aa3-da09-2462-8c70-1f7ace089b6b.png">


##Dialogflow for Android
Dialogflow Android SDKのソースコード、サンプルコード、ドキュメンテーションはすべてこちらの[リポジトリ](https://github.com/dialogflow/dialogflow-android-client
)から確認することができます。

###AIDataService
最も実装の自由度の高いライブラリ。文字列をAIDataServiceに投げると適切なIntentの結果を返してくれる。

<img width="505" alt="Screen Shot 0030-02-09 at 10.33.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/3ebc2756-3bdc-9556-0042-a465ef017fe1.png">

###AIService
音声の録音をするライブラリ。録音が終了すると自動的に音声をDialogflowに飛ばし、適切なIntentの結果を返してくれる。Androidのマイクを扱う時と同じ要領で扱える。start stop メソッドなどがある。

<img width="503" alt="Screen Shot 0030-02-09 at 10.37.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/4a153cd6-7e4f-d10e-3de4-c93121912c1d.png">

###AIButton
最も実装が少ないライブラリ。Buttonを扱う時と同じ要領で扱え、自動的に音声をDialogflowに飛ばしてくれる。

<img width="482" alt="Screen Shot 0030-02-09 at 10.40.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/e4e8678c-7e2b-4e8a-bf03-a5a02fb5e0cb.png">

###AIDialog
AIButtonとDialog版

<img width="461" alt="Screen Shot 0030-02-09 at 10.40.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/1490e48e-5d9b-73cc-6685-db32b8ecf95c.png">

##Androidアプリにチャットボットを導入してみる
今回作成したサンプルは全て[こちらのリポジトリ](https://github.com/flatfisher/android-dialogflow-chatbot-sample)にございます。シンプルに紹介したいため難しい設計などはしてません。より良い方法などがあればPRをいただけたら嬉しいです:)

####チャットボット作成の流れ
- チャット画面の作成
    - EditText
    - Button
    - ScrollView
- AIDataServiceの準備
- Dialogflowと接続
    - AccessTokenと言語を設定

    
###チャット画面の作成
チャット画面にはこちらのライブラリを使用します。少ないコードで簡単にチャット画面を作成することができます。

- [ChatMessageView](https://github.com/bassaer/ChatMessageView
)

####ChatMessageViewの準備: アイコンや名前を設定

<img width="500" alt="Screen Shot 0030-02-09 at 10.44.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/4302ba4e-6f7b-0fb7-a4f3-e5763706dad2.png">

###AIDataServiceの準備

####Dialogflowと接続
Client access tokenと言語を登録

<img width="500" alt="Screen Shot 0030-02-09 at 10.45.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/6887946d-a605-a66a-da1f-52725c6e9670.png">

###リスナーの動き

- 送信ボタンをクリック
- EditTextの文字をAIDataServiceにセット＆リクエスト
- Dialogflowからの結果をChatMessageViewに反映

###チャット画面を更新＆Dialogflowにリクエストを投げる

<img width="500" alt="Screen Shot 0030-02-09 at 10.46.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/b04548d2-9823-3fb8-9140-8e378c45ad59.png">

###Dialogflowの結果をChatMessageViewに反映

<img width="500" alt="Screen Shot 0030-02-09 at 10.47.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/75ad1e1c-e516-1b84-15b6-247adfcaa03f.png">

###アプリのフロー

<img width="643" alt="Screen Shot 0030-02-09 at 13.20.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/114922/c82c3550-488a-d0aa-ccd9-49223d0429ee.png">

##結果
![sample.gif](https://qiita-image-store.s3.amazonaws.com/0/114922/d70dc09a-6dd1-f8fc-eddb-e5655b1c6b31.gif)

##Dialogflow Tips
Dialogflow開発のTipsを紹介したいと思います。

###料金プラン
- Dialogflow Standard Edition
    - 無料
    - APIリクエスト数に制限がある
    - APIリクエストが少ない小規模なプロジェクトやDialogflowを試したい人向け
    - コミュニティと電子メールによるサポート


- Dialogflow Enterprise Edition
    - 従量課金制
    - APIリクエスト数に制限が無い
    - 大規模なプロジェクト向け
    - コミュニティ、電子メール、Google Cloudサポートによるサポート

###教材や質問サイトは？

公式リファレンス (英語)
https://dialogflow.com/docs/getting-started/basics


Qiita (日本語)
https://qiita.com/tags/dialogflow


公式Q&Aフォーラム (英語)
https://productforums.google.com/forum/#!forum/dialogflow

Google+ Dialogflow コミュニティ (英語)
https://plus.google.com/communities/103318168784860581977


Stack Overflow (英語)
https://stackoverflow.com/questions/tagged/dialogflow 


GCPUG Slack (日本語)
- dialogflow_ja チャンネル
- assistant_ja チャンネル
- 招待フォーム
https://goo.gl/TFxUNC

GDG Ishinomaki Slack (日本語)
- dialogflow チャンネル
- 招待フォーム
https://goo.gl/PRCiHw