Passer au contenu

Google Tag gestionnaire avec le SDK Braze

Découvrez comment utiliser Google Tag gestionnaire (GTM) avec le SDK Braze, afin de contrôler à distance le suivi des événements Braze et les mises à jour des attributs utilisateur sans nécessiter de modifications de code ni de nouvelles versions de l’application.

À propos de Google Tag gestionnaire pour le Web

Google Tag gestionnaire (GTM) vous permet d’ajouter, de supprimer et de modifier à distance des balises sur votre site web, sans nécessiter de mise en production ni de ressources techniques. Braze propose les modèles suivants pour le SDK Web :

Type de balise Cas d’utilisation
Balise d’initialisation Cette balise vous permet d’intégrer le SDK Web de Braze sans avoir à modifier le code de votre site.
Balise d’action Cette balise vous permet de créer des Content Cards, de définir les attributs utilisateur, de journaliser des événements e-commerce et de gérer la collecte des données.

Séquençage des balises pour les balises d’action Braze

La balise Braze Initialization doit se déclencher avant toute balise qui appelle des méthodes du SDK Braze (telles que braze.getUser(), braze.logCustomEvent() ou braze.logPurchase()). Si ces méthodes se déclenchent avant l’initialisation du SDK, vous pourriez rencontrer des erreurs comme Uncaught TypeError: Cannot read properties of undefined (reading 'getUser').

Pour configurer le séquençage des balises dans Google Tag gestionnaire :

  1. Ouvrez la balise qui appelle les méthodes du SDK Braze (comme une balise HTML personnalisée ou une balise d’action Braze).
  2. Accédez à Advanced Settings > Tag Sequencing.
  3. Sélectionnez A tag that fires before [this tag] is fired.
  4. Choisissez votre balise Braze Initialization.

Cela garantit que le SDK est entièrement chargé avant que d’autres balises ne tentent d’appeler les méthodes Braze.

Pour plus de détails, consultez Vérifier le séquençage des balises pour les événements personnalisés.

Journaliser des achats avec GTM

Dans les balises d’action Braze et les balises Custom HTML, appelez braze.logPurchase() pour enregistrer le chiffre d’affaires. L’ancien espace de noms appboy.logPurchase() n’est pas pris en charge dans les intégrations actuelles du SDK Web.

Journaliser des événements e-commerce avec GTM

Utilisez le type de balise Log eCommerce Event (New) dans la balise Braze Actions pour envoyer des événements e-commerce recommandés à Braze depuis votre couche de données GTM. Cette balise appelle braze.logEcommerceEvent() et nécessite le SDK Web version 6.8.0 ou ultérieure. Assurez-vous que votre balise Braze Initialization charge une version compatible du SDK.

La balise prend en charge les événements suivants :

Type d’événement de la balise Événement Braze
Product Viewed ecommerce.product_viewed
Cart Updated ecommerce.cart_updated
Checkout started ecommerce.checkout_started
Order placed ecommerce.order_placed

Pour journaliser ecommerce.order_cancelled ou ecommerce.order_refunded, utilisez une balise Custom HTML qui appelle braze.logCustomEvent(). Pour des exemples, consultez Journaliser des événements e-commerce.

Étape 1 : Envoyer l’événement à la couche de données

Dans le code de votre site, envoyez l’événement et son objet ecommerce à la couche de données. Par défaut, la balise lit le format standard de couche de données e-commerce GA4. Par exemple, pour journaliser une commande :

dataLayer.push({
  event: "purchase",
  ecommerce: {
    transaction_id: "T_12345",
    value: 29.97,
    currency: "USD",
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        item_variant: "green",
        price: 9.99,
        quantity: 3
      }
    ]
  }
});

Braze exige que les identifiants tels que item_id et transaction_id soient des chaînes de caractères. Envoyez-les en tant que chaînes de caractères, même si vos identifiants sont numériques.

Étape 2 : Créer un déclencheur dans GTM

  1. Dans votre conteneur GTM, accédez à Triggers et créez un nouveau déclencheur.
  2. Définissez le Trigger Type sur Custom Event.
  3. Définissez le Event Name sur l’événement que vous avez envoyé à la couche de données (par exemple, purchase).

Étape 3 : Créer la balise Braze Actions

  1. Dans GTM, accédez à Tags et créez une nouvelle balise avec le type Braze Actions Tag.
  2. Définissez le Tag Type sur Log eCommerce Event (New).
  3. Sélectionnez un eCommerce Event Type.
  4. Renseignez les champs pour ce type d’événement, comme décrit dans le tableau suivant.
  5. (Facultatif) Ajoutez des métadonnées.
  6. Sous Triggering, sélectionnez le déclencheur que vous avez créé à l’étape 2.
  7. Configurez le séquençage des balises pour que la balise Braze Initialization se déclenche en premier.
  8. Enregistrez et publiez votre conteneur.
Type d’événement e-commerce Champs de la balise Valeurs requises de la couche de données
Product Viewed Aucun. ecommerce.items et ecommerce.currency. Le premier élément correspond au produit consulté.
Cart Updated Cart ID est obligatoire. Cart Update Action peut être Replace, Add ou Remove, et sa valeur par défaut est Replace. ecommerce.items et ecommerce.currency. ecommerce.value est obligatoire lorsque l’action est Replace.
Checkout started Checkout ID est obligatoire. Cart ID est facultatif. ecommerce.items, ecommerce.currency et ecommerce.value.
Order placed Cart ID est facultatif. ecommerce.items, ecommerce.currency, ecommerce.value et ecommerce.transaction_id.

