Engage SDK Shopping:第三方技术集成说明

Google 将打造一种设备端 surface,该 surface 可按行业整理用户的应用,并且支持全新的沉浸式体验,使用户能够以个性化的方式消费和发现应用内容。这种全屏体验将为开发者合作伙伴提供机会,使其能够通过自己的应用以外的专用渠道展示最优质的富媒体内容。

本指南包含面向开发者合作伙伴的说明,介绍了如何使用 Engage SDK 填充这个新的途径区域和现有 Google 途径(例如 Entertainment Space),以便集成购物内容。

集成专区详情

术语

此集成包含以下五种集群类型:推荐精选购物车购物清单重新订购购物订单跟踪

  • 推荐集群用于显示来自单个开发者合作伙伴的个性化购物建议。此类推荐既可以针对用户个性化定制,也可以一般化(例如,热门商品)。您可以根据自己的需要,利用此类集群显示商品、活动、促销、推广、订阅。

    您的推荐将采用如下结构:

    • 推荐集群:一个界面视图,其中包含来自同一开发者合作伙伴的一组推荐。

    • ShoppingEntity:代表集群中的单个项的对象。

  • 精选集群用于在一个界面分组中展示来自多个开发者合作伙伴的精选实体。精选集群只有一个,并将显示在界面顶部附近,其展示位置的优先级高于所有推荐集群。每个开发者合作伙伴最多可以在精选集群中广播 10 个实体。

  • 购物车集群用于在一个界面分组中显示来自多个开发者合作伙伴的购物车预览,以促使用户完成购物车中的未付款交易。购物车集群只有一个,并将显示在界面顶部附近,其展示位置的优先级高于所有推荐集群。每个开发者合作伙伴最多可以在购物车集群中广播 3 个 ShoppingCart 实例。

    您的购物车将采用以下结构:

    • 购物车集群:一个界面视图,包含来自多个开发者合作伙伴的一组购物车预览。

    • 购物车:一个对象,代表单个开发者合作伙伴的购物车预览,并将显示在购物车集群中。ShoppingCart 必须显示购物车中项的总数量,还可以包含用户购物车中某些项的图片。

  • 购物清单集群用于在一个界面分组中显示来自多个开发者合作伙伴的购物清单预览,以提示用户返回相应应用更新清单并完成其中的购买交易。购物清单集群只有 1 个。

  • 重新订购集群用于在一个界面分组中显示来自多个开发者合作伙伴的先前订单预览,以提示用户重新订购。 重新订购集群只有一个。

    • 重新订购集群必须显示用户先前订单中项的总数量,并且还必须包含以下任一项:

      • 用户先前订单中的 X 个项的图片。
      • 用户先前订单中的 X 个项的标签。
  • 购物订单跟踪集群用于在一个界面分组中显示来自多个开发者合作伙伴的待处理或最近完成的购物订单预览,以便用户跟踪他们的订单。

    ShoppingOrderTracking 集群只有一个,并将显示在界面顶部附近,其展示位置的优先级高于所有推荐集群。每个开发者合作伙伴都可以在购物订单跟踪集群中广播多个 ShoppingOrderTrackingEntity 商品。

    • 您的 ShoppingOrderTrackingCluster 将采用以下结构:

      • ShoppingOrderTracking 集群:一个界面视图,包含来自多个开发者合作伙伴的一组订单跟踪预览
      • ShoppingOrderTrackingEntity:一个对象,代表单个开发者合作伙伴的购物订单跟踪预览,并将显示在购物订单跟踪集群中。ShoppingOrderTrackingEntity 必须显示订单状态和订单时间。我们强烈建议您为 ShoppingOrderTrackingEntity 填充预计送货时间,因为系统会在提供该信息时向用户显示该信息。

准备工作

最低 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'
}

如需了解详情,请参阅 Android 11 中的软件包可见性

摘要

设计的前提是已实现了绑定服务

对于不同的集群类型,客户端可以发布的数据受以下限制:

集群类型 集群限制 集群中的实体数上限
推荐集群 最多 5 个 最多 25 个 ShoppingEntity
精选集群 最多 1 个 最多 10 个 ShoppingEntity
购物车集群 最多 1 个 最多 3 个 ShoppingCart

