Assistantの実務開発中引っかかった話

![image.png](https://qiita-image-store.s3.amazonaws.com/0/108364/9feef817-ea7d-a806-83bf-47dc5d50792d.png)
[出處](https://smartio.life/smartspeaker/development/blog/vui-service2018-matome/)
最近Alexa, Cortana, Siri, Assistant などVUIサービスが多様にリリースされています。
その中で、自分なりのチャレンジで盛り上がっています。

今年は特に色んな機会を通じて良くチャレンジができました。
VUIを企画しながらびっくりするぐらい効果を高める道が見える時はすごく盛り上がります。
(まだ、作って壊してを繰り返しているが・・・ -_)
ざっくりこのような機会がありました。

- 引き取っている自社サービスのVUI導入企画・設計・デモ実装
- 1年前から本格的に活動しているゴスペルに何か役になるVUIサービスを企画
- [「Alexa Salon special @福岡 powered by Fusic」](https://fusic.co.jp/doings/226?fbclid=IwAR3AueIu6-s3MXNiIgzeZic6ol85m-2EaHVsRBefeMxTu3ig_U4ENreZkxM)
- VUI関連実務案件
- エンジニア合宿
- など

今のところで一番感じているのは、VUI設計の段階で作りたいパフォーマンスが**開発プラットフォームで本当に実現可能か**を先に調べたほうが重要だということです。以前、多分できると思って確認せずに要件定義・設計を進めましたが、結局構築の段階で頻繁な制限との衝突で設計を変えたり結構カオスになってしまったことがあります。

そして、言語によってサポートされて無い部分があったりしますので、特に先に確認しないといけません。
例えばAlexaの日本語にした場合は、*AMAZON.FallbackIntent*, *Follow-Up Mode*, *AMAZON.LITRAL*がサポートされないです。
Google Assistantの場合は、利用してするディバイスがスピーカーじゃないと色々サポートできない部分があります。
結構痛いところですね。
作りたいインタフェースの動作に関してはできるだけミニマムでモックを作ってみて実装可能を確認した上で設計することをおすすめします。

とりあえず、VUI実装してみた話を3日間の記事で喋っていきたいと思います。
日本語が下手なので読みにくいと思いますが、よろしくお願いいたします！

- [ ] 「言葉の帰還、消えたインターフェイス」 
- [x] 「注目されるAlexa、そして開発中引っかかった話」 
- [x] 「Assistantの実務開発中引っかかった話」   

#概要
さて、今日はGoogle Assistantの話です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108364/c4480cca-8a6b-9647-41b2-fa7a295467b3.png)
Google Assistantは「視覚的な側面」を維持しながらメッセージを通じ、アプリと対話をできるようにする最初の秘書です。30カ国の言語を理解可能で、日本語は2017年6月30日からサポートを始めました。基本、現地情報確認、一日計画、写真及びメディアを見る、Googleにお問い合わせなど豊富な機能があり、[サードパートアプリ](https://assistant.google.com/explore?hl=ja_jp)も多くあります。

自分もサードパートアプリを設計・開発しながら色々引っ掛かったりなど共有したい内容を話します。Actions on GoogleプラットホームのDialogflow V2エンジンで主にモバイルデバイス利用向けの開発でした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108364/4bc64c1c-77d5-ea1c-82bc-013e10d7d5da.png)
※ [参照](https://dialogflow.com/docs/integrations/actions/integration)
入門の方は[ドキュメント](https://dialogflow.com/docs)や分かりやすく説明されている[ブログ](https://qiita.com/kenz_firespeed/items/0979ceb05e4e3299f313)を参照してください。

#目次
 - 設計・開発しながら色々引っ掛かったりなど共有したい内容
  - Google AssistantはAndroidとiOS両方利用可能
  - モデル管理及びデプロイ用のcliツール
  - Fulfillmentの実装Firebaseのデプロイcliツール
  - モバイルデバイスは利用者無反応FallbackIntentをサポートしてない
  - 持続的に使用者にスピーチを投げるのはできない
  - Push Notifications機能は設定だけで簡単！だがクオリティ…
  - 短い処理制限時間、10秒
  - ゆっくり考えたり悩みながら対話できる！
  - Intentを呼び出す色んな方法
  - 対話の流れで持ち続けるセッションデータ
  - Firebaseプランの制約
  - Rich messages

## Google AssistantはAndroidとiOS両方利用可能
Google Assistantは[Android5.0以降](https://support.google.com/assistant/answer/7172657?co=GENIE.Platform%3DAndroid&hl=ja&oco=0)、[iPhoneとiPadの場合はiOS 10 以降を搭載](https://support.google.com/assistant/answer/7172657?co=GENIE.Platform%3DiOS&hl=ja&oco=0)されたら設置後利用可能です。
両方利用可能で嬉しいですね。だが、デバイスのOSによって、またはバージョンによって起動方法からプッシュ通知クオリティー、サポートインテントなどそれぞれ違うので実際に想定した通り動作するかを先に確認とって方が良いと思います。[公式ドキュメント](https://dialogflow.com/docs)に以下のようなメモがあるところは特に注意して先にご確認してください。
> Note: Reprompts aren't supported on all Actions on Google surfaces. We recommend you handle no-input errors but keep in mind that they may not appear on all user devices.

## モデル管理及びデプロイ用のcliツール
[*Jovo CLI*](https://www.jovo.tech/tutorials/deploy-dialogflow-agent)があります。
しかし、入門する方にはコンソール画面を利用することをオススメします。
最初のモデル定義の理解と色んなオプションを確認することができます。

##Fulfillmentの実装Firebaseのデプロイcliツール
良く使っている[firebase-tools](https://www.npmjs.com/package/firebase-tools)がありますね。
特にこのCLIは華やかですね。
使い方はすごく簡単で色んなブログに分かりやすく説明されているのですぐ利用できると思います。

## モバイルデバイスは利用者無反応FallbackIntentをサポートしてない
対話の流れによって、一定時間利用者の無反応に対するFallbackIntentを用意する必要があったり、意図的に利用者の次の回答を期待せずに次の処理を発生させる必要があります。(持続的に使用者にボールを投げる)
だが、残念ながらモバイルデバイスではその実装ができませんでした。[公式ドキュメント](https://developers.google.com/actions/assistant/reprompts#dynamic_reprompts)で紹介している*actions_intent_NO_INPUT*イベントを設定する方法はありますが、やっぱり[スピーカーデバイスだけサポートしている](https://stackoverflow.com/questions/52605242/reprompt-user-if-no-response-in-google-action)内容でした。

何か乗り換える戦略をトライして見ましが、結局、AOGサポートセンターに問い合わせして以下の回答をもらってからストップしました。
>…の問題に対応するためユーザーの無反応に対するFallbackIntentが必要ですが、何か方法はありませんか？
>> 結論から申し上げますと、モバイルデバイスにはご希望する機能を実装できません。…

対話の流れによって、特に要らない方もいると思いますが、自分の場合は切実したので結構痛いところでした。
[インテントリスト](https://developers.google.com/actions/reference/rest/intents)で他にもあると思いますが、先にご確認した上で設計しることが良いと思います。


## 持続的に使用者にスピーチを投げるのはできない
固有キーとかを取得して投げて見たりいくつかトライしてみましたが、やっぱり無理でした。よく考えて見るとPush Notificationsではない方式でVUIから利用者にスピーチして利用者の反応に関わらずまた次の動作をすることって、色んな危険性があるし、VUIとは距離があることになると思いました。

とりあえず、AOGサポートセンターに問い合わせして以下の回答をもらってからストップしました。
>…Push Notifications以外、Google Assistantが持続的に使用者にスピーチを投げることは実装可能な機能ですか？
>> Actions on Googleで開発するアプリは基本的にお互いに対話をやり取りすることが想定されています。 … ご希望する形での実装は難しく見えます。

## Push Notifications機能は設定だけで簡単！だがクオリティ…
Google Assistantは特に申請をせずに、比較的に簡単な設定だけで実装可能です。
最初、個人のハンズオンでやってみた「Github VUI」はざっくり以下の通りでした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108364/40894fb9-ef8a-627b-5220-0f2c3ebf9636.png)
動作はGitHub REST APIの[@octokit/rest](https://github.com/octokit/rest.js)で自分のプロジェクトリポジトリーのIssuesを確認します。その中で対応したいIssuesに対するブランチを生成、プルリクを作る単純な動作です。それは右側の通り、プッシュ通知が必要なGithubイベントを受け取るWebhookのエンドポイント用のトリガーを準備します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108364/83783535-bea1-c0cb-639b-1f6ec148dc73.png)
次は、そのトリガーの処理でFirebaseのDBにレコードが追加されると、そのイベントに反応するトリガーをまた準備し、プッシュ通知の処理をして通知を投げます。

やっぱり、この説明だけでは逆に混乱されると思いますので、この内容を忘れて、[公式ドキュメント](https://developers.google.com/actions/assistant/updates/notifications)と[Actions on Google tips sample](https://github.com/actions-on-google/dialogflow-updates-nodejs)を参考してください。自分は[この記事](https://qiita.com/rinpa/items/05e7cdbb1690164e741c)がとても助かりました。

だが、上端で話しました通り、デバイスのOSまたはバージョンによって、Push通知の動作がそれぞれでした。一番つらかったのは、Adroidの方はPush通知が来ても音が出てこないし、画面も開かれませんでした。ホームボタンを押して開いて見てからやっと通知が来たことを認知することができました。iOSの方も音が出てくるときもあるし出てこないときもあるし…少なくともアラーム設定などの問題ではありませんでしたが、きっと、何か抜けた何かがあるでしょうと思ってます。
※ 自分が開発で利用したディバイスはAdroid 6.0とiOS 12.0.1
※ Google Homeの方はデバイスのIPと専用SDKを利用して[他の方式でPush Notificationsが実装できるそう](https://chasuke.com/ghnotifier/)で、その動作もとてもきれいでした。
※ voice-activatedホームスピーカーの場合はPush Notificationsをサポートしてません。

###### *すみませんが、次からはササッと行きます！🔥🔥🔥*

## 短い処理制限時間、10秒
処理制限時間は10秒です。短すぎてFulfillmentの実装で利用したFirebaseのTime Out設定問題かと思ってましたが違いました。重い外部データを取得して来たり色んなパフォーマンスを再現する必要がありまして、AOGサポートセンターに問い合わせしましたが、やっぱり無理そうでした。
> 確認したところ、処理時間が10秒過ぎるとタイプアウトになってしまいますが、時間を増やす方法はありませんか？
>> お話した通り最大10秒間ですが、設定はできません。

## ゆっくり考えたり悩みながら対話できる！
ご存知だと思ってますが、Google Assistantは利用者の反応がなくても活性化されたマイクが中止されること以外は対話に特に問題ありません。他のようにそそくさとなり、話しなくても良くて、対話の流れで生まれた悩みなどで時間を持つことができます。やっぱり **「視覚的な側面」を維持しながらメッセージを通じ、アプリと対話をできるようにするサービス**  ですね！

## Intentを呼び出す色んな方法
Intentを呼び出す方法は以下の方法があります。

 - 使用者の発話によるIntent呼出し
 - 色んな状況で呼び出されるFallback Intent
 - 設定したEventによってい呼び出されるIntent
 - 処理中followupEventメソッドでIntent呼び出し

方法は色々ありますが、利用目的に合わせて定義しておくとすごく便利です。

## 対話の流れで持ち続けるセッションデータ
対話の流れで持ち続けるセッションデータは基本Contextで管理できます。
自分は、けっこう気にして管理しながら進めないと行けなかったので、ちょっと面倒くさいでした。
 *Lifespan* は利用ケースによってとても便利でした。

## Firebase利用プランによっての制約
[You'll need to be on a paid plan to make external API requests.](https://stackoverflow.com/questions/42774807/cloud-functions-for-firebase-getaddrinfo-enotfound)
etc...

## Rich messages
https://dialogflow.com/docs/intents/rich-messages
👍

もし、何か実装に困ってご覧したかたは役にならなくてすみません！
色々困って解決方法を探している中でしたら、とりあえず、AOGのサポートセンターに投げることをおすすめします。
とても早く、問い合わせした問題に対する回答をしっかり受けれます！