ユーザーが利用している場所にリーチして、アプリのエンゲージメントを高めます。Engage SDK を統合すると、コレクション、エンターテイメント スペース、Google Play ストアなど、複数のオンデバイス サーフェスで、パーソナライズされたおすすめや継続コンテンツをユーザーに直接配信できます。統合により、平均的な APK に追加されるサイズは 50 KB(圧縮後)未満で、ほとんどのアプリで 1 週間程度の開発期間が必要です。詳しくは、ビジネスサイトをご覧ください。
このガイドでは、デベロッパー パートナーが Engage コンテンツ サーフェスに食品コンテンツ(食品の注文、食品やレストランのレビューと検索、食事の定期購入、レシピ)を配信する手順を説明します。
統合の詳細
用語
この統合には、おすすめコンテンツ、注目コンテンツ、食料品のショッピング カート、食料品のショッピング リスト、再注文の 5 種類のクラスタがあります。
おすすめコンテンツ クラスタには、特定のデベロッパー パートナーが提供するパーソナライズされたおすすめの食品情報が表示されます。このおすすめコンテンツは、ユーザーに合わせてパーソナライズすることも、一般的なもの(新しいセール品など)にすることもできます。これを使用して、レシピや店舗、料理、食料品などを必要に応じて表示できます。
- おすすめコンテンツ クラスタは、
ProductEntity、StoreEntity、またはRecipeEntityのリスティングで構成できますが、異なるタイプのエンティティを組み合わせることはできません。 
図 :`ProductEntity`、`StoreEntity`、`RecipeEntity`。 (*UI は説明のみを目的としています) - おすすめコンテンツ クラスタは、
 注目コンテンツ クラスタでは、複数のデベロッパー パートナーが提供するエンティティのセレクションが 1 つの UI グループに表示されます。1 つの注目クラスタが UI の上部付近に、どのおすすめコンテンツ クラスタよりも優先されて表示されます。各デベロッパー パートナーは、注目コンテンツ クラスタ内で最大 10 個のエンティティをブロードキャストできます。
図 : `RecipeEntity` を含むおすすめクラスタ。 (*UI は説明のみを目的としています) 食料品のショッピング カートクラスタは、複数のデベロッパー パートナーが提供するショッピング カートのプレビューを、1 つの UI グループで表示し、ユーザーにカート内の未払いの商品の決済を済ませるよう促します。食料品のショッピング カートクラスタは 1 つ表示されます。
食料品のショッピング カートクラスタは、カート内の合計アイテム数を示す必要があります。また、ユーザーのカートに X 個のアイテムの画像を含めることもできます。
図: 1 つのパートナーの食料品のショッピング カートクラスタ。(*UI は説明のみを目的としています) 
食料品のショッピング リスト クラスタでは、複数のデベロッパー パートナーが提供する食品のショッピング リストのプレビューが、1 つの UI グループに表示されます。これにより、対応するアプリに移動してリストを更新したり、リストの商品を購入したりするようユーザーに促すことができます。食料品のショッピング リスト クラスタは 1 つ表示されます。
    図: 1 つのパートナーの食料品のショッピング リスト クラスタ。(*UI は説明のみを目的としています) 再注文クラスタでは、複数のデベロッパー パートナーの注文履歴のプレビューを 1 つの UI グループに表示し、ユーザーに再注文を促すことができます。再注文クラスタは 1 つ表示されます。
再注文クラスタは、ユーザーの注文履歴内の合計アイテム数を示すとともに、次のいずれかを含める必要もあります。
- ユーザーの注文履歴内の X 個のアイテムの画像。
 - ユーザーの注文履歴内の X 個のアイテムのラベル。
 
    図: 単一のパートナーの食料品の再注文クラスタ。(*UI は説明のみを目的としています) 
事前作業
最小 API レベル: 19
アプリに com.google.android.engage:engage-core ライブラリを追加します。
dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.5.2'
}
まとめ
この設計は、バインドされたサービスの実装に基づいています。
クライアントが公開できるデータには、各種クラスタに関する次の上限が適用されます。
| クラスタタイプ | クラスタ数の上限 | クラスタ内のエンティティ数の上限 | 
|---|---|---|
| おすすめコンテンツ クラスタ | 最大 7 個 | 最大 50 個(ProductEntity、RecipeEntity、または StoreEntity) | 
  
| 注目コンテンツ クラスタ | 最大 1 個 | 最大 20 個(ProductEntity、RecipeEntity、または StoreEntity) | 
  
| 食料品のショッピング カートクラスタ | 最大 1 個 | ShoppingCartEntity が最大 1 個 | 
  