只有每个商家都有单独购物车的应用才应支持多个购物车。

购物清单集群 最多 1 个 最多 1 个 ShoppingListEntity
购物重新订购集群 最多 1 个 最多 1 个 ReorderEntity
购物订单跟踪集群 最多 3 个 最多 3 个 ShoppingOrderTrackingEntity

第 1 步:提供实体数据

SDK 定义了不同的实体来代表每种内容类型。购物类别支持以下实体:

  1. ShoppingEntity
  2. ShoppingCart
  3. ShoppingList
  4. Reorder
  5. ShoppingOrderTracking

下面的图表列出了每种类型的可用属性和相关要求。

ShoppingEntity

ShoppingEntity 对象代表开发者合作伙伴想要发布的商品、促销、特惠、订阅或活动。

ShoppingEntity
属性 要求 说明 格式
海报图片 必需 必须提供至少一张图片。 如需相关指导,请参阅图片规范
操作 URI 必需

指向应用中用于显示相应实体详细信息的页面的深层链接。

注意:您可以使用深层链接进行归因。 请参阅此处的常见问题解答

URI
标题 可选 实体的名称。

自由文本

建议的文本大小:少于 90 个字符(如果文本过长,可能会显示省略号)

价格 - 当前 在特定条件下必需

实体的当前价格。

如果提供带删除线的价格,则必须提供

自由文本
价格 - 删除线 可选 实体的原始价格,在界面中带有删除线。 自由文本
宣传信息 可选 用于展示实体的促销、活动或最新动态的宣传信息(如果有)。

自由文本

建议的文本大小:少于 45 个字符(如果文本过长,可能会显示省略号)

宣传信息附属细则 可选 宣传信息的附属细则文本。

自由文本

建议的文本大小:少于 45 个字符(如果文本过长,可能会显示省略号)

评分(可选)- 注意:所有评分都将依照我们的标准星级分级制度显示。
评分 - 最大值 可选

评分量表的最大值。

如果同时提供当前评分值,则必须提供

数值 >= 0.0
评分 - 当前值 可选

评分量表的当前值。

如果同时提供最大评分值,则必须提供

数值 >= 0.0
评分 - 数量 可选

实体评分的计数。

注意:如果您的应用可控制向用户显示计数的方式,请提供此字段。使用简洁的字符串。 例如,如果计数为 1,000,000,请考虑使用 1M 之类的缩写,这样在屏幕尺寸较小的屏幕上,计数就不会被截断。

字符串
评分 - 计数值 可选

实体评分的计数。

注意:如果您没有自行处理显示缩写逻辑,请提供此字段。如果同时存在“计数”和“计数值”,系统会向用户显示“计数”。

DisplayTimeWindow(可选)- 设置要在界面上显示内容的时间范围
开始时间戳 可选

纪元时间戳,在其之后相应内容应显示在 surface 上。

如果未设置,相应内容将有资格显示在 surface 上。

纪元时间戳(以毫秒为单位)
结束时间戳 可选

纪元时间戳,在其之后相应内容不再显示在 surface 上。

如果未设置,相应内容将有资格显示在 surface 上。

纪元时间戳(以毫秒为单位)

ShoppingCart

属性 要求 说明 格式
操作 URI 必需

指向合作伙伴应用中的购物车的深层链接。

注意:您可以使用深层链接进行归因。 请参阅此常见问题解答

URI
项数 必需

购物车中项的数量(而不仅仅是商品数量)。

例如:如果购物车中有 3 件相同的衬衫和 1 顶帽子,则此数字应为 4。

整数 >= 1
操作文本 可选

购物车中相应按钮的号召性用语文本(例如您的购物袋)。

如果开发者未提供任何操作文本,系统将默认使用查看购物车

此属性在 1.1.0 及更高版本中受支持。

字符串
标题 可选

购物车的标题(例如您的购物袋)。

如果开发者未提供标题,则使用默认标题“您的购物车”

如果开发者合作伙伴为每个商家发布单独的购物车,请在标题中添加商家名称

