Ir para o conteúdo

Gerenciar posicionamentos de Banner

Aprenda a criar e gerenciar posicionamentos de Banner no SDK da Braze, incluindo como acessar suas propriedades exclusivas e registrar impressões. Para saber mais sobre o assunto de forma geral, consulte Sobre Banners.

Sobre solicitações de posicionamento

Quando você cria posicionamentos no seu app ou site, seu app envia uma solicitação para a Braze buscar mensagens de Banner para cada posicionamento.

  • Você pode solicitar até 10 posicionamentos por solicitação de atualização.
  • Para cada posicionamento, a Braze retorna o Banner de maior prioridade que o usuário é elegível para receber.
  • Se mais de 10 posicionamentos forem solicitados em uma atualização, apenas os primeiros 10 são retornados; os demais são descartados.

Por exemplo, um app pode solicitar três posicionamentos em uma solicitação de atualização: homepage_promo, cart_abandonment e seasonal_offer. Cada solicitação retorna o Banner mais relevante para aquele posicionamento.

Limite de frequência para solicitações de atualização

Se você estiver em versões mais antigas do SDK (antes do Swift 13.1.0, Android 38.0.0, Web 6.1.0, React Native 17.0.0 e Flutter 15.0.0), apenas uma solicitação de atualização é permitida por sessão de usuário.

Se você estiver em versões mínimas mais novas do SDK (Swift 13.1.0+, Android 38.0.0+, Web 6.1.0+, React Native 17.0.0+ e Flutter 15.0.0+), as solicitações de atualização são controladas por um algoritmo de token bucket para evitar polling excessivo:

  • Cada sessão de usuário começa com cinco tokens de atualização.
  • Os tokens são reabastecidos a uma taxa de um token a cada 180 segundos (3 minutos).

Cada chamada explícita para requestBannersRefresh consome um token. A atualização automática que ocorre no início de uma nova sessão ou quando changeUser é chamado não consome um token, pois essa atualização é uma publicação do último Banner em cache para aquele usuário. Se você tentar uma atualização quando não houver tokens disponíveis, o SDK não faz a solicitação e registra um erro até que um token seja reabastecido. Isso é importante para atualizações durante a sessão e atualizações disparadas por eventos. Para implementar atualizações dinâmicas (por exemplo, após um usuário completar uma ação na mesma página), chame o método de atualização após o evento personalizado ser registrado, mas observe um delay necessário para a Braze ingerir e processar o evento antes que o usuário se qualifique para uma Campaign de Banner diferente.

Criar um posicionamento

Pré-requisitos

Estas são as versões mínimas do SDK necessárias para criar posicionamentos de Banner:

Etapa 1: Criar posicionamentos na Braze

Se ainda não o fez, você precisará criar posicionamentos de Banner na Braze, que são usados para definir os locais em seu app ou site que podem exibir Banners. Para criar um posicionamento, acesse Configurações > Posicionamentos de Banners e selecione Criar posicionamento.

Seção de posicionamentos de Banner para criar IDs de posicionamento.

Dê um nome ao seu posicionamento e atribua um ID de posicionamento. Consulte outras equipes antes de atribuir um ID, pois ele será usado durante todo o ciclo de vida do cartão e não deve ser alterado posteriormente. Para saber mais, consulte IDs de posicionamento.

Detalhes de posicionamento que indicam que um Banner será exibido na barra lateral esquerda para campanhas de promoção de vendas de primavera.

Etapa 2: Atualize os posicionamentos no seu app

Para atualizar os posicionamentos, chame requestBannersRefresh() para o seu SDK.

requestBannersRefresh() mescla os resultados no cache de Banners existente. Apenas os IDs de posicionamento que você informar são adicionados, atualizados ou removidos:

  • Se o servidor retornar um Banner para um posicionamento solicitado, o Banner em cache desse posicionamento é substituído.
  • Se o servidor não retornar nenhum Banner para um posicionamento solicitado, esse posicionamento é removido do cache.
  • Banners em cache de posicionamentos que você não solicitou permanecem no cache até expirarem.

Para saber quantos posicionamentos você pode solicitar por atualização, consulte Sobre solicitações de posicionamento. Você pode atualizar diferentes conjuntos de posicionamentos ao longo do tempo (por exemplo, os posicionamentos da tela atual) e manter no cache os Banners de outros posicionamentos.

O comportamento de atualização de Banners tem dois caminhos:

  1. Atualização explícita: Você pode chamar o método de atualização a qualquer momento durante uma sessão ativa.
  2. Atualização automática em uma nova sessão: Depois que você faz pelo menos uma solicitação de atualização explícita, o SDK pode solicitar novamente os IDs de posicionamento mais recentes quando uma nova sessão da Braze começa (por exemplo, após changeUser() ou após o tempo limite de uma sessão).

A função da inscrição em eventos de Banner varia de acordo com a plataforma:

  • iOS e Android: subscribeToBannersEvents() no Android (ou subscribeToEvents() no Swift) registra um manipulador de eventos. A atualização automática no início da sessão não depende de a inscrição estar ativa.
  • Web: A atualização automática no início da sessão depende do registro de subscribeToBannersEvents() (ou do obsoleto subscribeToBannersUpdates()). Sem uma inscrição ativa, o SDK não repete automaticamente a atualização em uma nova sessão.