| 食料品のショッピング リストクラスタ | 最大 1 個 | ShoppingListEntity が最大 1 個 | 
  
| 食料品の再注文クラスタ | 最大 1 個 | ReorderEntity が最大 1 個 | 
  
ステップ 1: エンティティ データを提供する
この SDK では、各アイテムタイプを表すさまざまなエンティティを定義しています。食品カテゴリでは、次のエンティティがサポートされています。
ProductEntityStoreEntityRecipeEntityFoodShoppingCartFoodShoppingListFoodReorderCluster
下記の表に、各タイプで使用可能な属性と、必須か任意かをまとめています。
ProductEntity
ProductEntity オブジェクトは、デベロッパー パートナーが公開する個々のアイテム(食料品、レストランの料理、プロモーションなど)を表します。
    ProductEntity の属性
    | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| ポスター画像 | 必須 | 画像を少なくとも 1 つ指定する必要があります。 | 詳しくは、画像の仕様をご覧ください。 | 
| アクション URI | 必須 | 
       商品の詳細を表示するアプリ内のページへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。 よくある質問をご覧ください  | 
    URI | 
| タイトル | 任意 | 商品名。 | 自由形式のテキスト 推奨テキストサイズは 90 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| 価格 - 現在 | 条件付きで必須 | 商品の現在の価格。 取り消し線が引かれた価格を指定する場合は必須です。  | 
    自由形式のテキスト | 
| 価格 - 取り消し線 | 任意 | エンティティの元の価格(UI では取り消し線が引かれます) | 自由形式のテキスト | 
| コールアウト | 任意 | 商品のプロモーション、イベント、または更新情報(利用可能な場合)をアピールするためのコールアウト | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| コールアウトの注意事項 | 任意 | コールアウトに関する注意事項のテキスト。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 評価(省略可)- 注: 評価はすべて Google の標準評価システムを使用して表示されます。 | |||
| 評価 - 最大値 | 任意 | 段階別評価の最高値。 現在の評価値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 現在の値 | 任意 | 段階別評価の現在の値。 評価の最高値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 件数 | 任意 | 商品の評価の件数。 注: アプリでユーザーに表示するカウントの形式を制御する場合は、このフィールドを指定します。簡潔な文字列を使用します。たとえば、カウントが 1,000,000 の場合は、小さいディスプレイ サイズでカウントが切り捨てられないように、1M などの省略形を使用することを検討してください。  | 
    文字列 | 
| Rating - Count Value | 任意 | 商品の評価の件数。 注: 表示の省略形のロジックを自分で処理しない場合は、このフィールドを指定します。[Count] と [Count Value] の両方が存在する場合、ユーザーには [Count] が表示されます。  | 
    Long | 
| DisplayTimeWindow(省略可)- コンテンツがサーフェスに表示される時間帯を設定します | |||
| 開始タイムスタンプ | 任意 | 
       このエポック タイムスタンプ以降にコンテンツがサーフェスに表示されます。 設定されていない場合、コンテンツはサーフェスに表示されます。  | 
    エポック タイムスタンプ(ミリ秒) | 
| 終了タイムスタンプ | 任意 | 
       このエポック タイムスタンプ以降は、コンテンツがサーフェスに表示されなくなります。 設定されていない場合、コンテンツはサーフェスに表示されます。  | 
    エポック タイムスタンプ(ミリ秒) | 
StoreEntity
StoreEntity オブジェクトは、レストランや食料品店など、デベロッパー パートナーが公開する個々の店舗を表します。
    StoreEntity の属性
    | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| ポスター画像 | 必須 | 画像を少なくとも 1 つ指定する必要があります。 | 詳しくは、画像の仕様をご覧ください。 | 
| アクション URI | 必須 | 店舗の詳細を表示するアプリ内のページへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。 よくある質問をご覧ください  | 
    URI | 
| タイトル | 任意 | 店舗の名前。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 場所 | 任意 | 店舗の場所。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| コールアウト | 任意 | 店舗のプロモーション、イベント、最新情報を告知するためのコールアウト(該当する場合)。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| コールアウトの注意事項 | 任意 | コールアウトに関する注意事項のテキスト。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 説明 | 任意 | 店舗の説明。 | 自由形式のテキスト 推奨テキストサイズは 90 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| カテゴリ | 任意 | 店舗のカテゴリ。飲食店の場合、料理の種類(「フレンチ」、「ニューアメリカン」、「ラーメン」、「高級料理」など)を指定できます。  | 
    自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 注: すべての評価は、Google の標準評価システムを使用して表示されます。 | |||
