SDK Engage Social: instruções técnicas de integração de terceiros

O Google está criando uma plataforma no dispositivo que organiza os apps dos usuários por categoria e possibilita uma nova experiência imersiva para consumo e descoberta de conteúdo personalizado de apps. Essa experiência de tela cheia oferece aos parceiros de desenvolvimento uma oportunidade de mostrar os melhores conteúdos avançados em um canal dedicado fora do app.

Este documento contém instruções para que os parceiros de desenvolvimento integrem o conteúdo social deles usando o SDK Engage para preencher essa nova área da plataforma.

Detalhe de integração

A seção abaixo mostra os detalhes da integração.

Terminologia

Os clusters de recomendação mostram sugestões personalizadas de um parceiro de desenvolvimento.

As recomendações têm esta estrutura:

Cluster de recomendação: uma visualização de interface que contém um grupo de recomendações do mesmo parceiro de desenvolvimento.

Cada cluster de recomendação consiste em um destes dois tipos de entidades:

  • PortraitMediaEntity
  • SocialPostEntity

A PortraitMediaEntity precisa conter uma imagem em modo retrato para a postagem. Os metadados relacionados ao perfil e à interação são opcionais.

  • Postagem

    • Imagem em modo retrato e carimbo de data/hora ou
    • Imagem em modo retrato + conteúdo de texto e carimbo de data/hora
  • Perfil

    • Avatar, nome ou identificador, imagem extra
  • Interação

    • Somente contagem e rótulo ou
    • Contagem e recurso visual (ícone)

A SocialPostEntity contém metadados relacionados a perfil, postagem e interação.

  • Perfil

    • Avatar, nome ou identificador, texto e outra imagem
  • Postagem

    • Texto e carimbo de data/hora ou
    • Rich media (imagem ou URL avançado) e carimbo de data/hora ou
    • Texto e rich media (imagem ou URL avançado) e carimbo de data/hora
  • Interações

    • Somente contagem e rótulo ou
    • Contagem e recurso visual (ícone)

Pré-trabalho

Nível mínimo da API: 19

Adicione a biblioteca com.google.android.play:engage ao app:

dependencies {
    // Make sure you also include that repository in your project's build.gradle file.
    implementation 'com.google.android.engage:engage-core:1.4.0'
}

Resumo

O design é baseado na implementação de um serviço vinculado.

Os dados que um cliente pode publicar estão sujeitos aos seguintes limites para diferentes tipos de clusters:

Tipo de cluster Limites de cluster Limites mínimos de entidades em um cluster Limites máximos de entidades em um cluster
Clusters de recomendação No máximo 5 No mínimo 5 (PortraitMediaEntity ou SocialPostEntity) No máximo 25 (PortraitMediaEntity ou SocialPostEntity)

Etapa 1: fornecer dados da entidade

O SDK definiu entidades diferentes para representar cada tipo de item. O SDK oferece suporte às entidades abaixo na categoria "Social":

  1. PortraitMediaEntity
  2. SocialPostEntity

As tabelas abaixo descrevem os atributos e os requisitos disponíveis para cada tipo.

PortraitMediaEntity

Atributo Requisito Descrição Formato
Action URI Obrigatório

Link direto para a entidade no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

URI
Metadados relacionados à postagem (obrigatório)
Image(s) Obrigatório

As imagens precisam estar na proporção de retrato.

A interface pode mostrar apenas uma imagem quando várias são fornecidas. No entanto, a interface pode mostrar uma indicação visual de que há mais imagens no app.

Se a postagem for um vídeo, o provedor precisará mostrar uma miniatura do vídeo como uma imagem.

Consulte as orientações em Especificações de imagem.
Text content Opcional O texto principal de uma postagem, atualização etc. String (máximo recomendado de 140 caracteres)
Timestamp Opcional Hora em que a postagem foi publicada. Carimbo de data/hora da época em milissegundos
Metadados relacionados ao perfil (opcional)
Nome Obrigatório Nome ou identificador do perfil, por exemplo, "João Silva", "@EquipePixel". String (máximo recomendado de 25 caracteres)
Avatar Obrigatório

Foto do perfil ou imagem do avatar do usuário.

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
Additional Image Opcional

Selo do perfil. Por exemplo: selo de autenticidade

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
Metadados relacionados a interações (opcional)
Count Obrigatório Indicação do número de interações, por exemplo, "3,7 M". String (máximo recomendado de 20 caracteres para a combinação de contagem + rótulo)
Gravadora

Opcional

Um Recurso visual precisa ser fornecido.

Indicação do motivo da interação, por exemplo, "Curtidas". String (máximo recomendado de 20 caracteres para a combinação de contagem + rótulo)
Visual

