OK, c’est un titre peu attrayant pour un article de blog, mais soyez assuré que le contenu compense largement cette obscurité.
Récemment, mon jouet préféré au monde, le conteneur de serveur de Google Tag Manager, a introduit la capacité de gérer opérations asynchrones dans les variables.
Cela se fait via une interface JavaScript connue sous le nom de Promise. UN Promesse est un moyen d’exécuter du code en JavaScript sans savoir quelle sera sa valeur finale. La partie « promesse » de ce concept signifie que le code promesses qu’il atteindra finalement une valeur, de sorte que un autre code qui s’appuie sur cette valeur peut s’exécuter en conséquence.
Dans cette récente mise à jour, les API de balise côté serveur ont été mises à jour pour gérer les promesses.
Qu’est-ce que cela signifie en pratiqueest que vous pouvez attacher une variable à une balise, avoir cette variable renvoie une promesse de terminer une opération asynchroneet la balise sera attendre automatiquement que la Promesse se résolve avant d’achever ses travaux.
Et alors quoi, je vous entends demander? Vous pouvez enfin Enrichir les flux de données qui passent dans un conteneur de serveur Sans avoir à créer des clients et des balises personnalisés pour cela!
Notez simplement que tout ce que nous traversons dans cet article nécessite implicitement que vous utilisiez ou créiez des modèles personnalisés, car Google Tag Manager côté serveur n’a pas d’option “Variable JavaScript personnalisée” pour exécuter du code ad hoc.
X
La newsletter Mijoter
Abonnez-vous à la newsletter Simmer pour recevoir les dernières nouvelles et le contenu de Simo Ahava dans votre boîte de réception !
Qu’est-ce qui a changé
Auparavant, les variables de Google Tag Manager étaient traitées de manière synchrone.
Cela signifiait que lorsque l’exécution de GTM a commencé à analyser une variable, elle l’a exécutée en ligne par ligne jusqu’à ce qu’elle atteigne un return
déclaration dans le contexte d’exécution. Cette valeur a ensuite été renvoyée à la source invoquée la variable en premier lieu.
Si la variable essayait d’exécuter un asynchrone Fonctionnement, ce qui signifie qu’il a fait quelque chose qui finalement renvoyer une valeur mais pas lorsque la variable a été exécutée de manière synchrone, la variable renverrait simplement un undefined
Valeur car GTM n’attendrait pas que la variable se termine.
Avec ce changement, les variables peuvent maintenant retourner un Promesse, que le code d’exécution attend alors de résoudre avant de continuer. En d’autres termes, la variable n’a pas à se résoudre immédiatement à une valeur – elle peut renvoyer une promesse solennelle qu’elle finira par atteindre une valeur (bien sûr dans un délai donné). temps libre).
Et pourquoi est-ce un gros problème ? Car jusqu’à présent, si vous vouliez avoir votre Mots clés et Clients attendez une opération asynchrone, vous deviez intégrer ces appels asynchrones dans la balise / le code client lui-même.
Maintenant, tout ce que vous avez à faire est de vous assurer que la variable renvoie une promesse, et tout ce qui a appelé la variable attendra consciencieusement que cette promesse soit résolue ou rejetée.
Comment travailler avec les promesses
Heureusement, vous n’avez pas à vous soucier de l’interface Promise elle-même.
Bien que vous peut utiliser le nouveau Promise
API pour créer des promesses personnalisées, et les programmeurs les plus endurcis peuvent certainement utiliser Promise.all
Pour enchaîner plusieurs promesses, de nombreuses API de marquage côté serveur intégrées ont été automatiquement mises à jour pour utiliser l’interface Promise.
Voici un exemple d’utilisation Promise.all
dans un modèle variable :
// Run multiple API calls and return a single Promise that's resolved when all the API calls have resolved
const Promise = require('Promise');
const sendHttpRequest = require('sendHttpRequest');
return Promise.all([
sendHttpRequest(FIRST_API_URL, FIRST_API_OPTIONS),
sendHttpRequest(SECOND_API_URL, SECOND_API_OPTIONS)
]).then(results => {
// results will equal [{statusCode: 200, headers: {}, body: ...}, {statusCode: 200, headers: {}, body: ...}];
if (results.filter(result => result.statusCode === 200).length === 2) {
return "Both API calls executed successfully!";
} else {
return "Oops, something went wrong!";
}
});
Comment les API existantes ont changé
Le BigQuery
, sendHttpGet
et sendHttpRequest
API (Et la nouvelle API Firestore!) sont probablement ceux que vous utiliserez le plus dans ce nouveau contexte. Ils vous permettent d’exécuter des requêtes HTTP asynchrones vers des points de terminaison (tels que votre API d’enrichissement), et la réponse peut ensuite être utilisée pour enrichir les flux de données de vos balises et de vos clients.
Pour travailler avec eux, il vous suffit d’utiliser la nouvelle syntaxe Promise-friendly. Si vous l’exécutez dans une variable, rappelez-vous que la variable doit rendre la promesse. La valeur de retour réelle sera définie sur ce que le Promesse Méthodes d’instance renvoie finalement.
Promet un temps mort après 5 secondes s’il n’est ni résolu ni rejeté. Si l’API a son propre délai d’expiration défini (comme le
sendHttpRequest
), alors cela sera honoré à la place.
Voici un exemple de la façon dont vous aborderiez une simple requête GET. Cette API interroge l’API publique Circle.so et renvoie le nombre de membres de la communauté pour lesquels le jeton d’authentification est créé.
const sendHttpRequest = require('sendHttpRequest');
const JSON = require('JSON');
const AUTH_TOKEN = 'XXXXXXXXXXXXX';
const API_URL = 'https://app.circle.so/api/v1/community_members';
const OPTIONS = {
headers: {Authorization: 'Token ' + AUTH_TOKEN},
method: 'GET',
timeout: 2000
};
// Return the Promise
return sendHttpRequest(API_URL, OPTIONS).then(success_result => {
const members = JSON.parse(success_result.body);
// When the Promise resolves (successfully), the length of the array in the response body is returned
return members.length;
});
Les promesses ont trois méthodes :
.then()
Prend deux fonctions comme paramètres (ci-dessus, je n’utilise que le premier, cependant). Le premier est pour ce qui se passe lorsque la promesse est résolue avec succès, et la seconde est pour ce qui se passe lorsque la promesse est rejetée..catch()
Prend une seule fonction en tant que paramètre, et il est exécuté si la promesse est rejetée. Il s’agit d’un moyen pratique d’isoler le code uniquement pour la résolution d’erreur..finally()
prend une seule fonction comme paramètre, et c’est toujours exécuté que la promesse ait été résolue ou rejetée.
Donc, dans l’exemple ci-dessus, je me concentre uniquement sur résolution réussiemais je pourrais tout aussi bien ajouter un .catch()
y aller pour gérer les problèmes. Cependant, comme il s’agit d’une simple requête GET, je ne vois aucune raison de traiter spécifiquement les cas d’erreur, donc je suis d’accord avec le renvoi de la variable undefined
en cas d’erreur.
Mise en cache
Pour éviter que le même appel d’API ne se reproduise encore et encore, il existe un mise en cache mécanisme en place. Le cache est limité à la demande entrante, donc une fois qu’une nouvelle demande arrive dans le conteneur du serveur, le cache est réinitialisé.
Le cache ne fonctionne que si la réponse est cacheable. En d’autres termes, le cache n’est pas forcé sur les ressources qui ne doivent pas être mises en cache.
Si vous souhaitez ajouter une mise en cache supplémentaire avec plus de contrôle, vous pouvez utiliser le templateDataStorage
API pour cela.
Rappelez-vous que toutes les demandes sortantes sont prises en compte sortie réseau trafic par le service cloud, et vous devrez payer pour cette utilisation du réseau. Ainsi, la mise en cache est une chose très importante à mettre en place – d’une manière ou d’une autre.
Une chose que je ferais aimer à voir est l’option pour remplacer l’objet Event Data produit par le Client avec ces variables asynchrones. De cette façon, vous pourriez ajouter les variables d’enrichissement à l’objet Event Data lui-même, et elles seraient disponibles pour toutes les balises, déclencheurs et variables qui utilisent cet objet.
Cela réglerait complètement le problème de mise en cache, car la variable fonctionnerait une seule fois: lorsqu’il est résolu dans l’objet de données de l’événement.
Résumé
Bien qu’il s’agisse d’un aperçu très technique, j’espère que vous voyez la promesse (jeu de mots) de cette mise à jour de Google Tag Manager côté serveur.
Enrichissement du flux de données a été l’une des choses dont j’ai parlé en tant qu’argument de vente unique d’une solution de gestion de balises côté serveur, donc je suis vraiment content que nous enfin avoir un moyen pratique de le faire. C’était deux ans puisque le balisage côté serveur dans GTM a été annoncé publiquement, après tout !
Désormais, la balle est dans le camp de la communauté.
Soyez créatif avec ces modèles variables !
Je veux voir la galerie communautaire farci avec des variables utilitaires pour interroger différentes API, gérer les communications HTTP et exécuter des opérations asynchrones pour enrichir les clients et les balises qui pourraient en bénéficier.
Que pensez-vous de cette sortie ? Pouvez-vous penser à des cas d’utilisation où ces nouvelles promesses pourraient être particulièrement utiles ?