Google アシスタントのアクションでユーザーを引きつける

1. 概要

Actions on Google は、Google アシスタントのバーチャル パーソナル アシスタント機能を拡張してソフトウェアを作成できるデベロッパー プラットフォームです。スマート スピーカー、スマートフォン、自動車、テレビ、ヘッドフォンなど 10 億以上のデバイスに対応しています。ユーザーは、Google アシスタントとの会話を通じて、食料品の購入から乗車の予約までさまざまなタスクを実行できます。(何ができるかについては、アクション ディレクトリをご覧ください)。Actions on Google を使用することで、ユーザーとサードパーティ サービス間の便利で効果的な会話型エクスペリエンスを簡単に作成、管理できます。

これは高度な Codelab モジュールであり、Google アシスタントのアクションを構築した経験がある方を対象としています。Actions on Google での開発経験がない場合は、入門コース(レベル 1レベル 2レベル 3)でプラットフォームの使い方を習得することを強くおすすめします。これらの高度なモジュールでは、アクションの機能を拡張し、オーディエンスを拡大するために役立つ一連の機能をご紹介します。

アクションの成功を測定する重要な方法の 1 つが、ユーザー エンゲージメントです。最初のインタラクション後にユーザーを呼び戻すのにアクションがどの程度役立っているかを把握する必要があります。これを簡単に行うために、アクションにいくつかの機能を実装して、ユーザーが会話に戻れるようにします。

この Codelab では、ユーザー エンゲージメント機能と Actions on Google のベスト プラクティスについて説明します。

a3fc0061bd01a75.png 266

作成するアプリの概要

構築済みの機能を次のものに拡張して活用できるようにします。

  • 毎日の更新をユーザーに送信し、タップしてアクションに話しかけてもらう
  • アクションにリンクしたプッシュ通知をユーザーに送信する
  • モバイル ウェブブラウザからユーザーにアクションを促すリンクを作成する

学習内容

  • ユーザー エンゲージメントの概要と、アクションを成功に導くために重要である理由
  • アクションを変更してユーザー エンゲージメントを高める方法
  • さまざまな種類のアクションで使用するユーザー エンゲージメント機能
  • Actions API を使用してアシスタントから通知を送信する方法

必要なもの

次のツールが必要です。

  • 任意の IDE またはテキスト エディタ(WebStormAtomSublime など)
  • Node.js、npm、git がインストールされたシェルコマンドを実行するターミナル
  • ウェブブラウザ(Google Chrome など)
  • Firebase コマンドライン インターフェースを使用したローカル開発環境
  • アシスタントを搭載したモバイル デバイス(Android または iOS)(このプロジェクトの作成に使用するのと同じ Google アカウントでアシスタントにログインする必要があります)。

必須ではありませんが、JavaScript(ES6)に精通していることを強く推奨します。

2. プロジェクトを設定する

このセクションでは、事前に作成したアクションにユーザー エンゲージメント機能を追加する方法について説明します。

サンプルについて

この Codelab のサンプルは、「Action Gym."」という架空のジム用のシンプルなアクションです。アクションは、毎日ローテーションされるクラスのリストなど、ジムに関する情報を提供します。クラスリストをローテーションすると有用な情報が毎日提供されるため、このような有益なアクションはすべてのユーザー エンゲージメント機能に適しています。

次の図に、Action Gym のサンプル 会話フローを示します。

e2d6e4ad98948cf3.png

追加するエンゲージメント機能に合わせて、ダイアログを少し変更します。ただし、会話の一般的なデザインはそれほど変わりません。

ベースファイルをダウンロードする

次のコマンドを実行して、この Codelab の GitHub リポジトリのクローンを作成します。

git clone https://github.com/actions-on-google/user-engagement-codelab-nodejs

プロジェクトとエージェントを設定する

Actions プロジェクトと Dialogflow エージェントを設定するには、次の手順を行います。

  1. Actions Console を開きます。
  2. [新しいプロジェクト] をクリックします。
  3. [Project Name](プロジェクト名)に名前を入力します(例: engagement-codelab)。
  4. [プロジェクトの作成] をクリックします。
  5. カテゴリを選択するのではなく、[その他のオプション] セクションまで下にスクロールして [会話] カードをクリックします。
  6. [アクションのビルド] をクリックしてオプションを展開し、[アクションを追加] を選択します。
  7. [Add Your First Action] をクリックします。
  8. [Create Action] ダイアログで [Custom Intent] を選択し、[Build] をクリックして Dialogflow コンソールを起動します。
  9. Dialogflow コンソールのエージェント作成ページで、[Create] をクリックします。
  10. 左側のナビゲーションの 6bf56243a8a11a3b.png(歯車アイコン)をクリックします。
  11. [Export and Import]、[Restore from Zip] の順にクリックします。
  12. 先ほどダウンロードした /user-engagement-codelab-nodejs/start/ ディレクトリから agent.zip ファイルをアップロードします。
  13. RESTORE」と入力して [復元] をクリックします。
  14. [完了] をクリックします。