Em todos os casos, você precisa fazer pelo menos uma solicitação de atualização explícita por ciclo de vida do app para que o SDK saiba quais IDs de posicionamento manter atualizados. Os Banners não são buscados automaticamente na primeira inicialização sem essa chamada inicial, e os IDs de posicionamento rastreados são redefinidos quando o app reinicia.

As atualizações automáticas no início da sessão não consomem um token de limite de frequência.

import * as braze from "@braze/web-sdk";

braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
AppDelegate.braze?.banners.requestBannersRefresh(placementIds: ["global_banner", "navigation_square_banner"])
ArrayList<String> placementIds = new ArrayList<>();
placementIds.add("global_banner");
placementIds.add("navigation_square_banner");
Braze.getInstance(context).requestBannersRefresh(placementIds);
Braze.getInstance(context).requestBannersRefresh(listOf("global_banner", "navigation_square_banner"))
Braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
This feature is not currently supported on Roku.

Etapa 3: Escute as atualizações

Use subscribeToBannersEvents para escutar eventos de Banner e, em seguida, chame requestBannersRefresh para buscar os posicionamentos. O SDK chama seu manipulador com um objeto de evento. Use um switch em event.type para tratar cada tipo de evento. Para saber mais sobre os valores dos eventos, consulte Inscrições em eventos.

Se você estiver usando JavaScript puro com o SDK Web da Braze, registre seu manipulador antes de chamar requestBannersRefresh.

import * as braze from "@braze/web-sdk";

const placementIds = ["global_banner", "navigation_square_banner"];

// - Available in version 7.0.0+
const subscriptionId = braze.subscribeToBannersEvents((event) => {
  switch (event.type) {
    case braze.ChannelEventType.CACHE_REPLAY:
      // Sent once, right away, with the Banners that are already cached.
      // Render them now instead of waiting for the network.
      console.log("Cached Banners:", Object.keys(event.cacheSnapshot.banners));
      break;

    case braze.ChannelEventType.CACHE_LOAD:
      // The cache changed without a refresh, such as after changeUser().
      // The snapshot can be empty, so clear Banners from the previous user.
      console.log("Cache reloaded:", Object.keys(event.cacheSnapshot.banners));
      break;

    case braze.ChannelEventType.DATA_UPDATED:
      // A refresh finished, even if nothing changed, or a Banner was dismissed.
      console.log("Banners were updated:", event.reason);
      break;

    case braze.ChannelEventType.ERROR:
      switch (event.retryState) {
        case braze.RetryState.SDK_WILL_RETRY:
          // The SDK is retrying. Keep the current Banners and wait.
          break;
        case braze.RetryState.INTEGRATOR_MAY_RETRY: {
          // The SDK stopped retrying. Try again later, and limit how often you retry.
          const delayMs = event.rateLimitedUntil
            ? Math.max(event.rateLimitedUntil.getTime() - Date.now(), 0)
            : 30000;
          setTimeout(() => braze.requestBannersRefresh(placementIds), delayMs);
          break;
        }
        case braze.RetryState.DO_NOT_RETRY:
          // The failure is final. For example, Banners are disabled for this workspace.
          if (event.reason === braze.ChannelErrorReason.FEATURE_DISABLED) {
            // Hide the Banner containers.
          }
          break;
      }
      break;
  }
});

const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
  console.log("Banners were updated");
});

// Always refresh after your subscriber function has been registered
braze.requestBannersRefresh(placementIds);

// Remove the subscription when you no longer need it
// braze.removeSubscription(subscriptionId);

Se você estiver usando React com o SDK Web da Braze, configure subscribeToBannersEvents dentro de um hook useEffect e chame requestBannersRefresh depois de registrar seu listener.

import * as braze from "@braze/web-sdk";

useEffect(() => {
  const placementIds = ["global_banner", "navigation_square_banner"];

  // - Available in version 7.0.0+
  const subscriptionId = braze.subscribeToBannersEvents((event) => {
    switch (event.type) {
      case braze.ChannelEventType.CACHE_REPLAY:
      case braze.ChannelEventType.CACHE_LOAD:
        // Cached Banners, sent right away on subscribe or after the cache reloads
        console.log("Cached Banners:", Object.keys(event.cacheSnapshot.banners));
        break;

      case braze.ChannelEventType.DATA_UPDATED:
        // A refresh finished, even if nothing changed, or a Banner was dismissed
        console.log("Banners were updated:", event.reason);
        break;

      case braze.ChannelEventType.ERROR:
        if (event.retryState === braze.RetryState.INTEGRATOR_MAY_RETRY) {
          // The SDK stopped retrying. Try again later, and limit how often you retry.
          const delayMs = event.rateLimitedUntil
            ? Math.max(event.rateLimitedUntil.getTime() - Date.now(), 0)
            : 30000;
          setTimeout(() => braze.requestBannersRefresh(placementIds), delayMs);
        }
        break;
    }
  });

  const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
    console.log("Banners were updated");
  });

  // Always refresh after your subscriber function has been registered
  braze.requestBannersRefresh(placementIds);

  // Cleanup listeners
  return () => {
    braze.removeSubscription(subscriptionId);
    braze.removeSubscription(deprecatedSubscriptionId);
  };
}, []);

Para saber quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em eventos.