| 評価 - 最大値 | 任意 | 段階別評価の最高値。 現在の評価値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 現在の値 | 任意 | 段階別評価の現在の値。 評価の最高値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 件数 | 任意 | ショップの評価の件数。 注: アプリでユーザーへの表示方法を制御する場合は、このフィールドを指定します。ユーザーに表示できる簡潔な文字列を指定します。たとえば、カウントが 1,000,000 の場合は、1M などの略語を使用することを検討してください。そうすることで、表示サイズが小さい場合に切り捨てられるのを防ぐことができます。  | 
    文字列 | 
| Rating - Count Value | 任意 | ショップの評価の件数。 注: 表示の省略形のロジックを自分で処理したくない場合は、このフィールドを指定します。Count と Count Value の両方が存在する場合は、Count を使用してユーザーに表示します。  | 
    Long | 
RecipeEntity
RecipeEntity オブジェクトは、デベロッパー パートナーが公開するレシピアイテムを表します。
    RecipeEntity の属性
    | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| ポスター画像 | 必須 | 画像を少なくとも 1 つ指定する必要があります。 | 詳しくは、画像の仕様をご覧ください。 | 
| アクション URI | 必須 | レシピの詳細を表示するアプリ内のページへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。 よくある質問をご覧ください  | 
    URI | 
| タイトル | 任意 | レシピの名前。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 作者 | 任意 | レシピの作者。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 調理 / 準備時間 | 任意 | レシピの調理時間。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| コールアウト | 任意 | レシピのプロモーション、イベント、最新情報を告知するためのコールアウト(該当する場合)。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| カテゴリ | 任意 | レシピのカテゴリ。 | 自由形式のテキスト 推奨テキストサイズは 45 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 説明 | 任意 | レシピの説明。 | 自由形式のテキスト 推奨テキストサイズは 90 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| 注: すべての評価は、Google の標準評価システムを使用して表示されます。 | |||
| 評価 - 最大値 | 任意 | 段階別評価の最高値。 現在の評価値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 現在の値 | 任意 | 段階別評価の現在の値。 評価の最高値も指定する場合は必須です。  | 
    0.0 以上の数値。 | 
| 評価 - 件数 | 任意 | レシピの評価の件数。 注: アプリでユーザーへの表示方法を制御する場合は、このフィールドを指定します。ユーザーに表示できる簡潔な文字列を指定します。たとえば、カウントが 1,000,000 の場合は、1M などの略語を使用することを検討してください。そうすることで、表示サイズが小さい場合に切り捨てられるのを防ぐことができます。  | 
    文字列 | 
| Rating - Count Value | 任意 | レシピの評価の件数。 注: 表示の省略形のロジックを自分で処理したくない場合は、このフィールドを指定します。Count と Count Value の両方が存在する場合は、Count を使用してユーザーに表示します。  | 
    Long | 
FoodShoppingCart
        | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| アクション URI | 必須 | 
       パートナーのアプリ内のショッピング カートへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。よくある質問をご覧ください  | 
    URI | 
| アイテム数 | 必須 | ショッピング カート内のアイテムの数(商品以外も含む)。 たとえば、カートにオレンジが 3 個、リンゴが 1 個ある場合は、この数値は 4 になります。  | 
    1 以上の整数 | 
| タイトル | 任意 | カートのタイトル(カートなど)。 デベロッパーがタイトルを指定しない場合は、デフォルトの [カート] に設定されます。  | 
    自由形式のテキスト 推奨テキストサイズは 25 文字未満(長すぎるテキストは省略記号が表示されます)  | 
  
| アクション テキスト | 任意 | 
       ショッピング カート上のボタンの行動を促すフレーズのテキスト(ショッピング バッグなど)。 デベロッパーからアクション テキストが提供されていない場合、デフォルトで [カートを表示] が使用されます。 この属性はバージョン 1.1.0 以降でサポートされます。  | 
    文字列 | 
| カート画像 | 任意 | カート内の各商品の画像。 優先度順で最大 10 枚の画像を指定できます。実際に表示される画像の枚数は、デバイスのフォーム ファクタによって異なります。  | 
    詳しくは、画像の仕様をご覧ください。 | 
| アイテムラベル | 任意 | ショッピング リストのアイテムのラベルのリスト。 実際に表示されるラベルの数は、デバイスのフォーム ファクタによって異なります。  | 
    
       自由形式のテキストラベルのリスト 推奨テキストサイズは 20 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| DisplayTimeWindow(省略可)- コンテンツがサーフェスに表示される時間帯を設定します | |||
| 開始タイムスタンプ | 任意 | 
       このエポック タイムスタンプ以降にコンテンツがサーフェスに表示されます。 設定されていない場合、コンテンツはサーフェスに表示されます。  | 
    エポック タイムスタンプ(ミリ秒) | 