フルフィルメントをデプロイする

Actions プロジェクトと Dialogflow エージェントの準備が整ったため、Firebase Functions CLI を使用してローカルの index.js ファイルをデプロイします。

ベースファイル クローンの /user-engagement-codelab-nodejs/start/functions/ ディレクトリから、次のコマンドを実行します。

firebase use <PROJECT_ID>
npm install
firebase deploy

数分後、[Deploy complete!](デプロイが完了しました)と表示されます。これは、Webhook が Firebase に正常にデプロイされたことを示します。

デプロイ URL を取得する

Dialogflow に Cloud Functions の関数の URL を提供する必要があります。この URL を取得する手順は次のとおりです。

  1. Firebase コンソールを開きます。
  2. 該当する Actions プロジェクトを一覧から選択します。
  3. 左側のナビゲーション バーで [関数の開発 > Functions] に移動します。[データ共有設定を選択] のメッセージが表示されたら、[後で行う] をクリックしても無視します。
  4. [ダッシュボード] タブに [Trigger] の下に URL を含む「fulfillment」があります。この URL は保存しておいてください。次のセクションで Dialogflow にコピーする必要があります。

1741a329947975db.png

Dialogflow で Webhook URL を設定する

ここで、フルフィルメントに Webhook を使用するように Dialogflow エージェントを更新する必要があります。そのための手順は次のとおりです。

  1. Dialogflow コンソールを開きます(必要な場合は Firebase コンソールを閉じることができます)。
  2. 左側のナビゲーションで [Fulfillment] をクリックします。
  3. Webhook を有効にする
  4. コピーした URL が Firebase ダッシュボードに表示されている場合は、貼り付けてください。
  5. [保存] をクリックします。

プロジェクトが正しく設定されていることを確認する

アクション ジムに関する情報は、営業時間を含むハードコードされたテキスト レスポンスや、曜日ごとのクラス スケジュールのリストを含むテキスト レスポンスなど、アクションを呼び出せるようにする必要があります。

Actions シミュレータでアクションをテストするには:

  1. Dialogflow コンソールで、左側のナビゲーションにある [Integrations] > [Google Assistant] をクリックします。
  2. [Auto-preview changes] が有効になっていることを確認し、[Test] をクリックして Actions プロジェクトを更新します。
  3. Actions Simulator が、Actions プロジェクトを読み込みます。アクションをテストするには、入力欄に「Talk to my test app」と入力して Enter キーを押します。
  4. Action Gym にようこそ。プロンプトに従って会話を進め、フルフィルメントが各入力に対するレスポンスを確保していることを確認します。

60acf1ff87b1a87f.png

3. 定期購入を毎日追加する

ユーザーへのアピールの一般的な方法は、最も役に立つタイミングで情報を提供することです。そのためには、特定のインテントの日次更新にサブスクライブするオプションをユーザーに提供します。登録すると、そのインテントのフルフィルメントに直接リンクするアシスタント通知が送信されます。

このステップでは、毎日の通知の登録について学習し、アクションのクラスリスト インテントに追加します。この手順に沿って操作すると、アクションの会話は次の図のようになります。

f48891c8118f7436.png

ユーザーを引きつける方法

スマートフォン ユーザーは、おそらくプッシュ通知をよくご存知でしょう。プッシュ通知はアプリ固有の情報やアップデートを提供します。「1 日の更新情報」の定期購入は、アシスタントに代わってモバイル デバイスのユーザーにアクセスする簡単な方法です。更新を送信するインテントがユーザーに日々価値を提供し続ける場合に限ります。

毎日の通知は便利なエンゲージメント ツールですが、必ずしもすべてのアクションに組み込むべきではありません。毎日の通知の登録をアクションに追加するかどうかを決定する際は、次のヒントを参考にしてください。

  • 毎日更新すると、毎日役立つ情報がユーザーに届くようにします。毎日の通知をタップしても、毎回同じメッセージが表示されると、数日後に登録が解除される可能性があります。
  • ユーザーが 1 日の更新情報にすぐに飛び込むようなダイアログを用意しましょう。ユーザーは会話の最初から始めるとは限らないため、提供できるコンテキストは限られるべきです。
  • 毎日の通知に登録するように促す前に、ユーザーにアクションのメリットを示します。ユーザーは定期購入を選べる状況で、「このコンテンツを毎日見たい」と考えます。
  • ユーザーに何度もチャンネル登録を提案して困惑させないようにする定期購読の内容がすぐにユーザーに伝えられるので、すぐに登録できます。
  • 更新インテントがトリガーされた後の会話は短くします。1 日の更新のほとんどは、1 つのレスポンスで構成し、ユーザー入力なしで閉じる必要があります。

毎日の通知をオンにする

