Engage SDK 클러스터 게시 가이드라인

이 가이드에는 개발자가 Engage SDK와 통합할 때 사용할 수 있는 클러스터 게시 가이드라인이 포함되어 있습니다.

맞춤 콘텐츠 클러스터

클러스터 제목

사용자에게 클러스터의 콘텐츠에 관한 유용한 정보를 더 많이 전달하는 고유하고 관련성 있는 클러스터 제목을 제공하는 것이 좋습니다.

다음은 콘텐츠에 기반한 적절한 클러스터 제목을 보여주는 예입니다.

  • 쇼핑 관련 클러스터
    • 번개 특가
    • 주간 필수 구매
    • Pixel Buds 구매 관련
    • 여성용 장화
  • 건강 관련 도서 클러스터
    • 건강, 정신, 몸
    • 건강 관련 추천 서비스
    • 피트니스 관련 베스트셀러

클러스터 콘텐츠

맞춤 콘텐츠 클러스터를 게시할 때 개발자는 사용자가 개발자의 애플리케이션에 로그인했는지 여부를 고려해야 합니다.

사용자가 로그인한 경우

사용자가 개발자 앱에 로그인했다면 맞춤 또는 사용자 제작 콘텐츠 클러스터를 게시하는 것이 좋습니다. 맞춤설정된 사용자 제작 콘텐츠는 사용자와 더 관련성이 높기 때문에 사용자가 Google 표시 경로에서 개발자 앱을 방문할 가능성이 더 높아집니다.

  • 맞춤 추천을 게시할 수 있습니다.
    • 다음은 맞춤 추천의 예입니다.
      • 사용자의 시청 기록을 바탕으로 추천
      • 사용자의 읽기 기록에 있는 책과 유사한 책
      • 사용자가 좋아하는 아티스트의 노래
  • 사용자 제작 콘텐츠 라이브러리를 게시할 수 있습니다.
    • 다음은 사용자 제작 콘텐츠 라이브러리의 예입니다.
      • 개발자 앱의 사용자 관심 목록
      • 개발자 앱에서 사용자가 좋아하는 아티스트에 관한 자체 보고 목록
맞춤 콘텐츠 유형 콘텐츠 최신성 전략 콘텐츠 최신성 가이드라인
맞춤 추천

관대

사용자가 매일 새로운 맞춤 콘텐츠를 확인할 수 있도록 맞춤 콘텐츠를 하루에 한 번 업데이트하는 것이 좋습니다.

사용자는 추천 콘텐츠가 어떻게 표시될지 정확히 예상할 수 없으므로 콘텐츠 최신성 전략은 관대할 수 있습니다.
사용자 제작 콘텐츠 라이브러리

엄격

사용자가 개발자 앱을 종료할 때 콘텐츠 라이브러리를 업데이트하는 것이 좋습니다.

이 콘텐츠가 Google 표시 경로에 표시되는 데이터와 동기화되는 것이 중요합니다. 맞춤 추천과 달리 사용자는 콘텐츠 세트를 정확하게 예상하기 때문입니다. 게시가 크게 지연될 경우 사용자에게 혼란을 줄 수 있습니다. 따라서 콘텐츠 최신성 전략은 엄격해야 합니다.

사용자가 로그인하지 않은 경우

사용자가 개발자 앱에 로그인하지 않은 경우에도 사용자가 Google 표시 경로에서 개발자 앱을 방문하도록 클러스터를 게시하는 것이 좋습니다.

  • 맞춤설정되지 않은 추천 클러스터를 게시해야 합니다.
    • 다음은 맞춤설정되지 않은 추천의 예입니다.
      • 올해 가장 많이 읽은 책 10권
      • 신작 영화
      • 인기 급상승 팟캐스트
  • 로그인 카드를 게시합니다.
    • 사용자가 개발자 앱에 로그인하도록 유도하기 위해 개발자는 맞춤설정되지 않은 콘텐츠 클러스터와 함께 로그인 카드를 게시할 수도 있습니다. 로그인 카드를 게시하는 방법에 관한 자세한 내용은 아래 섹션을 참고하세요.
맞춤 콘텐츠 유형 콘텐츠 최신성 전략 콘텐츠 최신성 가이드라인
맞춤설정되지 않은 추천

관대

추천을 하루에 한 번 업데이트하는 것이 좋습니다.