Si ecommerce.currency n’est pas défini, la balise utilise le champ currency du premier élément. La balise définit la source de l’événement sur google_tag_manager_web.

Mappage de la couche de données

Lorsque l’option Automatically parse e-commerce event from the data layer est sélectionnée (par défaut), la balise mappe les valeurs de la couche de données aux propriétés de l’événement Braze comme suit :

Propriété Braze Valeur de la couche de données
currency ecommerce.currency
total_value ecommerce.value
order_id ecommerce.transaction_id
products[].product_id ecommerce.items[].item_id
products[].product_name ecommerce.items[].item_name
products[].variant_id ecommerce.items[].item_variant. Valeur par défaut : item_id.
products[].price ecommerce.items[].price
products[].quantity ecommerce.items[].quantity. Valeur par défaut : 1.
products[].image_url ecommerce.items[].image_url
products[].product_url ecommerce.items[].product_url

Saisir manuellement les valeurs de l’événement

Si votre site utilise un format de couche de données e-commerce personnalisé, décochez Automatically parse e-commerce event from the data layer. Saisissez ensuite les valeurs de l’événement dans la balise. Vous pouvez utiliser des variables GTM dans n’importe lequel de ces champs.

Champ Description
Currency Obligatoire. Un code de devise ISO 4217, tel que USD.
Total Value Obligatoire pour Cart Updated avec l’action Replace, Checkout started et Order placed.
Order ID Obligatoire pour Order placed.
Products Obligatoire. Ajoutez une ligne pour chaque produit. Product ID, Product Name et Price sont obligatoires. Variant ID prend par défaut la valeur de l’identifiant produit, et Quantity prend par défaut la valeur 1. Image URL, Product URL et Product Metadata (JSON) sont facultatifs. Pour Product Viewed, la balise utilise la première ligne.

Métadonnées des événements e-commerce

Ajoutez des métadonnées pour envoyer des paires clé-valeur supplémentaires avec l’événement. Braze envoie les métadonnées de l’événement dans l’objet metadata de l’événement, et les métadonnées produit dans l’objet metadata de chaque produit.

Métadonnées de l’événement

Utilisez le tableau eCommerce Event Metadata pour ajouter des métadonnées au niveau de l’événement. Ce tableau est disponible que l’analyse automatique soit activée ou non. Pour chaque ligne, saisissez une Metadata property key et une Metadata property value. Vous pouvez utiliser une variable GTM comme valeur. La balise ignore les lignes dont la clé ou la valeur est vide.

Certains types d’événements prennent en charge des clés de métadonnées reconnues. Par exemple, utilisez checkout_url pour Checkout started et order_status_url pour Order placed. Pour la liste complète, consultez Schémas d’événements.

Métadonnées produit

Utilisez la colonne Product Metadata (JSON) du tableau Products pour ajouter des métadonnées à un produit individuel. Saisissez un objet JSON, tel que {"color": "green", "size": "M"}. Les métadonnées produit présentent les limitations suivantes :

  • Les métadonnées produit ne sont disponibles que lorsque vous décochez Automatically parse e-commerce event from the data layer.
  • La balise envoie les métadonnées produit pour les événements Cart Updated, Checkout started et Order placed. Elle n’envoie pas de métadonnées produit pour Product Viewed, car cet événement ne possède pas de tableau de produits. Utilisez plutôt le tableau eCommerce Event Metadata pour Product Viewed.
  • Si le JSON n’est pas un objet valide, la balise l’ignore.

Vérifier les événements e-commerce

Le SDK Web de Braze valide chaque événement e-commerce. Si une valeur est invalide, le SDK ne journalise pas l’événement et écrit une erreur dans la console du navigateur. GTM affiche tout de même la balise comme déclenchée. Pour résoudre un problème d’événement manquant :

  1. Sélectionnez Enable GTM Tag Debugging dans la balise. La balise journalise alors un message dans la console du navigateur lorsqu’elle ne peut pas lire une valeur de la couche de données, ne trouve aucun produit ou ignore des métadonnées produit invalides.
  2. Ouvrez la console de développement de votre navigateur et recherchez les erreurs du SDK Web de Braze.
  3. Vérifiez les champs obligatoires pour votre type d’événement. Confirmez que les identifiants sont des chaînes de caractères, que price et total_value sont des nombres valides et que quantity est un nombre entier.

Pour les schémas d’événements et la validation à l’ingestion, consultez Journaliser des événements e-commerce et Validation des événements et résolution des problèmes.

Journaliser des événements personnalisés avec GTM

Vous pouvez journaliser des événements personnalisés à l’aide d’une balise Custom HTML dans GTM. Cette approche utilise la couche de données GTM pour transmettre les données d’événement de votre site à une balise GTM qui appelle le SDK Web de Braze.

Étape 1 : Envoyer l’événement à la couche de données

Dans le code de votre site, envoyez un événement à la couche de données à l’endroit où vous souhaitez déclencher l’événement personnalisé. Par exemple, pour journaliser un événement personnalisé lors d’un clic sur un bouton :

<button onclick="dataLayer.push({'event': 'my_custom_event'});">Track Event</button>

Étape 2 : Créer un déclencheur dans GTM

  1. Dans votre conteneur GTM, accédez à Triggers et créez un nouveau déclencheur.
  2. Définissez le Trigger Type sur Custom Event.
  3. Définissez le Event Name sur la même valeur que celle que vous avez envoyée à la couche de données (par exemple, my_custom_event).
  4. Choisissez quand le déclencheur doit se déclencher (par exemple, All Custom Events).