自由文本

建议的文本大小:少于 25 个字符(如果文本过长,可能会显示省略号)

购物车图片 可选

购物车中每件商品的图片。

可按优先顺序提供最多 10 张图片;实际显示的图片数量取决于设备的外形规格。

如需相关指导,请参阅图片规范
项标签 可选

购物清单中项的标签列表。

实际显示的标签数量取决于设备的外形规格。

自由文本标签列表

建议的文本大小:少于 20 个字符(如果文本过长,可能会显示省略号)

上次用户互动时间戳 可选 从公元纪年开始经过的毫秒数,用于标识用户上次与购物车互动的时间。

开发者合作伙伴会将此值作为输入传递,以便为每个商家发布单独的购物车,并且可能会用于排名。

纪元时间戳(以毫秒为单位)
DisplayTimeWindow(可选)- 设置要在 surface 上显示的内容的时间范围
开始时间戳 可选

纪元时间戳,在其之后相应内容应显示在 surface 上。

如果未设置,相应内容将有资格显示在 surface 上。

纪元时间戳(以毫秒为单位)
结束时间戳 可选

纪元时间戳,在其之后相应内容不再显示在 surface 上。

如果未设置,相应内容将有资格显示在 surface 上。

纪元时间戳(以毫秒为单位)

ShoppingList

属性 要求 说明 格式
操作 URI 必需

指向合作伙伴应用中的购物清单的深层链接。

注意:您可以使用深层链接进行归因。 请参阅此处的常见问题解答

URI
项数 必需 购物清单中项的数量。 整数 >= 1
标题 可选

列表的标题(例如“您的购物清单”)。

如果开发者未提供标题,则使用默认标题“购物清单”

自由文本

建议的文本大小:少于 25 个字符(如果文本过长,可能会显示省略号)

项标签 必需

购物清单中项的标签列表。

必须提供至少 1 个标签,并且可按优先顺序提供最多 10 个标签;实际显示的图片数量取决于设备的外形规格。

自由文本标签列表

建议的文本大小:少于 20 个字符(如果文本过长,可能会显示省略号)

ShoppingReorderCluster

属性 要求 说明 格式
操作 URI 必需

指向合作伙伴应用中的重新订购部分的深层链接。

注意:您可以使用深层链接进行归因。 请参阅此处的常见问题解答

URI
操作文本 可选

“重新订购”部分上相应按钮的号召性用语文本(例如“重新订购”)。

如果开发者未提供任何操作文本,系统将默认使用“重新订购”。

此属性在 1.1.0 及更高版本中受支持。

字符串
项数 必需

先前订单中项的数量(而不仅仅是商品数量)。

例如:如果先前订单中有 3 小杯咖啡和 1 个羊角面包,则此数值应为 4。

整数 >= 1
标题 必需 重新订购项的标题。

自由文本

建议的文本大小:少于 40 个字符(如果文本过长,可能会显示省略号)

项标签

可选

(如未提供,则应提供海报图片)

先前订单的项标签列表。

可按优先顺序提供最多 10 个标签;实际显示的标签数量取决于设备的外形规格

自由文本列表

每个标签建议的文本大小:少于 20 个字符(如果文本过长,可能会显示省略号)

海报图片

可选

(如未提供,则应提供项标签)

先前订单中项的图片。

可按优先顺序提供最多 10 张图片;实际显示的图片数量取决于设备的外形规格。

如需相关指导,请参阅图片规范

ShoppingOrderTrackingCluster

属性 要求 说明 格式
标题 必需

所跟踪包裹/商品的短标题或跟踪编号。

自由文本

建议的文本大小:50 个字符(如果文本过长,将会显示省略号)

订单类型 必需

被跟踪的包裹/物品的简短标题或跟踪编号。

枚举:IN_STORE_PICKUP、SAME_DAY_DELIVERY、MULTI_DAY_DELIVERY

状态 必需

订单的当前状态。

例如:“无法送达”“运送中”“延迟”“已发货”“已送达”“缺货”“可订购”

自由文本

建议的文本大小:25 个字符(如果文本过长,将会显示省略号)