event.cacheSnapshot.banners é um objeto que mapeia cada ID de posicionamento para o respectivo Banner. Ele pode incluir posicionamentos de atualizações anteriores, e não apenas os IDs de posicionamento da sua chamada mais recente de requestBannersRefresh. Se você só se interessa por determinados posicionamentos, leia esses IDs de posicionamento no snapshot e ignore o restante.

Use subscribeToBannersEvents no SDK Web 7.0.0 e posteriores. subscribeToBannersUpdates é o padrão anterior, obsoleto a partir da versão 7.0.0. O padrão anterior entrega apenas os Banners atuais, então não informa por que os Banners mudaram nem quando uma atualização falhou.

// - Available in version 19.0.0+
let placementIds = ["global_banner", "navigation_square_banner"]
let cancellable = brazeClient.braze()?.banners.subscribeToEvents { event in
  switch event {
  case .cacheReplay(let cacheSnapshot), .cacheLoad(let cacheSnapshot):
    cacheSnapshot.banners.forEach { placementId, banner in
      print("Received banner: \(banner) with placement ID: \(placementId)")
    }
  case .dataUpdated(let cacheSnapshot, let reason):
    cacheSnapshot.banners.forEach { placementId, banner in
      print("Received banner: \(banner) with placement ID: \(placementId)")
    }
  default:
    break
  }
}
// Always refresh after your subscriber is registered
brazeClient.braze()?.banners.requestBannersRefresh(placementIds: placementIds)

let placementIds = ["global_banner", "navigation_square_banner"]
let cancellable = brazeClient.braze()?.banners.subscribeToUpdates { banners in
  banners.forEach { placementId, banner in
    print("Received banner: \(banner) with placement ID: \(placementId)")
  }
}
// Always refresh after your subscriber is registered
brazeClient.braze()?.banners.requestBannersRefresh(placementIds: placementIds)

Use subscribeToEvents(_:) no SDK Swift 19.0.0 e posteriores. subscribeToUpdates(_:) é o padrão anterior, obsoleto a partir da versão 19.0.0.

Para saber quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em eventos.

Estas etapas exigem o SDK Android 44.0.0 ou posterior. Use-as para renderizar Banners sem reagir a dados em cache.

  1. val bannerSubscriber = IEventSubscriber<BannersEvent> { event ->
      when (event) {
        is BannersEvent.CacheReplay -> {
          // Cached Banners. Don't show fallback content based on this event.
        }
        is BannersEvent.DataUpdated -> {
          val cachedPlacementIds = event.cacheSnapshot.banners.values.map { it.placementId }
          Log.d(TAG, "Banner cache updated: $cachedPlacementIds")
          // Update any Banners that are already on screen.
        }
        else -> Unit
      }
    }
    Braze.getInstance(context).subscribeToBannersEvents(bannerSubscriber)
    
  2. Chame requestBannersRefresh com os IDs de posicionamento da tela atual. Informe um retorno de chamada de conclusão para saber quando a atualização termina.

    val requestedPlacementIds = listOf("global_banner", "navigation_square_banner")
    
    Braze.getInstance(context).requestBannersRefresh(
      requestedPlacementIds,
      object : IValueCallback<BannersUpdatedEvent> {
        override fun onSuccess(value: BannersUpdatedEvent) {
          // The refresh finished. Check each requested placement.
        }
      }
    )
    
  3. No retorno de chamada, chame getBanner para cada ID de posicionamento solicitado. Se getBanner retornar null, o posicionamento não tem conteúdo de Banner para o usuário atual. Exiba seu conteúdo de fallback para esse posicionamento.

    requestedPlacementIds.forEach { placementId ->
      val banner = Braze.getInstance(context).getBanner(placementId)
      if (banner == null) {
        Log.d(TAG, "No Banner content for $placementId")
      } else {
        Log.d(TAG, "Banner available for ${banner.placementId}")
      }
    }
    
  4. Quando não precisar mais do assinante, remova-o.

    Braze.getInstance(context).removeSingleSubscription(bannerSubscriber, BannersEvent::class.java)
    

Lembre-se do seguinte:

  • Banners em cache de posicionamentos que você não solicitou permanecem no cache, então os eventos DataUpdated podem incluir posicionamentos de outras telas. Filtre pelos IDs de posicionamento da tela atual.
  • Um posicionamento solicitado sem conteúdo de Banner não aparece no evento DataUpdated. Use getBanner no retorno de chamada de conclusão em vez de esperar por um Banner correspondente em um evento.
  • Uma atualização concluída envia um evento DataUpdated mesmo quando o conteúdo do Banner não mudou.

Os eventos chegam em uma thread em segundo plano. Mude para a thread principal antes de atualizar as visualizações.

Use subscribeToBannersEvents no SDK Android 44.0.0 e posteriores. subscribeToBannersUpdates é o padrão anterior, obsoleto a partir da versão 44.0.0.

Para saber quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em eventos.

const bannerCardsSubscription = Braze.addListener(
  Braze.Events.BANNER_CARDS_UPDATED,
  (data) => {
    const banners = data.banners;
    console.log(
      `Received ${banners.length} Banner Cards with placement IDs:`,
      banners.map((banner) => banner.placementId)
    );
  }
);
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.
StreamSubscription bannerStreamSubscription = braze.subscribeToBanners((List<BrazeBanner> banners) {
  for (final banner in banners) {
    print("Received banner: " + banner.toString());
  }
});
This feature is not currently supported on Roku.

Etapa 4: Insira usando o ID de posicionamento

