Google Nest Hubに対応したアプリケーションを開発しよう!
UI開発者 加藤Googleは先日Google Nest Hubを発売しました。Nest Hubは音声で操作することが前提とされた画面付きのスマートスピーカーで「スマートディスプレイ」とも呼ばれています。タブレットに近い存在ですが、持ち運ぶ前提ではないことや、音声操作が基本であるなどの違いがあります。
Google Nest Hubに表示する画像はInteractive Canvasというフレームワークをもちいて作ります。Google Nest Hubでフルスクリーン表示や、データのビジュアライズを行う際はInteractive Canvasによる実装が必須となっています。
実はInteractive Canvasの正体はWebページです。Google Assistantにレスポンスを返す際にURLを指定するだけでNest Hubがページをロードし、画面に表示してくれます。今回はInteractive Canvasを利用してGoogle Nest Hubに画像を表示する一連の流れをご紹介します。
※Interactive Canvasのステータスは現在デベロッパープレビューとなっており「Games & fun」カテゴリのアプリケーションにしか適用できないようです。
ディスプレイに画像が表示されるまでの流れ
実装の前に、ディスプレイに画像が表示されるまでの流れを見てみましょう。
- ユーザーが発話した内容をNest Hubが聞き取る
- 聞き取った内容についてGoogle Assistantが解析を行う
- 解析結果がいずれかのインテントにマッチした場合フルフィルメントを実行する
- ディスプレイに表示するURLをレスポンスに含めて返却する
- Nest Hubは受け取ったURLをロードする
- ロードが完了したら画面に表示される
大きな流れはスマートスピーカーアプリを実装するときと変わりありません。違うのはレスポンスにURLを含めること、表示するWebアプリを実装する必要があることの2点です。
実装
実装には大きく2つのオブジェクトが必要になります。1つはImmersive Response、もう1つはAssitantCanvas APIです。
ImmersiveResponse
はフルフィルメントで使用するレスポンス用のオブジェクトで、表示するURLとそのページに渡すパラメーターをプロパティに持ちます。以下にフルフィルメントのサンプルを記載します。
const functions = require('firebase-functions');
const {dialogflow, ImmersiveResponse} = require('actions-on-google');
const app = dialogflow({debug: true});
app.intent('example', (conv) => {
conv.ask('Immersive Responseと一緒に返すテキスト');
conv.ask(new ImmersiveResponse({
url: 'https://example.com', // 画面に表示するURLを指定する
state: {
'params': 'Webページに渡したいパラメーターを設定する'
}
}));
});
一度URLをレスポンスに含めたあとは、以降のレスポンスにURLを含める必要はありません。別のWebページを表示したい場合は、再度レスポンスに別のURLを含めればリロードされます。
AssitantCanvas APIは表示するWebページ側で使用するAPIです。まずはWebページ側で必要なCSSとJavaScriptを読み込みます。
<link rel="stylesheet" href="https://www.gstatic.com/assistant/immersivecanvas/css/styles.css">
<script src="https://www.gstatic.com/assistant/immersivecanvas/js/immersive_canvas_api.js"></script>
style.cssにはInteractive Canvasを使用したときにディスプレイの上部に強制的に表示されるヘッダー部分の余白を確保するためのスタイルが定義されています。JavaScriptにはGoogle Assistantとやり取りするためのAPIが定義されておりassistantCanvas
というオブジェクトがグローバルオブジェクトとして追加され使用できるようになります。
続いて、JavaScript内でGoogle Assistantからのロードを検知するコールバック関数を定義します。
const callbacks = {
onUpdate(state) {
// stateに応じて描画処理を分ける
}
}
assistantCanvas.ready(callbacks); // コールバック関数を登録する
フルフィルメントからImmersiveResponse
をGoogle Assistantが受け取ったとき、assistantCanvas.ready
に登録されたコールバック内のonUpdate
というメソッドが実行されます。ImmersiveResponse
にstate
オブジェクトが含まれていれば、その値が引数として渡されます。あとは引数に応じて描画を変える処理を実装していくだけです。
シミュレーターでの動作確認
Webページ側の描画処理が完成したら、Actions on Googleのシミュレーターで動作を確認してみましょう。テストを行う前にActions ConsoleでImmersiveResponse
を受け取れるように設定する必要があります。サイドナビの「Directory Information」を選択します。Categoryから「Games & fun」を選択すると一番下に「Interactive Canvas」の項目が表示されます。「Yes」にチェックを入れれば設定は完了です。
設定が完了したらサイドナビからSimulatorのページを開きメッセージを入力してみましょう。
ユーザーの発話からエンティティを抽出し画面に表示しています。Interactive Canvasを利用したGoogle Nest Hubへの表示方法は以上です。
設計・実装時の注意点
Googleが提供しているデザインガイドラインでは下記の点などに注意するよう書かれています。
- 画面の上部にはHeaderが、下部にはトランスクリプトが表示されるため画面の上下に重要な情報を配置しないこと
- ポップアップ、モーダル、キーボードやページネーションなどWebアプリでよく使われるナビゲーションは使用しないこと
- Interactive Canvasを使って実装する前に音声だけで主要な機能を使用できるかを確認すること
- タッチ操作でしか利用できないような設計をしないこと
- ユーザーはデバイスから離れたところにいる可能性があるため、シンプルで分かりやすく見やすい画面を実装すること
- タイトルは32tp、続く文章は24ptで表示することを推奨しています。
Google AssistantはAndroidスマートフォンだけでなく、Google Homeなどのスマートスピーカーや今回ご紹介した画面付きのGoogle Nest Hubなどさまざまなデバイスで利用できます。そのためGoogle Assistant用のアプリケーションを作る際は、どのデバイスでも主要な機能は使えるように考慮して設計する必要があります。すでに車にも音声アシスタントが搭載されてきており、今後も考慮すべき環境は増える一方です。今のうちからナレッジをためていければと思います。