订购时间 必需

下单时间(以毫秒为单位)的纪元时间戳。

如果没有预计送货时间范围,系统会显示订单时间

纪元时间戳(以毫秒为单位)
操作 URI 必需

指向合作伙伴应用中的订单跟踪部分的深层链接。

URI
OrderDeliveryTimeWindow(可选)- 为正在跟踪的订单设置时间范围,该时间范围从下单时间到预计/实际送达时间。
OrderDeliveryTimeWindow - 开始时间 可选

纪元时间戳(以毫秒为单位),订单将在此时间或之后送达或可以自提。

纪元时间戳(以毫秒为单位)
OrderDeliveryTimeWindow - 结束时间 可选

订单送达或可供自提的时间(以自公元纪年以来的毫秒数表示)。

纪元时间戳(以毫秒为单位)
海报图片 可选

订单中包含的一件商品/产品的图片。

建议的宽高比为 1:1

如需相关指导,请参阅图片规范
项数 可选 订单中的商品数量。 整数 >= 1
说明 可选

用于描述订单中商品的一整段文本。

注意:向用户显示的是说明或字幕列表,不能同时显示。

自由文本

建议的文本大小:180 个字符

字幕列表 可选

最多 3 个字幕,每个字幕都是一行文本。

注意:向用户显示的是说明或字幕列表,不能同时显示。

自由文本

每个字幕建议的文本大小:最多 50 个字符

订单价值 - 当前价格 可选 订单的当前价值。 自由文本
订单号 可选 可用于唯一标识订单的订单号/ID。

自由文本

建议的文本大小:最多 25 个字符

跟踪编号 可选 订单/包裹送达的跟踪编号(如果订单需要送达)。

自由文本

建议的文本大小:最多 25 个字符

图片规范

下面列出了图片资源必须遵循的规范:

宽高比 最小像素 建议的像素

方形 (1x1)

非精选集群的首选

300x300 1200x1200

横向 (1.91x1)

精选集群的首选

600x314 1200x628
纵向 (4x5) 480x600 960x1200

文件格式

PNG、JPG、静态 GIF、WebP

文件大小上限

5120 KB

其他建议

  • 图片安全区域:将重要内容放在图片中间 80% 的区域内。
  • 请使用透明背景,以便图片可在“深色主题”和“浅色主题”设置中正常显示。

第 2 步:提供集群数据

建议在后台执行内容发布作业(例如,使用 WorkManager),并安排定期执行或按事件执行(例如,每当用户打开应用时,或当用户刚刚将商品添加到购物车时)。

AppEngageShoppingClient 负责发布购物集群。

以下 API 可用于在客户端中发布集群:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishFeaturedCluster
  • publishShoppingCart
  • publishShoppingCarts
  • publishShoppingList
  • publishShoppingReorderCluster
  • publishShoppingOrderTrackingCluster
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteFeaturedCluster
  • deleteShoppingCartCluster
  • deleteShoppingListCluster
  • deleteShoppingReorderCluster
  • deleteShoppingOrderTrackingCluster
  • deleteUserManagementCluster
  • deleteClusters

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 对象可以具有以下属性:

属性 要求 说明
ShoppingEntity 列表 必需 构成此推荐集群的推荐的 ShoppingEntity 对象列表。
标题 必需

推荐集群的标题。

建议的文本大小:少于 25 个字符(如果文本过长,可能会显示省略号)

副标题 可选 推荐集群的副标题。
操作 URI 可选

指向合作伙伴应用中向用户显示完整推荐列表的页面的深层链接。

注意:您可以使用深层链接进行归因。 请参阅此处的常见问题解答

Kotlin

client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Black Friday Deals")
                        .build())
                .build())

Java

client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Black Friday Deals")
                        .build())
                .build());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除所有现有的推荐集群数据。
  • 系统会解析请求中的数据,并将其存储在新的推荐集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

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());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 FeaturedCluster 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的精选集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishShoppingCart

此 API 用于发布 ShoppingCartCluster 对象。

Kotlin

