AmauriC / tarteaucitron.js

RGPD friendly cookie manager
https://tarteaucitron.io/
MIT License
920 stars 369 forks source link

Comment configurer le suivi des conversions spécifiques Google Ads ? #1001

Closed thierryler closed 1 year ago

thierryler commented 2 years ago

Bonjour,

Dans Google Ads, on peut préciser le montant d'une conversion. Par exemple si je veux suivre la page de validation de commande, sachant que chaque client va avoir un montant de commande différent. cf. https://support.google.com/google-ads/answer/6095947

La doc de Google Ads donne cet exemple :

<script>
  gtag('event', 'conversion', {'send_to': 'AW-123456789/AbC-D_efG-h12_34-567',
    'value': 123.05,
    'currency': 'USD'
  });
</script> 

En gros, en plus de la référence, il faut donc ajouter la valeur et la devise.

Dans mon code j'ai :

googleadsId = "AW-10947646675" // Only on specific pages, else null
tarteaucitron.user.gtagUa = 'G-VC3EJMPZD8'
tarteaucitron.user.gtagMore = function () {
  (tarteaucitron.job = tarteaucitron.job || []).push('gtag')
  (tarteaucitron.job = tarteaucitron.job || []).push('googleads')
  tarteaucitron.user.googleadsId = null
  if (googleadsId) {
    tarteaucitron.user.googleadsId = googleadsId
  }
}

J'imagine qu'il faut compléter avec un truc dans ce genre :

tarteaucitron.user.googleadsId = googleadsId
tarteaucitron.user.googleadsAmount = 123,45
tarteaucitron.user.googleadsCurrency = "EUR"

Mais je ne trouve pas ce qu'il faut mettre exactement...

AmauriC commented 2 years ago

En effet ces valeurs n'existent pas mais je peux les ajouter.

J'essai de m'en occuper rapidement ;)

thierryler commented 2 years ago

Ah oui ce serait vraiment super. Merci beaucoup d'avance.

Tu pourras aussi m'indiquer où sera la doc, svp. ?

lucmuller commented 2 years ago

??

Les évènements ne devraient-il pas être gérés au cas par cas dans un script dédié lorsqu'ils surviennent ? Ici, nous avons clairement un event lié à une page particulière et une action de l'utilisateur.

J'ai pour ma part, récemment implémenté du tracking sur le dataLayer de google analytics, je procède ainsi : J'ai un script JS dédié dans lequel je réalise les appels lorsque TAC me renvoie l'event que le script est chargé. En l'occurrence, dans le cas présenté ici, ne suffirait-il pas de faire :

document.addEventListener("googleads_loaded", function() {
  gtag('event', 'conversion', {'send_to': 'AW-123456789/AbC-D_efG-h12_34-567',
    'value': 123.05,
    'currency': 'USD'
  });
});
AmauriC commented 2 years ago

Je ne savais pas que c'était possible mais je préfère cette méthode, plus propre et qui évite de surcharger la configuration.

thierryler commented 2 years ago

Oui oui c'est uniquement sur la page de confirmation de commande.

Ce que j'ai en tête c'est un truc du style, avec la syntaxe de Twig :

{% if amount %}
tarteaucitron.user.googleadsAmount = {{ amount }}
tarteaucitron.user.googleadsCurrency = "EUR"
{% endif %}
lucmuller commented 2 years ago

Je ne savais pas que c'était possible mais je préfère cette méthode, plus propre et qui évite de surcharger la configuration.

J'aurais tendance à dire que toutes les fonctions More quelque chose qui permettent d'ajouter du script sont un peu inutile vu que TAC envoie un Event lors du chargement des services.

C'est d'ailleurs assez pratique pour exécuter des scripts uniquement lorsqu'un utilisateur à donné son consentement.

thierryler commented 2 years ago

Mais au final, tu conseilles de faire quoi, dans mon cas où le code est défini dans mon template.twig, qui est référencé par ma page commande.twig mais aussi par toutes les autres pages du site ?

lucmuller commented 2 years ago

Ben, ton code, c'est du javascript...

Donc quelque chose du style :

{% if amount %}
document.addEventListener("googleads_loaded", function() {
  gtag('event', 'conversion', {'send_to': 'AW-123456789/AbC-D_efG-h12_34-567',
    'value': {{ amount }},
    'currency': 'EUR'
  });
});
{% endif %}

