GoogleHomeで複雑な手順を通知する方法の検討(雑記)
手順が複雑な操作が必要なものについて、音声のみのガイダンスで目的を達成しようとするとなかなか難しい。
メラビアンの法則によると、純粋な話し言葉の要素だけで相手に伝わる情報量(影響度?)は7%程度らしい。
GoogleHomeにて複雑な操作を実現する際にのアプローチはどんなものがあるか検討する。
案1 ピラミッド型会話モデルで目的を達成する
通常の会話処理をそのまま複数回にわたって、ユーザーとやり取りし、目的を達成する。いわゆるアーキネーターのような感じ。
理屈ではどんなことも実現できそうだけど、何段階目かの会話でユーザーが嫌になりそう。
VUIエンジニアが、嫌にならないような会話の組み立て方を行うことで、ストレスなく実現できる?疑問。
案2 表示可能なデバイスと連携し、複雑な手順を表示する
表示情報に頼る。モニター付きスマートスピーカーを利用するorスマートフォンなどに通知を飛ばし処理を引き継ぐ。
音声のみ比べて多く情報を表示でき、選択結果の受け取りをまた会話にすることができればかなり複雑なことに対応できる。
公式:画面表現を含んだ応答の記事
Responses | Actions on Google | Google Developers
公式:複数のデバイスをまたがる会話について
Surface Capabilities | Actions on Google | Google Developers
案3 ユーザーアカウントに紐づいたメールアドレスに複雑な手順を記載する
音声でGoogleアカウントにサインインできるため、サインイン情報を取得し、ユーザーのメールに詳細情報などを記載する。
実際には案2とやってることはほぼ同じで、シームレスさが落ちるため実装としてはあまり良くない。
あえて挙げるなら、スマートフォンを持ってない人へも対応できる点がメリットか?
でも設置のためにスマートフォンがそもそも必要なような…。
その他
案がそんなにあげられなかったので、既存アプリの調査結果を記事に反映させる。
メモ
Googleのガイドラインによると、ユースケースとしてそもそもVUIに適切かを検討する必要がありそうだ。
https://developers.google.com/actions/design/principles#_2
機械的に延々とリストの内容を読み上げたりするとか、多くの選択肢を説明してその中から一つ選んで下さいとか言われても、人間には対応できない。
そのため、VUIではシンプルな処理しか対応すべきでないか?というと、多分そうでもない。
あらゆる操作の入口として会話からスタートする、というアプローチはあっていいと思う。
Google "Assistant"というように、それ自体は実処理をせず、何かしらの高度な操作・情報へのアクセスへの橋渡しとして働かせることが本来に近いのかもしれない。
とするとVUI専用アプリを作成して何かしますよ、というのは一時的なものなのかもなあと感じる。
ChromeExtensionのメッセージ通信にchrome.storageを用いる案
ChromeExtensionの設計において、
popup-background間のメッセージ通信はchrome.runtime.sendMessageを利用する。
また、content scriptに対しては、chrome.tabs.queryを利用する。
これらの通信方式の別案として、chrome.storageを使った通信方式ができるのではないかと考えたので記事にする。
chrome.storage.onChanged.addListenerという関数があり、これはstorageのデータ変更を監視できる関数だ。
通信を送る側は、メッセージ内容をstorageに保管する。
受信側は、リスナーが反応して、storageの中身であるメッセージ内容を取り出す、というイメージだ。
storage通信を行うメリットとしては、Extensionのパーミッション設定レベルを下げることができる点だ。
chrome.tabs.queryを利用した通信では、パーミッション設定としてmanifest.json上のpermission項目にtabsを追加する必要があるが、
これを付与した場合、Extensionインストール時の警告として若干キツメの文言が出てしまう。*1
一方、storage通信ではtabsパーミッションが不要となるるため、警告内容がマイルドになり、インストール時のユーザー離脱を減らせる…かもしれない。*2
参考
ChromeExtensionのメッセージ通信についての解説
var.blog.jp
タブ通信方法など
y-anz-m.blogspot.com
ChromeStorageについての分かりやすいまとめ
qiita.com
終わりに
本来のstorageの使い方ではないので、多用するようだとあんまり良くないことも起こりそう。
例えば、データ保存にstorageを多用するExtensionだと、メッセージ通信・非メッセージ通信(本来のstorageの用途)の分岐処理の実装などが必要となる。
ただまあ、作業していてふと思いついたので記事として残しておく。
アプリ開発者向けGoogleHomeの応答速度改善ネタ(メモ書き)
GoogleCloudPlatformのCloud Functionsにてasia-northeast1リージョン(東京リージョン)が使えるようになったようだ。
fishさんが早速試していた。
早速試してみた。us-centralと比較すると平均2倍くらい速いレスポンス。初回リクエストに関しては10倍くらい違った。 #cloudfunctions pic.twitter.com/I7yv06GfQj
— fish (@canoefishing) June 27, 2018
これはFirebase Functionsもキテルのかなと思ったが、全然そんなことはなかった。
(既存はus-central1だが、新規プロジェクト立ち上げてリージョン指定してもそのままだった…)
一応現時点でも、Fullfillment指定をGCPにして応答を返すようにすれば、GoogleHomeアプリへ速度的な恩恵を受けることができると思う。
また以下の方の記事ではGCPならcold start速いよとの記載があるので、トータル速度的には結構有利になりそうだ。
matthewayne.com
応答速度で壁になってるアプリがあればこれで突破できるかもしれない。という案。
参考
公式
Cloud Functions Locations | Cloud Functions Documentation | Google Cloud
リージョン毎の対応機能リスト(あんま更新されてなさそう)
Global Locations - Regions & Zones | Google Cloud
Cloud Functions とFirebase Functions
Google Cloud Functions と Firebase | Firebase
その他
性能評価しようか悩んだが、firebaseでもそのうちリージョン対応しそう。(そのうちがいつなのかは分からないが…。)
いずれにせよ、なんか今だけ通用するネタになりそうなのでやめた😐
Chrome web storeの検索への反映が遅い件について
ChromeExtensionを作成し、一般に公開した。
しかし公開されましたと表示されたが、検索Boxにアプリ名を入れても一向にHitせず非常に焦る。
調査した所、検索用のindex作成がかなり時間かかるようで気長に待てとのことのようだ。
実際、自分のアプリも2日程度経過したら反映された。
急いで公開する場合などは、あらかじめマージンを取る必要がありそうだ。
その他
一度公開されれば、verup等を行っても検索によるアプリの表示には影響が無いようだ。
Chromeでのjavascriptの制約について(未解決)
Chromeにて、requestFullscreen(最大化の実行)をjavascript経由で実行すると怒られた。
ログには以下の警告が出ている。
Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.
あまり見慣れないエラー。
javascript固有の問題かと思ったけど、むしろChrome固有の仕様のようだ。
公式リファレンスが見当たらなかった。
調べた感じだと自動再生ポリシー関連だと思うが、確度無し。
解決しなかった
chrome://flags/#autoplay-policy
にアクセスして、No user gesture is requiredを選択するが、やはり解消されない。
自動再生ポリシーに直接関与してないようだ。
ActionsSDK v2対応: 非同期処理の書き方(雑記)
インテント受け取り後に、非同期処理をPromiseチェーンで処理を書くと、下記のエラーが出てどうにも動かない。
No response has been set. Is this being used in an async call that was not returned as a promise to the intent handler?
Promiseそんなに習熟してないので、コードが悪いのかと延々と検証していたが、
一番短いコードでも動かなかったので何だこりゃと思って調査した。
原因
Google公式によると、v2での非同期処理はインテントハンドラに返さないとダメということだ。
参考リンク:v2移行ガイド
Actions on Google Node.js Client Library Version 1 Migration Guide | Actions on Google | Google Developers
重要な部分の引用
Additionally, async tasks now have built-in direct support in the library. To perform an async task, you must return a Promise to the intent handler. (さらに、非同期タスクにはライブラリ内の組み込みの直接サポートが追加されました。 非同期タスクを実行するには、インテントハンドラにPromiseを返す必要があります。)
くそー、何回も読んだページだけど、全然理解して無かったということか…。
その他の参考記事
StackOverFlow
stackoverflow.com
サンプルソース
app.intent('actions.intent.MAIN', conv => { return handleConversation(conv) }) function handleConversation(conv) { // Promiseを返す return ( Promise.resolve(conv) .then(checkUserData) // .then(SuperFunc) // .then(UltraFunc) // .then(DragonFunc) .then(conv => { conv.close('デバッグです') return }) .catch(err => { console.log('handleConversation', err) conv.close( 'アプリに問題が発生しました。後ほどもう一度お試しください。終了します。' ) return }) ) } function checkUserData(conv) { return new Promise(resolve => { // 何らかの処理 resolve(conv) }) }
動くと嬉しい。