| 終了タイムスタンプ | 任意 | 
       このエポック タイムスタンプ以降は、コンテンツがサーフェスに表示されなくなります。 設定されていない場合、コンテンツはサーフェスに表示されます。  | 
    エポック タイムスタンプ(ミリ秒) | 
FoodShoppingList
        | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| アクション URI | 必須 | 
       パートナーのアプリ内のショッピング リストへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。 よくある質問をご覧ください  | 
    URI | 
| アイテム数 | 必須 | ショッピング リストのアイテム数。 | 1 以上の整数 | 
| タイトル | 任意 | 
       リストのタイトル(食料品リストなど)。 デベロッパーがタイトルを指定しない場合は、デフォルトの [ショッピング リスト] に設定されます。  | 
    自由形式のテキスト 推奨テキストサイズは 25 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| アイテムラベル | 必須 | ショッピング リストのアイテムのラベルのリスト。 少なくとも 1 つのラベルを指定する必要があり、優先度順に最大 10 個のラベルを指定できます。実際に表示されるラベルの数は、デバイスのフォーム ファクタによって異なります。  | 
    自由形式のテキストラベルのリスト 推奨テキストサイズは 20 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
FoodReorderCluster
        | 属性 | 必須 / 任意 | 説明 | 形式 | 
|---|---|---|---|
| アクション URI | 必須 | 
       パートナーのアプリ内の再注文へのディープリンク。 注: アトリビューションにはディープリンクを使用できます。 よくある質問をご覧ください  | 
    URI | 
| アクション テキスト | 任意 | 
       再注文のボタンの行動を促すフレーズのテキスト(もう一度注文など)。 デベロッパーからアクション テキストが提供されていない場合、デフォルトで再注文が使用されます。 この属性はバージョン 1.1.0 以降でサポートされます。  | 
    文字列 | 
| アイテム数 | 必須 | 
       前回の注文におけるアイテムの数(商品以外も含む)。 たとえば、前回の注文内容が S サイズのコーヒー 3 杯、クロワッサン 1 つの場合、この数は 4 になります。  | 
    1 以上の整数 | 
| タイトル | 必須 | 再注文アイテムのタイトル。 | 自由形式のテキスト 推奨テキストサイズは 40 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| アイテムラベル | 任意 (指定しない場合は、ポスター画像を指定する必要があります)。  | 
    前回の注文のアイテムラベルのリスト。 優先度順で最大 10 個のラベルを指定できます。実際に表示されるラベルの数は、デバイスのフォーム ファクタによって異なります。  | 
    自由形式のテキストのリスト ラベルあたりの推奨テキストサイズは 20 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| ポスター画像 | 任意 (指定しない場合は、商品ラベルを指定する必要があります)  | 
    前回の注文に含まれる商品アイテムの画像。 優先度順で最大 10 枚の画像を指定できます。実際に表示される画像の枚数は、デバイスのフォーム ファクタによって異なります。  | 
    詳しくは、画像の仕様をご覧ください。 | 
画像の仕様
画像アセットの要件となる仕様は次のとおりです。
| アスペクト比 | 最小ピクセル数 | 推奨ピクセル数 | 
|---|---|---|
スクエア(1×1) 推奨  | 
    300×300 | 1200×1200 | 
| 横向き(1.91×1) | 600×314 | 1200×628 | 
| 縦向き(4×5) | 480×600 | 960×1200 | 
ファイル形式
PNG、JPG、静止 GIF、WebP
最大ファイルサイズ
5120 KB
その他の推奨事項
- 画像のセーフエリア: 重要なコンテンツは、画像の中央 80% の範囲内に配置してください。
 - 透明な背景を使用して、ダークモードとライトモードの設定で画像が適切に表示されるようにします。
 
