Ir para o conteúdo

Gerenciar posicionamentos de Banner

Aprenda como criar e gerenciar posicionamentos de Banner no SDK da Braze, incluindo o acesso às suas propriedades exclusivas e o registro de impressões. Para mais informações gerais, veja 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: Atualizar os posicionamentos no seu app

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

requestBannersRefresh() mescla os resultados no cache de Banners existente. Somente 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.
  • Os 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 conjuntos diferentes de posicionamentos ao longo do tempo (por exemplo, os posicionamentos da tela atual) e manter no cache os Banners de outros posicionamentos.

A atualização de Banners funciona de duas formas:

  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, depois de changeUser() ou após o tempo limite de uma sessão).

O papel 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 de subscribeToBannersEvents() (ou do método descontinuado subscribeToBannersUpdates()) estar registrado. Sem uma inscrição ativa, o SDK não repete a atualização automaticamente 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. Sem essa chamada inicial, os Banners não são buscados automaticamente na primeira inicialização. Além disso, os IDs de posicionamento rastreados são redefinidos quando o app é reiniciado.

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: Escutar 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 event.type em um switch para tratar cada tipo de evento. Para saber mais sobre os valores dos eventos, consulte Inscrições em eventos.

Se você usa JavaScript puro com o Web SDK 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ê usa React com o Web SDK 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 associa cada ID de posicionamento ao seu 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 no snapshot e ignore os demais.

Use subscribeToBannersEvents no Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0. O padrão anterior só entrega 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 Swift SDK 19.0.0 e posterior. subscribeToUpdates(_:) é o padrão anterior, descontinuado 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.

ArrayList<String> placementIds = new ArrayList<>();
placementIds.add("global_banner");
placementIds.add("navigation_square_banner");

// - Available in version 44.0.0+
Braze.getInstance(context).subscribeToBannersEvents(event -> {
  if (event instanceof BannersEvent.CacheReplay) {
    logBanners(((BannersEvent.CacheReplay) event).getCacheSnapshot());
  } else if (event instanceof BannersEvent.CacheLoad) {
    logBanners(((BannersEvent.CacheLoad) event).getCacheSnapshot());
  } else if (event instanceof BannersEvent.DataUpdated) {
    logBanners(((BannersEvent.DataUpdated) event).getCacheSnapshot());
  }
});
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds);

Braze.getInstance(context).subscribeToBannersUpdates(event -> {
  for (Banner banner : event.getBanners()) {
    Log.d(TAG, "Received banner: " + banner.getPlacementId());
  }
});
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds);

private void logBanners(BannersCacheSnapshot cacheSnapshot) {
  for (Banner banner : cacheSnapshot.getBanners().values()) {
    Log.d(TAG, "Received banner: " + banner.getPlacementId());
  }
}
val placementIds = listOf("global_banner", "navigation_square_banner")

// - Available in version 44.0.0+
Braze.getInstance(context).subscribeToBannersEvents { event ->
  when (event) {
    is BannersEvent.CacheReplay -> logBanners(event.cacheSnapshot)
    is BannersEvent.CacheLoad -> logBanners(event.cacheSnapshot)
    is BannersEvent.DataUpdated -> logBanners(event.cacheSnapshot)
    else -> {}
  }
}
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds)

Braze.getInstance(context).subscribeToBannersUpdates { event ->
  event.banners.forEach { banner ->
    Log.d(TAG, "Received banner: ${banner.placementId}")
  }
}
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds)

private fun logBanners(cacheSnapshot: BannersCacheSnapshot) {
  cacheSnapshot.banners.values.forEach { banner ->
    Log.d(TAG, "Received banner: ${banner.placementId}")
  }
}

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

Use subscribeToBannersEvents no Android SDK 44.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado 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: Inserir usando o ID de posicionamento

Crie um elemento contêiner para o Banner. Não se esqueça de definir a largura e a altura dele.

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

Se você usa JavaScript puro com o Web SDK 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 Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0.

Se você usa React com o Web SDK 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 só atualiza uma BannerUIView ou BannerView quando o conteúdo em cache daquele posicionamento muda (é adicionado, removido ou atualizado). Os 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 só atualiza uma BannerView quando o conteúdo em cache daquele posicionamento muda (é adicionado, removido ou atualizado). Os 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ê usa 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 Android SDK da Braze. Esse módulo é separado de 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")
}

Se quiser, passe 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ê usa 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 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: Enviar 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 ficam armazenados em um cache separado na memória e não são mantidos quando o app é reiniciado. Nenhuma configuração extra é necessária, 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 os métodos do SDK para inserir um banner—então não é necessário rastrear as impressões manualmente.

Registro de cliques

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

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

Se você usa os métodos integrados padrão do SDK para inserir banners e o 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 é necessário nenhum código adicional.

Blocos de código personalizado

Se o seu banner usa o bloco de editor Código personalizado 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 oferece uma camada de comunicação entre o HTML interno do banner e o SDK da Braze principal.

Implementações de UI personalizada (headless)

Se você está criando uma UI totalmente personalizada usando as propriedades personalizadas do banner em vez de renderizar o HTML do banner, precisa registrar manualmente os cliques e as impressões a partir do 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 UI 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 UI personalizada considerar que o banner foi “visualizado”. Crie uma lógica robusta para definir o que conta como impressão e evitar eventos duplicados. Por exemplo, registre somente quando o banner entrar na viewport (ou equivalente) e não registre novamente quando o mesmo banner voltar a aparecer na 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 Android SDK

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

// 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 React Native SDK 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 Flutter SDK

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). Passe o parâmetro opcional buttonId 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 Android SDK

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

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

Consulte o repositório do React Native SDK 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 Flutter SDK

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 é 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 algum.

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 de editor Código personalizado, você pode disparar uma dispensa diretamente do HTML do Banner usando brazeBridge.closeMessage().

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

Dispensar um banner programaticamente

Se você usa 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 personalizada, 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. O método de dispensa pode ser chamado várias vezes com segurança: 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 com braze.getAllBanners() ou a partir 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 renderizar novamente. Os widgets BannerView são ocultados quando recebem BannerDismissedEvent. BannersEvent.DismissEvent representa o ciclo de vida de análise de dados dessa dispensa, e não um sinal para ocultar a visualização.

Use dismiss() no contexto do banner quando disponível. Esse método é idempotente e dispara automaticamente o retorno de chamada onDismiss. 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 é 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 são 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 ter 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 com dimensões fixas 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!