毎日の通知の登録をウェルカム インテントに追加して、ユーザーを会話の開始に導きます。または、ユーザーを会話内の任意の場所にディープリンクするための、より具体的なインテントです。この Codelab では、対話が毎日変化するため、どのクラスが使用可能かをユーザーが思い出せるように、Class List インテントが最適です。

Class List インテントで毎日の更新を有効にするには、次の手順を行います。

  1. Actions Console で [Develop](開発)タブをクリックし、左側のナビゲーション バーで [Actions](アクション)を選択します。
  2. [Actions] リストで、[Class List] をクリックします。
  3. [ユーザー エンゲージメント] で [ユーザーに毎日の最新情報を提供する] をオンにします。
  4. 日々の更新を説明するわかりやすいコンテンツ タイトルを設定します。コンテキストは「1 日に何時間お送りいたしますか?」となります。そのため、読み上げる際にタイトルが具体的で適切なサウンドになるようにしてください。この例では、[コンテンツのタイトル] を list of upcoming Action Gym classes に設定します。
  5. ページの上部にある [保存] をクリックします。

c00885cc30e14d68.png

Dialogflow の設定

Dialogflow コンソールで次の手順に沿って、日次更新サブスクリプション フローのインテントを作成します。

ユーザーに定期購入を促す

  1. ユーザーが毎日の最新情報を受け取るよう要求する新しいインテントを設定します。Dialogflow コンソールで、新しいインテントを作成するには、左側のナビゲーションの [Intents] の横にある [+] ボタンをクリックします。
  2. この新しいインテントに Setup Updates という名前を付けます。
  3. [トレーニング フレーズ] で、次のユーザー式を追加します。
  • Send daily reminders
  • Reminder
  • Remind me
  • Updates
  • Upcoming classes
  1. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  2. ページの上部にある [保存] をクリックします。

5C70FAA02151DA0.PNG

ユーザーの判断に対処する

  1. 定期購読の更新プロンプトへのユーザーの応答を処理する新しいインテントを設定します。左側のナビゲーションで、[Intents] の横にある [+] ボタンをクリックして新しいインテントを作成します。
  2. この新しいインテントに Confirm Updates という名前を付けます。
  3. [イベント] セクションで actions_intent_REGISTER_UPDATE を追加します。この Dialogflow イベントは、ユーザーが定期購入を更新するかどうかにかかわらず、1 日の更新定期購入フローを終了するとトリガーされます。
  4. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  5. ページの上部にある [保存] をクリックします。

b871c2bdadac8abc.png

フルフィルメントを実装する

Webhook にフルフィルメントを実装する手順は次のとおりです。

読み込みの依存関係

b2f84ff91b0e1396.pngindex.js ファイルで、require() 関数を更新して、actions-on-google パッケージから RegisterUpdate パッケージを追加します。インポートは次のようになります。

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
} = require('actions-on-google');

候補ワードの更新

b2f84ff91b0e1396.pngindex.js ファイルの候補ワードのタイトルのリストに DAILY エントリを追加します。これにより、Suggestion の定義は次のようになります。

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
};

新しいインテントのフルフィルメントを追加する

ユーザーが定期購入を希望すると述べたら、更新のターゲット インテント(クラスリスト)と型(DAILY)を指定して RegisterUpdate ヘルパーを呼び出し、毎日の更新定期購入フローを開始します。定期購入フローが終了すると、定期購入が成功したかどうかを示す status 引数を含む actions_intent_REGISTER_UPDATE イベントがトリガーされます。定期購入のステータスに応じて変化するフォローアップ プロンプトをお客様に提供します。

b2f84ff91b0e1396.png index.js ファイルに、次のコードを追加します。

index.js

// Start opt-in flow for daily updates
app.intent('Setup Updates', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'Class List',
    frequency: 'DAILY',
  }));
});

// Confirm outcome of opt-in for daily updates
app.intent('Confirm Updates', (conv, params, registered) => {
  if (registered && registered.status === 'OK') {
     conv.ask(`Gotcha, I'll send you an update everyday with the ` +
     'list of classes. Can I help you with anything else?');
  } else {
    conv.ask(` I won't send you daily reminders. Can I help you with anything else?`);
  }
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS, Suggestion.CLASSES]));
  }
});

代替メッセージをユーザーに提示する

クラスリスト レスポンスでは、毎日更新される更新情報が毎日提供されますが、それでも問題が発生します。この通知は、ユーザーが毎日の通知をタップするとトリガーされます。そのため、こうした通知を受け取った場合でも、毎日の通知を受け取るように登録できます。では、ユーザーが再度定期購入する必要があると思わせるにはどうすればよいでしょうか。

幸いなことに、conv オブジェクトの引数には、ユーザーが会話を開始した場所に関する情報が含まれています。conv 引数に UPDATES セクションが含まれているかどうかを確認できます。このセクションには、ユーザーが毎日の更新通知から会話を開始したことを示し、応答を適宜変更します。また、この会話ブランチを使用すると、クラスのリストを提供した直後にダイアログを閉じることができます。これは、1 日の更新回数を短く抑えるためのベスト プラクティスに準拠しています。