ステップ 2: クラスタデータを提供する
WorkManager などを使用して、コンテンツ公開ジョブをバックグラウンドで実行し、定期的に、またはイベントごとに(ユーザーがアプリを開いたときや、カートに商品を追加したときなど)スケジュールを設定することをおすすめします。
AppEngageFoodClient は、食品クラスタの公開を行います。
クライアントでクラスタを公開するには、次の API があります。
isServiceAvailablepublishRecommendationClusterspublishFeaturedClusterpublishFoodShoppingCartpublishFoodShoppingListpublishReorderClusterpublishUserAccountManagementRequestupdatePublishStatusdeleteRecommendationsClustersdeleteFeaturedClusterdeleteFoodShoppingCartClusterdeleteFoodShoppingListClusterdeleteReorderClusterdeleteUserManagementClusterdeleteClusters
isServiceAvailable
この API は、サービスを統合に使用できるかどうか、コンテンツをデバイスに表示できるかどうかを確認するために使用されます。
Kotlin
client.isServiceAvailable.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Handle IPC call success
        if(task.result) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
}
Java
client.isServiceAvailable().addOnCompleteListener(task - > {
    if (task.isSuccessful()) {
        // Handle success
        if(task.getResult()) {
          // Service is available on the device, proceed with content publish
          // calls.
        } else {
          // Service is not available, no further action is needed.
        }
    } else {
      // The IPC call itself fails, proceed with error handling logic here,
      // such as retry.
    }
});
publishRecommendationClusters
この API は、RecommendationCluster オブジェクトのリストを公開するために使用されます。
RecommendationCluster オブジェクトには次の属性があります。
| 属性 | 必須 / 任意 | 説明 | 
|---|---|---|
| ProductEntity、StoreEntity、RecipeEntity のリスト | 必須 | このおすすめコンテンツ クラスタのおすすめコンテンツを構成するエンティティのリスト。単一クラスタ内のエンティティは、同じタイプにする必要があります。 | 
| タイトル | 必須 | おすすめコンテンツ クラスタのタイトル(感謝祭メニュー大幅割引など)。 推奨テキストサイズは 25 文字未満(テキストが長すぎると省略記号が表示されます)  | 
  
| 字幕 | 任意 | おすすめコンテンツ クラスタのサブタイトル。 | 
| アクション URI | 任意 | 
       おすすめコンテンツの完全なリストをユーザーに表示するパートナー アプリ内のページへのディープリンク。 注: アトリビューションにはディープリンクを使用できます。よくある質問をご覧ください  | 
  
Kotlin
client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Big savings on Thanksgiving menu")
                        .build())
                .build())
Java
client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Big savings on Thanksgiving menu")
                        .build())
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- 既存のおすすめコンテンツ クラスタのデータがすべて削除されます。
 - リクエストのデータが解析され、新しいおすすめコンテンツ クラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
publishFeaturedCluster
この API は、FeaturedCluster オブジェクトを公開するために使用されます。
Kotlin
client.publishFeaturedCluster(
            PublishFeaturedClusterRequest.Builder()
                .setFeaturedCluster(
                    FeaturedCluster.Builder()
                        ...
                        .build())
                .build())
