本指南包含一组集群发布指南,开发者在与Engage SDK集成时可以使用。
推荐集群
集群标题
我们建议提供一个独特且相关的集群标题,以便用户更深入地了解集群的内容。
以下是一些基于内容的良好集群标题示例
- 与购物相关的集群
- 闪电促销
- 每周必买
- 与您购买的Pixel Buds相关
- 女式雨靴
- 健康类书籍集群
- 身心健康
- 健康方面的推荐
- 健身类畅销书
集群内容
发布推荐集群时,开发者必须考虑用户是否登录到开发者的应用程序。
用户已登录时
如果用户已登录开发者应用,我们建议发布个性化或用户生成的内容集群。由于个性化和用户生成的内容与用户更相关,因此他们更有动力从Google界面访问开发者应用。
- 可以发布个性化推荐。
- 以下是一些个性化推荐的示例
- 基于用户观看历史的精选推荐。
- 与用户阅读历史中书籍类似的书籍。
- 用户最喜爱的艺术家的歌曲。
- 以下是一些个性化推荐的示例
- 可以发布用户生成的内容库。
- 以下是一些用户生成的内容库示例
- 开发者应用中的用户观看列表。
- 开发者应用中用户自报的最喜爱艺术家列表。
- 以下是一些用户生成的内容库示例
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
个性化推荐 | 宽松 我们建议每天更新一次推荐,以便用户每天都能看到新的推荐。 |
由于用户对推荐内容没有确切的预期,因此内容新鲜度策略可以比较宽松。 |
用户生成的内容库 | 严格 我们建议在用户退出开发者应用时更新内容库。 |
此内容必须与Google界面上显示的数据同步非常重要。这是因为与个性化推荐不同,用户期望的是一组确切的内容。任何发布的重大延迟都会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
用户未登录时
如果用户未登录开发者应用,我们仍然建议发布集群,以便鼓励用户从Google界面访问开发者应用。
- 应发布非个性化推荐集群。
- 以下是一些非个性化推荐的示例
- 今年阅读量排名前十的书籍。
- 新上映的电影。
- 热门播客。
- 以下是一些非个性化推荐的示例
- 发布登录卡片。
- 为了鼓励用户登录开发者应用,开发者可以选择与非个性化推荐集群一起发布登录卡片。请查看以下部分,了解有关如何发布登录卡片的更多详细信息。
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
非个性化推荐 | 宽松 我们建议每天更新一次推荐。 |
由于用户对推荐内容没有确切的预期,因此内容新鲜度策略可以比较宽松。 |
推荐中的登录卡片 | 严格 我们建议在用户退出开发者应用时更新登录卡片状态。 用户登录后,开发者必须通过调用 |
登录状态必须与Google界面同步非常重要。当用户已登录时,在Google界面上看到登录卡片会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
续播集群
发布续播集群时,开发者必须考虑用户是否登录到开发者的应用程序。
用户已登录时
- 应发布用户生成的续播集群。
- 以下是一些用户生成的续播集群示例
- 继续观看用户上次离开的地方。
- 继续阅读用户上次离开的地方。
- 以下是一些用户生成的续播集群示例
续播类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
用户生成的续播集群 | 严格 我们建议在用户退出开发者应用时更新内容库。 |
此内容必须与Google界面上显示的数据同步非常重要。这是因为与个性化推荐不同,用户期望的是一组确切的内容。任何发布的重大延迟都会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
用户未登录时
续播旅程主要面向已登录用户;但是,如果您的应用支持访客会话,您也可以为未登录用户发布续播集群。
用户管理集群
用户管理集群的主要目的是促使用户在提供商应用上执行某些操作。登录操作会将用户定向到应用的登录页面,以便应用可以发布内容(或提供更个性化的内容)
登录卡片
属性 | 要求 | 描述 |
---|---|---|
操作Uri | 必需 | 指向操作的深层链接(即导航到应用登录页面) |
图像 | 可选 - 如果未提供,则必须提供标题 |
卡片上显示的图片 16:9宽高比的图片,分辨率为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
如果由于用户未登录而未发布内容,我们建议发布登录卡片。如果由于任何原因提供商无法发布登录卡片,我们建议使用状态代码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());
用于集群发布的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);
}
处理广播意图
除了通过作业进行发布内容API调用外,还需要设置一个BroadcastReceiver
来接收内容发布请求。
但是,开发者必须注意不要仅仅依赖广播,因为它们只在某些情况下触发——主要是应用重新激活和强制数据同步。只有当Engage服务确定内容可能已过期时,才会触发它们。这样,即使应用程序长时间未打开,也可以更有把握地确保用户拥有最新的内容体验。
必须通过以下两种方式设置BroadcastReceiver
- 使用
Context.registerReceiver()
动态注册BroadcastReceiver
类的实例。这使得仍然驻留在内存中的应用程序可以进行通信。 - 在
AndroidManifest.xml
文件中使用<receiver>
标签静态声明一个实现。这允许应用程序在未运行时接收广播意图,并且还允许应用程序发布内容。