client.publishShoppingCart(
            PublishShoppingCartRequest.Builder()
                .setShoppingCart(
                    ShoppingCart.Builder()
                        ...
                        .build())
                .build())

Java

client.publishShoppingCart(
            new PublishShoppingCartRequest.Builder()
                .setShoppingCart(
                    new ShoppingCart.Builder()
                        ...
                        .build())
                .build())

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 ShoppingCart 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的购物车集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishShoppingCarts

此 API 用于发布多个 ShoppingCart 对象。这适用于按商家发布单独购物车的开发者合作伙伴。使用此 API 时,在商品名中包含商家名称。

Kotlin

client.publishShoppingCarts(
            PublishShoppingCartClustersRequest.Builder()
                .addShoppingCart(
                    ShoppingCart.Builder()
                        ...
                        .build())
                .build())

Java

client.publishShoppingCarts(
            new PublishShoppingCartClustersRequest.Builder()
                .addShoppingCart(
                    new ShoppingCart.Builder()
                        ...
                        .build())
                .build())

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 ShoppingCart 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的购物车集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishShoppingList

此 API 用于发布 FoodShoppingList 对象。

Kotlin

client.publishFoodShoppingList(
            PublishFoodShoppingListRequest.Builder()
                .setFoodShoppingList(
                    FoodShoppingListEntity.Builder()
                        ...
                        .build())
                .build())

Java

client.publishFoodShoppingList(
            new PublishFoodShoppingListRequest.Builder()
                .setFoodShoppingList(
                    new FoodShoppingListEntity.Builder()
                        ...
                        .build())
                .build());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 FoodShoppingList 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的购物清单集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishShoppingReorderCluster

此 API 用于发布 ShoppingReorderCluster 对象。

Kotlin

client.publishShoppingReorderCluster(
            PublishShoppingReorderClusterRequest.Builder()
                .setReorderCluster(
                    ShoppingReorderCluster.Builder()
                        ...
                        .build())
                .build())

Java

client.publishShoppingReorderCluster(
            new PublishShoppingReorderClusterRequest.Builder()
                .setReorderCluster(
                    new ShoppingReorderCluster.Builder()
                        ...
                        .build())
                .build());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 ShoppingReorderCluster 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的重新订购集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishShoppingOrderTrackingCluster

此 API 用于发布 ShoppingOrderTrackingCluster 对象。

Kotlin

client.publishShoppingOrderTrackingCluster(
            PublishShoppingOrderTrackingClusterRequest.Builder()
                .setShoppingOrderTrackingCluster(
                    ShoppingOrderTrackingCluster.Builder()
                        ...
                        .build())
                .build())

Java

client.publishShoppingOrderTrackingCluster(
            new PublishShoppingOrderTrackingClusterRequest.Builder()
                .setShoppingOrderTrackingCluster(
                    new ShoppingOrderTrackingCluster.Builder()
                        ...
                        .build())
                .build());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 ShoppingOrderTrackingCluster 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的购物订单跟踪集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

publishUserAccountManagementRequest

此 API 用于发布登录卡片。登录操作会将用户定向到应用的登录页面,以便应用能够发布内容(或提供更个性化的内容)。

以下元数据是登录卡片的一部分:

属性 要求 说明
操作 URI 必需 指向操作的深层链接(比如进入应用登录页面)
图片 可选;如果不提供图片,则必须提供标题

卡片上显示的图片

宽高比为 16x9 且分辨率为 1264x712 的图片

标题 可选;如果不提供标题,则必须提供图片 卡片上的标题
操作文本 可选 CTA 上显示的文字(比如“登录”)
副标题 可选 卡片上的可选副标题

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());

当服务收到请求时,系统会在一项事务中执行以下操作:

  • 系统会移除开发者合作伙伴的现有 UserAccountManagementCluster 数据。
  • 系统会解析请求中的数据,并将其存储在经过更新的 UserAccountManagementCluster 集群中。

如果发生错误,系统将拒绝整个请求,并保留现有状态。

updatePublishStatus