Java
client.publishFeaturedCluster(
            new PublishFeaturedClusterRequest.Builder()
                .setFeaturedCluster(
                    new FeaturedCluster.Builder()
                        ...
                        .build())
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の 
FeaturedClusterデータが削除されます。 - リクエストのデータが解析されて、更新された注目コンテンツ クラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
publishFoodShoppingCart
この API は、FoodShoppingCart オブジェクトを公開するために使用されます。
Kotlin
client.publishFoodShoppingCart(
            PublishFoodShoppingCartClusterRequest.Builder()
                .setShoppingCart(
                    FoodShoppingCart.Builder()
                        ...
                        .build())
                .build())
Java
client.publishFoodShoppingCart(
            new PublishFoodShoppingCartClusterRequest.Builder()
                .setShoppingCart(
                    new FoodShoppingCart.Builder()
                        ...
                        .build())
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の 
FoodShoppingCartデータが削除されます。 - リクエストのデータが解析されて、更新されたショッピング カートクラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
publishFoodShoppingList
この API は、FoodShoppingList オブジェクトを公開するために使用されます。
Kotlin
client.publishFoodShoppingList(
            PublishFoodShoppingListRequest.Builder()
                .setFoodShoppingList(
                    FoodShoppingListEntity.Builder()
                        ...
                        .build())
                .build())
Java
client.publishFoodShoppingList(
            new PublishFoodShoppingListRequest.Builder()
                .setFoodShoppingList(
                    new FoodShoppingListEntity.Builder()
                        ...
                        .build())
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の 
FoodShoppingListデータが削除されます。 - リクエストのデータが解析されて、更新されたショッピング リストクラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
publishReorderCluster
この API は、FoodReorderCluster オブジェクトを公開するために使用されます。
Kotlin
client.publishReorderCluster(
            PublishReorderClusterRequest.Builder()
                .setReorderCluster(
                    FoodReorderCluster.Builder()
                        ...
                        .build())
                .build())
Java
client.publishReorderCluster(
            new PublishReorderClusterRequest.Builder()
                .setReorderCluster(
                    new FoodReorderCluster.Builder()
                        ...
                        .build())
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の 
FoodReorderClusterデータが削除されます。 - リクエストのデータが解析されて、更新された再注文クラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
publishUserAccountManagementRequest
この API は、ログインカードを公開するために使用されます。ログイン アクションにより、ユーザーをアプリのログインページに誘導し、アプリでコンテンツを公開(または、よりパーソナライズされたコンテンツを提供)できるようにします。
次のメタデータはログインカードの一部です。
| 属性 | 必須 / 任意 | 説明 | 
|---|---|---|
| アクション URI | 必須 | アクションへのディープリンク(アプリのログインページへの移動など) | 
| 画像 | 省略可 - 指定しない場合は、タイトルを指定する必要があります | 
       カードに表示される画像 解像度 1264×712 でアスペクト比 16×9 の画像  | 
  
| タイトル | 省略可 - 指定しない場合は、画像を指定する必要があります | カード上のタイトル | 
| アクション テキスト | 任意 | 行動を促すフレーズ(ログインなど)で表示されるテキスト | 
| 字幕 | 任意 | カードの字幕(省略可) | 
Kotlin
var SIGN_IN_CARD_ENTITY =
      SignInCardEntity.Builder()
          .addPosterImage(
              Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build()
client.publishUserAccountManagementRequest(
            PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());
Java
SignInCardEntity SIGN_IN_CARD_ENTITY =
      new SignInCardEntity.Builder()
          .addPosterImage(
              new Image.Builder()
                  .setImageUri(Uri.parse("http://www.x.com/image.png"))
                  .setImageHeightInPixel(500)
                  .setImageWidthInPixel(500)
                  .build())
          .setActionText("Sign In")
          .setActionUri(Uri.parse("http://xx.com/signin"))
          .build();
client.publishUserAccountManagementRequest(
            new PublishUserAccountManagementRequest.Builder()
                .setSignInCardEntity(SIGN_IN_CARD_ENTITY)
                .build());
サービスがリクエストを受信すると、1 つのトランザクション内で次のアクションが行われます。
- デベロッパー パートナーが提供した既存の 
UserAccountManagementClusterデータが削除されます。 - リクエストのデータが解析されて、更新済みのユーザー アカウント管理クラスタに保存されます。
 
エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
updatePublishStatus
社内の業務上の理由でいずれのクラスタも公開されていない場合は、updatePublishStatus API を使用して公開ステータスを更新することを強くおすすめします。公開ステータスの更新が必要な理由は:
- ダッシュボードではこのステータスの値に基づいて、統合の健全性などの指標が追加されるため、コンテンツが公開されている(STATUS == PUBLISHED)場合でも公開ステータスを明示する必要があります。
 - コンテンツは未公開でも統合ステータスが壊れていなければ(STATUS == NOT_PUBLISHED)、アプリの健全性ダッシュボードでアラートがトリガーされるのを回避できます。未公開ステータスを明示することで、プロバイダにとって想定済みの理由からコンテンツが非公開であるという確認がとれます。
 - デベロッパーは、データの公開状況に関する情報を提供できます。
 - Google が、ステータス コードを使用してアプリ内で特定のアクション(コンテンツの表示や制覇など)を行うようユーザーに促すことがあります。
 
利用可能な公開ステータス コードは、次のとおりです。
// Content is published
AppEngagePublishStatusCode.PUBLISHED,
// Content is not published as user is not signed in
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN,
// Content is not published as user is not subscribed
AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SUBSCRIPTION,
// Content is not published as user location is ineligible
AppEngagePublishStatusCode.NOT_PUBLISHED_INELIGIBLE_LOCATION,
// Content is not published as there is no eligible content
AppEngagePublishStatusCode.NOT_PUBLISHED_NO_ELIGIBLE_CONTENT,
// Content is not published as the feature is disabled by the client
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_FEATURE_DISABLED_BY_CLIENT,
// Content is not published as the feature due to a client error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_CLIENT_ERROR,
// Content is not published as the feature due to a service error
// Available in v1.3.1
AppEngagePublishStatusCode.NOT_PUBLISHED_SERVICE_ERROR,
// Content is not published due to some other reason
// Reach out to engage-developers@ before using this enum.
AppEngagePublishStatusCode.NOT_PUBLISHED_OTHER
ユーザーがログインしていないためにコンテンツが公開されていない場合、Google は、ログインカードを公開することをおすすめします。なんらかの理由でプロバイダがログインカードを公開できない場合は、ステータス コード NOT_PUBLISHED_REQUIRES_SIGN_IN を使用して、updatePublishStatus API を呼び出すことをおすすめします。
Kotlin
client.updatePublishStatus(
   PublishStatusRequest.Builder()
     .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
     .build())
Java
client.updatePublishStatus(
    new PublishStatusRequest.Builder()
        .setStatusCode(AppEngagePublishStatusCode.NOT_PUBLISHED_REQUIRES_SIGN_IN)
        .build());
deleteRecommendationClusters
この API は、おすすめコンテンツ クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteRecommendationClusters()
Java
client.deleteRecommendationClusters();
サービスがリクエストを受信すると、おすすめコンテンツ クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteFeaturedCluster
この API は、注目コンテンツ クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteFeaturedCluster()
Java
client.deleteFeaturedCluster();
サービスがリクエストを受信すると、注目コンテンツ クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteFoodShoppingCartCluster
この API は、食料品ショッピング カート クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteFoodShoppingCartCluster()
Java
client.deleteFoodShoppingCartCluster();
サービスがリクエストを受信すると、食品 ショッピング カート クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteFoodShoppingListCluster
この API は、食料品ショッピング リスト クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteFoodShoppingListCluster()
Java
client.deleteFoodShoppingListCluster();
サービスがリクエストを受信すると、食品 ショッピング リスト クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteReorderCluster
この API は食料品再注文クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteReorderCluster()
Java
client.deleteReorderCluster();
サービスがリクエストを受信すると、再注文クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteUserManagementCluster
この API は、ユーザー アカウント管理クラスタのコンテンツを削除するために使用されます。
Kotlin
client.deleteUserManagementCluster()
Java
client.deleteUserManagementCluster();
サービスがリクエストを受信すると、ユーザー アカウント管理クラスタから既存のデータが削除されます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
deleteClusters
この API は、特定のクラスタタイプのコンテンツを削除するために使用されます。
Kotlin
client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_FEATURED)
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      ...
      .build())
Java
client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_FEATURED)
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                ...
                .build());
サービスがリクエストを受信すると、指定したクラスタタイプに一致するすべてのクラスタから既存のデータが削除されます。クライアントは、1 つまたは複数のクラスタタイプを渡すこともできます。エラーが発生した場合は、リクエスト全体が拒否され、それまでの状態が維持されます。
エラー処理
publish API のタスク結果をリッスンすることで、フォローアップ処理を行い、正常なタスクを復元して再送信できるようにすることを強くおすすめします。
client.publishRecommendationClusters(
              new PublishRecommendationClustersRequest.Builder()
                  .addRecommendationCluster(...)
                  .build())
          .addOnCompleteListener(
              task -> {
                if (task.isSuccessful()) {
                  // do something
                } else {
                  Exception exception = task.getException();
                  if (exception instanceof AppEngageException) {
                    @AppEngageErrorCode
                    int errorCode = ((AppEngageException) exception).getErrorCode();
                    if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
                      // do something
                    }
                  }
                }
              });
