1. ✅ Apprenez une METHODE qui marche pour votre SEO ! Formation à distance avec Olivier Duffez et Fabien Facériès + aide pour prise en charge du financement
    Rejeter la notice

Tarteaucitron : Comment configurer GTM sans cookie ?

Discussion dans 'Google Analytics' créé par ortolojf, 14 Juillet 2020.

  1. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Bonjour

    Voici mon script PHP clientId.php

    PHP:

    <?php
        
    echo (int)hexdec(substr(hash('sha256'urldecode($_GET['userAgent']) . $_SERVER['REMOTE_ADDR']), -10)) % 10 ** 10 '.' time();
    ?>

    Ce script est destiné à produire le client_id de GA.

    Voici le script de GTM pour tarteaucitron :

    Code:
    
    tarteaucitron.user.googletagmanagerId = 'GTM-WKXYXXX';
            (tarteaucitron.job = tarteaucitron.job || [{
          'userID' : 'unknown',
          'storage': 'none',
          'store_gac' : false,
          'client_id': getClientId()
        }]).push('googletagmanager');
      </script>
    
    
    Je n'ai pas mis le code de la fonction Javascript getClientId(), qui lance clientId .php et reçoit l'id_client.

    Voici un exemple d'id_client : 7982804053.1594744121

    Ma question est : Avec tarteaucitron et GTM, comment faire en sorte que GTM ne dépose aucun cookie ?

    Merci beaucoup.

    P.S. Ma configuration de GTM est avec anonymize_ip = true.
     
  2. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Pardon

    Voici la fonction Javascript getClientId() :

    $web_url provient de PHP .


    Code:
    
        <script type="text/javascript">
        function getClientId() {
           var d = new Date();
           var url = new URL('" . $web_url . "' + '/tarteaucitron/clientId.php?userAgent=' + encodeURIComponent(window.navigator.userAgent) + '\&timestamp=' + d.getTime());
               console.log('URL = ' + url);
    
                fetch(url, {
                        method: "GET",
                        headers: {
                                "Content-Type": "text/plain"
                        }
                }).then(function(response) {
                        response.text().then(function(text) {
                                return text;
                        }, function(err) {
                                console.log('Erreur storing User Cookies preferences' + err);
                               return null;
                        })
                }, function(err) {
                        console.log('Erreur Fetching text ' + err);
                        return null;
                })
        }
         </script>
    
    
     
  3. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Rebonjour

    J'ai adapté les fonctions UUID($anonid) et ClientUUID($anonid) de Javascript en PHP.

    Client_UUID() est beaucoup mieux que ma précédente version de clientId().

    D'autre part, $_GET['userAgent'] et $_GET['nbre_accept'] sont l'UserAgent du visiteur et le nombre d'acceptations ( ou de refus ), du visiteur.

    nbre_accept set à modifier le clientId, et tous les 3 mois( ou tous les 13 mois ), le clientId est changé.

    Ce script doit être lancée en fetch, pour disposer de l'adresse ip.

    En effet, mon site a un cache html, l'ip n'est pas disponible.

    Merci beaucoup de vos réponses.

    Amicalement.


    PHP:

    <?php
    define
    ("COOKIE_TIMEOUT_3_MOIS"788400);
    define("COOKIE_TIMEOUT_13_MOIS"34164000);
    function 
    UUID($anon_id)
    {
            
    // Binary Value
            
    $nstr '';
            
    // Convert Namespace UUID to bits
            
    for($i 0$i strlen($anon_id); $i+=2) {
                    
    $nbre = (int)(dechex(hexdec(substr($anon_id$i1))) . dechex(hexdec(substr($anon_id$i 11))));
                    
    $nstr .= chr($nbre);
            }
            
    // Calculate hash value
            
    $hash sha1($nstr $anon_id);
            
    // 32 bits for "time_low"
            
    $data_1 substr($hash08);
            
    // 16 bits for "time_mid"
            
    $data_2 substr($hash84);
            
    // 16 bits for "time_hi_and_version",
            // four most significant bits holds version number 3
            
    $tmp_data3 = (hexdec(substr($hash124)) & 0x0fff) | 0x4000;
            
    $data3 substr(dechex($tmp_data3), 04);
            
    // 16 bits, 8 bits for "clk_seq_hi_res",
            // 8 bits for "clk_seq_low",
            // two most significant bits holds zero and one for variant DCE1.1
            
    $tmp_data4 = (hexdec(substr($hash164)) & 0x3fff) | 0x8000;
            
    $data4 substr(dechex($tmp_data4), 04);
            
    // 48 bits for "node"
            
    $data5 substr($hash2012);
            
    $result $data_1 '-' $data_2 '-' $data3 '-' $data4 '-' $data5;
            return(
    $result);
    }
    function 
    Client_UUID($anon_id)
    {
            
    $hash sha1($anon_id);
            
    $anon_id sha1($hash);
            
    $hashed crc32($anon_id) + crc32($anon_id);
            
    $regex "{^(0+)}";
            
    $regex2 ="{^[0]+(.+)}";
            if(
    preg_match($regex$hashed))
            {
                if(
    preg_match($regex2$hashed$array_match))
                {
                    
    $regex3 "{" $array_match[0] . "$}";
                    
    // Debut avec des zéro;
                    
    $prefix preg_replace($regex3''$hashed);
                    
    $tmp_len strlen($prefix);
                    
    // Remplacement avec des chiffres différents de zéro.
                    
    $tmp_prefix '';
                    for(
    $i 0$i $tmp_len$i++)
                    {
                            
    $nbre + ($i 2) % 10;
                            
    $tmp_prefix .= (string)$nbre;
                    }
                    
    $tmp_prefix .= preg_replace($regex''$hashed);
                    
    $hashed $tmp_prefix;
                }
            }
            return 
    $hashed '.' time();
    }
    function 
    clientId() {
            
    // Create an anonymous ID - we double hash with salt, GA won't who's who
            
    $server $_SERVER['HTTP_HOST'] . $_SERVER['SERVER_ADDR'];
            
    $salt sha1($server);
            
    $add_date = (string)floor(1.0 time() / COOKIE_TIMEOUT_3_MOIS) + (int)urldecode($_GET['nbreAccept']);
            
    $hash_const sha1($add_date $_SERVER['REMOTE_ADDR'] . $salt);
            
    $hash_const2 sha1($add_date urldecode($_GET['userAgent']) . $_SERVER['REMOTE_ADDR']);
            
    // Client ID
            
    $CID UUID($hash_const);
            
    // User ID
            
    $UID Client_UUID($hash_const2);
            return 
    $UID;
    }
    echo 
    clientId();
    ?>

     
  4. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Bonjour

    J'essaye de remplir dataLayer avec les variables qui vont bien, pour qu'il n'y ait pas de cookie, et initialiser client_id ( ou clientId je ne sais pas ), avec la fonction ci-dessus Client_UUID($anonid).

    Voici ce que j'ai :

    Code:
    
    <script>
    
    getClientId().then(function(response) {
        console.log('clientId = ' + response);
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            'clientId': response,
            'storage': 'none',
            'storeGac': false,
            event: 'gtm.dom'
        });
        tarteaucitron.user.googletagmanagerId = 'GTM-WK6D676';
        (tarteaucitron.job = tarteaucitron.job || [{
        }]).push('googletagmanager');
        (tarteaucitron.job = tarteaucitron.job || []).push('star_cookie');
    })
    
    </script>
    
    
    getClientId() rend une Promise et le résultat de Client_UUID($anonid).

    response est correct, mais les données ( collect ) transmises ne correspondent pas.

    C'est possible de tester le résultat avec la console Javascript.

    Le cid transmis est différent et _gid aussi.

    Voici l'url : https://www.pronostics-courses.fr

    Ma window.dataLayer est-elle correctement remplie ?

    Merci beaucoup de votre aide.

    Amicalement.
     
  5. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Bonjour

    Avec le mode "inspect" de Chrome, je regarde les data transmises à GTM.

    Normalement, il devrait y avoir mon gtm.cid

    Voici le dataLayer en amont de GTM ( avec tarteaucitron ) :

    Cà ne marche pas, quel que soit le nom gtm.cid.

    J'ai essayé : userId, userID, clientId, client_id.

    Que faire ?

    getClientId est dans le Javascript ( sur mon site ), et lance clientId.php qui rend lui-même un id client codé.

    Vous pouvez le visualiser en mode inspect.


    Code:
    
    getClientId().then(function(response){
            console.log('clientId = '+response);
            window.dataLayer=window.dataLayer||[];
            window.dataLayer.push({
                    'storage':'none',
                    'gtm.cid':response,
                    'event':'gtm.dom'
            });
            tarteaucitron.user.googletagmanagerId='GTM-WK6D676';
            (tarteaucitron.job=tarteaucitron.job||[{}]).push('googletagmanager');
            (tarteaucitron.job=tarteaucitron.job||[]).push('star_cookie');
    })
    
    
    Pardon.

    Est-ce que ma déclaration de window.dataLayer ( dans une fonction ) est correcte ?

    Merci beaucoup.

    Amicalement.
     
  6. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Bonjour

    J'ai troqué mes lancements de script PHP contre une fonction de type UUID_V4, et adapté à un localstorage.

    J'alimente le dataLayer avec la fonction window.apply() dans le script tarteaucitron.services.js

    Je donne le code après.


    Voici :

    Code:
    
    <script>
    
    function sha1 (str) {
    function hex (value) {
    var s = (value >>> 0).toString(16)
    while (s.length < 8) s = '0' + s
    return s
    }
    function limit (n) {
    return n & 0xffffffff
    }
    function rotateLeft (n, s) {
    return (n << s) | (n >>> (32 - s))
    }
    var H0 = 0x67452301
    var H1 = 0xefcdab89
    var H2 = 0x98badcfe
    var H3 = 0x10325476
    var H4 = 0xc3d2e1f0
    var i, j
    var blockstart
    var W = new Array(80)
    var A, B, C, D, E
    var temp
    str = unescape(encodeURIComponent(str))
    str = str.split(/.*?/).map(function (s) {
    return s.charCodeAt(0)
    })
    var length = str.length
    var words = []
    for (i = 0; i < length - 3; i += 4) {
    j = str[i] << 24 | str[i + 1] << 16 | str[i + 2] << 8 | str[i + 3]
    words.push(j)
    }
    switch (length % 4) {
    case 0:
    i = 0x80000000
    break
    case 1:
    i = str[length - 1] << 24 | 0x800000
    break
    case 2:
    i = str[length - 2] << 24 | str[length - 1] << 16 | 0x8000
    break
    case 3:
    i = str[length - 3] << 24 | str[length - 2] << 16 | str[length - 1] << 8 | 0x80
    break
    }
    words.push(i)
    while ((words.length % 16) != 14) {
    words.push(0)
    }
    words.push(length >>> 29)
    words.push(limit(length << 3))
    for (blockstart = 0; blockstart < words.length; blockstart += 16) {
    for (i = 0; i < 16; i++) {
    W[i] = words[blockstart + i]
    }
    for (i = 16; i < 80; i++) {
    W[i] = rotateLeft(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1)
    }
    A = H0
    B = H1
    C = H2
    D = H3
    E = H4
    for (i = 0; i <= 19; i++) {
    temp = limit(rotateLeft(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5a827999)
    E = D
    D = C
    C = rotateLeft(B, 30)
    B = A
    A = temp
    }
    for (i = 20; i <= 39; i++) {
    temp = limit(rotateLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ed9eba1)
    E = D
    D = C
    C = rotateLeft(B, 30)
    B = A
    A = temp
    }
    for (i = 40; i <= 59; i++) {
    temp = limit(rotateLeft(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8f1bbcdc)
    E = D
    D = C
    C = rotateLeft(B, 30)
    B = A
    A = temp
    }
    for (i = 60; i <= 79; i++) {
    temp = limit(rotateLeft(A, 5) + (B ^ C ^ D) + E + W[i] + 0xca62c1d6)
    E = D
    D = C
    C = rotateLeft(B, 30)
    B = A
    A = temp
    }
    H0 = limit(H0 + A)
    H1 = limit(H1 + B)
    H2 = limit(H2 + C)
    H3 = limit(H3 + D)
    H4 = limit(H4 + E)
    }
    return hex(H0) + hex(H1) + hex(H2) + hex(H3) + hex(H4)
    }
    function hexdec (hexString) {
    // discuss at: http://locutus.io/php/hexdec/
    // original by: Philippe Baumann
    // example 1: hexdec('that')
    // returns 1: 10
    // example 2: hexdec('a0')
    // returns 2: 160
    hexString = (hexString + '').replace(/[^a-f0-9]/gi, '')
    return parseInt(hexString, 16)
    }
    function chr (code) {
    return(String.fromCharCode(code));
    }
    function aleatoire(size) {
    var liste = ["a","b","c","d","e","f", "0","1","2","3","4","5","6","7","8","9"];
    var result = '';
    for (i = 0; i < size; i++) {
    result += liste[Math.floor(Math.random() * liste.length)];
    }
    return result;
    }
    function ClientUUID()
    {
    var anon_id = aleatoire(60);
    // Binary Value
    nstr = '';
    // Convert Namespace UUID to bits
    for(i = 0; i < anon_id.length; i+=2) {
    var nbre = (hexdec(anon_id.substr(i, 1))).toString(16) + (hexdec(anon_id.substr(i + 1, 1))).toString(16);
    nstr += chr(Number(nbre));
    }
    // Calculate hash value
    hash = sha1(nstr + anon_id);
    // 32 bits for "time_low"
    data_1 = hash.substr(0, 8);
    // 16 bits for "time_mid"
    data_2 = hash.substr(8, 4);
    // 16 bits for "time_hi_and_version",
    // four most significant bits holds version number 3
    tmp_data3 = (hexdec(hash.substr(12, 4)) & 0x0fff) | 0x4000;
    data3 = tmp_data3.toString(16).substr(0, 4);
    // 16 bits, 8 bits for "clk_seq_hi_res",
    // 8 bits for "clk_seq_low",
    // two most significant bits holds zero and one for variant DCE1.1
    tmp_data4 = (hexdec(hash.substr(16, 4)) & 0x3fff) | 0x8000;
    data4 = tmp_data4.toString(16).substr(0, 4);
    // 48 bits for "node"
    data5 = hash.substr(20, 12);
    result = data_1 + '-' + data_2 + '-' + data3 + '-' + data4 + '-' + data5;
    return result;
    }
    function apply_gtm() {
    window.apply('js', new Date())
    // defines window.localstorage key
    const GA_LOCAL_STORAGE_KEY = 'ga:clientId'
    const GA_MEASUREMENT_ID = 'UA-XXXXXXXXX-Y';
    // checks if localstorage is available
    if (window.localStorage) {
    // checks if user was already connected and loads client_id from localstorage
    if (localStorage.getItem(GA_LOCAL_STORAGE_KEY)) {
    // creates new tracker with same client_id as the last time the user visited
    window.apply('js', new Date())
    window.apply('config', GA_MEASUREMENT_ID, {
    'send_page_view': true,
    'storage': 'none',
    'gac_storage': false,
    'client_id': localStorage.getItem(GA_LOCAL_STORAGE_KEY)
    })
    } else {
    // creates client_id and saves it in localStorage -> currently random UUIDv4
    window.localStorage.setItem(GA_LOCAL_STORAGE_KEY, ClientUUID())
    // creates new tracker with the new client_id
    window.apply('js', new Date())
    window.apply('config', GA_MEASUREMENT_ID, {
    'send_page_view': true,
    'storage': 'none',
    'gac_storage': false,
    'client_id': localStorage.getItem(GA_LOCAL_STORAGE_KEY)
    })
    }
    console.log('client_id = ' + localStorage.getItem(GA_LOCAL_STORAGE_KEY))
    }
    }
    window.dataLayer = window.dataLayer || [];
    tarteaucitron.user.googletagmanagerId = 'GTM-WKXDYYY';
    (tarteaucitron.job = tarteaucitron.job || [{
    }]).push('googletagmanager');
    (tarteaucitron.job = tarteaucitron.job || []).push('star_cookie');
    </script>
    
    

    Voilà le code dans tarteaucitron.services.js :

    Cà ne marche pas, les _gid et cid envoyés à GTM ( collect de mode inspect ), n'ont pas changé.


    Code:
    
    // google tag manager
    tarteaucitron.services.googletagmanager = {
           "key": "googletagmanager",
           "type": "api",
           "name": "Google Tag Manager",
           "uri": "https://adssettings.google.com/",
           "needConsent": true,
           "cookies": ['_ga', '_gat', '__utma', '__utmb', '__utmc', '__utmt', '__utmz', '__gads', '_drt_', 'FLC', 'exchange_uid', 'id', 'fc', 'rrs', 'rds', 'rv', 'uid', 'UIDR', 'UID', 'clid', 'ipinfo', 'acs', 'ID_COOKIE'],
           "js": function () {
                   "use strict";
                   // When user allow cookie
                   if (tarteaucitron.user.googletagmanagerId === undefined) {
                           return;
                   }
                   gestion_cookies('ACCEPT', 'accept_cookies');
    
                   window.dataLayer = window.dataLayer || [];
    
                   window.apply = function apply(){dataLayer.push(arguments);
                       console.log(arguments);
                   }
    
                   apply_gtm();
    
    //                window.dataLayer.push({
    //                    'gtm.start': new Date().getTime(),
    //                    event: 'gtm.js'
    //                });
    
                   tarteaucitron.addScript('https://www.googletagmanager.com/gtm.js?id=' + tarteaucitron.user.googletagmanagerId);
           },
           "fallback": function () {
                   "use strict";
                   // when use deny cookie
                   gestion_cookies('DENY', 'accept_cookies');
           }
    };
    
    
     
    #6 ortolojf, 18 Juillet 2020
    Dernière édition: 18 Juillet 2020
  7. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Bon

    Voilà ( d'après le collect ) ce que j'envoie à GTM :

    Code:
    
    Array(6)
    0: {storage: "none"}
    1: {storeGac: false}
    2: {userId: "995137dc-03f1-4b8a-8b98-939d9e912265"}
    3: {gtm.start: 1595242296248, event: "gtm.js", gtm.uniqueEventId: 0}
    4: {event: "gtm.dom", gtm.uniqueEventId: 2}
    5: {event: "gtm.load", gtm.uniqueEventId: 3}
    push: ƒ ()length: 
    6__proto__: Array(0)
    
    
    Est-ce que les noms des variables sont corrects ?

    Merci beaucoup.
     
  8. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 104
    J'aime reçus:
    12
    Voilà voilà

    Cà marche.

    Merci beaucoup à Google. ;)
     
Chargement...
Similar Threads - Tarteaucitron configurer GTM Forum Date
Configurer le script Tarteaucitron pour Facebook commentaires Développement d'un site Web ou d'une appli mobile 28 Avril 2018
Preuve consentement et tarteaucitron. Développement d'un site Web ou d'une appli mobile 8 Juillet 2020
dataLayer GTM et tarteaucitron ? Administration d'un site Web 22 Juin 2020
tarteaucitron et analytics pour conformité RGPD Google Analytics 18 Décembre 2018
Tarteaucitron et Adsense Droit du web (juridique, fiscalité...) 4 Juin 2018
Tarteaucitron suffisant pour les réseaux sociaux ? Droit du web (juridique, fiscalité...) 6 Mai 2018
Comment charger tarteaucitron de manière asynchrone ? Google Analytics 8 Mars 2018
Anonymiser ip avec tarteaucitron ? Administration d'un site Web 13 Février 2018
Quel script de consentement <=> tarteaucitron en pur php ? Développement d'un site Web ou d'une appli mobile 19 Août 2016
Script Tarteaucitron pour les nouvelles règles UE sur les cookies sur joomla Demandes d'avis et de conseils sur vos sites 2 Octobre 2014