如果由于任何内部业务原因,所有集群均未发布,我们强烈建议使用 updatePublishStatus API 更新发布状态。 这样做非常重要,因为:

  • 在所有情况下都提供状态,即使内容已发布 (STATUS == PUBLISHED) 也不例外,这一点至关重要,因为只有这样才能填充信息中心,以便信息中心使用此明确状态传达集成的运行状况和其他指标。
  • 如果未发布任何内容,但集成状态未被破坏 (STATUS == NOT_PUBLISHED),Google 可避免在应用运行状况信息中心内触发提醒。它会确认内容是因提供商意料之中的情况而未发布。
  • 它可帮助开发者深入了解数据发布/未发布的详细情况。
  • 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 建议发布登录卡片。 如果提供商因任何原因无法发布登录卡片,我们建议调用 updatePublishStatus API 并将状态代码设为 NOT_PUBLISHED_REQUIRES_SIGN_IN

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();

当服务收到请求时,此 API 会从建议集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteFeaturedCluster

此 API 用于删除精选集群的内容。

Kotlin

client.deleteFeaturedCluster()

Java

client.deleteFeaturedCluster();

当服务收到请求时,此 API 会从精选集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteShoppingCartCluster

此 API 用于删除购物车集群的内容。

Kotlin

client.deleteShoppingCartCluster()

Java

client.deleteShoppingCartCluster();

当服务收到请求时,此 API 会从购物车集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteShoppingListCluster

此 API 用于删除购物清单集群的内容。

Kotlin

client.deleteShoppingListCluster()

Java

client.deleteShoppingListCluster();

当服务收到请求时,此 API 会从购物清单集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteShoppingReorderCluster

此 API 用于删除购物重新订购集群的内容。

Kotlin

client.deleteShoppingReorderCluster()

Java

client.deleteShoppingReorderCluster();

当服务收到请求时,此 API 会从购物重新订购集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteShoppingOrderTrackingCluster

此 API 用于删除购物订单跟踪集群的内容。

Kotlin

client.deleteShoppingOrderTrackingCluster()

Java

client.deleteShoppingOrderTrackingCluster();

当服务收到请求时,此 API 会从购物订单跟踪集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

deleteUserManagementCluster

此 API 用于删除 UserAccountManagement 集群的内容。

Kotlin

client.deleteUserManagementCluster()

Java

client.deleteUserManagementCluster();

当服务收到请求时,此 API 会从 UserAccountManagement 集群中移除现有数据。如果发生错误,系统将拒绝整个请求,并保留现有状态。

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());

当服务收到请求时,此 API 会从所有与指定集群类型匹配的集群中移除现有数据。客户端可以选择传递一个或多个集群类型。如果发生错误,系统将拒绝整个请求,并保留现有状态。

错误处理

强烈建议开发者监听来自发布 API 的任务结果,以便执行后续操作,从而恢复并重新提交成功的任务。

Kotlin

client.publishRecommendationClusters(
        PublishRecommendationClustersRequest.Builder()
          .addRecommendationCluster(..)
          .build())
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          // do something
        } else {
          val exception = task.exception
          if (exception is AppEngageException) {
            @AppEngageErrorCode val errorCode = exception.errorCode
            if (errorCode == AppEngageErrorCode.SERVICE_NOT_FOUND) {
              // do something
            }
          }
        }
      }

Java

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 步:处理广播 intent

除了通过作业发出发布内容 API 调用外,还需要设置 BroadcastReceiver 来接收内容发布请求。

广播 intent 主要用于重新激活应用和强制同步数据。不应过于频繁地发送广播 intent。仅在 Engage Service 确定内容可能已过时(例如,内容是一周前的)的情况下,广播 intent 才会触发。这样一来,开发者将更加确信,即使应用长时间未执行,用户也能够获得新鲜的内容体验。

必须通过以下两种方式设置 BroadcastReceiver

  • 使用 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 shopping cart cluster publish when PUBLISH_SHOPPING_CART broadcast
  // is received
  // Trigger shopping list cluster publish when PUBLISH_SHOPPING_LIST broadcast
  // is received
  // Trigger reorder cluster publish when PUBLISH_REORDER_CLUSTER broadcast is
  // received
  // Trigger shopping order tracking cluster publish when
  // PUBLISH_SHOPPING_ORDER_TRACKING_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))