Étape 3 : Créer une balise Custom HTML

  1. Dans GTM, accédez à Tags et créez une nouvelle balise.
  2. Définissez le Tag Type sur Custom HTML.
  3. Dans le champ HTML, ajoutez le code suivant :

     <script>
     window.braze.logCustomEvent("my_custom_event");
     </script>
    
  4. Sous Triggering, sélectionnez le déclencheur que vous avez créé à l’étape 2.
  5. Enregistrez et publiez votre conteneur.

Pour inclure des propriétés d’événement, transmettez-les comme second argument :

<script>
window.braze.logCustomEvent("my_custom_event", {"property_key": "property_value"});
</script>

Environnements CSP stricts (basés sur le nonce)

La balise Braze Initialization ne prend actuellement pas en charge la transmission de contentSecurityNonce à braze.initialize(). Si votre site applique une CSP stricte basée sur le nonce, utilisez une balise Custom HTML au lieu de la balise Braze Initialization.

  1. Suspendez ou supprimez la balise Braze Initialization de votre conteneur GTM si vous l’avez déjà configurée.
  2. Envoyez votre nonce généré par le serveur vers dataLayer avant l’extrait de code GTM dans le HTML de votre site :

     <script nonce="SERVER_GENERATED_NONCE">
       dataLayer = window.dataLayer || [];
       dataLayer.push({ cspNonce: 'SERVER_GENERATED_NONCE' });
     </script>
    
  3. Dans GTM, créez une Data Layer Variable mappée sur cspNonce (par exemple, DLV - cspNonce).
  4. Créez une balise Custom HTML avec le déclencheur défini sur Initialization - All Pages :

    Personnalisez le modèle suivant pour votre environnement.

     <script nonce="{{DLV - cspNonce}}">
       var s = document.createElement('script');
       s.src = 'https://js.appboycdn.com/web-sdk/YOUR_SDK_VERSION/braze.min.js';
       s.setAttribute('nonce', '{{DLV - cspNonce}}');
       s.onload = function() {
         braze.initialize('YOUR_API_KEY', {
           baseUrl: 'YOUR_SDK_ENDPOINT',
           contentSecurityNonce: '{{DLV - cspNonce}}'
         });
         braze.openSession();
       };
       document.head.appendChild(s);
     </script>
    
  5. Pour la balise Braze Actions ou toute balise Custom HTML qui appelle des méthodes Braze, configurez le séquençage des balises pour qu’elle se déclenche après cette balise Custom HTML.

Dans le cadre de la politique de consentement des utilisateurs de l’UE de Google, les attributs personnalisés booléens suivants doivent être journalisés dans les profils utilisateur :

  • $google_ad_user_data
  • $google_ad_personalization

Si vous les définissez via l’intégration GTM, les attributs personnalisés nécessitent la création d’une balise HTML personnalisée. Voici un exemple de la manière de journaliser ces valeurs en tant que types de données booléens (et non en tant que chaînes de caractères) :

<script>
window.braze.getUser().setCustomUserAttribute("$google_ad_personalization", true);
</script>

Pour plus d’informations, consultez Audience Sync vers Google.

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Android de Braze.

Utilisation de Google Tag gestionnaire pour Android

Dans l’exemple suivant, une application de flux d’événements musicaux souhaite journaliser différents événements au fur et à mesure que les utilisateurs écoutent des chansons. À l’aide du Google Tag gestionnaire pour Android, ils peuvent contrôler quels fournisseurs tiers de Braze reçoivent cet événement, et créer des tags spécifiques à Braze.

Étape 1 : Créer un déclencheur pour les événements personnalisés

Les événements personnalisés sont enregistrés avec actionType réglé sur logEvent. Dans cet exemple, le fournisseur d’étiquettes personnalisées de Braze attend que le nom de l’événement personnalisé soit défini à l’aide de eventName.

Pour commencer, créez un déclencheur qui recherche un « nom de l’événement » qui équivaut à played song

Dans Google Tag Manager, un déclencheur personnalisé est défini pour déclencher certains événements lorsque « nom de l’événement » est égal à « chanson jouée ».

Ensuite, créez une nouvelle étiquette (également appelée “appel de fonction”) et entrez le chemin de classe de votre fournisseur d’étiquettes personnalisé décrit plus loin dans cet article. Cette étiquette sera déclenchée lorsque vous enregistrerez l’événement played song.

Dans les paramètres personnalisés de l’étiquette (également connus sous le nom de paire clé-valeur), définissez eventName comme played song. Il s’agit du nom de l’événement personnalisé enregistré dans Braze.

Une balise dans Google Tag Manager avec des champs de chemin de classe et de paires clé-valeur. Cette balise est définie pour répondre au déclencheur créé précédemment « chanson jouée ».

Vous pouvez également inclure des arguments de paires clé-valeur supplémentaires à la balise, qui seront envoyés en tant que propriétés d’événement personnalisé à Braze. eventName et actionType ne seront pas ignorés pour les propriétés d’événement personnalisé. Dans l’exemple de balise suivant, genre est transmis et défini à l’aide d’une variable de balise dans Google Tag gestionnaire, qui provient de l’événement personnalisé enregistré dans l’application.

Étant donné que Google Tag gestionnaire pour Android utilise Firebase comme couche de données, la propriété d’événement genre est envoyée à Google Tag gestionnaire en tant que variable “Firebase - Paramètre d’événement”.

Une variable du Google Tag Manager où « genre » est ajouté en tant que paramètre de l’événement pour la bibliothèque « Braze - événement de musique jouée ».