b2f84ff91b0e1396.png index.js ファイルで、次のコードを置き換えます。

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  const classesMessage =
  `On ${day} we offer the following classes: ${classes}. ` +
  `Can I help you with anything else?`;
  conv.ask(classesMessage);
  if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.HOURS]));
  }
});

これを次のコードに置き換えます。

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

毎日の通知をテストする

ターミナルで次のコマンドを実行して、更新した Webhook コードを Firebase にデプロイします。

firebase deploy

Actions シミュレータでカスタム プロンプトをテストする手順は次のとおりです。

  1. Actions Console で、[Test](テスト)に移動します。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. Learn about classes」と入力して Enter キーを押します。アクションからの返信が毎日のリマインダーを送信するようになりました。
  4. Send daily reminders」と入力して Enter キーを押します。
  5. 更新を確認する時間を入力し、Enter キーを押します。テストのため、現在の時刻から 3 ~ 5 分後に応答してください。

23a15ecac8c71787.png

更新を指定した時刻に、モバイル デバイスでアシスタントから通知が届くようになります。この通知が表示されるまでに数分かかる場合があります。通知をタップすると、アシスタントのクラスリスト インテントに直接ディープリンクされ、今後のクラスのリストが表示されます。

10347400066571

4. プッシュ通知を追加する

Actions の外部でユーザーとやり取りするもう 1 つの方法として、Actions API を呼び出してプッシュ通知をユーザーに送信できることが挙げられます。毎日の通知とは異なり、これらの通知は Google アシスタントによって自動的にスケジュール設定されないため、必要に応じて送信することができます。

このステップでは、新しいクラスのキャンセル インテントを追加し、クラスのキャンセルについて通知をユーザーに送信することで、アクションにプッシュ通知を実装する方法を学びます。通知の送信に必要な次の 3 つのコンポーネントも設定します。

  • Actions API アカウント - API に POST リクエストを送信して通知をユーザーに送信します。そのため、この API とやり取りするには、サービス アカウントと認証情報を設定する必要があります。
  • 権限ヘルパー - プッシュ通知の送信に必要なユーザー ID にアクセスするユーザーの権限が必要です。この例では、クライアント ライブラリ関数を使用して権限ヘルパーを呼び出し、この ID をリクエストします。
  • ストレージ - 会話の外部でユーザーにプッシュ通知を送信するには、ユーザー ID を自由にリコールできる場所に保存する必要があります。この例では、各ユーザーの情報を保存する Firestore データベースを設定します。

この手順に沿って操作した後、以下のダイアログをアクションの会話に追加します。

7c9d4b633c547823.png

ユーザーを引きつける方法

スマートフォン ユーザーは、おそらくプッシュ通知をよくご存知でしょう。プッシュ通知はアプリ固有の情報やアップデートを提供します。プッシュ通知は、ユーザーがモバイル アプリにアクセスするのに対し十分な理由がある場合に、アシスタントの外でも柔軟にアクセスできるようにします。毎日アップデートされることで、ユーザーは毎日通知が届くことをすでに認識しています。プッシュ通知では、通知の頻度が少ないか、1 日に複数の通知が届くかは問題になりません。

プッシュ通知は便利なエンゲージメント ツールですが、必ずしもすべてのアクションに組み込むべきではありません。アクションにプッシュ通知を追加するかどうかを決定する際は、次のヒントを参考にしてください。

  • プッシュ通知のスケジュールの例を計画します。1 日に 1 回だけプッシュ通知を送信する場合は、毎日更新することをご検討ください。
  • 通知を受け取るたびに、プッシュ通知が役立つ情報を送信することを確認してください。通知にはアクションのインテントへのディープリンクも含まれているため、そのインテントが有用で関連性があることを確認してください。
  • プッシュ通知の登録をはっきりと示す。各プッシュ通知に何ができるか、また、どれくらいの頻度で通知が送信されるのかを把握できるようにしてください。

Actions API を有効にする

  1. Google Cloud Console を開き、プルダウンから Actions プロジェクト名を選択します。

d015c1515b99e3db.png

  1. ナビゲーション メニュー(BlobInfo)で、[API とサービス] > [ライブラリ] に移動します。
  2. Actions API を検索し、[有効にする] をクリックします。

6D464F49C88E70B4.PNG

サービス アカウントの作成

Actions API には認証が必要なため、リクエストを送信するにはサービス アカウントを作成する必要があります。Actions API 用のサービス アカウント キーを作成してインストールする手順は次のとおりです。

  1. Google Cloud Console のナビゲーション メニュー(▾)で、[API とサービス] に移動します。
  2. [認証情報を作成 > サービス アカウント キー] をクリックします。
  3. [サービス アカウント] プルダウン メニューで [新しいサービス アカウント] を選択します。
  4. 次の情報を入力します。
  • サービス アカウント名: service-account
  • ロール: プロジェクト、オーナー
  • サービス アカウント ID: service-account(常に @<project_id>.iam.gserviceaccount.com が後に続く)
  • キータイプ: JSON
  1. [作成] をクリックします。
  2. ダウンロードした JSON ファイルをプロジェクトの /user-engagement-codelab/start/functions/ ディレクトリに移動します。
  3. JSON ファイルの名前を service-account.json に変更します。