// Register Featured Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_FEATURED))

// Register Shopping Cart Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_SHOPPING_CART))

// Register Shopping List Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_SHOPPING_LIST))

// Register Reorder Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_REORDER_CLUSTER))

// Register Shopping Order Tracking Cluster Publish Intent
  context.registerReceiver(AppEngageBroadcastReceiver(),
                           IntentFilter(Intents.ACTION_PUBLISH_SHOPPING_ORDER_TRACKING_CLUSTER))
}

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 shopping cart cluster publish when PUBLISH_SHOPPING_CART broadcast is
// received

// Trigger shopping list cluster publish when PUBLISH_SHOPPING_LIST broadcast is
// received

// Trigger reorder cluster publish when PUBLISH_REORDER_CLUSTER broadcast is
// received

// Trigger reorder cluster publish when PUBLISH_SHOPPING_ORDER_TRACKING_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));

// Register Featured Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.service.Intents.ACTION_PUBLISH_FEATURED));

// Register Shopping Cart Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_SHOPPING_CART));

// Register Shopping List Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_SHOPPING_LIST));

// Register Reorder Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_REORDER_CLUSTER));

// Register Shopping Order Tracking Cluster Publish Intent
context.registerReceiver(new AppEngageBroadcastReceiver(),
new IntentFilter(com.google.android.engage.shopping.service.Intents.ACTION_PUBLISH_SHOPPING_ORDER_TRACKING_CLUSTER));

}
  • AndroidManifest.xml 文件中使用 <receiver> 标记静态声明实现。这样一来,应用便可以在未运行时接收广播 intent,并且应用也可以发布内容。
<application>
   <receiver
      android:name=".AppEngageBroadcastReceiver"
      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.shopping.PUBLISH_SHOPPING_CART" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.shopping.PUBLISH_SHOPPING_LIST" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.shopping.PUBLISH_REORDER_CLUSTER" />
      </intent-filter>
      <intent-filter>
         <action android:name="com.google.android.engage.action.shopping.PUBLISH_SHOPPING_ORDER_TRACKING_CLUSTER" />
      </intent-filter>
   </receiver>
</application>

该服务会发送以下 intent

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION 建议在收到此 intent 时启动 publishRecommendationClusters 调用。
  • com.google.android.engage.action.PUBLISH_FEATURED 建议在收到此 intent 时启动 publishFeaturedCluster 调用。
  • com.google.android.engage.action.shopping.PUBLISH_SHOPPING_CART 建议在收到此 intent 时启动 publishShoppingCart 调用。
  • com.google.android.engage.action.shopping.PUBLISH_SHOPPING_LIST 建议在收到此 intent 时启动 publishShoppingList 调用。
  • com.google.android.engage.action.shopping.PUBLISH_REORDER_CLUSTER 建议在收到此 intent 时启动 publishReorderCluster 调用。
  • com.google.android.engage.action.shopping.PUBLISH_SHOPPING_ORDER_TRACKING_CLUSTER 建议在收到此 intent 时启动 publishShoppingOrderTrackingCluster 调用。

集成工作流

如需查看在集成完成后验证集成的分步指南,请参阅 Engage 开发者集成工作流程

常见问题解答

如需查看常见问题解答,请参阅 Engage SDK 常见问题解答

联系人

如果在集成过程中有任何疑问,请与 engage-developers@google.com 联系。我们的团队会尽快回复您。

后续步骤

完成此集成后,请执行下列后续步骤:

  • 发送电子邮件至 engage-developers@google.com,并将可供 Google 测试的集成 APK 添加为附件。
  • Google 会执行验证,并在内部进行审核,以确保集成按预期运行。如果需要更改,Google 会与您联系,将所有必要的详细信息告知您。
  • 测试完毕后,如果无需进行任何更改,Google 将与您联系,向您说明您已可以开始将经过更新的集成 APK 发布到 Play 商店。
  • 在 Google 确认经过更新的 APK 已发布到 Play 商店后,您的推荐精选购物车购物清单重新订购集群购物订单跟踪集群集群便可被发布并向用户显示。