Analytics

Présentation de GA Spy pour Google Analytics

Stephen Harris (c) Seer Interactive

Ceci est un article invité de Stephen Harris de Seer Interactive. Il a eu la gentillesse de partager sa solution géniale dans ce blog, donc je suis vraiment très reconnaissant pour sa contribution.

Si Google Tag Manager est chargé en tant qu’instrument principal de suivi sur une page Web (comme il se doit), alors tout le suivi de la page Web pourrait et devrait être configurable via GTM. Mais nous ne contrôlons pas toujours les circonstances, et il n’est pas rare de faire face à un suivi Google Analytics codé en dur en dehors de GTM.

Peut-être que le suivi GA ne peut pas être supprimé du code source du site Web assez rapidement. Peut-être que le site Web a un calendrier de publication qui ne répond pas aux besoins de mesure, ou peut-être que les responsables du site Web ne disposent pas de ressources suffisantes. Quelle que soit la raison, vous avez un « non » lorsque vous demandé insisté pour l’enlèvement. (Vous fait insistez pour l’enlever, n’est-ce pas ?)

Ou qu’en est-il lorsqu’il y a des commandes GA codées en dur dans une plate-forme ou un plugin ? Ça pourrait être foutu avec vos données. Mais il y a de fortes chances qu’il ne fasse rien du tout (car il suit le tracker GA par défaut inexistant) et il semble n’y avoir aucun moyen de le faire fonctionner via GTM.

Et même lorsque tout le suivi passe par Google Tag Manager, certaines choses peuvent être difficiles (voire impossibles) à mettre en œuvre à l’aide des modèles de balises (comme l’ajout de plug-ins GA ou la définition des champs de suivi Universal Analytics par défaut).

Voici une solution.

Table des matières

Table des matières

[+show] [–hide]

1. Espionner GA

Vous pouvez récupérer le code sur GitHub. Copiez-collez-le soit dans une balise HTML personnalisée dans Google Tag Manager, soit chargez-le dans le modèle de page proprement dit.

C’est appelé Espion GA car il peut détourner et contrôler en silence tous les suivis qui s’appuient sur la bibliothèque Universal Analytics de Google (analytics.js). Effectivement, c’est un écouteur Google Analytics qui fait du karaté.

Opération d'espionnage GA

Pour le dire en termes simples, le script écoute les interactions avec le ga() interface, renvoyant les arguments passés à la fonction pour que vous les traitiez dans le but que vous souhaitez. Par exemple, vous pouvez copier automatiquement tous les appels vers ga('send'...) pour dataLayer.push() syntaxe, vous permettant de répliquer de manière fluide le suivi Universal Analytics codé en dur dans Google Tag Manager.

Ce billet de blog est écrit en supposant que le suivi codé en dur concerne Universal Analytics, mais il existe une version du script pour la bibliothèque GA asynchrone (ga.js), à laquelle les mêmes concepts de base s’appliquent.

  • Code source pour ga-spy.js

  • Code source pour ga-spy_async.js

  • LISEZMOI

1.1. Code espion 101

Passons en revue la logique du script. Avant de l’implémenter, il est important d’avoir une idée de base de ce que fait réellement ce script. Une fois que vous aurez compris les bases, vous comprendrez également pourquoi cela devrait être considéré comme une solution temporaire. En effet, vous devez documenter l’utilisation de cette solution, de sorte que lorsque le code Universal Analytics codé en dur sera finalement supprimé du site, vous ne serez pas laissé pour compte avec des méthodes qui ne font vraiment rien.

Cette section explique également la plus grande mise en garde de ce script : Espion GA n’est pas garanti d’intercepter (ou même de détecter) le suivi qui se déclenche pendant le chargement de la page (par exemple, l’extrait GA standard) si le hack est déployé via GTM. La capture de ces demandes nécessite que vous déployiez le script sur le modèle de page lui-même, ce qui pourrait malheureusement nuire à l’utilité pour ceux qui n’ont pas de ressources de développement à portée de main.

Pour une ventilation plus technique, consultez le README.

1.2. Un bon espion commence par la recherche

Commençons par un aperçu du fonctionnement du tracker Universal Analytics sur la page.

De nombreux utilisateurs GA connaissent l’espace de noms JavaScript ga. Il s’agit de l’objet global de suivi avec la bibliothèque Universal Analytics (analytics.js). Lorsque le navigateur charge la page, cet objet est en fait traité deux fois. Tout d’abord, il est créé par l’extrait de code Universal Analytics, et il files d’attente toutes les commandes à ga() en attendant que la bibliothèque se charge. Ensuite, une fois la bibliothèque chargée, l’espace de noms est converti en une interface complète qui traite chaque commande au fur et à mesure de son exécution.