d9bd79d35691de3a.png

Firestore を有効にする

会話の外部に通知を送信するには、通知コードから参照できるユーザー ID を保存する手段が必要です。この例では、登録ユーザーのユーザー ID を保存するために Firestore データベースを使用しています。

次の手順で、アクション用の Firestore データベースを作成します。

  1. Firebase コンソールで Actions プロジェクト名を選択します。
  2. 左側のナビゲーションで [データベースの開発] に移動し、[データベースを作成] をクリックします。
  3. [テストモードで開始] を選択します。
  4. [有効にする] をクリックします。

6DFC386413954CAA.PNG

Dialogflow の設定

Dialogflow コンソールでプッシュ通知のオプトイン フローを作成するには、次の手順を行います。

ユーザーに定期購入を促す

  1. キャンセルされたクラスのプッシュ通知の登録を求めるユーザーに対応するため、新しいインテントを設定します。Dialogflow コンソールで、新しいインテントを作成するには、左側のナビゲーションの [Intents] の横にある [+] ボタンをクリックします。
  2. この新しいインテントに Setup Push Notifications という名前を付けます。
  3. [トレーニング フレーズ] で、次のユーザー式を追加します。
  • Subscribe to notifications
  • Send notification
  • Notify me
  • Send class notifications
  • Cancelled notifications
  1. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  2. ページの上部にある [保存] をクリックします。

3D99BC41D0492552.PNG

ユーザーの判断に対処する

  1. プッシュ通知のサブスクリプション プロンプトに対するユーザーの応答を処理する新しいインテントを設定します。左側のナビゲーションで、[Intents] の横にある [+] ボタンをクリックして新しいインテントを作成します。
  2. この新しいインテントに Confirm Push Notifications という名前を付けます。
  3. [イベント] セクションで actions_intent_PERMISSION を追加します。この Dialogflow イベントは、ユーザーがプッシュ通知の購読フローを完了すると(最終的に登録が発生したかどうかにかかわらず)、トリガーされます。
  4. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  5. ページの上部にある [保存] をクリックします。

d37f550c5e07cb73.png

プッシュ通知を処理する

プッシュ通知を特定のインテントにリンクすることで、プッシュ通知をタップしたユーザーはアクション内でそのインテントに直接ディープリンクされます。この例では、キャンセルされたクラスの詳細を提供する新しいインテントをプッシュ通知用に追加します。

ユーザーがプッシュ通知をタップすることでトリガーされるインテントを追加するには、次の手順を行います。

  1. Dialogflow コンソールで、新しいインテントを作成するには、左側のナビゲーションの [Intents] の横にある [+] ボタンをクリックします。
  2. この新しいインテントに Class Canceled という名前を付けます。
  3. [トレーニング フレーズ] で、Cancelationsユーザー式として追加します。
  4. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  5. ページの上部にある [保存] をクリックします。

940379556f559631.png

会話中にテスト通知を送信する

本番環境では、アクションのフルフィルメント コードとは別に、プッシュ通知を送信するスクリプトを用意する必要があります。この例では、アクションとの通信中にプッシュ通知を送信するために呼び出すインテントを作成します。このインテントはデバッグ専用です。実際には、プッシュ通知はフルフィルメントで処理したり、アクションの会話の一部としてトリガーしたりしないでください。

プッシュ通知をテストするインテントを作成する手順は次のとおりです。

  1. テストとデバッグを目的として、登録済みユーザーにプッシュ通知を送信できる新しいインテントを設定します。Dialogflow コンソールで、新しいインテントを作成するには、左側のナビゲーションの [Intents] の横にある [+] ボタンをクリックします。
  2. この新しいインテントに Test Notification という名前を付けます。
  3. [トレーニング フレーズ] で、Test notificationユーザー式として追加します。
  4. [Fulfillment] セクションで、[Enable webhook call for this intent] をオンにします。
  5. ページの上部にある [保存] をクリックします。

6967f5a997643eb8.png

プッシュ通知をオンにする

Class Canceled インテントのプッシュ通知を有効にする手順は次のとおりです。

  1. Dialogflow コンソールで、ナビゲーション バーの [Integrations] に移動します。
  2. [Google Assistant] カードで [Integration Settings] をクリックします。
  3. 暗黙的な呼び出しインテントとして [Class Canceled] を追加します。この手順は、ユーザーが(プッシュ通知をタップすることで)Class Canceled インテントによって会話を開始できることを Dialogflow が認識するために必要なものです。
  4. [閉じる] をクリックします。

