L'agent Javascript fourni par Captain Metrics vous permet de collecter toutes les visites et interactions de votre site web en temps réel.
Fonctionnalités clés
Conformément au RGPD, les données de visites sont maintenues dans le cache du navigateur (et non transmises) jusqu'à ce que le consentement de l'utilisateur soit acquis.
Il est possible de configurer votre propre nom de domaine pour la collecte des données.
Captain Metrics utilise uniquement des cookies "1st-party".
Vous pouvez activer le suivis des visiteurs vers vos domaines tiers (cross-domain) pour éviter de comptabiliser des doublons (blog.votre-site.com, boutique.votre-site.com etc...).
Calcul du temps passé par page à la seconde en tenant compte du "focus". Si votre site est ouvert dans un onglet non-visible, le temps passé sur la page sera mis en pause.
Prise en charge des contextes B2B : les visites peuvent être agrégées au niveau des organisations.
Les profils des visiteurs anonymes sont automatiquement fusionnés avec les profils authentifiés lorsque les utilisateurs se connectent.
Les visites des utilisateurs peuvent être signées (avec HMAC) pour protéger contre la corruption des historiques.
L'agent expose également une trousse à outils utiles pour d'autres besoins : fonctions md5, sha1, uuid, manipulation des cookies et des URLs...
Fonctionnement global
Lorsqu'un nouvel internaute anonyme (= non authentifié) visite votre site, l'agent va lui attribuer un identifiant d'utilisateur anonyme unique, le sauvegarder dans le navigateur et démarrer une nouvelle session.
Les capacités génériques de son navigateur sont également collectées (OS, taille d'écran, type de navigateur...).
Dès que l'utilisateur donne son consentement à la collecte des données de navigation, le plus souvent via votre bandeau d'acceptation des cookies, l'agent commencera à transmettre ce qu'il a collecté vers les serveurs de Captain Metrics.
Tous les utilisateurs anonymes ayant accepté les cookies ont un profil créé dans Captain Metrics, contenant l'historique de leurs interactions avec votre site.
Lorsque l'utilisateur anonyme se connecte sur votre site avec son identifiant, un profil "authentifié" est alors créé dans Captain Metrics et le profil anonyme est ensuite fusionné automatiquement.
Une nouvelle session est comptabilisée lorsque la précédente expire (après 30 minutes par défaut), ou que l'internaute revient sur votre site via une autre source de traffic.
Installation
L'agent doit être initialisé le plus tôt possible durant le chargement de la page, et placé entre les balises HTML <head> et </head>.
Son chargement est synchrone, et nous vous invitons à héberger le fichier https://cdn.captainmetrics.com/agent/v4.min.js sur votre propre site afin éviter tout ralentissement en cas de problème éventuel avec le Cloud de Captain Metrics.
<head>
....
<script src="https://cdn.captainmetrics.com/agent/v4.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.cmAgent = new window.CM.Agent({
projectId: 'YOUR_PROJECT_ID_HERE', // à remplacer avec votre ID projet
userConsent: false, // mettre à true si vous avez déjà le consentement de l'internaute pour les cookies
name: 'default_agent',
// OPTIONS
anonymizeIP: false, // false by default
sessionTimeout: 1800, // 30 mins
crossDomains: ['blog.mon-site.com', 'shop.mon-site.com'], // permet d'activer le suivi "cross-domains"
logLevel: 'debug', // permet d'obtenir des infos dans la console du navigateur
host: 'https://domaine-de-collecte.com' // permet d'envoyer les données vers votre propre domaine de collecte
channels: [
// ex: filtrer le trafic provenant de Paypal pour ne pas déclencher de nouvelle session lors du paiement
{matchType: 'exact', value: 'www.paypal.com / referral', action: 'keepSession'}
]
});
</script>
</head>
Utilisation
Consentement
Lorsque l'agent est initialisé avec le paramètre userConsent: false , les données recueillies sont sauvegardées dans le cache du navigateur et ne sont pas transmises à Captain Metrics.
Dès l'instant où votre utilisateur a accepté vos Conditions de Vie Privée relative à la collecte des données de visites, le plus souvent via votre bandeau de consentement aux "cookies" (GDPR), vous devez executer la fonction suivante :
cmAgent.userConsent();
L'appel à userConsent() aura pour effet de commencer le transfert des données précédemment stockées en cache.
Authentification des utilisateurs
Dès que l'utilisateur se connecte sur votre site (via votre base de donnée utilisateur primaire), il faut transmettre l'ID utilisateur à l'agent de cette façon :
cmAgent.setUserId('USER_ID');
Si vous avez activé la signature HMAC des ID utilisateurs dans la configuration de votre projet, vous devez utiliser la fonction de la façon suivante :
cmAgent.setUserId('USER_ID', 'USER_ID_HMAC');
Transmission des données
La fonction distpach() permet de transférer les données collectées.Toutes les fonctions de collecte des données détaillées ci-dessous ne seront pas transmises tant que la fonction dispatch() ne sera pas appelée.
// exemple
cmAgent.setUserId('USER_ID');
cmAgent.pageview();
cmAgent.dispatch();
Profil des utilisateurs
Pour mettre à jour le profil de vos utilisateur depuis le frontend de votre site web :
// tous les champs sont optionnels
cmAgent.updateUserProfile({
// set permet de modifier les champs du profil
set: {
'email': 'john@yopmail.com',
'emailMd5': 'xxxxxx', // calculé automatiquement si laissé vide
'emailSha1': 'xxxxxx', // calculé automatiquement si laissé vide
'emailSha256': 'xxxxxx', // calculé automatiquement si laissé vide
'firstName': 'John',
'lastName': 'Doe',
'signedUpAt': "2018-06-25T13:42:13.582Z", // Format RFC3339
'newsletterConsent:' true,
'remarketingConsent': true,
'language': 'fr',
'country': 'FR',
'timezone': 'Europe/Paris',
'city': 'Paris',
'state': 'Ile-de-France',
'postalCode': '75015',
'gender': "male", // male ou female
'websiteURL': 'https://captainmetrics.com',
'telephone': "+33601010101", // Format international E.164 si possible
'twitterUsername': "twitter_handle",
'facebookUsername': "elonmusk",
'photoURL': 'https://lh5.googleusercontent.com/-q1lsmiHWbZ8/AAAAAAAAAAI/AAAAAAAACWE/dIZniOuKcbM/photo.jpg',
'latitude': 47.78809649999999,
'longitude': 1.0804708000000574
},
// addTags permet de mettre à jour une liste tags
addTags: ['vip'],
// setTags permet de remplacer la liste des tags
setTags: ['vip'],
// removeTags permet de supprimer des tags
removeTags: ['vip'],
// addProperties permet de mettre à jour des propriétés personnalisées
addProperties: {
// les dates doivent suivre le format suivant :
'lastPhoneCallAt': {
'$date': '2022-01-01 12:00:00',
'$timezone': 'Europe/Paris',
},
'mybool': true,
'myInteger': 123,
'myFloat': 124.23,
'myString': "bonjour !"
},
// setProperties permet de REMPLACER toutes les propriétés personnalisées
setProperties: {
'mystring': 'hey'
},
removeProperties: ['prop_key1', 'prop_key2', ...]
});
Pages vues
La fonction pageview() permet de suivre l'historique de navigation de l'utilisateur. Elle peut renseigner les meta-données d'un article de blog ou d'un produit, et s'utilise comme ceci :
cmAgent.pageview();
// options
cmAgent.pageview({
title: 'Titre de la page', // par défaut le titre est celui de votre page HTML document.title
page: 'https://mon-site.com/ma-page', // par défaut la page contient l'URL actuelle window.location.href
imageURL: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Paris_-_Eiffelturm_und_Marsfeld2.jpg/560px-Paris_-_Eiffelturm_und_Marsfeld2.jpg',
tags: ['tag1', 'tag2']
// props vous permet d'ajouter des dimensions personnalisées, utilisables dans les rapports
props: {
version: 2,
language: 'fr'
},
// meta spécifique aux articles de blog
article: {
author: 'John Doe', // champ requis
publishedAt: "2018-12-16T20:22:13.582Z", // champ requis, RFC3339
modifiedAt: "2019-04-15T06:54:40.816Z",
}
// meta spécifique aux produits de votre catalogue
product: {
externalId: 'iphone8-apple', // champ requis, ID du produit de votre base de donnée
name: 'iPhone 8', // champ requis
sku: 'iphone8-apple-sku',
brand: 'Apple',
category: 'Smartphones',
variant: 'Rose gold',
price: 1000.50, // float number
currency: "USD"
}
});
Événements personnalisés
Nous vous invitons à collecter toutes les interactions clés effectuées par vos utilisateurs, qui pourraient fournir des indications pertinentes concernant l'engagement sur votre site.
// exemple avec un internaute qui télécharge un livre blanc sur votre blog
cmAgent.event({
label: 'download_white_paper',
props: {
title: 'Customer Data Platform - White paper'
}
// options
value: 1.5, // permet d'incrémenter des compteurs propres à vos événements
nonInteractive: true // mettre ce champ à true si l'action n'a pas été déclenchée par l'utilisateur, exemple : l'opérateur de votre live-chat a fermé une discussion en cours
});
// les événements sont souvent déclenchés de façon asynchrones, n'oubliez pas de faire un dispatch() après la collecte :
cmAgent.dispatch();
Ecommerce
Pour suivre le status des paniers (ajout et modification), nécessaire à l'automatisation des relances d'abandon de panier, et au moteur de recommandation, il faut utiliser la fonction cart() suivante :
cmAgent.cart({
currency: 'EUR',
publicURL: 'https://yourwebsite.com/cart/xxxx/', // URL du panier, qui peut être utilisée dans les emails de relance d'abandon de panier
// items contient un tableau de produit présents dans le panier
items: [
{
externalId: 'iphone15-apple', // champ requis, ID du produit de votre base de donnée
name: 'iPhone 15', // champs requis
sku: 'iphone15-apple',
brand: 'Apple',
category: 'Smartphones',
variant: 'Rose gold',
price: 1000.50,
quantity: 1,
imageURL: 'https://url-of-the-product-image.jpg',
coupon: 'DISCOUNT_CODE'
props: {
experimentId: '123456'
}
},
...
]
});
La fonction cart() transmettra le panier uniquement s'il a été modifié. Vous pouvez donc l’appeler à chaque affichage de votre page panier.
Vous pouvez également mémoriser la Wish List actuelle de vos utilisateurs de la même façon que le panier :
cmAgent.wishList({
currency: 'EUR',
items: [...] // identique à la fonction setCart ci-dessus
});
Pour remonter les commandes des clients, c'est la fonction order() :
cmAgent.order({
conversionRuleId: 'sales', // champs requis, ID de la règle de conversion eCommerce créé lors de la config de votre projet
externalId: 'order_001', // champs requis, ID de la commande dans votre base de donnée eCommerce
// les champs suivants sont optionnels :
// tableau des produits présents dans le panier
items: [
{
externalId: 'iphone8-apple', // champ requis, ID du produit dans votre base de donnée //
name: 'iPhone 8', // champ requis
quantity: 3, // champs requis, nombre
sku: 'iphone8-apple',
brand: 'Apple',
category: 'Smartphones',
variant: 'Rose gold',
imageURL: 'https://url-of-the-product-image.jpg',
price: 1000.50
},
...
],
// tableau des éventuels codes de réductions appliqués dans la commande
// consultez la documentation sur les commandes eCommerce pour en savoir plus
discounts: [
{
kind: "discountCode", // champ requis, soit "manual" / "script" / "discountCode"
valueType: "fixedAmount", // champ requis, soit "fixedAmount" / "percentage"
value: 10.00, // champs requis, valeur de la réduction
allocationMethod: "across", // champs requis, soit "accross" / "each" / "one"
targetSelection: "all", // champs requis, soit "all" / "entitled" / "explicit"
targetType: "lineItem", // champs requis, soit "shippingLine" / "lineItem"
code: "SUMMERSALE", // champs requis si type == "discountCode"
title: "Promo perso" // champs requis si type == "manual"
},
...
],
// tableau des éventuels remboursements
refunds: [
{
externalId: "refundId", // champ requis
note: "bla bla bla...", // texte libre associé
createdAt: "2022-01-01 12:00:00", // champ requis, date de création du refund
updatedAt: "2022-01-01 12:00:00", // éventuelle date de modification du refund
// tableau des items associés au refund
items: [
{
externalId: "123456", // champ requis
quantity: 1, // champ requis
sku: "abc123",
subtotal: 10.12, // montant des items hors taxes
totalTax: 5.12
}
]
}
...
],
revenue: 3500.23, // chiffre d'affaire de la commande HT et sans frais de port
currency: "AUD", // devise, les conversions avec la devise du projet sont faites en temps réel, tout en maintenant la devise source
totalTips: 10.01, // total des éventuels pourboire
totalTax: 728.05, // total des taxes
totalShipping: 20.00, // total des frais de port
totalDiscounts: 140.00, // total des réductions appliquées
financialStatus: "paid", // statut de la commande, soit "pending" / "authorized" / "partially_paid" / "paid" / "partially_refunded" / "refunded" / "voided"
fulfillmentStatus: "fulfilled", // statut du traitement de la commande, soit "fulfilled" / "partial" / "restocked"
tags: ["tag1", "tag2"], // tags
publicURL: "https://my-order-url.com", // URL publique pour le suivi de commande
// propriétés éventuelles
props: {
payment_gateway: "Paypal"
}
});
Leads
Vous avez la possibilité de collecter des leads/deals, et de faire évoluer les états (nouveau, signé, perdu...) de ceux-ci (= stageId) directement depuis le frontend.
Pour modifier l'état d'un lead, il suffit de renvoyer le même externalId avec le nouveau stageId. Ou bien, vous pouvez modifier l'état du lead directement en utilisant l'API d'import des données.
// Collecter / modifier l'état d'un lead
cmAgent.lead({
externalId: 'lead-1', // ID du lead dans votre base de donnée
conversionRuleId: 'leads', // ID de la règle de conversion de leads configurée dans votre projet
stageId: 'new', // ID de l'état actuel du lead
revenue: 10000, // optionnel: montant du lead en centimes
currency: 'EUR', // optionnel: devise du montant
publicURL: 'https://yourwebsite.com/lead/xxxx/' // URL de suivi de l'avancement du lead, qui peut être communiquée au client dans les emails de relance
});
Souscriptions
Cette fonctionnalité est actuellement en beta test et sera documentée très prochainement, n'hésitez pas à nous contacter pour nous faire part de vos besoins à ce sujet.
B2B
Dans le monde des SaaS et boutiques B2B un client ne représente pas un seul utilisateur mais une organisation composée de plusieurs utilisateurs. L'agent Javascript vous permet de spécifier pour quelle société vos utilisateurs interagissent avec votre site, de la façon suivante :
// pour rattacher un utilisateur à une société (si ce n'est pas encore le cas) :
cmAgent.addUserToCompany('COMPANY_ID', {
role: 'CEO' // champ en option
});
// pour attacher les interactions de l'utilisateur à une société, notamment lorsqu'il se connecte sur votre site ou qu'il change de contexte :
cmAgent.setCompanyId('COMPANY_ID');
// si vous avez activité la signature HMAC des utilisateurs, vous devez renseigner les paramètres comme ceci :
cmAgent.setCompanyId('COMPANY_ID', 'COMPANY_ID_HMAC_SIGNATURE');
cmAgent.addUserToCompany('COMPANY_ID', {role: 'CEO'}, 'COMPANY_ID_HMAC_SIGNATURE');
Topics de notification
cmAgent.subscribeToNotificationTopic({
notificationTopicId: 'newsletter',
channel: 'email', // email / sms...
recipient: 'user@email.com',
// if the notification topic is a "collection"
collectionItemExternalId: 'product-id'
});
Réconciliation Cross-Device & Cross-domain
Afin de maintenir la consistance du tracking entre différent domaines ou sous-domaines, l'agent JS peut injecter l'ID de l'utilisateur et du client dans les URL des crossDomains configurés comme ceci :
window.cmAgent = new window.CM.Agent({
...
crossDomains: ['your-other-domain.com']
});
Il est également possible de spécifier vous-même les paramètres de "Linking" pour pré-initialiser l'agent JS avec un user ID. Ceci est indispensable pour votre stratégie de réconcialiation cross-device.
Les paramètres sont :
Paramètre
Description
_uid
User ID
_uidh
Signature HMAC 256 du User ID, si vous avez activé la signature des User ID dans les paramètres de votre projet
_auth
_cid
Client ID (= device ID), c'est l'ID du navigateur web. Cet ID est automatiquement injecté lors du Linking Cross-Domain.
_coid
Company ID. A utiliser dans le cadre d'un tracking B2B.
_coidh
Signature HMAC 256 du Company ID.
Exemple : si envoyez un SMS de suivi de commande contenant une URL du type https://your-website.com?_uid=USER_ID&_auth=true , et que le navigateur mobile contenait déjà un historique anonyme passé, il sera alors fusionné avec le profil du USER_ID spécifié dans l'URL.
Custom dimensions
La plupart des hits (pageview, event etc...) acceptent un objet props pour vous permettre de joindre tous types de données custom, à l'exception des sessions qui sont gérées automatiquement par l'Agent JS.
Il est parfois utile de pouvoir joindre des données custom au niveau de la session. Pour cela il faut initialiser l'Agent JS en spécifiant la valeur de sessionCustomDimension1 comme ceci :
window.cmAgent = new window.CM.Agent({
...
sessionCustomDimension1: 'custom value stored with the session'
});
Filtrer le trafic
Lorsqu'une visite provient d'une source de trafic différente de la session actuelle, une nouvelle session démarre. Ce mécanisme pose malheureusement problème lorsque votre internaute est redirigé vers une passerelle de paiement externe (Paypal, site de la banque...) : une nouvelle session sera déclenchée après le règlement lorsque la page de confirmation de commande s'affichera et votre tunnel de conversion attribuera des ventes à votre passerelle de paiement.
Pour éviter ce problème vous pouvez créer des filtres comme ceci lors de l'initialisation de l'agent JS :
window.cmAgent = new window.CM.Agent({
...
// ex: filtrer le trafic provenant de Paypal pour ne pas déclencher de nouvelle session lors du paiement
channels: [
{
matchType: 'exact',
value: 'www.paypal.com / referral',
action: 'keepSession'
}
]
});
Boîte à outils
Pour vous aider à scripter vos bandeaux de consentement aux cookies, et autre... nous avons exposé quelques outils présents dans l'agent Javascript, ils s'utilisent comme ceci :
// hash md5 et sha1
window.CM.Tools.md5('string to hash');
window.CM.Tools.sha1('string to hash');
// UUID V4 (ex: 3e342bc1-eab4-477a-be2d-1545b1600575)
window.CM.Tools.uuid();
// ad block detection
window.CM.Tools.hasAdBlock(); // true / false
// cookies manipulation
window.CM.Tools.cookie.get('COOKIE_NAME');
window.CM.Tools.cookie.set('COOKIE_NAME', 'COOKIE_VALUE', expirationInSeconds, crossSubdomain, isSecure); // crossSubdomain et isSecure sont optionnels
// URL manipulation
window.CM.Tools.getQueryParam(window.location.href, 'PARAMETER_NAME');
window.CM.Tools.getHashParam(window.location.href, 'ANCHOR_PARAMETER_NAME'); // pour récupérer un paramètre dans une ancre
window.CM.Tools.updateURLParam(window.location.href, 'PARAMETER_NAME', 'PARAMETER_VALUE');
// Base 64
window.CM.Tools.encodeBase64('STRING_TO_ENCODE_IN_BASE64');
window.CM.Tools.decodeBase64('BASE64_STRING_TO_DECODE');