毎日の通知

毎日の通知は、毎日、指定された時間に送信されます。毎日のルーティンの一部として適切なアクションに対して、またはアクションによる類似したエクスペリエンスをユーザーが定期的にリクエストする場合などは、毎日の通知が便利です。この機能は、指定された時間にプッシュ通知を送信し、ユーザーにアクションのトリガーを促します。

前提条件

ユーザーがアシスタントから受け取った通知をタップすると呼び出されるトリガー インテントとして、アクション プロジェクト内の 1 つ以上のアクションを設定しておく必要があります。

自動検出フロー

これは、毎日の通知をアクションに追加できる最も簡単なフローです。有料会員登録のリクエストを開始するトリガー インテントを設定するだけで済みます。ユーザーへのオプトインの表示は Google 側で処理されます。

コンソールの設定

ウェブブラウザでアクション コンソールを開き、次の操作を行います。

  1. [ビルド] > [アクション] の順に移動します。
  2. 毎日の通知を有効にする追加のトリガー インテントに一致するアクションをクリックします。
  3. [ユーザー エンゲージメント] セクションまでスクロールして、[ユーザーに毎日の通知を提供する] をオンにします。
  4. コンテンツのタイトルを入力します。
  5. [保存] をクリックします。

高度な機能(オプション)

このガイドでは、Actions on Google Updates API のサンプルを使用して、アプリケーションの毎日の通知で使用できる高度な機能の設定方法について説明します。ユーザーがこのアクションを呼び出すと、アクションの開発に関するヒントを再生するかどうか尋ねられます。ユーザーが指定するカテゴリのヒント、ランダムなカテゴリのヒント、または最新のヒントを再生できます。

インポート

次のいくつかのセクションで使用するため、フルフィルメント コードで次のインポートを宣言する必要があります。

Dialogflow
const {
  dialogflow,
  RegisterUpdate,
  Suggestions
} = require('actions-on-google');
const app = dialogflow();
Actions SDK
const {
  actionssdk,
  RegisterUpdate,
  Suggestions
} = require('actions-on-google');
const app = actionssdk();

オプトイン ユーザー

オプトインの処理を Google に任せるのではなく、アクションでオプトイン チップの表示を制御する場合は、アクションにオプトイン フローを直接実装できます。

オプトイン フローの開始

コンソールの設定の説明に従って、通知を受け取るインテントを設定します。

オプトイン フローをトリガーするときに、ユーザーに有料会員登録を促すチップを送信します。次の例では、チップのタイトルとして「Send daily」を使用しています。

Node.js
conv.ask('I can send you those updates daily. Would you like that?');
conv.ask(new Suggestions('Send daily'));
Java
ResponseBuilder rb = getResponseBuilder(request);
String[] suggestions = {"Send daily"};
rb.addSuggestions(suggestions);
return rb.build();
Dialogflow JSON

下記の JSON は、Webhook レスポンスを示します。

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "I can send you those updates daily. Would you like that?"
            }
          }
        ],
        "suggestions": [
          {
            "title": "Send daily"
          }
        ]
      },
      "userStorage": "{\"data\":{}}"
    }
  },
  "outputContexts": [
    {
      "name": "/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{}"
      }
    }
  ]
}
Actions SDK JSON

下記の JSON は、Webhook レスポンスを示します。

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "I can send you those updates daily. Would you like that?"
              }
            }
          ],
          "suggestions": [
            {
              "title": "Send daily"
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}
Dialogflow
  1. setup_update などの別のインテントを追加します。
  2. ユーザー表現に毎日の通知プロンプトの正確な値(例: Send daily)を設定します。
  3. [インテント] の [アクションとパラメータ] セクションで、configure_updates のような名前のアクションを追加します。
Actions SDK

ユーザー表現が毎日の通知プロンプトの値と一致したときに、actions_intent_CONFIGURE_UPDATES イベントを処理する関数をトリガーするように NLU ソリューションを設定する必要があります。文字列マッチングの基本的な例を示します。

Actions SDK Node.js
app.intent('actions.intent.TEXT', (conv) => {
  if (conv.input.raw === 'Send daily') {
    conv.ask(new RegisterUpdate({
      intent: 'update_of_the_day',
      frequency: 'DAILY',
    }));
  }
});
Actions SDK Java
public ActionResponse configureUpdates(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  String userInput = request.getRawInput().getQuery();
  if (userInput.equals("Send daily")) {
    rb.add(new RegisterUpdate().setIntent("intent_name"));
  }
  return rb.build();
}
Actions SDK JSON

下記の JSON は、Webhook レスポンスを示します。

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "PLACEHOLDER"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.REGISTER_UPDATE",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValueSpec",
            "intent": "update_of_the_day",
            "triggerContext": {
              "timeContext": {
                "frequency": "DAILY"
              }
            }
          }
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}