1ac725231ed279a1.png

  1. Actions Console で [Develop](開発)タブをクリックし、左側のナビゲーション バーで [Actions](アクション)を選択します。
  2. [Actions] リストで [Class Canceled] をクリックします。
  3. [ユーザー エンゲージメント] の [プッシュ通知を送信しますか?] をオンにします。
  4. プッシュ通知を説明するわかりやすいコンテンツ タイトルを設定します。コンテキストは「\u2020」に関するプッシュ通知を送信しても構いません。そのため、タイトルは説明的で、音声でも正しく聞こえるようにしてください。この例では、[コンテンツのタイトル] を class cancelations に設定します。
  5. ページの上部にある [保存] をクリックします。

4304c7cd575f6de3.png

フルフィルメントを実装する

Webhook にフルフィルメントを実装する手順は次のとおりです。

読み込みの依存関係

b2f84ff91b0e1396.pngindex.js ファイルで、require() 関数を更新して、actions-on-google パッケージから UpdatePermission パッケージを追加します。インポートは次のようになります。

index.js

const {
  dialogflow,
  Suggestions,
  RegisterUpdate,
  UpdatePermission,
} = require('actions-on-google');

候補ワードの更新

b2f84ff91b0e1396.pngindex.js ファイルの候補ワードのタイトルのリストに NOTIFICATIONS エントリを追加します。これにより、Suggestion の定義は次のようになります。

index.js

// Suggestion chip titles
const Suggestion = {
  HOURS: 'Ask about hours',
  CLASSES: 'Learn about classes',
  DAILY: 'Send daily reminders',
  NOTIFICATIONS: 'Get notifications',
};

新しいインポートを設定する

Firestore データベースに接続するには、firebase-admin パッケージを追加し、データベースに格納されているフィールドの定数を追加します。また、認証と Actions API へのリクエストを処理するために、google-auth-library パッケージと request パッケージをインポートします。

b2f84ff91b0e1396.pngindex.js ファイルで、次のコードをインポートをインポートします。

index.js

// Firebase admin import
const admin = require('firebase-admin');

// Initialize Firestore
admin.initializeApp();
const db = admin.firestore();

// Firestore constants
const FirestoreNames = {
 INTENT: 'intent',
 USER_ID: 'userId',
 USERS: 'users',
};

// Actions API authentication imports
const {auth} = require('google-auth-library');
const request = require('request');

クラスのキャンセル通知の設定を提案する

b2f84ff91b0e1396.png index.js ファイルで、次のコードを置き換えます。

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like me to send you daily reminders of upcoming classes, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.HOURS]));
    };
  };
});

これを次のコードに置き換えます。

index.js

// Class list intent handler
app.intent('Class List', (conv, {day}) => {
  if (!day) {
    day = DAYS[new Date().getDay()];
  }
  const classes =
  [...new Set(schedule.days[day].map((d) => `${d.name} at ${d.startTime}`))]
  .join(', ');
  let classesMessage = `On ${day} we offer the following classes: ${classes}. `;
  // If the user started the conversation from the context of a daily update,
  // the conv's arguments will contain an 'UPDATES' section.
  let engagement = conv.arguments.get('UPDATES');
  // Check the conv arguments to tailor the conversation based on the context.
  if (engagement) {
    classesMessage += `Hope to see you soon at Action Gym!`;
    conv.close(classesMessage);
  } else {
    classesMessage += `Would you like to receive daily reminders of upcoming classes, subscribe to notifications about cancelations, or can I help you with anything else?`;
    conv.ask(classesMessage);
    if (conv.screen) {
      conv.ask(new Suggestions([Suggestion.DAILY, Suggestion.NOTIFICATIONS,
Suggestion.HOURS]));
    };
  };
});

新しいインテントのフルフィルメントを追加する

ユーザーがプッシュ通知のサブスクライブを希望する場合は、UpdatePermission ヘルパーを呼び出してユーザーに権限をリクエストします。成功すると、PERMISSION 引数が conv オブジェクトの引数に追加され、会話の方向性を確認できます。

ユーザーの権限を取得したら、conv オブジェクトの引数からユーザー ID を取得して、データベースに保存します。後でこのユーザー ID を Actions API に送信します。Actions API はこれにより通知を受信するユーザーを決定します。

最後に、プッシュ通知をタップすることでトリガーされる Class Canceled インテントのフルフィルメントを追加します。この例ではレスポンスがプレースホルダ文字列ですが、このアクションの本番環境バージョンでは、どのスクリプトがキャンセルされたかについて、通知スクリプトによって動的な情報が提供されます。

b2f84ff91b0e1396.png index.js ファイルに、次のコードを追加します。

index.js

// Call the User Information helper for permission to send push notifications
app.intent('Setup Push Notifications', (conv) => {
 conv.ask('Update permission for setting up push notifications');
 conv.ask(new UpdatePermission({intent: 'Class Canceled'}));
});