Opcional

Se esse atributo não for usado, será necessário fornecer um Rótulo.

Indicação do motivo da interação. Por exemplo, uma imagem mostrando o ícone de curtidas, emojis.

É possível fornecer mais de uma imagem, embora nem todas possam aparecer em todos os formatos.

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
DisplayTimeWindow (opcional): define uma janela de tempo para que um conteúdo seja mostrado na plataforma
Start Timestamp Opcional

Carimbo de data/hora da época depois da qual o conteúdo será mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Carimbo de data/hora da época em milissegundos
End Timestamp Opcional

Carimbo de data/hora da época depois da qual o conteúdo não será mais mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Carimbo de data/hora da época em milissegundos

SocialPostEntity

Atributo Requisito Descrição Formato
Action URI Obrigatório

Link direto para a entidade no app do provedor.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

URI

Metadados relacionados à postagem (obrigatório)

Pelo menos um TextContent, Image ou WebContent é necessário

Image(s) Opcional

As imagens precisam estar na proporção de retrato.

A interface pode mostrar apenas uma imagem quando várias são fornecidas. No entanto, a interface pode mostrar uma indicação visual de que há mais imagens no app.

Se a postagem for um vídeo, o provedor precisará mostrar uma miniatura do vídeo como uma imagem.

Consulte as orientações em Especificações de imagem.
Text content Opcional O texto principal de uma postagem, atualização etc. String (máximo recomendado de 140 caracteres)
Visualização do link (opcional)
Link Preview - Title Obrigatório Texto para indicar o título do conteúdo da página da Web String
Link Preview - Hostname Obrigatório Texto para indicar o proprietário da página da Web, por exemplo, "INSIDER" String
Link Preview - Image Opcional Imagem principal do conteúdo da Web Consulte as orientações em Especificações de imagem.
Timestamp Opcional Hora em que a postagem foi publicada. Carimbo de data/hora da época em milissegundos
Metadados relacionados ao perfil (opcional)
Nome Obrigatório Nome, ID ou identificador do perfil, por exemplo, "João Silva", "@EquipePixel" String (máximo recomendado de 25 caracteres)
Texto adicional Opcional

Pode ser usado como ID ou identificador do perfil ou metadados adicionais

Por exemplo, "@Joao-Silva", "5 milhões de seguidores", "Talvez você goste", "Em alta", "5 novas postagens"

String (máximo recomendado de 40 caracteres)
Avatar Obrigatório

Foto do perfil ou imagem do avatar do usuário.

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
Additional Image Opcional

Selo do perfil, por exemplo: selo de autenticidade

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
Metadados relacionados a interações (opcional)
Count Obrigatório Indicação do número de interações, por exemplo, "3,7 M". String (máximo recomendado de 20 caracteres para a combinação de contagem + rótulo)
Gravadora

Opcional

Um Recurso visual precisa ser fornecido.

Indicação do motivo da interação. Por exemplo, "Curtidas". String (máximo recomendado de 20 caracteres para a combinação de contagem + rótulo)
Visual

Opcional

Se esse atributo não for usado, será necessário fornecer um Rótulo.

Indicação do motivo da interação. Por exemplo, uma imagem mostrando o ícone de curtidas, emojis.

É possível fornecer mais de uma imagem, embora nem todas possam aparecer em todos os formatos.

Imagem quadrada 1:1

Consulte as orientações em Especificações de imagem.
DisplayTimeWindow (opcional): define uma janela de tempo para que um conteúdo seja mostrado na plataforma
Start Timestamp Opcional

Carimbo de data/hora da época depois da qual o conteúdo será mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Carimbo de data/hora da época em milissegundos
End Timestamp Opcional

Carimbo de data/hora da época depois da qual o conteúdo não será mais mostrado na plataforma.

Se não for definido, o conteúdo poderá ser mostrado na plataforma.

Carimbo de data/hora da época em milissegundos

Especificações da imagem

As imagens precisam ser hospedadas em CDNs públicas para que possam ser acessadas pelo Google.

Formatos de arquivo

PNG, JPG, GIF estático, WebP

Tamanho máximo do arquivo

5.120 KB

Recomendações adicionais

  • Área de segurança da imagem: posicione o conteúdo importante no centro da imagem, ocupando 80% do espaço.
  • Use um plano de fundo transparente para que a imagem possa ser exibida corretamente nas configurações do tema claro e escuro.

Etapa 2: fornecer dados do cluster

É recomendável executar o job de publicação de conteúdo em segundo plano (por exemplo, usando o WorkManager) e o programar com frequência ou por evento (por exemplo, toda vez que o usuário abrir o app ou seguir uma nova conta).

