Cílem tohoto článku je podat pomocnou ruku každému nebožákovi, který dostal za úkol implementovat Gemius tracking v souladu s novými cookie souhlasy a nechce se spokojit s příšerným výsledkem.
Varování: Článek obsahuje blbý kecy na Gemius a proto by ho nikdo z Gemius neměl číst.
Co mám v batůžku
- Single Page Aplikace
- Cookie Consent Platforma (CMP)
- Google Tag Manager
- Dokumentace k nástroji Gemius Prism
- Gemius
Cíl
Spouštět Gemius tracking tak, aby reflektoval nastavení cookie consentů.
Consent ano
Když mám consent, tak chci, aby HTTP komunikace vypadala např. takto:
Consent ne
Když nemám consent, chci aby HTTP request vypadal takto.
Cesta
Co nám říká dokumentace?
Pokud nemáš CMP platformu s tcf api, tak implementuj do existující implementace navíc:
window.pp_gemius_consent = true/false
Tak a to by mělo být všechno. Tedy u normálního trackeru. Ne zde.
V čem je problém?
Gemius ignoruje nastavení consentů u SPA. Což je trochu nepříjemné chování.
Situace 1
Uživatel přijde na web poprvé. Souhlas nám ještě nedal. Nic tedy netrackuji.
Uživatel interagoval s Cookie lištou, souhlas máme, přes GTM nastavujeme window.pp_gemius_consent = true
Zavádíme loader xgemius.js a přes metodu pp_gemius_hit posíláme HIT.
Pošle se hit.
Uživatel odebere consent.
Nastavím
window.pp_gemius_consent = false
Uživatel vytvoří virtuální pageview a pošle se?
Event jako kdyby consent existoval.
Situace 2
Uživatel přijde na web poprvé. Souhlas nám ještě nedal. Nic tedy netrackuji.
Vzhledem k tomu, že Gemius umí režim DNT, tedy Do Not Track, mohu ho instruovat aby měřil zobrazení stránky bez použití cookies.
window.pp_gemius_consent = false
Pokud chci mít všechny metriky co nejrelevantnější, samotný Gemius doporučuje implementovat 10s timeout, během kterého pokud uživatel nedá souhlas, tak se stejně pošle pageview bez consentu, tedy stejně jako kdyby uživatel dal odmítnout. Jeho volba zůstane vyslyšena a naše klíčové metriky zůstanou věrohodné. Double win.
Uživatel tedy na nás kašle, souhlas nám nedá, uběhne 10s a timer spustí DNT gemius event.
Uživatel se ale asi jenom dloubal v nose a nestihl to za těch 10s zmáčknout ale nakonec prst z nosu vyndal, klikl na souhlasím s cookies a brouzdá po naší skvělé SPA dál. Vyrobil další pageview.
Instruuji tedy gemius tracker window.pp_gemius_consent = true a přes pp_gemius_hit posíláme HIT.
Opět DNT. Takže i když souhlas mám, gemius tracker jej má nastavený v paměti, tak jej ignoruje když se sitiuace změní.
Situace 3
Ať to nastavíme jakkoliv s consenty, tak se propadnou metriky Real Users, ikdyž Gemius tvrdí, že ne.
Odpočívadlo
Píšeme na Gemius Client Care, zda nám s tím mohou pomoci, jelikož toto chování úplně neodpovídá chování, které by SPA tracking měl následovat.
Odpověď je šokující. Problém je, že Google Tag Manager Encryptuje něco a proto je to rozbitý. Máme to tedy udělat bez GTM a bude to určitě dobrý.
Tak tady mi poprvé začalo cukat oční víčko.
Udělal jsem si triviální analýzu gemius snippetu a tedy prosím, pro nastavování dvou proměnných ve window scope a asynchronním načtení scriptu xgemius.js to nedělá nic.
Žádná Encrypto tentononc se neděje.
Loader Gemius
<!--//--><![CDATA[//><!-- var pp_gemius_identifier = 'IDENTIFIER'; var pp_gemius_use_cmp = true; // lines below shouldn't be edited function gemius_pending(i) { window[i] = window[i] || function() { var x = window[i + '_pdata'] = window[i + '_pdata'] || []; x[x.length] = arguments; }; }; gemius_pending('gemius_hit'); gemius_pending('gemius_event'); gemius_pending('pp_gemius_hit'); gemius_pending('pp_gemius_event'); (function(d, t) { try { var gt = d.createElement(t), s = d.getElementsByTagName(t)[0], l = 'http' + ((location.protocol == 'https:') ? 's' : ''); gt.setAttribute('async', 'async'); gt.setAttribute('defer', 'defer'); gt.src = l + '://PREFIX.hit.gemius.pl/xgemius.js'; s.parentNode.insertBefore(gt, s); } catch (e) {} })(document, 'script');
Také dostáváme hint, že máme použít tcfapi a cmp, což nepodporujeme a nemáme k tomu důvod, jelikžo si triggering a consenty řešíme vlastní cestou.
Také máme použít 10s timer aby byly lepší data u uživatelů bez consentu.
Prostě sorry jako, ale fakt jste mi nepomohli a dokumentace je mizerná.
Bláto
Úkol zněl jasně, implementovat Gemius tak, aby když uživatel dá consent, aby to trackovalo s consenty a když je nedá, aby to trackovalo s DNT. To celé na SPA aplikaci s v našem případě s GTM.
Naprosto normální požadavky na tracking v roce 2022. Gemius -> nelze. Nazdar.
Se s tim smiř? Nikdy!
Tady začíná ta špinavá část cesty.
Deobfuskace trackeru
Vím že mě zajímá, která část trackeru nastavuje DNT.
Je to metoda init()
init: function() { setInterval(gemius_hcconn.timer, 60 * 1000); gemius_hcconn.add_event(window, 'message', gemius_hcconn.msgreceiver); gemius_hcconn.getdntcookie(); gemius_hcconn.getfpcap(); gemius_hcconn.hssl = (gemius_hcconn.ssl || gemius_hcconn.getchromever() >= 67) ? 1 : 0; gemius_hcconn.flashv = gemius_hcconn.getflashv(); if (gemius_hcconn.dnt == 0 && gemius_hcconn.explicit_consent !== false) { gemius_hcconn.getfpcookie(); gemius_hcconn.waiting_for_fpdata = ((gemius_hcconn.fpdata.length > 0 && gemius_hcconn.fpdata[0] == '-') || gemius_hcconn.fpdata == '') ? 1 : 0; } else { gemius_hcconn.waiting_for_fpdata = 0; gemius_hcconn.fpdata = "-DNT"; } try { if (gemius_hcconn.dnt == 0 && gemius_hcconn.explicit_consent !== false) { gemius_hcconn.waiting_for_lsdata = (typeof window.postMessage != 'undefined' && typeof localStorage != 'undefined' && localStorage != null) ? 1 : 0; if (gemius_hcconn.waiting_for_lsdata == 0) { gemius_hcconn.lsdata = '-NOTSUP'; } }
Nikoho asi nepřekvapí, že init se volá jednou při načtení.
Pak už nikdy nepočítá, že by se consent mohl změnit. Což by asi stačilo u webu z roku devatenátsetnebreč, ale Single Page Aplikace roku 2022 má jiné požadavky. Jedině refresh. Jasně, tak kvůli jednomu dřevnímu nástroji bude refreshovat celou aplikaci. Ani náhodou.
Takže před každým odeslaným hitem reinicializuji tracker.
window.gemius_hcconn.init()
Doufal jsem, že si při reinicializaci vezme hodnoty aktuálních consentů ale ne. Stále ignore.
Tak jedu dál a vidím, že si interně ukládá hodnotu consentu do proměnné jako 0 či 1
window.gemius_hcconn.dnt
Takže stačí manipulovat s
window.gemius_hcconn.dnt = +!window.pp_gemius_consent
A jako zázrakem to začne fungovat.
Umývání holinek
Vzhledem k tomu, že abych to rozchodil, musel jsem sáhnout do interních a nedokumentovaných metod gemius trackeru, čímž jsem si pěkně zašpinil boty a je asi jasné, že to není oficiálně podporované řešení.
Ale takhle vypadá můj loader pro Gemius a SPA aplikace
function trackGemiusHit (consents, gemiusId) { // set consents status window.pp_gemius_consent = consents // init before every hit, because gemius is not able to dynamicaly react to consent changes if (typeof (window.gemius_hcconn) !== 'undefined' && typeof (window.gemius_hcconn.init) === 'function') { window.gemius_hcconn.dnt = +!window.pp_gemius_consent window.gemius_hcconn.init() } // track gemius hit if (typeof(window.pp_gemius_hit) === 'function' && typeof(pp_gemius_identifier) === 'string') { window.pp_gemius_hit(gemiusId) } } function gemius_pending(i) { window[i] = window[i] || function() { var x = window[i + '_pdata'] = window[i + '_pdata'] || []; x[x.length] = arguments; }; }; gemius_pending('gemius_hit'); gemius_pending('gemius_event'); gemius_pending('pp_gemius_hit'); gemius_pending('pp_gemius_event'); (function(d, t) { try { var gt = d.createElement(t), s = d.getElementsByTagName(t)[0], l = 'http' + ((location.protocol == 'https:') ? 's' : ''); gt.setAttribute('async', 'async'); gt.setAttribute('defer', 'defer'); gt.src = l + '://spir.hit.gemius.pl/xgemius.js'; s.parentNode.insertBefore(gt, s); } catch (e) {} })(document, 'script');
A na jednotlivých virtuálních pageviews akorát volám funkci trackGemiusHit.
Pokud mám consent
trackGemiusHit (true,’gemiusID854874654blabla’)
Pokud nemám consent
trackGemiusHit (false,’gemiusID854874654blabla’)