本指南包含一套集群发布指南,开发者可以在与 Engage SDK 集成时使用。
推荐集群
集群标题
建议提供一个独特且相关的集群标题,让用户更深入地了解集群的内容。
以下是一些根据内容制定的良好集群标题示例
- 与购物相关的集群
- 闪电促销
- 每周必买
- 与您购买 Pixel Buds 相关
- 女式雨靴
- 关于健康的书籍集群
- 健康、心灵与身体
- 健康领域为您推荐
- 健身类畅销书
集群内容
发布推荐集群时,开发者必须考虑用户是否登录了开发者的应用。
用户已登录
如果用户已登录开发者应用,建议发布个性化或用户生成的内容集群。由于个性化和用户生成的内容与用户更相关,因此他们更有动力从 Google 页面访问开发者应用。
- 可以发布个性化推荐。
- 以下是个性化推荐的一些示例
- 根据用户的观看历史推荐的热门选择。
- 与用户阅读历史中书籍相似的书籍。
- 用户最喜欢的艺术家的歌曲。
- 以下是个性化推荐的一些示例
- 可以发布用户生成的内容库。
- 以下是用户生成的内容库的一些示例
- 用户在开发者应用中的观看列表。
- 用户在开发者应用中自我报告的最喜欢的艺术家列表。
- 以下是用户生成的内容库的一些示例
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
个性化推荐 | 宽松 我们建议每天更新一次推荐内容,这样用户每天都能看到新的推荐。 |
由于用户对推荐内容没有明确的预期,因此内容新鲜度策略可以比较宽松。 |
用户生成内容库 | 严格 我们建议在用户退出开发者应用程序时更新内容库。 |
此内容必须与 Google 平台上显示的数据保持同步。这是因为与个性化推荐不同,用户期望看到一组确定的内容。发布任何重大延误都会让用户感到困惑。因此,内容新鲜度策略必须严格。 |
用户未登录时
即使用户未登录开发者应用程序,我们仍然建议发布聚类,以鼓励用户从 Google 平台访问开发者应用程序。
- 应发布非个性化推荐聚类。
- 以下是一些非个性化推荐的示例
- 今年阅读量排名前 10 的书籍。
- 新上映的电影。
- 热门播客。
- 以下是一些非个性化推荐的示例
- 发布登录卡片。
- 为了鼓励用户登录开发者应用程序,开发人员可以选择发布登录卡片以及非个性化推荐聚类。查看下面的部分,了解有关如何发布登录卡片的更多详细信息。
推荐类型 | 内容新鲜度策略 | 内容新鲜度指南 |
---|---|---|
非个性化推荐 | 宽松 我们建议每天更新一次推荐内容。 |
由于用户对推荐内容没有明确的预期,因此内容新鲜度策略可以比较宽松。 |
推荐中的登录卡片 | 严格 我们建议在用户退出开发者应用程序时更新登录卡片状态。 用户登录后,开发者必须通过调用 |
登录状态必须与 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>
标签静态声明实现。这允许应用程序在未运行时接收广播意图,并允许应用程序发布内容。