Fonctionnement de la bibliothèque GA

Ainsi, l’extrait de code Universal Analytics standard instancie ga comme une petite fonction qui enregistre tous les arguments que vous lui transmettez en tant que tableau dans ga.q. C’est ce qu’on appelle le file d’attente de commandes. Il est créé par la deuxième ligne de la fonction d’extrait de code d’installation GA, illustrée ici (agrémentée de noms de variables plus lisibles) :

window[gaObjName] = window[gaObjName] || function() {   ( window[gaObjName].q = window[gaObjName].q || [] ).push( arguments ) }, ga.l = 1 * new Date(); 

À part : remarquez des similitudes avec le format recommandé pour les poussées de couche de données ?

( window.dataLayer = window.dataLayer || [] ).push( { } ) 

Une fois cette file d’attente établie, l’extrait de code crée un chargeur de scriptsqui lance une requête asynchrone pour télécharger le analytics.js bibliothèque des serveurs de Google.

Une fois analytics.js chargé, il exécutera les commandes dans la file d’attente de commandes et remplacera la fonction de file d’attente ga avec un objet beaucoup plus robuste, que nous appelons le ga objet ou fonction. Une fois que cela arrive, ga arrête de suivre les commandes précédemment appelées et exécute les commandes dès qu’elles sont appelées.

1.3. Mouvements d’espionnage

Le cœur de ce script est le hijack une fonction. Ce qu’il fait est simple : il enregistre une référence privée au global ga objet, puis met à jour la référence globale (window.ga ou simplement ga) pour pointer vers une fonction personnalisée, que nous appellerons notre fonction “proxy”. Notez que si vous avez choisi de renommer la fonction globale autrement que gail fonctionnera toujours bien avec Espion GA.