Crie um elemento contêiner para o Banner. Defina a largura e a altura dele.

<div id="global-banner-container" style="width: 100%; height: 450px;"></div>

Se você estiver usando JavaScript puro com o SDK Web da Braze, chame o método insertBanner para substituir o HTML interno do elemento contêiner.

import * as braze from "@braze/web-sdk";

braze.initialize("sdk-api-key", {
  baseUrl: "sdk-base-url",
  allowUserSuppliedJavascript: true, // banners require you to opt-in to user-supplied javascript
});

// - Available in version 7.0.0+
braze.subscribeToBannersEvents((event) => {
  const container = document.getElementById("global-banner-container");

  switch (event.type) {
    case braze.ChannelEventType.CACHE_REPLAY:
    case braze.ChannelEventType.CACHE_LOAD:
    case braze.ChannelEventType.DATA_UPDATED: {
      // get this placement's banner. If it's missing the user did not qualify for one.
      const globalBanner = event.cacheSnapshot.banners["global_banner"];
      if (!globalBanner) {
        container.style.display = "none";
        return;
      }

      // Insert the banner which replaces the innerHTML of that container
      braze.insertBanner(globalBanner, container);

      // Special handling if the user is part of a Control Variant
      container.style.display = globalBanner.isControl ? "none" : "";
      break;
    }
    case braze.ChannelEventType.ERROR:
      if (event.reason === braze.ChannelErrorReason.FEATURE_DISABLED) {
        // Banners are disabled, so hide the container
        container.style.display = "none";
      }
      break;
  }
});

braze.subscribeToBannersUpdates((banners) => {
  // get this placement's banner. If it's `null` the user did not qualify for one.
  const globalBanner = braze.getBanner("global_banner");
  if (!globalBanner) {
    return;
  }

  const container = document.getElementById("global-banner-container");

  // Insert the banner which replaces the innerHTML of that container
  braze.insertBanner(globalBanner, container);

  // Special handling if the user is part of a Control Variant
  if (globalBanner.isControl) {
    // hide or collapse the container
    container.style.display = "none";
  }
});

braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);

Use subscribeToBannersEvents no SDK Web 7.0.0 e posteriores. subscribeToBannersUpdates é o padrão anterior, obsoleto a partir da versão 7.0.0.

Se você estiver usando React com o SDK Web da Braze, chame o método insertBanner com uma ref para substituir o HTML interno do elemento contêiner.

import { useRef } from 'react';
import * as braze from "@braze/web-sdk";

export default function App() {
    const bannerRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
       const globalBanner = braze.getBanner("global_banner");
       if (!globalBanner || globalBanner.isControl) {
           // hide the container
       } else {
           // insert the banner to the container node
           braze.insertBanner(globalBanner, bannerRef.current);
       }
    }, []);
    return <div ref={bannerRef}></div>
}

Após uma atualização, o SDK atualiza uma BannerUIView ou BannerView somente quando o conteúdo em cache daquele posicionamento muda (é adicionado, removido ou atualizado). Banners exibidos que não mudaram permanecem como estão. Chamar changeUser() atualiza todas as visualizações de Banner registradas.

// To get access to the Banner model object:
let globalBanner: Braze.Banner?
AppDelegate.braze?.banners.getBanner(for: "global_banner", { banner in
  self.globalBanner = banner
})

// UIKit implementation:
// If you simply want the Banner view, initialize a `UIView` with the placement ID:
if let braze = AppDelegate.braze {
  let bannerUIView = BrazeBannerUI.BannerUIView(
    placementId: "global_banner",
    braze: braze,
    // iOS does not perform automatic resizing or visibility changes.
    // Use the `processContentUpdates` parameter to adjust the size and visibility of your Banner according to your use case.
    processContentUpdates: { result in
      switch result {
      case .success(let updates):
        if let height = updates.height {
          // Adjust the visibility and/or height.
        }
      case .failure(let error):
        // Handle the error.
      }
    }
  )
}

// SwiftUI implementation:
// Similarly, if you want a Banner view in SwiftUI, use the corresponding `BannerView` initializer:
if let braze = AppDelegate.braze {
  let bannerView = BrazeBannerUI.BannerView(
    placementId: "global_banner",
    braze: braze,
    // iOS does not perform automatic resizing or visibility changes.
    // Use the `processContentUpdates` parameter to adjust the size and visibility of your Banner according to your use case.
    processContentUpdates: { result in
      switch result {
      case .success(let updates):
        if let height = updates.height {
          // Adjust the visibility and/or height according to your parent controller.
        }
      case .failure(let error):
        // Handle the error.
      }
    }
  )
}

Após uma atualização, o SDK atualiza uma BannerView somente quando o conteúdo em cache daquele posicionamento muda (é adicionado, removido ou atualizado). Banners exibidos que não mudaram permanecem como estão. Chamar changeUser() continua atualizando todas as BannerView registradas.

Para obter o Banner em código Java, use:

Banner globalBanner = Braze.getInstance(context).getBanner("global_banner");

Você pode criar Banners no layout de visualizações do Android incluindo este XML:

<com.braze.ui.banners.BannerView
    android:id="@+id/global_banner_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:placementId="global_banner" />

Se você estiver usando Android Views, use este XML:

<com.braze.ui.banners.BannerView
    android:id="@+id/global_banner_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:placementId="global_banner" />