Lorsqu’un utilisateur joue une chanson dans l’application, un événement sera enregistré via Firebase et Google Tag gestionnaire en utilisant le nom de l’événement d’analyse/analytique de Firebase qui correspond au nom du déclencheur de l’étiquette, played song:

Bundle params = new Bundle();
params.putString("genre", "pop");
params.putInt("number of times listened", 42);
mFirebaseAnalytics.logEvent("played song", params);
val params = Bundle()
params.putString("genre", "pop")
params.putInt("number of times listened", 42);
mFirebaseAnalytics.logEvent("played song", params)

Étape 2 : Enregistrer les attributs personnalisés

Les attributs personnalisés sont définis via un actionType réglé sur customAttribute. Le fournisseur de balises personnalisées Braze attend de la clé-valeur d’attribut personnalisée qu’elle soit définie via customAttributeKey et customAttributeValue :

Bundle params = new Bundle();
params.putString("customAttributeKey", "favorite song");
params.putString("customAttributeValue", "Private Eyes");
mFirebaseAnalytics.logEvent("customAttribute", params);
val params = Bundle()
params.putString("customAttributeKey", "favorite song")
params.putString("customAttributeValue", "Private Eyes")
mFirebaseAnalytics.logEvent("customAttribute", params)

Étape 3 : Appeler changeUser()

Les appels vers changeUser() sont réalisés via un actionType réglé sur changeUser. Le fournisseur de balises personnalisées Braze attend que l’ID utilisateur Braze soit réglé via une paire clé-valeur externalUserId dans votre balise :

Bundle params = new Bundle();
params.putString("externalUserId", userId);
mFirebaseAnalytics.logEvent("changeUser", params);
val params = Bundle()
params.putString("externalUserId", userId)
mFirebaseAnalytics.logEvent("changeUser", params)

Étape 4 : Ajouter un fournisseur d’étiquettes personnalisé

Une fois les tags et les déclencheurs gérés, vous devrez également implémenter Google Tag gestionnaire dans votre application Android, ce que vous trouverez dans la documentation de Google.

Une fois le gestionnaire Google Tag gestionnaire installé dans votre application, ajoutez un fournisseur d’étiquettes personnalisé pour appeler les méthodes du SDK Braze en fonction des tags que vous avez configurés dans le gestionnaire Google Tag gestionnaire.

Veillez à noter le “chemin de classe” du fichier - c’est ce que vous indiquerez lorsque vous configurerez une étiquette dans la console du gestionnaire Google.

Cet exemple illustre l’une des nombreuses façons dont vous pouvez structurer votre fournisseur d’étiquettes personnalisées. Plus précisément, il montre comment déterminer la méthode SDK Braze à appeler en fonction de la paire clé-valeur actionType envoyée par l’étiquette GTM.

Les actionType présentés dans cet exemple sont logEvent, customAttribute, et changeUser, mais il se peut que vous préfériez modifier la façon dont votre fournisseur d’étiquettes traite les données provenant de Google Tag gestionnaire.

public class BrazeGtmTagProvider implements CustomTagProvider {
  private static final String TAG = BrazeLogger.getBrazeLogTag(BrazeGtmTagProvider.class);
  private static final String ACTION_TYPE_KEY = "actionType";

  // Custom Events
  private static final String LOG_EVENT_ACTION_TYPE = "logEvent";
  private static final String EVENT_NAME_VARIABLE = "eventName";

  // Custom Attributes
  private static final String CUSTOM_ATTRIBUTE_ACTION_TYPE = "customAttribute";
  private static final String CUSTOM_ATTRIBUTE_KEY = "customAttributeKey";
  private static final String CUSTOM_ATTRIBUTE_VALUE_KEY = "customAttributeValue";

  // Change User
  private static final String CHANGE_USER_ACTION_TYPE = "changeUser";
  private static final String CHANGE_USER_ID_VARIABLE = "externalUserId";

  private static Context sApplicationContext;

  /**
   * Must be set before calling any of the following methods
   * so that the proper application context is available when needed.
   *
   * Recommended to be called in your {@link Application#onCreate()}.
   */
  public static void setApplicationContext(Context applicationContext) {
    if (applicationContext != null) {
      sApplicationContext = applicationContext.getApplicationContext();
    }
  }

  @Override
  public void execute(Map<String, Object> map) {
    BrazeLogger.i(TAG, "Got google tag manager parameters map: " + map);

    if (sApplicationContext == null) {
      BrazeLogger.w(TAG, "No application context provided to this tag provider.");
      return;
    }

    if (!map.containsKey(ACTION_TYPE_KEY)) {
      BrazeLogger.w(TAG, "Map does not contain the Braze action type key: " + ACTION_TYPE_KEY);
      return;
    }
    String actionType = String.valueOf(map.remove(ACTION_TYPE_KEY));

    switch (actionType) {
      case LOG_EVENT_ACTION_TYPE:
        logEvent(map);
        break;
      case CUSTOM_ATTRIBUTE_ACTION_TYPE:
        setCustomAttribute(map);
        break;
      case CHANGE_USER_ACTION_TYPE:
        changeUser(map);
        break;
      default:
        BrazeLogger.w(TAG, "Got unknown action type: " + actionType);
        break;
    }
  }

  private void logEvent(Map<String, Object> tagParameterMap) {
    String eventName = String.valueOf(tagParameterMap.remove(EVENT_NAME_VARIABLE));
    Braze.getInstance(sApplicationContext).logCustomEvent(eventName, parseMapIntoProperties(tagParameterMap));
  }