O AppEngageSocialClient é responsável pela publicação de clusters sociais.

Estas são as APIs para publicar clusters no cliente:

  • isServiceAvailable
  • publishRecommendationClusters
  • publishUserAccountManagementRequest
  • updatePublishStatus
  • deleteRecommendationsClusters
  • deleteUserManagementCluster
  • deleteClusters

isServiceAvailable

Essa API é usada para conferir se o serviço está disponível para integração e se o conteúdo pode ser apresentado no dispositivo.

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

Essa API é usada para publicar uma lista de objetos RecommendationCluster.

Um objeto RecommendationCluster pode ter os seguintes atributos:

Atributo Requisito Descrição
Listas de SocialPostEntity ou PortraitMediaEntity Obrigatório Uma lista de entidades que compõem as recomendações desse cluster de recomendação. As entidades de um único cluster precisam ser do mesmo tipo.
Título Obrigatório

O título do cluster de recomendação (por exemplo, Novidades dos seus amigos).

Tamanho de texto recomendado: menos de 25 caracteres (um texto muito longo será mostrado com reticências)

Action Uri Opcional

O link direto para a página no app do parceiro em que os usuários podem acessar a lista completa de recomendações.

Observação: é possível usar links diretos para atribuição. Consulte as perguntas frequentes.

Kotlin


client.publishRecommendationClusters(
            PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build())

Java


client.publishRecommendationClusters(
            new PublishRecommendationClustersRequest.Builder()
                .addRecommendationCluster(
                    new RecommendationCluster.Builder()
                        .addEntity(entity1)
                        .addEntity(entity2)
                        .setTitle("Latest from your friends")
                        .build())
                .build());

Quando o serviço recebe a solicitação, as ações abaixo ocorrem em uma transação:

  • Todos os dados do cluster de recomendação são removidos.
  • Os dados da solicitação são analisados e armazenados em novos clusters de recomendação.

Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

publishUserAccountManagementRequest

Essa API é usada para publicar um card de login. A ação de login direciona os usuários à página de login do app para que ele possa publicar ou oferecer conteúdo mais personalizado.

Os metadados abaixo fazem parte do card de login:

Atributo Requisito Descrição
Action Uri Obrigatório Link direto para a ação (ou seja, leva à página de login do app)
Imagem Opcional: se não for fornecido, o título precisa ser fornecido

Imagem mostrada no card

Imagens com proporção de 16 x 9 e resolução de 1.264 x 712

Título Opcional: se não for fornecido, a imagem precisará ser fornecida Título do card
Action Text Opcional Texto mostrado no CTA (por exemplo, "Fazer login")
Subtitle Opcional Subtítulo opcional do card

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

Quando o serviço recebe o pedido, as seguintes ações ocorrem em uma transação:

  • Os dados do UserAccountManagementCluster do parceiro do desenvolvedor são removidos.
  • Os dados do pedido são analisados e armazenados no cluster UserAccountManagementCluster atualizado.

Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

updatePublishStatus

Se, por qualquer motivo interno, nenhum dos clusters for publicado, é altamente recomendável atualizar o status de publicação usando a API updatePublishStatus. Isso é importante pelos seguintes motivos:

  • Informar o status em todos os casos possíveis, mesmo quando o conteúdo é publicado (STATUS == PUBLISHED), é fundamental para preencher painéis que usam o status explícito para transmitir informações de integridade e outras métricas da integração.
  • Se nenhum conteúdo for publicado, mas o status da integração não estiver corrompido (STATUS == NOT_PUBLISHED), o Google poderá evitar o acionamento de alertas nos painéis de integridade do app. Isso confirma que o conteúdo não foi publicado devido a uma situação esperada pelo provedor.
  • Ajuda os desenvolvedores a oferecer insights sobre quando os dados foram publicados ou não.
  • O Google pode usar os códigos de status para incentivar o usuário a executar ações específicas no app, como acessar o conteúdo ou resolver o problema.

Lista de códigos de status de publicação que podem ser usados:

// 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

Se o conteúdo não for publicado porque o usuário não estava conectado, o Google recomenda publicar o card de login. Se, por algum motivo, os provedores não conseguirem publicar o card de login, recomendamos chamar a API updatePublishStatus usando o código de status 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

Essa API é usada para excluir o conteúdo dos clusters de recomendação.

Kotlin


client.deleteRecommendationClusters()

Java


client.deleteRecommendationClusters();

Quando o serviço recebe o pedido, ele remove os dados atuais dos clusters de recomendação. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteUserManagementCluster

Essa API é usada para excluir o conteúdo do cluster UserAccountManagement.

Kotlin


client.deleteUserManagementCluster()

Java