Para usar o Jetpack Compose, adicione o artefato com.braze:android-sdk-jetpack-compose ao módulo do seu app. Use a mesma versão das suas outras dependências do SDK Android da Braze. Esse módulo é separado do android-sdk-ui e inclui o composable Banner em com.braze.jetpackcompose.banners.

import com.braze.jetpackcompose.banners.Banner

@Composable
fun myBannerSlot() {
    Banner(placementId = "global_banner")
}

Opcionalmente, informe heightCallback para receber a altura renderizada em dp quando o tamanho do banner mudar. Para referência, consulte o KDoc de Banner.

Se você não adicionar o módulo do Jetpack Compose, envolva a BannerView em uma AndroidView:

import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.ui.viewinterop.AndroidView
import com.braze.ui.banners.BannerView

@Composable
fun myBannerSlot() {
    AndroidView(
        factory = { context ->
            BannerView(context, "global_banner").apply {
                layoutParams = ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
                )
            }
        },
        update = { it.placementId = "global_banner" }
    )
}

Para obter o Banner em Kotlin, use:

val banner = Braze.getInstance(context).getBanner("global_banner")

Se você estiver usando a Nova Arquitetura do React Native, precisa registrar BrazeBannerView como um componente Fabric no seu AppDelegate.mm.

#ifdef RCT_NEW_ARCH_ENABLED
/// Register the `BrazeBannerView` for use as a Fabric component.
- (NSDictionary<NSString *,Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents {
  NSMutableDictionary * dictionary = [super thirdPartyFabricComponents].mutableCopy;
  dictionary[@"BrazeBannerView"] = [BrazeBannerView class];
  return dictionary;
}
#endif

Para a integração mais simples, adicione o seguinte snippet de JavaScript XML (JSX) à sua hierarquia de visualizações, informando apenas o ID de posicionamento.

<Braze.BrazeBannerView
  placementId='global_banner'
/>

Para obter o modelo de dados do Banner no React Native, ou para verificar se esse posicionamento está presente no cache do usuário, use:

const banner = await Braze.getBanner("global_banner");
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.

Para a integração mais simples, adicione o seguinte widget à sua hierarquia de visualizações, informando apenas o ID de posicionamento.

BrazeBannerView(
  placementId: "global_banner",
),
To get the Banner's data model in Flutter, use:

Você pode usar o método getBanner para verificar se esse posicionamento está presente no cache do usuário.

braze.getBanner("global_banner").then((banner) {
  if (banner == null) {
    // Handle null cases.
  } else {
    print(banner.toString());
  }
});
This feature is not currently supported on Roku.

Etapa 5: Envie um Banner de teste (opcional)

Antes de lançar uma Campaign de Banner, você pode enviar um Banner de teste para verificar sua integração. Os Banners de teste são armazenados em um cache separado na memória e não persistem quando o app é reiniciado. Não é necessária nenhuma configuração extra, mas seu dispositivo de teste precisa ser capaz de receber notificações por push em primeiro plano para exibir o teste.

Registrar impressões

A Braze registra automaticamente as impressões dos banners que estão visíveis quando você usa métodos do SDK para inserir um banner—então não é preciso rastrear impressões manualmente.

Registro de cliques

O método usado para registrar cliques em Banners depende de como seu Banner é renderizado e de onde está seu manipulador de cliques.

Conteúdo padrão do Banner (automático)

Se você usa os métodos padrão integrados do SDK para inserir Banners e seu Banner usa componentes padrão do editor (imagens, botões, texto), os cliques são rastreados automaticamente. O SDK anexa listeners de clique a esses elementos, então não é preciso nenhum código adicional.

Blocos de código personalizado

Se seu Banner usa o bloco de editor Custom Code no dashboard da Braze, você precisa usar brazeBridge.logClick() para registrar cliques dentro desse HTML personalizado. Isso vale mesmo quando você usa métodos do SDK para renderizar o Banner, porque o SDK não consegue anexar listeners automaticamente a elementos dentro do seu código personalizado.

<button onclick="brazeBridge.logClick()">
  Click me
</button>

Para a referência completa, consulte Código personalizado e ponte JavaScript para Banners. O brazeBridge fornece uma camada de comunicação entre o HTML interno do Banner e o SDK da Braze principal.

Implementações de interface personalizada (headless)

Se você está criando uma interface totalmente personalizada usando as propriedades personalizadas do Banner em vez de renderizar o HTML do Banner, precisa registrar manualmente cliques e impressões no código do seu app. Como o SDK não está renderizando o Banner, ele não tem como rastrear automaticamente as interações com os elementos da sua interface personalizada.

Para assinaturas de métodos e detalhes completos, consulte a documentação de referência do SDK da Braze.

Registro de impressões

Chame o método de impressão de Banner da plataforma quando sua interface personalizada considerar o Banner “visualizado”. Crie uma lógica robusta para definir o que conta como impressão e evitar eventos duplicados. Por exemplo, registre apenas quando o Banner entrar na viewport (ou equivalente) e não registre novamente quando o mesmo Banner voltar à tela pela rolagem ou quando seu componente for renderizado de novo sem um novo evento de visualização.

import * as braze from "@braze/web-sdk";

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
const banner = braze.getBanner("placement_id_homepage_top");
if (banner) {
  braze.logBannerImpressions([banner]);
}

Referência do Web SDK

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.getInstance(context).logBannerImpression("placement_id_homepage_top")
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.getInstance(context).logBannerImpression("placement_id_homepage_top");

Referência do SDK para Android

// Retrieve a banner and log an impression on it (for example, once when it enters viewport)
braze.banners.getBanner(for: "placement_id_homepage_top") { banner in
  banner?.context.logImpression()
}

Referência do SDK para Swift

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.logBannerImpression("placement_id_homepage_top");

Consulte o repositório do SDK para React Native para ver as assinaturas de métodos mais recentes.

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
braze.logBannerImpression("placement_id_homepage_top");

Referência do SDK para Flutter

Registro de cliques

Chame o método de clique de Banner da plataforma quando o usuário tocar no seu Banner personalizado (ou em um botão específico). Informe o buttonId opcional quando o clique for em um botão específico, para que a análise de dados atribua o clique corretamente.

import * as braze from "@braze/web-sdk";

// Log click
braze.logBannerClick("placement_id_homepage_top", buttonId);  // buttonID is optional

Referência do Web SDK

// Log click
Braze.getInstance(context).logBannerClick("placement_id_homepage_top", buttonId)  // buttonID parameter can be null
// Log click
Braze.getInstance(context).logBannerClick("placement_id_homepage_top", buttonId);  // buttonID parameter can be null

Referência do SDK para Android

// Retrieve a banner and log a click on it
braze.banners.getBanner(for: "placement_id_homepage_top") { banner in
  banner?.context.logClick(buttonId: buttonId)  // buttonID is optional
}

Referência do SDK para Swift

// Log click
Braze.logBannerClick("placement_id_homepage_top", buttonId);  // buttonID is optional

Consulte o repositório do SDK para React Native para ver as assinaturas de métodos mais recentes.

// Log click
braze.logBannerClicked("placement_id_homepage_top", buttonId);  // buttonID parameter can be null

Referência do SDK para Flutter

Registrar dispensas

As dispensas de Banner removem programaticamente um Banner de um posicionamento quando um usuário o dispensa ativamente. Depois de dispensado, o Banner fica suprimido para esse usuário. Na próxima vez que a lista de posicionamentos for atualizada, um novo banner será retornado se o usuário for elegível para um.

Pré-requisitos

Estas são as versões mínimas do SDK necessárias para registrar dispensas de Banner:

Integrações

Integrações padrão de Banner (editor de arrastar e soltar)

Se o seu Banner usa o editor de arrastar e soltar e inclui um componente de botão de dispensa, não é necessário nenhum código adicional. Quando um usuário clica no botão de dispensa, a mensagem é ocultada, dispara uma dispensa e, em seguida, registra um evento de dispensa para análise de dados.

Blocos de código personalizado

Se o seu Banner usa o bloco do editor Código personalizado, você pode disparar uma dispensa diretamente no HTML do Banner usando brazeBridge.closeMessage().

<button onclick="brazeBridge.closeMessage()">
  Dismiss
</button>

Dispensar um banner programaticamente

Se você estiver usando o BrazeBannerView padrão com o botão de dispensa criado no editor de arrastar e soltar, não é necessário nenhum código adicional; a dispensa é tratada automaticamente.

Para integrações de interface personalizadas, você pode chamar o método de dispensa diretamente na sua instância da Braze para dispensar um banner programaticamente e registrar um evento de dispensa. É seguro chamar o método de dispensa várias vezes. O SDK ignora chamadas duplicadas para o mesmo banner.

Estas são as versões mínimas do SDK necessárias para dispensar um banner programaticamente:

Passe o objeto Banner para braze.dismissBanner(). Você pode obter o objeto Banner de braze.getAllBanners() ou do objeto cacheSnapshot.banners de um evento subscribeToBannersEvents.

import * as braze from "@braze/web-sdk";

const banners = braze.getAllBanners();
const banner = banners["global_banner"];

if (banner) {
  braze.dismissBanner(banner);
}
import * as braze from "@braze/web-sdk";

const banners = braze.getAllBanners();
const banner = banners["global_banner"];

if (banner) {
  braze.dismissBanner(banner);
}
Braze.getInstance(context).dismissBanner("your-placement-id");
Braze.getInstance(context).dismissBanner("your-placement-id")

dismissBanner() remove o Banner do cache e publica BannersEvent.DataUpdated com ChannelUpdateReason.CLIENT_ACTION para que interfaces personalizadas possam ser renderizadas novamente. Os widgets BannerView ficam ocultos quando recebem BannerDismissedEvent. BannersEvent.DismissEvent representa o ciclo de vida de análise de dados dessa dispensa, não um sinal para ocultar a visualização.

Use dismiss() no contexto do banner quando ele estiver disponível. Esse método é idempotente e dispara o retorno de chamada onDismiss automaticamente. Se o contexto não estiver disponível, chame dismiss(using:) diretamente no banner. Os dois métodos devem ser chamados a partir da thread principal.

// Preferred: dismiss via context.
banner.context?.dismiss()

// Fallback: if context is unavailable.
banner.dismiss(using: braze)

Em Objective-C, eles estão disponíveis como [banner.context dismiss] e [banner dismissUsing:braze].

Braze.dismissBanner("your-placement-id");
braze.dismissBanner("your-placement-id");

Registrar análises de dados personalizadas na dispensa do banner

Para executar uma lógica personalizada quando um banner for dispensado, como registrar análises de dados, use o retorno de chamada de dispensa do seu SDK. O retorno de chamada recebe um objeto de evento com placementId, stableKey e trackingId do banner.

Use Banner.subscribeToDismissedEvent() para executar uma lógica personalizada quando um banner específico for dispensado. Inscreva-se no evento antes de exibir o banner.

import * as braze from "@braze/web-sdk";

// - Available in version 7.0.0+
braze.subscribeToBannersEvents((event) => {
  if (
    event.type !== braze.ChannelEventType.CACHE_REPLAY &&
    event.type !== braze.ChannelEventType.CACHE_LOAD &&
    event.type !== braze.ChannelEventType.DATA_UPDATED
  ) {
    return;
  }

  const banner = event.cacheSnapshot.banners["global_banner"];

  if (banner) {
    banner.subscribeToDismissedEvent(() => {
      // Run any custom logic here, such as logging custom analytics
      console.log("Banner was dismissed");
    });
  }
});

braze.subscribeToBannersUpdates((banners) => {
  const banner = banners["global_banner"];

  if (banner) {
    banner.subscribeToDismissedEvent(() => {
      // Run any custom logic here, such as logging custom analytics
      console.log("Banner was dismissed");
    });
  }
});

braze.requestBannersRefresh(["global_banner"]);

Use subscribeToBannersEvents no Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0.

import { useEffect } from "react";
import * as braze from "@braze/web-sdk";

useEffect(() => {
  // - Available in version 7.0.0+
  const subscriptionId = braze.subscribeToBannersEvents((event) => {
    if (
      event.type !== braze.ChannelEventType.CACHE_REPLAY &&
      event.type !== braze.ChannelEventType.CACHE_LOAD &&
      event.type !== braze.ChannelEventType.DATA_UPDATED
    ) {
      return;
    }

    const banner = event.cacheSnapshot.banners["global_banner"];

    if (banner) {
      banner.subscribeToDismissedEvent(() => {
        // Run any custom logic here, such as logging custom analytics
        console.log("Banner was dismissed");
      });
    }
  });

  const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
    const banner = banners["global_banner"];

    if (banner) {
      banner.subscribeToDismissedEvent(() => {
        // Run any custom logic here, such as logging custom analytics
        console.log("Banner was dismissed");
      });
    }
  });

  braze.requestBannersRefresh(["global_banner"]);

  return () => {
    braze.removeSubscription(subscriptionId);
    braze.removeSubscription(deprecatedSubscriptionId);
  };
}, []);