  private BrazeProperties parseMapIntoProperties(Map<String, Object> map) {
    BrazeProperties brazeProperties = new BrazeProperties();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
      final Object value = entry.getValue();
      final String key = entry.getKey();
      if (value instanceof Boolean) {
        brazeProperties.addProperty(key, (Boolean) value);
      } else if (value instanceof Integer) {
        brazeProperties.addProperty(key, (Integer) value);
      } else if (value instanceof Date) {
        brazeProperties.addProperty(key, (Date) value);
      } else if (value instanceof Long) {
        brazeProperties.addProperty(key, (Long) value);
      } else if (value instanceof String) {
        brazeProperties.addProperty(key, (String) value);
      } else if (value instanceof Double) {
        brazeProperties.addProperty(key, (Double) value);
      } else {
        BrazeLogger.w(TAG, "Failed to parse value into an BrazeProperties "
            + "accepted type. Key: '" + key + "' Value: '" + value + "'");
      }
    }

    return brazeProperties;
  }

  private void setCustomAttribute(Map<String, Object> tagParameterMap) {
    String key = String.valueOf(tagParameterMap.get(CUSTOM_ATTRIBUTE_KEY));
    Object value = tagParameterMap.get(CUSTOM_ATTRIBUTE_VALUE_KEY);

    Braze.getInstance(sApplicationContext).getCurrentUser(new IValueCallback<BrazeUser>() {
      @Override
      public void onSuccess(BrazeUser brazeUser) {
        if (value instanceof Boolean) {
          brazeUser.setCustomUserAttribute(key, (Boolean) value);
        } else if (value instanceof Integer) {
          brazeUser.setCustomUserAttribute(key, (Integer) value);
        } else if (value instanceof Long) {
          brazeUser.setCustomUserAttribute(key, (Long) value);
        } else if (value instanceof String) {
          brazeUser.setCustomUserAttribute(key, (String) value);
        } else if (value instanceof Double) {
          brazeUser.setCustomUserAttribute(key, (Double) value);
        } else if (value instanceof Float) {
          brazeUser.setCustomUserAttribute(key, (Float) value);
        } else {
          BrazeLogger.w(TAG, "Failed to parse value into a custom "
              + "attribute accepted type. Key: '" + key + "' Value: '" + value + "'");
        }
      }
    });
  }

  private void changeUser(Map<String, Object> tagParameterMap) {
    String userId = String.valueOf(tagParameterMap.get(CHANGE_USER_ID_VARIABLE));
    Braze.getInstance(sApplicationContext).changeUser(userId);
  }
}
class BrazeGtmTagProvider : CustomTagProvider {

  override fun execute(map: MutableMap<String, Any>) {
    BrazeLogger.i(TAG, "Got google tag manager parameters map: $map")

    if (sApplicationContext == null) {
      BrazeLogger.w(TAG, "No application context provided to this tag provider.")
      return
    }

    if (!map.containsKey(ACTION_TYPE_KEY)) {
      BrazeLogger.w(TAG, "Map does not contain the Braze action type key: $ACTION_TYPE_KEY")
      return
    }
    val actionType = map.remove(ACTION_TYPE_KEY).toString()

    when (actionType) {
      LOG_EVENT_ACTION_TYPE -> logEvent(map)
      CUSTOM_ATTRIBUTE_ACTION_TYPE -> setCustomAttribute(map)
      CHANGE_USER_ACTION_TYPE -> changeUser(map)
      else -> BrazeLogger.w(TAG, "Got unknown action type: $actionType")
    }
  }

  private fun logEvent(tagParameterMap: MutableMap<String, Any>) {
    val eventName = tagParameterMap.remove(EVENT_NAME_VARIABLE).toString()
    Braze.getInstance(sApplicationContext).logCustomEvent(eventName, parseMapIntoProperties(tagParameterMap))
  }

  private fun parseMapIntoProperties(map: Map<String, Any>): BrazeProperties {
    val brazeProperties = BrazeProperties()
    map.forEach { param ->
      val key = param.key
      val value = param.value
      when (value) {
        is Boolean -> brazeProperties.addProperty(key, value)
        is Int -> brazeProperties.addProperty(key, value)
        is Date -> brazeProperties.addProperty(key, value)
        is Long -> brazeProperties.addProperty(key, value)
        is String -> brazeProperties.addProperty(key, value)
        is Double -> brazeProperties.addProperty(key, value)
        else -> BrazeLogger.w(TAG, "Failed to parse value into an BrazeProperties "
            + "accepted type. Key: '" + key + "' Value: '" + value + "'")
      }
    }

    return brazeProperties
  }

  private fun setCustomAttribute(tagParameterMap: Map<String, Any>) {
    val key = tagParameterMap[CUSTOM_ATTRIBUTE_KEY].toString()
    val value = tagParameterMap[CUSTOM_ATTRIBUTE_VALUE_KEY]

    Braze.getInstance(sApplicationContext).getCurrentUser { brazeUser ->
      when (value) {
        is Boolean -> brazeUser.setCustomUserAttribute(key, value)
        is Int -> brazeUser.setCustomUserAttribute(key, value)
        is Long -> brazeUser.setCustomUserAttribute(key, value)
        is String -> brazeUser.setCustomUserAttribute(key, value)
        is Double -> brazeUser.setCustomUserAttribute(key, value)
        is Float -> brazeUser.setCustomUserAttribute(key, value)
        else -> BrazeLogger.w(
          TAG, "Failed to parse value into a custom "
            + "attribute accepted type. Key: '" + key + "' Value: '" + value + "'"
        )
      }
    }
  }