Non ?

A voir comment twig gère l'insertion de JS dans son moteur, car les { } présentes dans le code pourraient poser souci, mais il doit y avoir des possibilités d'injecter du js dans la template.

Après, comme dit, le mieux, c'est d'avoir un fichier javascript dédié dans le footer dans lequel tu va récupérer des variables définies dans la template twig.

Je peux pas répondre précisément, car c'est intimement lié à la structure et aux possibilités offertes par ton outils d'ecommerce.

++ tu dis :

mon template.twig, qui est référencé par ma page commande.twig mais aussi par toutes les autres pages du site ?

De mon point de vue ton code ne devrait se trouver que sur la page commande et pas sur toutes les autres. C'est bien pour ça qu'il doit être indépendant du chargement de TAC.

En résumé : Sur toutes les pages tu insères le script qui gère les initialisations de service TAC. Sur la page commande, tu ajoutes le script qui gère l'évènement "commande réalisée pour tel montant" et qui déclenche l'event que lorsque TAC envoie lui-même l'event googleads_loaded.

AmauriC commented 2 years ago

J'aurais tendance à dire que toutes les fonctions More quelque chose qui permettent d'ajouter du script sont un peu inutile vu que TAC envoie un Event lors du chargement des services.

Les events sont arrivés assez tard et avant c'était géré via les more.

Bien d'accord que ce n'est maintenant plus nécessaire.

Les dissocier du code du service et créer un nouveau fichier pour les events serait sûrement plus clair 👍

Je le note 📝

thierryler commented 2 years ago

J'ai écrit ça :

<script async src="https://www.googletagmanager.com/gtag/js?id=AW-10947646675"></script>

<script>
  tarteaucitron.init({
      "privacyUrl": "/{{ lang }}/cookies", /* Privacy policy url */
      "hashtag": "#tarteaucitron", /* Open the panel with this hashtag */
      "cookieName": "tarteaucitron", /* Cookie name */
      "orientation": "middle", /* Banner position (top - bottom - middle - popup) */
      "groupServices": false, /* Group services by category */
      "showAlertSmall": false, /* Show the small banner on bottom right */
      "cookieslist": true, /* Show the cookie list */
      "showIcon": true, /* Show cookie icon to manage cookies */
      // "iconSrc": "", /* Optionnal: URL or base64 encoded image */
      "iconPosition": "BottomLeft", /* Position of the icon between BottomRight, BottomLeft, TopRight and TopLeft */
      "adblocker": false, /* Show a Warning if an adblocker is detected */
      "DenyAllCta" : true, /* Show the deny all button */
      "AcceptAllCta" : true, /* Show the accept all button when highPrivacy on */
      "highPrivacy": true, /* HIGHLY RECOMMANDED Disable auto consent */
      "handleBrowserDNTRequest": false, /* If Do Not Track == 1, disallow all */
      "removeCredit": false, /* Remove credit link */
      "moreInfoLink": true, /* Show more info link */
      "useExternalCss": false, /* If false, the tarteaucitron.css file will be loaded */
      //"cookieDomain": ".my-multisite-domaine.fr", /* Shared cookie for subdomain website */
      "readmoreLink": "", /* Change the default readmore link pointing to tarteaucitron.io */
      "mandatory": true, /* Show a message about mandatory cookies */
      "closePopup": false, /* Bouton pour fermer la popup du bas */
  });
</script>

<script type="text/javascript">
  tarteaucitron.user.gtagUa = 'G-VC3EJMPZD8';
  tarteaucitron.user.gtagMore = function () { };
  (tarteaucitron.job = tarteaucitron.job || []).push('gtag');
  (tarteaucitron.job = tarteaucitron.job || []).push('googleads');

  let googleadsId = null;
  {% if googleadsId %}
    googleadsId = "{{ googleadsId }}";
  {% endif %}
  googleadsId = 'AW-10947646675'; // pour tester facilement
  tarteaucitron.user.googleadsId = googleadsId;

  let amount = null;
  {% if justPaidInvoice %}
    amount = justPaidInvoice.totalChargedPrice;
  {% endif %}
  amount = 123.45; // pour tester facilement
  if(googleadsId && amount) {
    document.addEventListener('googleads_loaded', function() {
      gtag('event', 'conversion', {
        send_to: googleadsId,
        value: amount,
        currency: 'EUR'
      });
    });
  }