Use subscribeToBannersEvents no Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0.

Defina a propriedade opcional onDismissCallback em BannerView.

import android.util.Log;
import com.braze.ui.banners.BannerView;
import kotlin.Unit;

// After obtaining your BannerView instance (for example from XML via findViewById, or `new BannerView(context, "global_banner")`)

bannerView.setOnDismissCallback((snapshot) -> {
  Log.d(TAG, "placementId: " + snapshot.getPlacementId()
    + ", stableKey: " + snapshot.getStableKey()
    + ", trackingId: " + snapshot.getTrackingId());

  // Run any custom logic here, such as logging custom analytics
  return Unit.INSTANCE;
});
import android.util.Log
import com.braze.ui.banners.BannerView

// After obtaining your BannerView instance (for example via findViewById or `BannerView(context, "global_banner")`)

bannerView.onDismissCallback = { snapshot ->
  Log.d(TAG, "placementId: ${snapshot.placementId}, stableKey: ${snapshot.stableKey}, trackingId: ${snapshot.trackingId}")

  // Run any custom logic here, such as logging custom analytics
}
// After initializing your banner view instance using UIKit or SwiftUI

bannerView.onDismiss = { event in
  print("Banner dismissed — placementId: \(event.placementId ?? "unknown")")
  print("  stableKey: \(event.stableKey ?? "unknown")")
  print("  trackingId: \(event.trackingId ?? "unknown")")

  // Run any custom logic here, such as logging custom analytics
}