  private fun changeUser(tagParameterMap: Map<String, Any>) {
    val userId = tagParameterMap[CHANGE_USER_ID_VARIABLE].toString()
    Braze.getInstance(sApplicationContext).changeUser(userId)
  }

  companion object {
    private val TAG = BrazeLogger.getBrazeLogTag(BrazeGtmTagProvider::class.java)
    private val ACTION_TYPE_KEY = "actionType"

    // Custom Events
    private val LOG_EVENT_ACTION_TYPE = "logEvent"
    private val EVENT_NAME_VARIABLE = "eventName"

    // Custom Attributes
    private val CUSTOM_ATTRIBUTE_ACTION_TYPE = "customAttribute"
    private val CUSTOM_ATTRIBUTE_KEY = "customAttributeKey"
    private val CUSTOM_ATTRIBUTE_VALUE_KEY = "customAttributeValue"

    // Change User
    private val CHANGE_USER_ACTION_TYPE = "changeUser"
    private val CHANGE_USER_ID_VARIABLE = "externalUserId"

    private var sApplicationContext: Context? = null

    /**
     * Must be set before calling any of the following methods so
     * that the proper application context is available when needed.
     *
     * Recommended to be called in your [Application.onCreate].
     */
    fun setApplicationContext(applicationContext: Context?) {
      if (applicationContext != null) {
        sApplicationContext = applicationContext.applicationContext
      }
    }
  }
}

Dans votre Application.onCreate() assurez-vous d’ajouter l’initialisation suivante pour l’extrait de code précédent :

BrazeGtmTagProvider.setApplicationContext(this.getApplicationContext());
BrazeGtmTagProvider.setApplicationContext(this.applicationContext)

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Braze Swift.

Utilisation de Google Tag gestionnaire pour Swift

Dans l’exemple suivant, une application de flux d’événements musicaux souhaite journaliser différents événements au fur et à mesure que les utilisateurs écoutent des chansons. À l’aide de Google Tag gestionnaire pour iOS, ils peuvent contrôler quels fournisseurs tiers de Braze reçoivent cet événement et créer des tags spécifiques à Braze.

Étape 1 : Créer un déclencheur pour les événements personnalisés

Les événements personnalisés sont enregistrés avec actionType réglé sur logEvent. Dans cet exemple, le fournisseur d’étiquettes personnalisées de Braze attend que le nom de l’événement personnalisé soit défini à l’aide de eventName.

Tout d’abord, créez un déclencheur qui recherche un eventName égal à played song.

Dans Google Tag Manager, un déclencheur personnalisé est défini pour déclencher certains événements lorsque « eventName » est égal à « played song ».

Ensuite, créez une nouvelle étiquette (également appelée “appel de fonction”) et entrez le chemin de classe de votre fournisseur d’étiquettes personnalisé décrit plus loin dans cet article. Cette étiquette sera déclenchée lorsque vous enregistrerez l’événement played song. Comme eventName est défini sur played song, il sera utilisé comme nom d’événement personnalisé enregistré dans Braze.

Une balise dans Google Tag Manager avec des champs de chemin de classe et de paires clé-valeur. Cette balise est définie pour répondre au déclencheur créé précédemment « chanson jouée ».

Vous pouvez également inclure des arguments de paires clé-valeur supplémentaires à la balise, qui seront envoyés en tant que propriétés d’événement personnalisé à Braze. eventName et actionType ne seront pas ignorés pour les propriétés d’événement personnalisé. Dans l’exemple de balise suivant, transmettez genre, qui a été défini à l’aide d’une variable de balise dans Google Tag gestionnaire et qui provient de l’événement personnalisé enregistré dans l’application.

La propriété de l’événement genre est envoyée à l’outil Google Tag gestionnaire en tant que variable « Firebase - paramètre de l’événement » étant donné que Google Tag gestionnaire pour iOS utilise Firebase comme couche de données.

Une variable du Google Tag Manager où « genre » est ajouté en tant que paramètre de l’événement pour la bibliothèque « Braze - événement de musique jouée ».

Lorsqu’un utilisateur joue une chanson dans l’application, enregistrez un événement via Firebase et Google Tag gestionnaire en utilisant le nom de l’événement d’analyse/analytique de Firebase qui correspond au nom du déclencheur de l’étiquette, played song:

let parameters: [String: Any] = ["genre": "pop",
                                 "number of times listened": 42]
Analytics.logEvent("played song", parameters: parameters)
NSDictionary *parameters = @{@"genre" : @"pop",
                             @"number of times listened" : @42};
[FIRAnalytics logEventWithName:@"played song" parameters:parameters];

Étape 2 : Enregistrer les attributs personnalisés

Les attributs personnalisés sont définis via un actionType réglé sur customAttribute. Le fournisseur de balises personnalisées Braze attend de la clé-valeur d’attribut personnalisée qu’elle soit définie via customAttributeKey et customAttributeValue :

let parameters: [String: Any] = ["customAttributeKey": "favoriteSong",
                                 "customAttributeValue": "Private Eyes"]
FIRAnalytics.logEvent(withName:"customAttribute", parameters: parameters)
NSDictionary *parameters = @{@"customAttributeKey" : @"favoriteSong",
                             @"customAttributeValue" : @"Private Eyes"};
[FIRAnalytics logEventWithName:@"customAttribute" parameters:parameters];

Étape 3 : Appeler changeUser()

Les appels vers changeUser() sont réalisés via un actionType réglé sur changeUser. Le fournisseur de balises personnalisées Braze attend que l’ID utilisateur Braze soit réglé via une paire clé-valeur externalUserId dans votre balise :