client.deleteUserManagementCluster();

Quando o serviço recebe o pedido, ele remove os dados atuais do cluster UserAccountManagement. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

deleteClusters

Essa API é usada para excluir o conteúdo de determinado tipo de cluster.

Kotlin


client.deleteClusters(
    DeleteClustersRequest.Builder()
      .addClusterType(ClusterType.TYPE_RECOMMENDATION)
      ...
      .build())

Java


client.deleteClusters(
            new DeleteClustersRequest.Builder()
                .addClusterType(ClusterType.TYPE_RECOMMENDATION)
                ...
                .build());

Quando o serviço recebe a solicitação, ele remove os dados de todos os clusters que correspondem aos tipos especificados. Os clientes podem transmitir um ou vários tipos de clusters. Em caso de erro, a solicitação inteira é rejeitada e o estado existente é mantido.

Tratamento de erros

É recomendável detectar o resultado da tarefa nas APIs de publicação. Com isso, uma ação de acompanhamento pode ser realizada para recuperar e reenviar uma tarefa bem-sucedida.

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

O erro é retornado como AppEngageException e a causa é incluída como um código de erro.

Código do erro Observação
SERVICE_NOT_FOUND O serviço não está disponível no dispositivo.
SERVICE_NOT_AVAILABLE O serviço está disponível no dispositivo em questão, mas não no momento da chamada (por exemplo, está desativado).
SERVICE_CALL_EXECUTION_FAILURE A execução da tarefa falhou devido a problemas de linha de execução. Nesse caso, ela pode ser repetida.
SERVICE_CALL_PERMISSION_DENIED O autor da chamada não tem permissão para fazer a chamada de serviço.
SERVICE_CALL_INVALID_ARGUMENT A solicitação contém dados inválidos (por exemplo, tem um número de clusters maior do que o permitido).
SERVICE_CALL_INTERNAL Há um erro no serviço.
SERVICE_CALL_RESOURCE_EXHAUSTED A chamada de serviço é feita com muita frequência.

Etapa 3: processar intents de transmissão

Além de fazer chamadas de API de conteúdo de publicação usando um job, também é necessário configurar um BroadcastReceiver para receber a solicitação de publicação de conteúdo.

O objetivo principal das intents de transmissão é reativar o app e forçar a sincronização de dados. As intents de transmissão não são projetadas para envio muito frequente. Elas só são acionadas quando o serviço do Engage determina que o conteúdo pode estar desatualizado (por exemplo, é de uma semana atrás). Dessa forma, há mais confiança de que o usuário poderá ter uma nova experiência de conteúdo, mesmo que o aplicativo não tenha sido executado por um longo período.

O BroadcastReceiver precisa ser configurado de duas maneiras:

  • Registre dinamicamente uma instância da classe BroadcastReceiver usando Context.registerReceiver(). Isso permite a comunicação de aplicativos que ainda estão ativos na memória.
class AppEngageBroadcastReceiver extends BroadcastReceiver {
// Trigger recommendation cluster publish when PUBLISH_RECOMMENDATION 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));

}

  • Declare estaticamente uma implementação com a tag <receiver> no arquivo AndroidManifest.xml. Isso permite que o aplicativo receba intents de transmissão quando não está em execução e também permite que ele publique o conteúdo.
<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>
   </receiver>
</application>

As intents a seguir serão enviadas pelo serviço:

  • com.google.android.engage.action.PUBLISH_RECOMMENDATION Recomendamos que você inicie uma chamada publishRecommendationClusters ao receber essa intent.

Fluxo de trabalho de integração

Para acessar um guia explicativo sobre como verificar a integração após a conclusão, consulte Fluxo de trabalho de integração de desenvolvedor.

Perguntas frequentes

Consulte as Perguntas frequentes sobre o SDK Engage para acessar as perguntas frequentes.

Contato

Entre em contato com engagement-developers@google.com se tiver perguntas durante o processo de integração. Nossa equipe vai responder assim que possível.

Próximas etapas

Depois de concluir essa integração, as próximas etapas serão as seguintes:

  • Envie um e-mail para engage-developers@google.com e anexe seu APK integrado pronto para ser testado pelo Google.
  • O Google realiza uma verificação e revisão interna para garantir que a integração funcione como esperado. Se for necessário fazer mudanças, o Google vai entrar em contato informando todos os detalhes necessários.
  • Quando o teste estiver concluído e nenhuma mudança for necessária, o Google vai entrar em contato para informar que você pode começar a publicar o APK atualizado e integrado na Play Store.
  • Depois que o Google confirmar a publicação do APK atualizado na Play Store, seus clusters de recomendação serão publicados e ficarão visíveis aos usuários.