// Handle opt-in or rejection of push notifications
app.intent('Confirm Push Notifications', (conv) => {
 if (conv.arguments.get('PERMISSION')) {
   let userId = conv.arguments.get('UPDATES_USER_ID');
   if (!userId) {
     userId = conv.request.conversation.conversationId;
   }
   // Add the current conversation ID and the notification's
   // target intent to the Firestore database.
   return db.collection(FirestoreNames.USERS)
   .add({
     [FirestoreNames.INTENT]: 'Class Canceled',
     [FirestoreNames.USER_ID]: userId,
   })
   .then(() => {
     conv.ask(`Great, I'll notify you whenever there's a class cancelation. ` +
     'Can I help you with anything else?');
   });
 } else {
   conv.ask(`Okay, I won't send you notifications about class cancelations. ` +
     'Can I help you with anything else?');
 }
 if (conv.screen) {
    conv.ask(new Suggestions([Suggestion.CLASSES, Suggestion.HOURS]));
  }
});

// Intent triggered by tapping the push notification
app.intent('Class Canceled', (conv) => {
 conv.ask('Classname at classtime has been canceled.');
});

テスト通知を追加する

ユーザーにプッシュ通知を送信するには、ユーザー ID、通知のタイトル、ターゲット インテントを指定した POST リクエストを Actions API に送信します。この例では、テスト通知インテントをトリガーすると、Firestore データベースに反復処理が適用され、通知を登録しているすべてのユーザーにプッシュ通知が送信されます。

この例では、Webhook フルフィルメントにプッシュ通知を送信するコードを含め、会話内でテスト インテントを呼び出してそのコードをトリガーすることに注意してください。公開するアクションでは、フルフィルメントとは別のスクリプトにプッシュ通知コードが存在する必要があります。

b2f84ff91b0e1396.png index.js ファイルに、次のコードを追加します。

index.js

// Debug intent to trigger a test push notification
app.intent('Test Notification', (conv) => {
 // Use the Actions API to send a Google Assistant push notification.
 let client = auth.fromJSON(require('./service-account.json'));
 client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation'];
 let notification = {
   userNotification: {
     title: 'Test Notification from Action Gym',
   },
   target: {},
 };
 client.authorize((err, tokens) => {
   if (err) {
     throw new Error(`Auth error: ${err}`);
   }
   // Iterate through Firestore and send push notifications to every user
   // who's currently opted in to canceled class notifications.
   db.collection(FirestoreNames.USERS)
       .where(FirestoreNames.INTENT, '==', 'Class Canceled')
       .get()
       .then((querySnapshot) => {
         querySnapshot.forEach((user) => {
           notification.target = {
             userId: user.get(FirestoreNames.USER_ID),
             intent: user.get(FirestoreNames.INTENT),
           };
           request.post('https://actions.googleapis.com/v2/conversations:send', {
             'auth': {
               'bearer': tokens.access_token,
             },
             'json': true,
             'body': {'customPushMessage': notification, 'isInSandbox': true},
           }, (err, httpResponse, body) => {
             if (err) {
               throw new Error(`API request error: ${err}`);
             }
             console.log(`${httpResponse.statusCode}: ` +
               `${httpResponse.statusMessage}`);
             console.log(JSON.stringify(body));
           });
         });
       })
       .catch((error) => {
         throw new Error(`Firestore query error: ${error}`);
       });
 });
 conv.ask('A notification has been sent to all subscribed users.');
});

プッシュ通知をテストする

ターミナルで次のコマンドを実行して、更新した Webhook コードを Firebase にデプロイします。

firebase deploy

Actions シミュレータで通知をテストする手順は次のとおりです。

  1. Actions Console で、[Test](テスト)タブに移動します。
  2. 入力欄に「Talk to my test app」と入力し、Enter キーを押します。
  3. Learn about classes」と入力して Enter キーを押します。
  4. Get notifications」と入力して Enter キーを押します。
  5. プッシュ通知を送信する権限をアクションにまだ付与していない場合は、「yes」と入力して Enter キーを押します。
  6. yes」と入力して Enter キーを押します。これで、このアクションのプッシュ通知が登録された Google アカウントが登録されました。

3a8704bdc0bcbb17.png

  1. no」と入力し、Enter キーを押して終了します。
  2. Talk to my test app」と入力し、Enter キーを押して新しい会話を開始します。
  3. Test notification」と入力して Enter キーを押します。

634dfcb0be8dfdec.png

数分以内に、アクション ジムからのテスト通知(モバイル デバイスのアシスタントのプッシュ通知)が届きます。この通知をタップすると、アクションの Class Canceled インテントにディープリンクされます。

33cbde513c10122e.png

5. アシスタント リンクを作成する

ここまでは、ユーザーをアクションに呼び戻すために実装できるエンゲージメント機能について説明しましたが、これらの機能は、アクションを発見して使用することを前提にしています。