let parameters: [String: Any] = ["externalUserId": "favorite userId"]
Analytics.logEvent(withName:"changeUser", parameters: parameters)
NSDictionary *parameters = @{@"externalUserId" : userId};
[FIRAnalytics logEventWithName:@"changeUser" parameters:parameters];

Étape 4 : Ajouter un fournisseur d’étiquettes personnalisé

Une fois les tags et les déclencheurs configurés, vous devrez également mettre en œuvre Google Tag gestionnaire dans votre application iOS, ce que vous trouverez dans la documentation de Google.

Une fois Google Tag gestionnaire installé dans votre application, ajoutez un fournisseur d’étiquettes personnalisé pour appeler les méthodes du SDK de Braze en fonction des tags que vous avez configurés dans Google Tag gestionnaire.

Assurez-vous de noter le « chemin de classe » vers le fichier. C’est ce que vous allez saisir lors de la définition d’une balise dans la console de Google Tag gestionnaire.

Cet exemple illustre l’une des nombreuses façons dont vous pouvez structurer votre fournisseur d’étiquettes personnalisées. Plus précisément, il montre comment déterminer la méthode SDK Braze à appeler en fonction de la paire clé-valeur actionType envoyée par l’étiquette GTM. Cet exemple suppose que vous avez assigné l’instance de Braze en tant que variable dans l’AppDelegate.

Les actionType pris en charge dans cet exemple sont logEvent, customAttribute, et changeUser, mais il se peut que vous préfériez modifier la façon dont votre fournisseur d’étiquettes traite les données provenant de Google Tag gestionnaire.

Ajoutez le code suivant à votre fichier BrazeGTMTagManager.swift.

import FirebaseAnalytics
import GoogleTagManager
import BrazeKit

let ActionTypeKey: String = "actionType"

// Custom Events
let LogEventAction: String = "logEvent"
let LogEventName: String = "eventName"

// Custom Attributes
let CustomAttributeAction: String = "customAttribute"
let CustomAttributeKey: String = "customAttributeKey"
let CustomAttributeValueKey: String = "customAttributeValue"

// Change User
let ChangeUserAction: String = "changeUser"
let ChangeUserExternalUserId: String = "externalUserId"

@objc(BrazeGTMTagManager)
final class BrazeGTMTagManager : NSObject, TAGCustomFunction {
  @objc func execute(withParameters parameters: [AnyHashable : Any]!) -> NSObject! {
    var parameters: [String : Any] = parameters as! [String : Any]
    guard let actionType: String = parameters[ActionTypeKey] as? String else {
      print("There is no Braze action type key in this call. Doing nothing.")
      return nil
    }
    parameters.removeValue(forKey: ActionTypeKey)
    if actionType == LogEventAction {
      logEvent(parameters: parameters)
    } else if actionType == CustomAttributeAction {
      logCustomAttribute(parameters: parameters)
    } else if actionType == ChangeUserAction {
      changeUser(parameters: parameters)
    }
    return nil
  }
  
  func logEvent(parameters: [String : Any]) {
    var parameters: [String : Any] = parameters
    guard let eventName: String = parameters[LogEventName] as? String else { return }
    parameters.removeValue(forKey: LogEventName)
    AppDelegate.braze?.logCustomEvent(name: eventName, properties: parameters)
  }
  
  func logCustomAttribute(parameters: [String: Any]) {
    guard let customAttributeKey = parameters[CustomAttributeKey] as? String else { return }
    let customAttributeValue = parameters[CustomAttributeValueKey]
    
    if let customAttributeValue = customAttributeValue as? String {
      AppDelegate.braze?.user.setCustomAttribute(key: customAttributeKey, value: customAttributeValue)
    } else if let customAttributeValue = customAttributeValue as? Date {
      AppDelegate.braze?.user.setCustomAttribute(key: customAttributeKey, value: customAttributeValue)
    } else if let customAttributeValue = customAttributeValue as? Double {
      AppDelegate.braze?.user.setCustomAttribute(key: customAttributeKey, value: customAttributeValue)
    } else if let customAttributeValue = customAttributeValue as? Bool {
      AppDelegate.braze?.user.setCustomAttribute(key: customAttributeKey, value: customAttributeValue)
    } else if let customAttributeValue = customAttributeValue as? Int {
      AppDelegate.braze?.user.setCustomAttribute(key: customAttributeKey, value: customAttributeValue)
    } else if let customAttibuteValue = customAttributeValue as? [String] {
      AppDelegate.braze?.user.setCustomAttributeArray(key: customAttributeKey, array: customAttibuteValue)
    }
  }
  
  func changeUser(parameters: [String: Any]) {
    guard let userId = parameters[ChangeUserExternalUserId] as? String else { return }
    AppDelegate.braze?.changeUser(userId: userId)
  }
}

Ajoutez le code suivant à votre fichier BrazeGTMTagManager.h :

@import Firebase;
@import GoogleTagManager;

@interface BrazeGTMTagManager : NSObject <TAGCustomFunction>

@end

Et ajoutez le code suivant à votre fichier BrazeGTMTagManager.m :

#import <Foundation/Foundation.h>
#import "BrazeGTMTagManager.h"
#import "BrazeKit"
#import "AppDelegate.h"

static NSString *const ActionTypeKey = @"actionType";

// Custom Events
static NSString *const LogEventAction = @"logEvent";
static NSString *const LogEventEventName = @"eventName";

// Custom Attributes
static NSString *const CustomAttributeAction = @"customAttribute";
static NSString *const CustomAttributeKey = @"customAttributeKey";
static NSString *const CustomAttributeValueKey = @"customAttributeValue";