</script>

Le code en Twig s'execute coté serveur, donc il n'est plus présent (ie. déjà remplacé) quand ça arrive sur le browser.

Est ce que c'est bon ? J'ai forcé les variable googleadsId et amount en dur pour tester facilement.

Je ne suis pas trop certain pour la partie send_to: googleadsId car la valeur est composée de 2 ids séparés par un slash dans l'exemple. Et dans Google Ads, il ne me génère pas d'exemple.

En outre j'ai une erreur dans la console, que je ne sais pas résoudre :-(

doc:996 Uncaught ReferenceError: gtag is not defined
    at HTMLDocument.<anonymous> (doc:996:7)
    at Object.sendEvent (tarteaucitron.js:925:22)
    at Object.addService (tarteaucitron.js:876:31)
    at tarteaucitron.js:559:47
    at Object.addScript (tarteaucitron.js:1876:17)
    at Object.addInternalScript (tarteaucitron.js:1908:23)
    at tarteaucitron.js:511:31
    at script.onreadystatechange.script.onload [as onreadystatechange] (tarteaucitron.js:1894:29)
Phoennix commented 1 year ago

Est-ce qu'en remplaçant ton appel à gtag('event', 'conversion', ... par window.gtag('event', 'conversion', ... ça règle ton erreur JavaScript ?

thierryler commented 1 year ago

