Actions on GoogleとRailsアプリの連携

[前回](https://qiita.com/tanaka512/items/29397e57effc47a1c94d)はAmazonAlexaのアプリを作成してみたので今回はGoogle版を作成してみました。
API.AIも絡むのでAlexaよりも最初難解でした。
Google Homeが年内日本発売予定なので楽しみですね:smiley:
今回は前回同様タブレットで音声のやり取りをしてます。
残念ながらまだ日本語に対応していない？(テストアプリだから動かない？)感じだったので英語でのやり取りです。

#イメージ
![ActionsOnGoogle.jpg](https://qiita-image-store.s3.amazonaws.com/0/200860/b46bc059-d374-72f7-2955-872fd345b67d.jpeg)

#会話の流れ
今回作成したアプリの会話の流れは↓のような感じ
※実際は英語です。

私：**「テストアプリを呼び出して」**
Googleアシスタント：**「了解。あなたのテストアプリを呼び出します」**
Googleアシスタント上のテストアプリ：**「こんにちは、私は社員サイトのアシスタントです。実施中のアンケートの数、最後に投稿されたノウハウの内容どちらを知りたいですか？」**
私：**「アンケートの数で」**
Googleアシスタント上のテストアプリ：**「現在X件のアンケートが実施中です」**

#Actions on Googleプロジェクトの作成
1. [コンソール](https://console.actions.google.com/u/0/)にサインイン
2. Add Projectからプロジェクトを追加
3. Use API.AI -> CREATE ACTIONS ON API.AIとクリック

CREATE ACTIONS ON API.AIをクリックするとAPI. AIのコンソールに飛ぶ。

#アプリ作成
##API. AIにエージェントを作成する
Alexaの時と同様に単語を登録したりIntentの定義をAPI. AIのコンソール上でする。
イメージ的にはAPI. AIは自然言語処理を元にユーザーが発した言葉から意味を解釈しIntentとして返すようなインターフェースを提供しているサービスである。なのでAPI. AIはActions on Googleを作るためのだけのものではなくLineBotやSlackBotの作成でも使用する事が可能である。
自前で自然言語処理が可能な方はAPI. AIを使わないでActions on Googleを作ることも出来る。

###Welcome Intentの作成
左のバーのIntentsをクリックするとすでにDefault Welcome Intentが作成されているはずなので、さらにそれをクリック。
Default Welcome Intentは自分のアプリが呼び出された際に実行されるIntentである。Text responseに返答する内容が記載されているので、削除して好きな言葉を入力する。
今回は「Hi! I am knox portal site assistant. Which would like to know. Number of questions or latest know-how.」
を入力してみた。

###Entitiesの作成
Entitiesとは会話上に必要となるパラメータを展開するためのものである。
今回の場合最初にアンケートの数か最新のノウハウどちらを聞きたいかをユーザーに問い合わせているので、「アンケートの数」か「最新のノウハウ」をパラメータとして受ける必要がある。
これが例えばラーメン屋の店員アプリの場合には「味噌ラーメン」か「塩ラーメン」のような感じになります。
↓のように設定した。

![ss001.png](https://qiita-image-store.s3.amazonaws.com/0/200860/f486b2b8-ab8c-15a9-61af-acf4f0eeee30.png)


左側の「latest_know_how」や「question_cnt」がRailsアプリに渡ってくるパラメータ文字列になる。
右側がそのパラメータに丸め込むための単語軍である。今回は1対1になっているが例えば「味噌ラーメン」の場合には「味噌」「味噌ラーメン」と1対2のような感じになる。

###Tell latest intentの作成
次に最新情報を教えるIntentを作成する。
左のバーのIntentの＋ボタンを押して新しいIntentを作成する。
User says欄にこのIntentを起動するためのフレーズを何個か設定する。
この場合Welcome Intentで欲しい情報がアンケートの数か最新のノウハウか問い合わせているので、ユーザーはそのどちらかを返答する事が予想されるので↓のように設定した。

![ss002.png](https://qiita-image-store.s3.amazonaws.com/0/200860/97eb05b5-ed00-a06e-77b7-6dd7b91bffc7.png)


フレーズを入力する過程でEntitiesに設定した単語に反応して勝手にEntitiesと紐付けてくれる。今回は４つしか設定していないがここで設定したフレーズをベースに学習が走り、Tell latest intentを発火させるのをユーザーがどのような言葉を発した時なのかを学習してくれる。
なので、上手に学習させればこのフレーズに厳密に合致した言葉を言わなくてもTell latest intentが発火してくれるというわけである。
※Alexaでも同じような設定をしたがここらへんの精度が各社の技術力の差になってくるのでは無いかと思われる。

このIntentに対する回答には必ずパラメータが必要なのでREQUIREDにチェックを入れておく。
PARAMETER NAMEに設定した文字列がキーとなってRailsアプリに渡ってくる。

###Webhookの設定
WebhookではIntentが実行された際のレスポンスを返却するためのPOST URLを設定出来る。
左のバーからFulfillmentを選択してURLにPOST先のURLを指定する。
その後、Tell latest intentの画面に戻り下の方にあるFulfillmentからUse webhookにチェックを入れる。

##Railsアプリの実装
HTTP POSTされる先のコードを実装する。
実装例は↓

```ruby:google_actions.rb
# Webhook
def googleap
  # Entitiesの作成で設定したパラメータ
  witch_to_speek = params[:result][:parameters][:witchToSpeek]

  # Tell latest intentの作成で作成したIntentの名前
  intent_name = params[:result][:metadata][:intentName]

  resp = "Sorry something is wrong."
  if witch_to_speek == "latest_know_how"  
    resp = "The latest know-how is XXXXXX."
  elsif witch_to_speek == "question_cnt"
    resp = "I have X questions."
  end

  respond_google_action(resp)
end


def respond_google_action(speak_str)
  respond_to do |format|
    msg = {
      :speech => speak_str,
      :displayText => speak_str,
      :data => {
        :google => {
          :expectUserResponse => false,
          :isSsml => false,
        }
      },
      :source => "(-_-)",
    }
    format.json  { render :json => msg }
  end
end
```
ポイントはspeechに喋って欲しい回答内容を設定し、expectUserResponseをfalseにすること。
expectUserResponseをtrueにすると会話が続行するので、speechの最後の一文に「次に知りたいことはなんですか？」を付け加えるなどしてユーザーとの応答を続けることが出来る。

#動作確認
##Integrations
API. AIコンソールの左のバーにあるIntegrationsを選択し、Google AssistantからTESTボタンを押すとVIEWというボタンが出てくるので、さらにそれを押すとActions on Googleのシュミレーター画面に飛ぶことが出来る。
シュミレータ上で↓のように今回テストしたActionのテストが可能である。

![ss003.png](https://qiita-image-store.s3.amazonaws.com/0/200860/b3c68eed-8e77-2bf0-b776-395e6d015146.png)


##実機でのテスト
シュミレータでのテスト内容はそのままAndroid端末等でも動作します。
Actionsを作成したのと同一のGoogleアカウントでサインインしたGoogleアシスタント端末に対して、「Talk to my test app」と話しかけるとテストアプリが応答してくれます。


#参考サイト
https://developers.google.com/actions/get-started/
https://api.ai/docs/
https://api.ai/docs/fulfillment#response
https://developers.google.com/actions/reference/rest/Shared.Types/AppResponse