ユーザーがアクションからの毎日の通知をオプトインすると、アシスタントはアクションの actions.intent.CONFIGURE_UPDATES インテントをトリガーします。

Dialogflow

呼び出し可能なインテントを設定します。たとえば configure_updates の場合は、インテントのイベントとして actions_intent_CONFIGURE_UPDATES を設定します。

Actions SDK

アクション パッケージでインテントを宣言します。

{
    "actions": [

      // other actions here

      {
        "description": "Configure Update Intent",
        "name": "Configure update",
        "fulfillment": {
          "conversationName": "configureUpdate"
        },
        "intent": {
          "name": "actions.intent.CONFIGURE_UPDATES"
        }
      }
    ],
    "conversations": {

      // other conversations here

      "configureUpdate": {
        "name": "configureUpdate",
        "url": "YOUR_ENDPOINT_URL",
        "fulfillmentApiVersion": 2
      }
    }
  }

有料会員登録の設定

ユーザーがオプトイン提案チップをタップすると、アシスタントは actions_intent_CONFIGURE_UPDATES インテントをトリガーし、ユーザーが選択したインテント名を含む UPDATE_INTENT 引数を渡します。

アクションはアシスタントに actions.intentREGISTER_UPDATE インテントを送信します。これは、通知トリガーと通知の頻度を設定するインテントです。

Node.js
app.intent('setup_update', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'update_of_the_day',
    frequency: 'DAILY',
  }));
});
Java
@ForIntent("setup_update")
public ActionResponse setupUpdate(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  Argument intent = request.getArgument("UPDATE_INTENT");
  rb.add(new RegisterUpdate().setIntent(intent.getName()));
  return rb.build();
}
Dialogflow JSON
{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "PLACEHOLDER"
            }
          }
        ]
      },
      "userStorage": "{\"data\":{}}",
      "systemIntent": {
        "intent": "actions.intent.REGISTER_UPDATE",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValueSpec",
          "intent": "update_of_the_day",
          "triggerContext": {
            "timeContext": {
              "frequency": "DAILY"
            }
          }
        }
      }
    }
  },
  "outputContexts": [
    {
      "name": "/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{}"
      }
    }
  ]
}
Actions SDK JSON
{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "PLACEHOLDER"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.REGISTER_UPDATE",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValueSpec",
            "intent": "update_of_the_day",
            "triggerContext": {
              "timeContext": {
                "frequency": "DAILY"
              }
            }
          }
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}

有料会員登録の最終処理

アクションを Dialogflow で作成している場合は、次の操作を行う必要があります。

  1. 別のインテント(finish_update_setup など)をもう 1 つ追加し、イベントとして actions_intent_REGISTER_UPDATE を設定します。
  2. インテントのアクションfinish.update.setup に設定します。

Webhook から有料会員登録の最終処理を行うには:

Node.js
app.intent('finish_update_setup', (conv, params, registered) => {
  if (registered && registered.status === 'OK') {
    conv.close(`Ok, I'll start giving you daily updates.`);
  } else {
    conv.close(`Ok, I won't give you daily updates.`);
  }
});
Java
public ActionResponse finishUpdateSetup(ActionRequest request) {
  ResponseBuilder responseBuilder = getResponseBuilder(request);
  if (request.isUpdateRegistered()) {
    responseBuilder.add("Ok, I'll start giving you daily updates.").endConversation();
  } else {
    responseBuilder.add("Ok, I won't give you daily updates.").endConversation();
  }
  return responseBuilder.build();
}
      