사용자는 추천 콘텐츠가 어떻게 표시될지 정확히 예상할 수 없으므로 콘텐츠 최신성 전략은 관대할 수 있습니다.
맞춤 콘텐츠의 로그인 카드

엄격

사용자가 개발자 앱을 종료할 때 로그인 카드 상태를 업데이트하는 것이 좋습니다.

사용자가 로그인한 후 개발자는 deleteUserManagementCluster() API를 호출하여 카드를 삭제해야 합니다.

로그인 상태가 Google 표시 경로와 동기화되어야 합니다. 이미 로그인되어 있을 때 Google의 표시 경로에 로그인 카드가 표시되면 사용자는 혼란스러울 수 있습니다. 따라서 콘텐츠 최신성 전략은 엄격해야 합니다.

연속 클러스터

연속 클러스터를 게시할 때 개발자는 사용자가 개발자의 애플리케이션에 로그인했는지 여부를 고려해야 합니다.

사용자가 로그인한 경우

  • 사용자가 생성한 연속 클러스터를 게시해야 합니다.
    • 다음은 사용자가 생성한 연속 클러스터의 예입니다.
      • 사용자가 시청을 중단한 부분부터 이어서 시청하기
      • 사용자가 중단한 부분부터 이어서 읽기
연속 유형 콘텐츠 최신성 전략 콘텐츠 최신성 가이드라인
사용자 생성 연속 클러스터

엄격

사용자가 개발자 앱을 종료할 때 콘텐츠 라이브러리를 업데이트하는 것이 좋습니다.

이 콘텐츠가 Google 표시 경로에 표시되는 데이터와 동기화되는 것이 중요합니다. 맞춤 추천과 달리 사용자는 콘텐츠 세트를 정확하게 예상하기 때문입니다. 게시가 크게 지연될 경우 사용자에게 혼란을 줄 수 있습니다. 따라서 콘텐츠 최신성 전략은 엄격해야 합니다.

사용자가 로그인하지 않은 경우

연속 여정은 주로 로그인한 사용자를 대상으로 합니다. 하지만 앱에서 게스트 세션을 지원하는 경우 로그아웃한 사용자를 위한 연속 클러스터를 게시할 수도 있습니다.

사용자 관리 클러스터

사용자 관리 클러스터의 주요 목표는 사용자가 제공업체 앱에서 특정 작업을 하도록 유도하는 것입니다. 로그인 작업은 앱이 콘텐츠를 게시하거나 더 맞춤설정된 콘텐츠를 제공할 수 있도록 사용자를 앱의 로그인 페이지로 안내합니다.

로그인 카드

속성 요구사항 설명
작업 URI 필수 작업으로 연결되는 딥 링크(앱 로그인 페이지로 이동)
이미지 선택사항 - 제공되지 않은 경우 제목을 입력해야 합니다.

카드에 표시된 이미지

해상도 1264x712의 16x9 가로세로 비율 이미지

제목 선택사항 - 제공되지 않은 경우 이미지를 제공해야 합니다. 카드상의 제목
작업 텍스트 선택사항 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를 설정해야 합니다.

그러나 개발자는 브로드캐스트에만 의존하지 않도록 주의해야 합니다. 브로드캐스트는 주로 앱 재활성화 및 데이터 동기화 강제와 같은 특정 시나리오에서만 트리거되기 때문입니다. 참여 서비스에서 콘텐츠가 오래되었을 수 있다고 판단하는 경우에만 트리거됩니다. 이를 통해 애플리케이션이 장기간 열리지 않은 경우에도 사용자에게 새로운 콘텐츠 환경이 제공될 수 있습니다.

BroadcastReceiver는 다음 두 가지 방법으로 설정해야 합니다.

  • Context.registerReceiver()를 사용하여 BroadcastReceiver 클래스의 인스턴스를 동적으로 등록합니다. 이렇게 하면 여전히 메모리에 있는 애플리케이션의 통신이 가능해집니다.
  • AndroidManifest.xml 파일에서 <receiver> 태그를 사용하여 구현을 정적으로 선언합니다. 이를 통해 애플리케이션이 실행 중이 아닐 때 브로드캐스트 인텐트를 수신할 수 있고, 애플리케이션이 콘텐츠를 게시할 수 있습니다.