Defina a prop onDismiss em Braze.BrazeBannerView para executar uma lógica personalizada quando um banner for dispensado.

import Braze from "@braze/react-native-sdk";

<Braze.BrazeBannerView
  placementId="global_banner"
  onDismiss={(event) => {
    console.log("placementId:", event.placementId, "stableKey:", event.stableKey, "trackingId:", event.trackingId);
    // Run any custom logic here, such as logging custom analytics
  }}
/>

Defina o parâmetro onDismiss em BrazeBannerView para executar uma lógica personalizada quando um banner for dispensado.

BrazeBannerView(
  placementId: 'global_banner',
  onDismiss: (BrazeBannerDismissEvent event) {
    print('placementId: ${event.placementId}, stableKey: ${event.stableKey}, trackingId: ${event.trackingId}');
    // Run any custom logic here, such as logging custom analytics
  },
)

Limite de armazenamento de dispensas pendentes

Os eventos de dispensa ficam armazenados localmente como entradas pendentes até que possam ser sincronizados com o servidor da Braze na próxima chamada de requestBannersRefresh.

Dimensões e tamanho

Veja o que você precisa saber sobre as dimensões e o tamanho dos banners:

  • Embora o criador permita que você faça uma prévia dos banners em diferentes dimensões, essas informações não são salvas nem enviadas para o SDK.
  • O HTML ocupará toda a largura do contêiner em que for renderizado.
  • Recomendamos criar um elemento de dimensão fixa e testar essas dimensões no criador.

Propriedades personalizadas