このエラーは AppEngageException として返されます。原因はエラーコードとして含まれます。
| エラーコード | エラー名 | 注 | 
|---|---|---|
1 | 
    SERVICE_NOT_FOUND | 
    そのデバイスではこのサービスを利用できません。 | 
2 | 
    SERVICE_NOT_AVAILABLE | 
    サービスをそのデバイスで利用することはできますが、呼び出し時には利用できません(明示的に無効になっている場合など)。 | 
3 | 
    SERVICE_CALL_EXECUTION_FAILURE | 
    スレッドに関する問題が発生し、タスクを実行できませんでした。その場合は再試行できます。 | 
4 | 
    SERVICE_CALL_PERMISSION_DENIED | 
    呼び出し元がサービスの呼び出しを行うことができません。 | 
5 | 
    SERVICE_CALL_INVALID_ARGUMENT | 
    リクエストに無効なデータが含まれています(クラスタ数が許容数を超えているなど)。 | 
6 | 
    SERVICE_CALL_INTERNAL | 
    サービス側でエラーが発生しています。 | 
7 | 
    SERVICE_CALL_RESOURCE_EXHAUSTED | 
    サービスの呼び出し頻度が高すぎます。 | 
ステップ 3: ブロードキャスト インテントを処理する
ジョブを介してコンテンツ公開 API の呼び出しを行うだけでなく、コンテンツ公開のリクエストを受信するために BroadcastReceiver を設定する必要もあります。
ブロードキャスト インテントの主目的は、アプリの再有効化とデータ同期の強制です。ブロードキャスト インテントは、頻繁に送信されることを想定した設計にはなっていません。Engage のサービスが、コンテンツが古い可能性がある(1 週間前など)と判断した場合にのみトリガーされます。そうすることで、アプリが長時間実行されていない場合でも、より確実にユーザーに新しいコンテンツを提供できます。
BroadcastReceiver は、次の 2 つの方法で設定する必要があります。
Context.registerReceiver()を使用して、BroadcastReceiverクラスのインスタンスを動的に登録します。これにより、メモリ内でまだアクティブになっているアプリからの通信が可能になります。
Kotlin
class AppEngageBroadcastReceiver : BroadcastReceiver(){
  // Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION
  // broadcast is received
  // Trigger featured cluster publish when PUBLISH_FEATURED broadcast is
  // received
  // Trigger food shopping cart cluster publish when PUBLISH_FOOD_SHOPPING_CART broadcast
  // is received
  // Trigger food shopping list cluster publish when PUBLISH_FOOD_SHOPPING_LIST broadcast
  // is received
  // Trigger reorder cluster publish when PUBLISH_REORDER_CLUSTER broadcast is
  // received
}
fun registerBroadcastReceivers(context: Context){
  var  context = context
  context = context.applicationContext
// Register Recommendation Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_RECOMMENDATION),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
// Register Featured Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FEATURED),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
// Register food Shopping Cart Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FOOD_SHOPPING_CART),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
// Register food Shopping List Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FOOD_SHOPPING_LIST),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
// Register Reorder Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_REORDER_CLUSTER),
                           com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                           /*scheduler=*/null)
}
Java
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION broadcast
// is received
// Trigger featured cluster publish when PUBLISH_FEATURED broadcast is received
// Trigger food shopping cart cluster publish when PUBLISH_FOOD_SHOPPING_CART broadcast is
// received
// Trigger food shopping list cluster publish when PUBLISH_FOOD_SHOPPING_LIST broadcast is
// received
// Trigger reorder cluster publish when PUBLISH_REORDER_CLUSTER broadcast is
// received
}
public static void registerBroadcastReceivers(Context context) {
context = context.getApplicationContext();
// Register Recommendation Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_RECOMMENDATION),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);
// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);
// Register food Shopping Cart Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_FOOD_SHOPPING_CART),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);
// Register food Shopping List Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_FOOD_SHOPPING_LIST),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);
// Register Reorder Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
                         new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_REORDER_CLUSTER),
                         com.google.android.engage.service.BroadcastReceiverPermissions.BROADCAST_REQUEST_DATA_PUBLISH_PERMISSION,
                         /*scheduler=*/null);
}
AndroidManifest.xmlファイルで<receiver>タグを使用して、実装を静的に宣言します。これにより、アプリが実行されていないときでもブロードキャスト インテントを受信し、コンテンツを公開できるようになります。
<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      android:permission="com.google.android.engage.REQUEST_ENGAGE_DATA"
      android:exported="true"
      android:enabled="true">
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_RECOMMENDATION" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.PUBLISH_FEATURED" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.food.PUBLISH_FOOD_SHOPPING_CART" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.food.PUBLISH_FOOD_SHOPPING_LIST" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.food.PUBLISH_REORDER_CLUSTER" />
      </intent-filter>
   </receiver>