function hijack(){   // The current global GA object (could be GA command queue or loaded GA object).   var gaOrig = window.ga;   // Replace global GA object with a proxy.   window.ga = proxy;   // Maintain references to GA's public interface.   for( k in gaOrig )      if( gaOrig.hasOwnProperty( k ) )         proxy[k] = gaOrig[k]; } 

Les proxy la fonction imite les membres de données et les méthodes de l’original ga une fonction. Ainsi, il se comporte comme l’original, ce que nous accomplissons en renvoyant ses arguments au ga fonction (et renvoyant le résultat). Mais, seulement si nous le choisissons. Nous pouvons rejeter le message, simplement en n’envoyant pas le message à l’original ga fonction, et ainsi intercepter et empêcher le GA codé en dur d’exécuter complètement ses requêtes.

function proxy(){   // Grab all arguments as an array.   var args = [].slice.call( arguments );   // Unless processArgs() returns false ...   if( processArgs( args ) )      // ... pass through to original GA object.      return gaOrig.apply( gaOrig, args ); }; 

Les processArgs La fonction vous délègue simplement le traitement et le filtrage de toutes les commandes (via la fonction d’écoute personnalisée).

function processArgs( a ){   // Call listener, return false only if listener returns false.   return listener( a ) !== false; } 

1.4. Il est temps d’espionner

Dès que Espion GA est exécuté, il instancie la file d’attente de commandes si elle n’existe pas déjà, comme le ferait l’extrait Universal Analytics. Dans ce script et dans l’extrait de code Universal Analytics, nous veillons à ne pas définir aveuglément une nouvelle variable et à ne pas perdre les données précédentes.

if( ! window[gaObjName] ){ // If global object doesn't exist ...   ga = function(){     if( ! window[gaObjName].q )       window[gaObjName].q = [];       window[gaObjName].q.push( arguments );   };   ga.l = 1 * new Date();   window[gaObjName] = ga; } 

Remarque : le code ci-dessus fait exactement la même chose que la deuxième ligne de la fonction d’extrait de code d’installation GA, illustrée sous Un bon espion commence par la recherche ci-dessus.

Ensuite, qu’elle ait déjà existé ou qu’elle soit à peine initiée, Espion GA détournements ga.

Si ga s’avère être la méthode de suivi Universal Analytics entièrement formée, alors analytics.js a déjà été chargé et nous serons exploités dans tous les appels ultérieurs à ga jusqu’à ce que la page soit déchargée. Travail terminé. Depuis le mondial ga l’objet ne garde pas la trace de l’exécution précédente ga() commandes, nous ne pouvons pas accéder aux informations transmises dans ces commandes. Ce serait utile si nous pouvions accéder à l’historique des commandes, mais nous ne serions toujours pas en mesure de bloquer ces hits, car JavaScript ne prend pas en charge l’inversion du temps (ne fonctionnera pas : setTimeout( hijack, -5 )).

Toutefois, si Espion GA trouve le file d’attente de commandes instancié dans gaalors nous savons que si/quand analytics.js se charge, il remplacera la file d’attente de commandes détournée (notre proxy) avec la méthode de suivi Universal Analytics actuelle. Nous pouvons facilement le détourner à nouveau, mais le timing est important. Nous voulons le mondial ga objet doit exister pendant une période aussi courte que possible pour éviter de manquer des commandes avant que nous parvenions à le détourner.

Toute fonction dans la file d’attente de commandes sera exécutée dès que le ga l’objet est prêt. Nous ajoutons donc le hijack fonction, tendant ainsi un piège ga l’objet se déclenchera immédiatement lors du chargement et mettra notre proxy à sa place devant le ga l’objet est même disponible pour d’autres scripts.

La seule autre chose que nous devons faire est d’exécuter la pile de commandes existantes via l’écouteur, et lorsqu’il renvoie false, filtrez simplement cette commande hors de la file d’attente.

2. Fiabilité et mises en garde

Cela devrait être une solution extrêmement fiable. En fait, la méthode d’écoute par “détournement” d’une fonction est utilisée par un certain nombre de bibliothèques Google, y compris les propres Data Layer et Autotrack de GTM. Attention c’est possible Espion GA peut être interrompu par une mise à jour de analytics.js, mais le ga interface Espion GA s’appuie sur est entièrement défini dans l’extrait de code d’installation standard d’Universal Analytics, de sorte qu’une rupture due à des mises à jour inopinées de la bibliothèque est hautement improbable.

Néanmoins, il y a quelques mises en garde importantes à noter avant de l’utiliser.

2.1. Comportement inhabituel pour une bibliothèque commune

Chaque fois que cela est utilisé pour modifier ou bloquer un ga commande, je considérerais cela comme une solution “hacky”. Bien que le code soit sain, une telle utilisation modifie le comportement typique du ga() fonction, ce qui le fait fonctionner différemment de ce qu’il fonctionne sur 99% des autres sites Web. Cela peut entraver le dépannage et dérouter ceux qui découvrent Google Analytics ou JavaScript.

Conseil : Vous pouvez savoir que vous avez affaire à un GA piraté en vérifiant la présence de la propriété _gaOrig dans l’objet global Google Analytics. Par défaut ce serait : window.ga._gaOrig.

Dans certains cas, le détournement de la fonction GA est rendu nécessaire par des fournisseurs tiers qui exigent que leur JavaScript soit implémenté avec un tracker GA codé en dur.

Dans d’autres cas, comme lors d’une migration de Google Analytics codé en dur vers Google Tag Manager, ce traitement ne devrait être acceptable qu’en tant que solution à court terme.

2.2. Impossible d’intercepter les pages vues codées en dur à partir de GA

Si Espion GA s’exécute avant le chargement de analytics.js, vous pourrez accéder à 100 % des commandes mises en file d’attente dans analytics.js et les bloquer. Mais si Espion GA s’exécute après, alors il n’a aucune idée des coups (le cas échéant) qui ont été tirés précédemment. Donc, si vous voulez intercepter toutes les commandes codées en dur, Espion GA doit être déployé directement sur la page. Cependant, à de nombreuses fins, ce n’est pas du tout nécessaire.

Malheureusement, dans certains cas où le déploiement sur la page est nécessaire, l’impossibilité d’apporter des modifications sur la page est le problème même qui a motivé le besoin de Espion GA en premier lieu, faisant de cette solution un catch-22. Pour les migrations GTM, une façon d’atténuer ce problème consiste à demander à avoir Espion GA placé sur la page en même temps que GTM est ajouté.

Remarque : si le chargement synchrone de Google Tag Manager est pris en charge, le codage en dur Espion GA ne sera plus nécessaire, mais toujours recommandé, car le chargement de tout élément de manière synchrone dans le <head> dégradera la vitesse de chargement des pages.

2.3. Incomplet

Actuellement, Espion GA n’intercepte que les commandes GA qui sont appelées sur le global ga object, mais il existe d’autres moyens d’envoyer des commandes à analytics.js. De nombreux plugins GA et certaines implémentations personnalisées appellent des commandes directement sur l’objet tracker (c’est-à-dire ga.getAll()[0].send('event')). La prise en charge de l’interception de ces commandes pourrait être ajoutée ultérieurement.

Une autre limite est que Espion GA ne peut traiter que les valeurs transmises aux commandes GA. Il ne donne pas accès aux valeurs par défaut pour tous les champs renseignés par analytics.js.

Un effet de ces deux faits est que Espion GA ne captera pas les modifications de hit (ou les hits supplémentaires) effectuées par les plugins GA (et d’autres implémentations utilisant l’API Tasks). C’est par conception et aucun support n’est prévu pour cela. (Si vous en voyez le besoin, décrivez le cas d’utilisation et votez pour cette amélioration ici.)

2.4. Plus de code !

En tant que développeur, j’ai de nombreuses protestations contre la déclaration suivante, mais je ne peux pas nier sa vérité essentielle : code is bad. Cela signifie que peu importe la qualité du code, aucun code n’est meilleur. Le code conduit à des bogues qui conduisent à plus de code, ce qui conduit à plus de bogues. Même le code à l’épreuve des balles nécessite un certain degré de maintenance. Le plus gros problème est peut-être qu’une solution basée sur du code impose une barrière de compétences plus élevée pour la gestion et la personnalisation de la solution. En règle générale, nous devrions éviter le code personnalisé chaque fois qu’il existe une alternative valable.

3. Utilisation

3.1. Placement

Si vous avez besoin d’intercepter des commandes GA qui s’exécutent lors du chargement de la page ou peu de temps après (telles que la création d’un tracker ou 'pageview' dans l’extrait d’installation GA de base), vous devrez déployer Espion GA dans une balise de script en ligne ou un script externe (sans async ou alors defer attributs) au-dessus de la première commande GA (généralement dans l’extrait de code GA de base).

<html>   <head>   ...     // GA Spy:     <script>       ;window.gaSpy = window.gaSpy...     </script>      // Universal Analytics snippet:     <script>       (function(i,s,o,g,r,a,m)...     </script>   ...   </head>

Si les commandes que vous devez intercepter sont déclenchées par une action de l’utilisateur, ce n’est pas un problème et vous pouvez déployer Espion GA en utilisant GTM.

GA Spy en HTML personnalisé

3.2. Votre auditeur

Ce script ne sera pas faire quoi que ce soit en soi. Vous devez implémenter toutes les actions dans votre custom listener fonction de rappel. Vous pouvez faire des choses comme :

  1. Accéder et modifier les arguments envoyés à ga().

  2. Accéder aux informations sur la portée de la commande (nom du tracker, type de hit, etc.)

  3. Bloquer le coup en retournant false (renvoyant simplement des valeurs “fausses” comme 0 ou alors undefined ne bloquera pas le coup).

  4. Et tout ce que vous pouvez faire en JavaScript 🙂

Dans de nombreux cas, nous voudrons pousser les valeurs d’accès sur le dataLayer afin qu’ils soient accessibles dans GTM.

<script>   gaSpy(function(obj) {          // Do something with the arguments to ga():     var args = obj.args;      // Do something with details about the tracker itself:     var details = obj.the;    }); </script>

Naturellement, tout appel vers gaSpy() doivent être chronométrés pour qu’ils aient lieu après vous avez chargé le Espion GA code lui-même.

Consultez le fichier README pour plus de détails sur les données transmises à la fonction de rappel, ainsi que des informations supplémentaires. Espion GA options de configuration.

3.3. À l’écoute de GTM

Si vous utilisez Espion GA dans GTM, l’auditeur doit généralement ignorer toutes les commandes de GTM. Ne pas le faire pourrait entraîner le blocage des hits GTM ou une boucle infinie. Nous pouvons le faire en vérifiant le nom du tracker. GTM utilise des noms de tracker commençant par “gtm” suivi de l’horodatage de la création du tracker.

Cependant, cette méthode ne fonctionnera pas lorsque des rappels sont passés à la place d’une commande GA. GTM ne semble pas les utiliser actuellement, mais nous ne pouvons pas faire grand-chose avec eux de toute façon, donc par précaution, tout auditeur devrait également ignorer les rappels.

Utilisez ce code en haut de votre fonction de rappel pour éviter les problèmes :

gaSpy( function( ev ){   if( ev.the.callback )     return;   if( ev.the.trackerName && ev.the.trackerName.substr( 0, 3 ) == 'gtm' )      return;   // Your code here }); 

Ce n’est pas infaillible, mais cela fonctionnera à moins que le suivi codé en dur n’utilise un nom de suivi commençant par “gtm” (ou si les noms de suivi dans GTM sont personnalisés, ce qui est probablement fait comme une alternative à cette solution). Par exemple, cette méthode ne fonctionnera pas pour le suivi intégré de Wistia, car le code de Wistia envoie (par erreur) des hits via chaque tracker nommé sur la page.

4. Exemples

4.1. Consigner les commandes GA

La journalisation des commandes GA est un moyen utile de voir facilement quelles commandes sont récupérées par Espion GAvous permettant de voir quelles choses Espion GA peut bloquer et/ou verrouiller afin d’exécuter un comportement personnalisé. Par rapport aux extensions de navigateur et au verbeux analytics_debug.js, Espion GA la journalisation peut être très minimaliste. Vous pouvez même vous connecter en utilisant uniquement des emojis si vous le souhaitez ! Et il a l’avantage de fonctionner même lorsque le coup ne se déclenche pas (comme lors de l’utilisation de l’opt-out GA ou des bloqueurs de suivi).

Ce rappel d’écouteur imprimera ga() arguments exactement tels qu’ils sont donnés :

gaSpy( function gaSpy_cb_( ev ){     console.debug.apply( console, ev.args ) }); 

Ou consultez l’un des exemples sur GitHub pour quelque chose d’un peu plus robuste :

Console enregistrant les requêtes GA

Comme il s’agit d’un seul script, vous pouvez le transformer en un bookmarklet. Cela pourrait également bloquer tous les hits, il sert donc de bookmarklet en «mode test», qui enregistre et empêche tout hit d’être déclenché.

4.2. Accéder aux données de commande GA codées en dur via GTM

Si vous savez exactement ce que vous cherchez, vous pouvez simplement rechercher ce format et l’envoyer à dataLayer. N’oubliez pas de définir un nom d’événement dans le dataLayer.push(), afin que vous puissiez créer un déclencheur GTM basé sur l’événement. Voici un exemple qui synchronise les événements codés en dur à partir du plugin de partage social ShareThis et les transmet à GTM :

gaSpy( function gaSpy_cb_( ev ){   var a = ev.args;   if( a[0] == "send"     && a[1] == "event"     && a[2] == "ShareThis" ){     dataLayer.push({       'event' : 'spy.ga.socialPlugin',       'spy.ga.socialPlugin' : {         'network' : a[3],         'url' : a[4]       }     });   }   return false; }); 

Voici un exemple plus robuste qui envoie toutes les commandes non-GTM à dataLayer.

Couche de données d'espionnage GA

La plupart du code nécessaire pour cela normalise simplement les arguments de commande (puisque les commandes GA ont un format flexible pour définir les valeurs de champ). Il gère également la portée des données (différents trackers, plugins) et efface également les champs d’accès uniquement après l’événement GTM concerné.

5. Prochaines étapes

Même s’il s’agit d’une méthode fiable et relativement simple pour travailler avec le suivi GA codé en dur, j’espère que ce n’était pas votre premier choix. Même si cela résout de vrais problèmes de données et aide à consolider votre implémentation dans GTM, c’est une façon délicate de le faire. Vous pouvez obtenir le même résultat avec une configuration beaucoup plus simple : pas de suivi codé en dur, et pas d’espionnage ! Ne vous contentez pas de faire fonctionner le suivi ; poursuivre une mise en œuvre propre. Même si cela prendra un certain temps, prévoyez de supprimer le suivi codé en dur.

Votre script fait fonctionner votre code Universal Analytics différemment de ce qu’il fonctionnerait sur pratiquement tous les autres sites Web, déroutant les dépanneurs et les apprenants. Donc, même si vous pensez que la suppression du suivi codé en dur est imminente, assurez-vous de notez votre utilisation de GA Spy (en évidence) dans votre documentation de suivi.

Si vous utilisez Espion GA pour traiter le code d’une plate-forme ou d’un plugin tiers, contactez les développeurs. Faites-leur savoir que leur script n’est pas compatible avec GTM. (En fait, vous devriez le faire avant d’implémenter Espion GA; ils pourraient être réactifs et corriger leur code rapidement !)

6. Rétroaction

Cette méthode a été conçue pour être flexible et a été testée avec diverses configurations, mais cela ne veut pas dire qu’elle est à l’épreuve des balles. Au contraire, je suis impatient de découvrir des bugs, des incompatibilités avec les plugins du navigateur et des problèmes similaires. Naturellement, j’avoue qu’il serait plus agréable de savoir qu’il n’y en a pas 🙂

Veuillez publier tout problème ou suggestion en tant que nouveau problème sur GitHub s’il n’a pas déjà été ajouté. Assurez-vous de voter pour les correctifs et les améliorations que vous souhaitez voir implémentés (en cliquant sur la petite icône de pouce levé) !

7. Résumé (par Simo)

C’est du JavaScript de premier ordre ici! Ce que Stephen a construit est un…

Source : www.simoahava.com

Articles similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Index