Dialogflow JSON
{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "finish_update_setup",
      "displayName": "finish_update_setup"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": [
            {
              "name": "REGISTER_UPDATE",
              "extension": {
                "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValue",
                "status": "OK"
              }
            },
            {
              "name": "text",
              "rawText": "11:30am",
              "textValue": "11:30am"
            }
          ]
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}
Actions SDK JSON
{
  "user": {},
  "device": {},
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "conversation": {},
  "inputs": [
    {
      "rawInputs": [],
      "intent": "actions.intent.REGISTER_UPDATE",
      "arguments": [
        {
          "name": "REGISTER_UPDATE",
          "extension": {
            "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValue",
            "status": "OK"
          }
        },
        {
          "name": "text",
          "rawText": "11:30am",
          "textValue": "11:30am"
        }
      ]
    }
  ],
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

毎日の通知のカスタマイズ

毎日の通知は、各ユーザーに合わせたエクスペリエンスを提供するようカスタマイズできます。毎日の通知をカスタマイズするには、ユーザーをオプトインする際に使用した引数値を指定します。この値は、通知によってトリガーされたインテントに渡されます。

パラメータの定義

ここでは、パラメータの設定方法について説明します。アプリでは、さまざまな方法を使用できます。たとえば、ユーザーがリストまたはカルーセルから選択できるようにすることもできます。

Dialogflow
  1. Dialogflow コンソールでアプリを開き、Entities ページに移動します。
  2. [エンティティの作成] をクリックして、エンティティに名前を設定します。例: tipCategory
  3. パラメータに関連のあるエントリと同義語を追加します。たとえば、Actions on Google のヒントサンプルのカテゴリの場合、tools、development などを追加します。
  4. [保存] をクリックして、通知からトリガーするインテントを開きます。たとえば、Actions on Google のヒントサンプルの場合は、tell_tip インテントを開きます。
  5. [アクションとパラメータ] セクションで、イベントとして actions.intent.CONFIGURE_UPDATES を設定します。同じセクションで、選択した名前のパラメータを追加し、タイプを以前に作成したエンティティに設定します。たとえば、Actions on Google Update API のサンプルの場合、パラメータの名前は category、エンティティは tip-category です。
  6. 有料会員登録の設定の説明に従って、CONFIGURE_UPDATES インテントの処理に定義したインテントに移動します。Actions on Google のヒントサンプルの場合、setup_update インテントです。
  7. [アクションとパラメータ] セクションで、選択した名前の必須パラメータを追加し、タイプを以前に作成したエンティティに設定します。

次のスニペットは、クライアント ライブラリを使用してパラメータの値を読み取り、登録リクエストで使用する方法を示しています。

Node.js
app.intent('setup_update', (conv) => {
  conv.ask(new RegisterUpdate({
    intent: 'update_of_the_day',
    arguments: [
      {
        name: 'category',
        textValue: 'Daily_lowest_temperature',
      },
    ],
    frequency: 'DAILY',
  }));
});
Java
@ForIntent("setup_update")
public ActionResponse setupUpdate2(ActionRequest request) {
  List<Argument> args =
      Arrays.asList(
          new Argument()
              .setName("category")
              .setTextValue(request.getParameter("category").toString()));
  return getResponseBuilder(request)
      .add(new RegisterUpdate().setIntent("intent_name").setArguments(args).setFrequency("DAILY"))
      .build();
}
Dialogflow JSON
{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "PLACEHOLDER"
            }
          }
        ]
      },
      "userStorage": "{\"data\":{}}",
      "systemIntent": {
        "intent": "actions.intent.REGISTER_UPDATE",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValueSpec",
          "intent": "update_of_the_day",
          "arguments": [
            {
              "name": "category",
              "textValue": "Daily_lowest_temperature"
            }
          ],
          "triggerContext": {
            "timeContext": {
              "frequency": "DAILY"
            }
          }
        }
      }
    }
  },
  "outputContexts": [
    {
      "name": "/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{}"
      }
    }
  ]
}
Action SDK

actions_intent_CONFIGURE_UPDATES を処理する関数でパラメータの値を要求する必要があります。この値は、次回の登録時に使用されます。次のスニペットは、この処理を Node.js と Actions on Google のクライアント ライブラリで行った場合の例です。

Actions SDK Node.js
app.intent('actions.intent.TEXT', (conv) => {
  if (conv.input.raw === 'Send daily') {
    conv.ask(new RegisterUpdate({
      intent: 'update_of_the_day',
      arguments: [
        {
          name: 'category',
          textValue: 'Daily_lowest_temperature',
        },
      ],
      frequency: 'DAILY',
    }));
  }
});
Actions SDK Java
@ForIntent("actions.intent.CONFIGURE_UPDATES")
public ActionResponse configureUpdatesActionsSdk(ActionRequest request) {
  List<Argument> args =
      Arrays.asList(
          new Argument()
              .setName("category")
              .setTextValue(request.getParameter("category").toString()));
  return getResponseBuilder(request)
      .add(new RegisterUpdate().setIntent("intent_name").setArguments(args).setFrequency("DAILY"))
      .build();
}

@ForIntent("actions.intent.TEXT")
public ActionResponse text(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  String input = request.getRawInput().getQuery();
  if (input.equals("DAILY_NOTIFICATION_SUGGESTION")) {
    rb.add("For which category do you want to receive daily updates?");
  } else {
    rb.add("Sorry, I didn't get that. Please try again later").endConversation();
  }
  return rb.build();
}
Actions SDK JSON
{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "PLACEHOLDER"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.REGISTER_UPDATE",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.RegisterUpdateValueSpec",
            "intent": "update_of_the_day",
            "arguments": [
              {
                "name": "category",
                "textValue": "Daily_lowest_temperature"
              }
            ],
            "triggerContext": {
              "timeContext": {
                "frequency": "DAILY"
              }
            }
          }
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}

毎日の通知をテストする

毎日の通知をテストする独自のアクションがない場合は、サンプルの設定と実行の手順に従い、Actions on Google ヒントサンプルのテスト バージョンをデプロイできます。