モバイル デバイスのユーザーをアシスタントのアクションに直接リンクするアシスタント リンクを作成できます。アシスタント リンクは標準のハイパーリンクなので、ウェブサイトやソーシャル メディアの投稿(ブログやソーシャル メディアなど)に追加できます。

このステップでは、アシスタント リンクの概要、アクションのウェルカム インテント用のリンクの作成方法、テスト用のシンプルなウェブサイトに追加する方法について説明します。

ユーザーを引きつける方法

初めてユーザーにアクションを促すのは、特にアシスタントで明示的にアクションを呼び出す必要がある場合には、困難です。アシスタントのリンクは、このアクションへの直接リンクをユーザーに提供することでこうした手間を軽減します。ユーザーがアシスタント搭載デバイスでアシスタントのリンクにアクセスすると、アクションに直接移動します。ユーザーがモバイル以外のデバイス、またはアシスタントをサポートしていないその他のデバイスでリンクを開くと、そのユーザーは Actions ディレクトリのリスト(公開されている場合)に誘導されます。そのため、リンクを使用して、ユーザーは引き続きアクションをマーケティングできます。

アシスタント リンクは便利なエンゲージメント ツールです。ウェブサイトやソーシャル メディアでアクションを宣伝する場合は、アシスタント リンクを作成することをおすすめします。アシスタント リンクを作成して配布する前に、以下のヒントをご確認ください。

  • アシスタント リンクは、アクションの公開後にのみ機能します。プロジェクトが下書き状態の場合、リンクはご自身のデバイスでのみ機能します。それ以外のユーザーは、Actions ディレクトリの 404 ページが表示されます。
  • アルファ版またはベータ版の環境でアクションをリリースすると、ユーザーは公開前にアシスタント リンクをテストできます。アシスタントのリンクをテストできるのは、アルファ版またはベータ版に参加しているユーザーのみです。
  • アシスタント リンクのリンク先のインテントが、新規ユーザーに良い第一印象を与えるようにする。アシスタント リンクのデフォルトのデスティネーションは、ウェルカム インテントです。このアクションは、アクションの導入を適切に行えるはずです

ウェルカム インテントのアシスタント リンクを作成する手順は次のとおりです。

  1. Actions Console で [Develop](開発)タブをクリックし、左側のナビゲーション バーで [Actions](アクション)を選択します。
  2. [Actions] リストで [actions.intent.MAIN] をクリックします。
  3. [Links] で [Do you want to enable a URL for this Action] オプションを切り替えます。
  4. アクションを説明する、わかりやすいリンクタイトルを設定します。タイトルには、ユーザーがアクションで達成できることを表す単純な動詞と名詞のペアを含めます。この例では、[リンクのタイトル] を learn about Action Gym に設定します。
  5. このページの下部から HTML スニペットをコピーして、後で保存してください。
  6. ページの上部にある [保存] をクリックします。

55341b8102b71eab.png

テスト用ウェブサイトをデプロイする

アシスタント リンクをテストするには、Firebase ツールを使用して、フルフィルメントとともにテストウェブサイトをデプロイします。この例ではすでにシンプルなテストウェブサイトを用意していますので、アシスタントのリンクを追加してください。

フルフィルメントの /user-engagement-codelab-nodejs/start/public/ ディレクトリに移動し、index.html ファイルをテキスト エディタで開きます。

b2f84ff91b0e1396.pngindex.html ファイルのアシスタント リンクの HTML スニペットを本文要素に貼り付けます。ファイルは次のようなスニペットになります。

index.html

<body>
    <p>
     <a href="https://assistant.google.com/services/invoke/uid/000000efb5f2fd97">🅖 Ask my test app to learn about Action Gym
     </a>
    </p>
</body>

ターミナルで、次のコマンドを実行してテストウェブサイトを Firebase にデプロイします。

firebase deploy

deploy コマンドの実行が終了したら、出力の Hosting URL をメモします。

b01e8d322fb5d623.png

モバイル デバイスのウェブブラウザでこの URL にアクセスすると、テストウェブサイトにアシスタントのリンクが表示されます。モバイル デバイスでこのリンクをクリックすると、アシスタントのアクションのウェルカム インテントに移動します。

599845d647f5b624.png

パソコンのブラウザで Hosting URL にアクセスしてみても、アクションが公開されていないため、アシスタント ディレクトリの 404 ページが表示されます。

6. 次のステップ

おめでとうございます!

ここでは、アクションの開発時のユーザー エンゲージメントの重要性、そのプラットフォームで利用可能なユーザー エンゲージメント機能、各機能をアクションに追加する方法について学習しました。

その他の学習リソース

以下のリソースで、アクションのユーザー エンゲージメントの詳細をご確認ください。

Twitter で @ActionsOnGoogle をフォローして最新情報をチェックしてください。また、作成したアクションについて、ハッシュタグ #AoGDevs でツイートしてください。

フィードバック アンケート

終了する前に、こちらのフォームに記入して、ご意見、ご感想をお寄せください。