本指南包含一组集群发布指南,开发者在集成 Engage SDK 时可以使用。
推荐集群
集群标题
我们建议提供独特且相关的集群标题,让用户更深入了解集群的内容。
以下是一些根据内容分类的优秀集群标题示例
- 购物相关集群
- 秒杀优惠
- 每周必买
- 与您购买 Pixel Buds 相关
- 女士雨靴
- 健康类书籍集群
- 健康、心灵与身体
- 为您推荐的健康内容
- 健身畅销书
集群内容
发布推荐集群时,开发者必须考虑用户是否已登录开发者的应用。
当用户已登录时
如果用户已登录开发者应用,我们建议发布个性化或用户生成的内容集群。由于个性化和用户生成的内容与用户更相关,他们更有动力从 Google 界面访问开发者应用。
- 可以发布个性化推荐。
- 以下是一些个性化推荐的示例
- 根据用户观看历史记录精选。
- 与用户阅读历史记录中的书籍相似的书籍。
- 用户最喜欢艺术家的歌曲。
- 以下是一些个性化推荐的示例
- 可以发布用户生成的内容库。
- 以下是一些用户生成的内容库的示例
- 用户在开发者应用中的观看列表。
- 用户在开发者应用中自行报告的最喜欢艺术家列表。
- 以下是一些用户生成的内容库的示例
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
个性化推荐 | 宽松 我们建议每天更新一次推荐,以便用户每天都能看到新的推荐。 |
由于用户对推荐内容没有确切的期望,因此内容新鲜度策略可以宽松一些。 |
用户生成的内容库 | 严格 我们建议用户退出开发者应用时更新内容库。 |
此内容必须与 Google 界面上显示的数据同步,这一点很重要。这是因为与个性化推荐不同,用户期望的是精确的内容集。任何显著的发布延迟都会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
当用户未登录时
如果用户未登录开发者应用,我们仍然建议发布集群,以鼓励用户从 Google 界面访问开发者应用。
- 应发布非个性化推荐集群。
- 以下是一些非个性化推荐的示例
- 今年阅读量前 10 的书籍。
- 新上映的电影。
- 热门播客。
- 以下是一些非个性化推荐的示例
- 发布登录卡片。
- 为了鼓励用户登录开发者应用,开发者可以选择在非个性化推荐集群中发布登录卡片。请查看以下部分,了解如何发布登录卡片的更多详细信息。
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
非个性化推荐 | 宽松 我们建议每天更新一次推荐。 |
由于用户对推荐内容没有确切的期望,因此内容新鲜度策略可以宽松一些。 |
推荐中的登录卡片 | 严格 我们建议用户退出开发者应用时更新登录卡片状态。 用户登录后,开发者必须通过调用 |
登录状态与 Google 界面同步非常重要。用户在已登录的情况下在 Google 界面看到登录卡片会感到困惑。因此,内容新鲜度策略必须严格。 |
继续集群
发布继续集群时,开发者必须考虑用户是否已登录开发者的应用。
当用户已登录时
- 应发布用户生成的继续集群。
- 以下是一些用户生成的继续集群示例
- 从用户上次暂停的地方继续观看。
- 从用户上次暂停的地方继续阅读。
- 以下是一些用户生成的继续集群示例
继续类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
用户生成的继续集群 | 严格 我们建议用户退出开发者应用时更新内容库。 |
此内容必须与 Google 界面上显示的数据同步,这一点很重要。这是因为与个性化推荐不同,用户期望的是精确的内容集。任何显著的发布延迟都会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
当用户未登录时
继续旅程主要面向已登录用户;但是,如果您的应用支持访客会话,您也可以为未登录用户发布继续集群。
用户管理集群
用户管理集群的主要目的是提示用户在提供方应用上执行某些操作。登录操作会将用户引导至应用的登录页面,以便应用可以发布内容(或提供更多个性化内容)
登录卡片
属性 | 要求 | 说明 |
---|---|---|
操作 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() appEngagePublishClient.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(); appEngagePublishClient.publishUserAccountManagementRequest( new PublishUserAccountManagementRequest.Builder() .setSignInCardEntity(SIGN_IN_CARD_ENTITY) .build());
用户登录后,开发者必须通过调用 deleteUserManagementCluster()
API 删除卡片。
更新发布状态
如果由于任何内部业务原因,没有发布任何集群,我们强烈建议使用 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
如果内容因用户未登录而未发布,我们建议发布登录卡片。如果提供方因任何原因无法发布登录卡片,我们建议调用 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());
用于集群发布的 WorkManager
我们建议使用 WorkManager 来发布集群,因为它是后台工作的推荐解决方案,其执行必须既具有机会性又具有保证性。
- WorkManager 会尽快执行您的后台工作。
- WorkManager 处理在各种条件下启动您的工作的逻辑,即使在用户离开您的应用后也能如此。
当用户离开应用时,我们建议启动一个后台作业,该作业发布继续集群和推荐集群。处理此逻辑的一个好地方是 Activity.onStop()
,它在用户离开应用时调用。
我们建议使用 PeriodicWorkRequest
来安排每 24 小时发布集群的定期作业。通过使用 CANCEL_AND_REENQUEUE
策略来触发作业,开发者可以确保 WorkManager 在用户每次离开应用时发送更新的数据。这有助于防止用户看到过时的数据。
以下示例对此进行了演示
// Define the PublishClusters Worker requiring input
public class PublishClusters extends Worker {
public PublishClusters(Context appContext, WorkerParameters workerParams) {
super(appContext, workerParams);
}
@NonNull
@Override
public Result doWork() {
// publish clusters
}
...
}
public static void schedulePublishClusters(Context appContext) {
// Create a PeriodicWorkRequest to schedule a recurring job to update
// clusters at a regular interval
PeriodicWorkRequest publishClustersEntertainmentSpace =
// Define the time for the periodic job
new PeriodicWorkRequest.Builder(PublishClusters.class, 24, TimeUnit.HOURS)
// Set up a tag for the worker.
// Tags are Unique identifier, which can be used to identify that work
// later in order to cancel the work or observe its progress.
.addTag("Publish Clusters to Entertainment Space")
.build();
// Trigger Periodic Job, this will ensure that the periodic job is triggered
// only once since we have defined a uniqueWorkName
WorkManager.getInstance(appContext).enqueueUniquePeriodicWork(
// uniqueWorkName
"publishClustersEntertainmentSpace",
// If a work with the uniqueWorkName is already running, it will cancel the
// existing running jobs and replace it with the new instance.
// ExistingPeriodicWorkPolicy#CANCEL_AND_REENQUEUE
ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,
// Recurring Work Request
publishClustersEntertainmentSpace);
}
处理广播 intent
除了通过作业进行发布内容 API 调用外,还需要设置一个 BroadcastReceiver
来接收内容发布请求。
但是,开发者必须注意不要仅仅依赖广播,因为它们只在某些场景下触发——主要是用于应用重新激活和强制数据同步。它们仅在 Engage 服务确定内容可能已过时时触发。这样,即使应用长时间未打开,用户也能更有信心地获得新鲜内容体验。
BroadcastReceiver
必须通过以下两种方式设置
- 使用
Context.registerReceiver()
动态注册BroadcastReceiver
类的一个实例。这使得仍存在于内存中的应用能够进行通信。 - 在您的
AndroidManifest.xml
文件中使用<receiver>
标签静态声明一个实现。这允许应用在未运行时接收广播 intent,也允许应用发布内容。