Você pode usar propriedades personalizadas da sua campanha de Banner para recuperar dados chave-valor através do SDK e modificar o comportamento ou a aparência do seu app. Por exemplo, você poderia:

  • Enviar metadados para análise de dados de terceiros ou integrações.
  • Usar metadados como um timestamp ou objeto JSON para disparar lógica condicional.
  • Controlar o comportamento de um Banner com base em metadados incluídos, como ratio ou format.

Pré-requisitos

Você precisará adicionar propriedades personalizadas à sua campanha de Banner. Além disso, estas são as versões mínimas do SDK necessárias para acessar propriedades personalizadas:

Acessar propriedades personalizadas

Para acessar as propriedades personalizadas de um banner, use um dos seguintes métodos com base no tipo da propriedade definido no dashboard. Se a chave não corresponder a uma propriedade desse tipo ou não existir, o método retorna null.

// Returns the Banner instance
const banner = braze.getBanner("placement_id_homepage_top");

// banner may be undefined or null
if (banner) {

  // Returns the string property
  const stringProperty = banner.getStringProperty("color");

  // Returns the boolean property
  const booleanProperty = banner.getBooleanProperty("expanded");

  // Returns the number property
  const numberProperty = banner.getNumberProperty("height");

  // Returns the timestamp property (as a number)
  const timestampProperty = banner.getTimestampProperty("account_start");

  // Returns the image URL property as a string of the URL
  const imageProperty = banner.getImageProperty("homepage_icon");

  // Returns the JSON object property
  const jsonObjectProperty = banner.getJsonProperty("footer_settings");
}
// Passes the specified banner to the completion handler
AppDelegate.braze?.banners.getBanner(for: "placement_id_homepage_top") { banner in
  // Returns the string property
  let stringProperty: String? = banner.stringProperty(key: "color")

  // Returns the boolean property
  let booleanProperty: Bool? = banner.boolProperty(key: "expanded")

  // Returns the number property as a double
  let numberProperty: Double? = banner.numberProperty(key: "height")

  // Returns the Unix UTC millisecond timestamp property as an integer
  let timestampProperty: Int? = banner.timestampProperty(key: "account_start")

  // Returns the image property as a String of the image URL
  let imageProperty: String? = banner.imageProperty(key: "homepage_icon")

  // Returns the JSON object property as a [String: Any] dictionary
  let jsonObjectProperty: [String: Any]? = banner.jsonObjectProperty(key: "footer_settings")
}
// Returns the Banner instance
Banner banner = Braze.getInstance(context).getBanner("placement_id_homepage_top");

// banner may be undefined or null
if (banner != null) {
  // Returns the string property
  String stringProperty = banner.getStringProperty("color");

  // Returns the boolean property
  Boolean booleanProperty = banner.getBooleanProperty("expanded");

  // Returns the number property
  Number numberProperty = banner.getNumberProperty("height");

  // Returns the timestamp property (as a Long)
  Long timestampProperty = banner.getTimestampProperty("account_start");

  // Returns the image URL property as a String of the URL
  String imageProperty = banner.getImageProperty("homepage_icon");

  // Returns the JSON object property as a JSONObject
  JSONObject jsonObjectProperty = banner.getJSONProperty("footer_settings");
}
// Returns the Banner instance
val banner: Banner = Braze.getInstance(context).getBanner("placement_id_homepage_top") ?: return

// Returns the string property
val stringProperty: String? = banner.getStringProperty("color")

// Returns the boolean property
val booleanProperty: Boolean? = banner.getBooleanProperty("expanded")

// Returns the number property
val numberProperty: Number? = banner.getNumberProperty("height")

// Returns the timestamp property (as a Long)
val timestampProperty: Long? = banner.getTimestampProperty("account_start")

// Returns the image URL property as a String of the URL
val imageProperty: String? = banner.getImageProperty("homepage_icon")

// Returns the JSON object property as a JSONObject
val jsonObjectProperty: JSONObject? = banner.getJSONProperty("footer_settings")
// Get the Banner instance
const banner = await Braze.getBanner('placement_id_homepage_top');
if (!banner) return;

// Get the string property
const stringProperty = banner.getStringProperty('color');

// Get the boolean property
const booleanProperty = banner.getBooleanProperty('expanded');

// Get the number property
const numberProperty = banner.getNumberProperty('height');

// Get the timestamp property (as a number)
const timestampProperty = banner.getTimestampProperty('account_start');

// Get the image URL property as a string
const imageProperty = banner.getImageProperty('homepage_icon');

// Get the JSON object property
const jsonObjectProperty = banner.getJSONProperty('footer_settings');
// Fetch the banner asynchronously
_braze.getBanner(placementId).then(('placement_id_homepage_top') {
  // Get the string property
  final String? stringProperty = banner?.getStringProperty('color');

  // Get the boolean property
  final bool? booleanProperty = banner?.getBooleanProperty('expanded');

  // Get the number property
  final num? numberProperty = banner?.getNumberProperty('height');

  // Get the timestamp property
  final int? timestampProperty = banner?.getTimestampProperty('account_start');

  // Get the image URL property
  final String? imageProperty = banner?.getImageProperty('homepage_icon');

  // Get the JSON object property
  final Map<String, dynamic>? jsonObjectProperty = banner?.getJSONProperty('footer_settings');

  // Use these properties as needed in your UI or logic
});
New Stuff!