// Change User
static NSString *const ChangeUserAction = @"changeUser";
static NSString *const ChangeUserExternalUserId = @"externalUserId";

@implementation BrazeGTMTagManager

- (NSObject *)executeWithParameters:(NSDictionary *)parameters {
  NSMutableDictionary *mutableParameters = [parameters mutableCopy];
  
  NSString *actionType = mutableParameters[ActionTypeKey];
  if (!actionType) {
    NSLog(@"There is no Braze action type key in this call. Doing nothing.", nil);
    return nil;
  }
  
  [mutableParameters removeObjectForKey:ActionTypeKey];
  
  if ([actionType isEqualToString:LogEventAction]) {
    [self logEvent:mutableParameters];
  } else if ([actionType isEqualToString:CustomAttributeAction]) {
    [self logCustomAttribute:mutableParameters];
  } else if ([actionType isEqualToString:ChangeUserAction]) {
    [self changeUser:mutableParameters];
  } else {
    NSLog(@"Invalid action type. Doing nothing.");
  }
  return nil;
}

- (void)logEvent:(NSMutableDictionary *)parameters {
  NSString *eventName = parameters[LogEventEventName];
  [parameters removeObjectForKey:LogEventEventName];
  [AppDelegate.braze logCustomEvent:eventName
                         properties:parameters];
}

- (void)logCustomAttribute:(NSMutableDictionary *)parameters {
  NSString *customAttributeKey = parameters[CustomAttributeKey];
  id customAttributeValue = parameters[CustomAttributeValueKey];
  
  if ([customAttributeValue isKindOfClass:[NSString class]]) {
    [AppDelegate.braze logCustomEvent:customAttributeKey
                           properties:parameters];
  } else if ([customAttributeValue isKindOfClass:[NSDate class]]) {
    [AppDelegate.braze.user setCustomAttributeWithKey:customAttributeKey
                                            dateValue:customAttributeValue];
  } else if ([customAttributeValue isKindOfClass:[NSNumber class]]) {
    if (strcmp([customAttributeValue objCType], [@(YES) objCType]) == 0) {
      [AppDelegate.braze.user setCustomAttributeWithKey:customAttributeKey
                                              boolValue:[(NSNumber *)customAttributeValue boolValue]];
    } else if (strcmp([customAttributeValue objCType], @encode(short)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(int)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(long)) == 0) {
      [AppDelegate.braze.user setCustomAttributeWithKey:customAttributeKey
                                               intValue:[(NSNumber *)customAttributeValue integerValue]];
    } else if (strcmp([customAttributeValue objCType], @encode(float)) == 0 ||
               strcmp([customAttributeValue objCType], @encode(double)) == 0) {
      [AppDelegate.braze.user setCustomAttributeWithKey:customAttributeKey
                                            doubleValue:[(NSNumber *)customAttributeValue doubleValue]];
    } else {
      NSLog(@"Could not map NSNumber value to Braze custom attribute:%@", customAttributeValue);
    }
  } else if ([customAttributeValue isKindOfClass:[NSArray class]]) {
    [AppDelegate.braze.user setCustomAttributeArrayWithKey:customAttributeKey
                                                     array:customAttributeValue];
  }
}

- (void)changeUser:(NSMutableDictionary *)parameters {
  NSString *userId = parameters[ChangeUserExternalUserId];
  [AppDelegate.braze changeUser:userId];
}

@end

Résolution des problèmes

Sessions du SDK Web attribuées au mauvais utilisateur

Si GTM déclenche les balises d’initialisation ou d’événement de Braze avant que votre application identifie l’utilisateur connecté, les sessions et les événements peuvent être rattachés au mauvais profil. Initialisez le SDK Web, appelez changeUser() avec l’external_id de l’utilisateur connecté, puis appelez openSession() avant toute balise qui enregistre des événements ou définit des attributs. Utilisez le séquencement des balises GTM ou des déclencheurs de consentement pour que les balises Braze ne s’exécutent qu’après la fin de votre flux d’authentification.

Journalisation console du SDK Web avec Shopify ou les installations par balise de script

L’intégration de l’application Shopify charge le SDK Web avec la journalisation console désactivée. Configurez la journalisation dans votre balise d’initialisation GTM ou dans les options d’initialize(). Le tableau de bord de Braze n’inclut pas de contrôle de journalisation pour ces chargeurs.

Si des journaux Braze apparaissent dans la console du navigateur, supprimez enableLogging: true de la balise d’initialisation GTM ou du HTML personnalisé avant de publier en production. Après l’initialisation, utilisez toggleLogging() ou le paramètre d’URL ?brazeLogging=true. Pour l’ensemble des options du SDK Web, consultez Journalisation détaillée.

Si Braze ne s’initialise pas ou si les événements n’apparaissent pas comme prévu, vérifiez que votre conteneur GTM est publié, que les déclencheurs et l’ordre de déclenchement des balises correspondent à votre cycle de vie et stratégie d’initialisation du SDK, et que les appareils de test ne bloquent pas les endpoints de Braze.

En cas d’échec d’initialisation, vérifiez que la balise Braze ou le fournisseur d’étiquettes personnalisé reçoit le actionType et les paramètres attendus (consultez les onglets Android, Swift et Web sur cette page). Pour activer la journalisation détaillée lors de la validation des événements déclenchés par GTM, activez la journalisation de débogage du SDK de votre plateforme comme décrit dans les guides d’intégration de la plateforme accessibles depuis ces onglets.

New Stuff!