</application>
サービスによって次のインテントが送信されます。
com.google.android.engage.action.PUBLISH_RECOMMENDATIONこのインテントを受信したときに、publishRecommendationClustersの呼び出しを開始することをおすすめします。com.google.android.engage.action.PUBLISH_FEATUREDこのインテントを受信したときに、publishFeaturedClusterの呼び出しを開始することをおすすめします。com.google.android.engage.action.food.PUBLISH_FOOD_SHOPPING_CARTこのインテントを受信したときに、publishFoodShoppingCartの呼び出しを開始することをおすすめします。com.google.android.engage.action.food.PUBLISH_FOOD_SHOPPING_LISTこのインテントを受信したときに、publishFoodShoppingListの呼び出しを開始することをおすすめします。com.google.android.engage.action.food.PUBLISH_REORDER_CLUSTERこのインテントを受信したときに、publishReorderClusterの呼び出しを開始することをおすすめします。
統合ワークフロー
統合完了後に検証を行う手順のガイドについては、デベロッパー向けの Engage 統合ワークフローをご覧ください。
よくある質問
よくある質問については、Engage SDK に関するよくある質問をご覧ください。
お問い合わせ
統合プロセスについてご不明な点がありましたら、engage-developers@google.com までお問い合わせください。担当チームができる限り速やかに返信いたします。
次のステップ
この統合が完了した後のステップは次のとおりです。
- Google によるテストの準備が整った統合済みの APK を添付して、
engage-developers@google.comにメールを送信します。 - Google が社内で検証とレビューを行い、統合が適切に機能するか確認します。変更が必要な場合は、Google から詳細をご連絡いたします。
 - テストが完了し、変更の必要もない場合は、更新された統合済みの APK を Google Play ストアに公開できるようになったことを Google からお知らせします。
 - 更新された APK が Google Play ストアに公開されていることを Google が確認したら、おすすめコンテンツ、注目コンテンツ、ショッピング カート、ショッピング リスト、再注文の各クラスタが公開され、ユーザーに表示されます。