Pas mieux :-(

Uncaught TypeError: window.gtag is not a function
thierryler commented 1 year ago

Est ce qu'il est possible que l'event googleads_loaded soit lancé avant que gtag ne soit chargé ?

Phoennix commented 1 year ago

Effectivement, la fonction gtag n'est définie qu'au moment de l'exécution de la fonction addScript située dans le service googleads. Or cette fonction addScript n'est exécutée que bien après que les events googleads_loaded (et même googleads_added) aient été lancés.

image

Personnellement, je n'ai pas converti mes scripts pour utiliser les évènements de Tarte au Citron, j'utilise toujours les fonctions comme tarteaucitron.user.googleadsmore, je sais qu'elles sont lancées après que les variables dont j'ai besoin soient initialisées.

Tu peux modifier ton code comme ceci :

<script src="https://www.googletagmanager.com/gtag/js?id=AW-10947646675"></script>

<script>
  tarteaucitron.init({
      "privacyUrl": "/{{ lang }}/cookies", /* Privacy policy url */
      "hashtag": "#tarteaucitron", /* Open the panel with this hashtag */
      "cookieName": "tarteaucitron", /* Cookie name */
      "orientation": "middle", /* Banner position (top - bottom - middle - popup) */
      "groupServices": false, /* Group services by category */
      "showAlertSmall": false, /* Show the small banner on bottom right */
      "cookieslist": true, /* Show the cookie list */
      "showIcon": true, /* Show cookie icon to manage cookies */
      // "iconSrc": "", /* Optionnal: URL or base64 encoded image */
      "iconPosition": "BottomLeft", /* Position of the icon between BottomRight, BottomLeft, TopRight and TopLeft */
      "adblocker": false, /* Show a Warning if an adblocker is detected */
      "DenyAllCta" : true, /* Show the deny all button */
      "AcceptAllCta" : true, /* Show the accept all button when highPrivacy on */
      "highPrivacy": true, /* HIGHLY RECOMMANDED Disable auto consent */
      "handleBrowserDNTRequest": false, /* If Do Not Track == 1, disallow all */
      "removeCredit": false, /* Remove credit link */
      "moreInfoLink": true, /* Show more info link */
      "useExternalCss": false, /* If false, the tarteaucitron.css file will be loaded */
      //"cookieDomain": ".my-multisite-domaine.fr", /* Shared cookie for subdomain website */
      "readmoreLink": "", /* Change the default readmore link pointing to tarteaucitron.io */
      "mandatory": true, /* Show a message about mandatory cookies */
      "closePopup": false, /* Bouton pour fermer la popup du bas */
  });

  let googleadsId = null;
  {% if googleadsId %}
    googleadsId = "{{ googleadsId }}";
  {% endif %}
  googleadsId = 'AW-10947646675'; // pour tester facilement

  let amount = null;
  {% if justPaidInvoice %}
    amount = justPaidInvoice.totalChargedPrice;
  {% endif %}
  amount = 123.45; // pour tester facilement

  tarteaucitron.user.googleadsId = googleadsId;
  tarteaucitron.user.gtagUa = 'G-VC3EJMPZD8';
  tarteaucitron.user.gtagMore = function () { 
    if(googleadsId && amount) {
      window.gtag('event', 'conversion', {
        send_to: googleadsId,
        value: amount,
        currency: 'EUR'
      });
    }
  };
  (tarteaucitron.job = tarteaucitron.job || []).push('gtag', 'googleads');
</script>

Et les conversions seront bien envoyées à Google Ads (code testé sans la partie Twig) :

image

thierryler commented 1 year ago

Ca a l'air de fonctionner. Merci beaucoup.

J'ai mis le code sur cette page : https://force4disc.com/hello

Par contre, je ne sais pas comment remplir la partie "send_to".

Dans l'exemple donné dans la doc de Google, ils mettent :

'send_to': 'AW-123456789/AbC-D_efG-h12_34-567'

Mais je ne suis pas certain de bien comprendre ce qu'on doit concatener. Et le configurateur en ligne de Google Ads n'indique rien évidement...

Sinon, mon code donne ça à ce stade :

<script type="text/javascript">
  {# Google Analytics #}
  tarteaucitron.user.gtagUa = 'G-VC3EJMPZD8';

  {# Google ads #}
  let googleadsId = null;
  {% if googleadsId %}
    googleadsId = "{{ googleadsId }}";
  {% endif %}
  googleadsId = 'AW-10947646675'; // pour tester facilement
  tarteaucitron.user.googleadsId = googleadsId;

  let amount = null;
  {% if justPaidInvoice %}
    amount = justPaidInvoice.totalChargedPrice;
  {% endif %}
  amount = 123.45; // pour tester facilement

  tarteaucitron.user.gtagMore = function () { 
    if(googleadsId && amount) {
      window.gtag('event', 'conversion', {
        send_to: googleadsId,
        value: amount,
        currency: 'EUR'
      });
    }
  };

  {# Linked'in #}
  tarteaucitron.user.linkedininsighttag = '4415690';

  {# Activations #}
  (tarteaucitron.job = tarteaucitron.job || []).push('gtag');
  (tarteaucitron.job = tarteaucitron.job || []).push('googleads');
  (tarteaucitron.job = tarteaucitron.job || []).push('linkedininsighttag');
</script>
AmauriC commented 1 year ago

Merci @Phoennix , en effet dans l'event loaded il faut souvent ajouter un setTimeout pour être sûr que tout est chargé.

Ajouter un event sur addScript ça pourrait être pratique? js_loaded_gtag ?

@thierryler cool que la solution pour tout faire fonctionner via tarteaucitron fonctionne 👍 Pour la suite, il y a des supports dédié aux outils de Google ;)

thierryler commented 1 year ago

Oui merci encore beaucoup.

Vous pensez quoi du fait de regrouper les "push" à la fin ?

Les supports de Google ne répondent pas. Je ne dois pas encore être assez gros... Je lançais surtout une bouteille à la mer...

lucmuller commented 1 year ago

Ajouter un event sur addScript ça pourrait être pratique? js_loaded_gtag ?

Je ne sais pas si la question est générale à TAC, mais je part du principe que l'event 'nomservice_loaded' est déclenché après que tout le service soit chargé.

Si tel n'est pas le cas, ça me semble problématique, non ?

Est-ce qu'il ne faudrait pas alors deux events différents, si c'est possible :

AmauriC commented 1 year ago

L'event est bien appelé après la fonction js mais il peux y avoir un délai le temps que la balise script soit effectivement chargé par le navigateur. https://github.com/AmauriC/tarteaucitron.js/blob/master/tarteaucitron.js#L877

Ajouter un event systématiquement ici https://github.com/AmauriC/tarteaucitron.js/blob/master/tarteaucitron.js#L1895 remplacera tous les ...More.

stale[bot] commented 1 year ago

This issue has been automatically marked as inactive because it has not had activity for 20 days. It will be closed in 5 days if no further activity occurs. Thank you for your contributions.