Jak korzystać z danych Google Consent Mode w Big Query
Z naszych poprzednich artykułów dowiedzieliście się czym jest Google Consent Mode oraz jak wpływa na dane dostępne w Google Analytics 4. W tym artykule zajmiemy się kwestią wykorzystania danych GCM w Big Query. Z artykułu dowiesz się:
- Jakie dane dostępne są w Big Query dla sesji z odrzuconą zgodą analytics_storage?
- Jak odrzucona zgoda wpływa na zbieranie user_id?
- Jak obliczyć orientacyjną liczbę sesji oraz użytkowników dla sesji z odrzuconą zgodą analytics_storage?
Jakie dane dostępne są przy użyciu Google Consent Mode?
Wiemy już, że tagi Google Analytics przy poprawnie wdrożonym Google Consent Mode uruchamiają się nawet w przypadku braku udzielonych zgód. Działają wtedy w specjalnym trybie i wysyłają do serverów Google Analytics okrojone informacje. Doprecyzowując, tryb ten polega na wysłaniu pingów bez plików cookie, czyli żadne informacje o zdarzeniach nie zostaną powiązane z trwałym identyfikatorem użytkownika.
Brak udzielonej zgody analytics storage blokuje możliwość zapisywanie plików cookie po stronie klienta. W związku z tym przy każdej odsłonie tworzony jest nowy client_id oraz zostaje wysłane zdarzenie session_start, które na podstawie timestamp tworzy ga_session_id. Mimo to dla pingów bez udzielonych zgód obydwa identyfikatory nie trafiają do GA i nie są wykorzystywane do obliczeń, co mocno zakłamywałoby faktyczny obraz ruchu pod kątem liczby sesji i liczby użytkowników.
Oznacza to, że dla użytkowników, którzy nie udzielili zgód w GA mamy prawdziwe pomiary liczby zdarzeń (z wyjątkiem session_start oraz first_visit), natomiast sesje oraz użytkownicy są dostępne jako dane pochodzące z modelowania behawioralnego. Więcej na ten temat znajdziecie w tym artykule: https://bettersteps.pl/blog/ga4-z-consent-mode-google-vs-brak-consent-mode-google/
Jakie dane Google Consent Mode dostępne są w Big Query?
Główną różnicą w eksporcie Big Query dla danych pochodzących z sesji, w których zgoda analytics_storage została odrzucona jest brak danych z modelowania behawioralnego. W związku z tym nie jesteśmy w stanie określić w sposób standardowy liczby użytkowników oraz liczby sesji, bo do dyspozycji brakuje nam dwóch kluczowych wymiarów: user_pseudo_id oraz ga_session_id.
Poza tym musimy pamiętać, że liczba zdarzeń session_start oraz first_visit jest sztucznie zawyżona, ponieważ są one wysyłane przy każdej odsłonie, ale pozostałe zdarzenia będą dostępne normalnie i możemy z nich korzystać bez żadnych poprawek.
Na powyższym przykładzie widzimy, że wymiary user_pseudo_id oraz ga_session_id przy zapytaniu BQ zwracają wartość null.
Kolejną rzeczą, którą możemy zobaczyć to powtarzające się eventy session_start oraz first_visit dla tego samego użytkownika w ramach tej samej sesji. Skąd wiadomo, że te przykładowe dane pochodzą od jednego użytkownika? Objaśniam w kolejnej części artykułu.
Jak samodzielnie utworzyć liczbę sesji oraz użytkowników?
Standardowa metoda obliczania użytkowników zakładała liczenie unikatowych wartości user_pseduo_id.
0
1
2
3
SELECT
COUNT (DISTINCT user_pseudo_id)
FROM `bettersteps.analytics_166108814.events_*`
Natomiast, żeby obliczyć sesje musieliśmy zliczyć unikatowo konkatenacje user_pseudo_id oraz parametru ga_session_id
0
1
2
3
4
5
SELECT
COUNT (DISTINCT (concat (user_pseudo_id,
(select value.int_value from unnest(event_params)
where key = "ga_session_id"))))
FROM `bettersteps.analytics_166108814.events_*`
Brak tych wymiarów uniemożliwia wykorzystanie powyższych metod do obliczeń.
User id
Z dokumentacji wiem, że user_id jest dostępnym wymiarem w danych pochodzących z sesji z odrzuconą zgodą analytics_storage. Tak samo jest w BQ. Jeżeli nasza strona posiada funkcjonalność autoryzacji i mamy wdrożone user_id to możemy je wykorzystać do obliczania liczby użytkowników.
Dane te, będą dokładniejsze, bo przedstawią faktyczną liczbę użytkowników, więc jeżeli liczbę użytkowników raportujemy z wykorzystaniem user_id to nic się nie zmienia. Obliczenie liczby sesji jest nieco bardziej skomplikowanym procesem.
Przyjmijmy założenie, że po 30 minutach przerwy między następującymi po sobie zdarzeniami rozpoczyna się nowa sesja. Oczywiście czas ten zależy od ustawień naszej usługi GA4.
Żeby oznaczyć taką flagę skorzystamy z funkcji timestamp_diff oraz lag.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT
event_date,
TIMESTAMP_MICROS( event_timestamp)
as event_timestamp,
event_name,
user_first_touch_timestamp,
user_pseudo_id,
(select value.int_value from unnest(event_params)
where key = 'ga_session_id') as ga_session_id,
TIMESTAMP_DIFF( TIMESTAMP_MICROS( event_timestamp),
LAG(TIMESTAMP_MICROS( event_timestamp))
over (partition by user_id
order by event_timestamp), minute) as timestamp_diff,
user_id
FROM `bettersteps.analytics_166108814.events_*`
order by event_timestamp
Interesują mnie wartości minutowe, dlatego w parametrze funkcji timestamp_diff zadeklarowałem minute.
Kolejnym krokiem jest rozpoznanie, kiedy tworzy się nowa sesja. Wykorzystamy do tego prostą instrukcję warunkową case.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
with gcm as
(
SELECT
event_date,
TIMESTAMP_MICROS( event_timestamp)
as event_timestamp,
event_name,
user_first_touch_timestamp,
user_pseudo_id,
(select value.int_value from unnest(event_params)
where key = 'ga_session_id') as ga_session_id,
TIMESTAMP_DIFF(TIMESTAMP_MICROS(event_timestamp),
LAG(TIMESTAMP_MICROS( event_timestamp))
over (partition by user_id
order by event_timestamp),
minute) as timestamp_diff,
user_id
FROM `bettersteps.analytics_166108814.events_*`
order by event_timestamp
)
SELECT
*,
(case
when timestamp_diff > 30 then "new_session"
end) as session_info
from gcm
Teraz, gdy już wiem, kiedy rozpoczyna się moja sesja, mogę przypisać jej fikcyjne id.
W tym celu wykonam grupowanie eventów pochodzących z jednej sesji za pomocą funkcji countif, a jako id sesji przypiszę user_first_touch_timestamp przy użyciu funkcji min.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
with gcm as
(
SELECT
event_date,
TIMESTAMP_MICROS( event_timestamp) as event_timestamp,
event_name,
user_first_touch_timestamp,
user_pseudo_id,
(select value.int_value from unnest(event_params)
where key = 'ga_session_id') as ga_session_id,
TIMESTAMP_DIFF( TIMESTAMP_MICROS( event_timestamp),
LAG(TIMESTAMP_MICROS( event_timestamp))
over (partition by user_id order
by event_timestamp), minute)
as timestamp_diff,
user_id
FROM `bettersteps.analytics_166108814.events_*`
order by event_timestamp
),
gcm_v2 as
(
SELECT
*,
(case
when timestamp_diff > 30 then "new_session"
end) as session_info
from gcm
),
gcm_v3 as
(
SELECT
*,
countif(session_info in ("new_session"))
over (order by event_timestamp) as session_group
from gcm_v2
)
SELECT
*,
min(user_first_touch_timestamp)
over (partition by session_group) as session_id
from gcm_v3
order by event_timestamp
Dzięki tym operacjom zamodelowałem id sesji, które mogę teraz wykorzystać do obliczeń.
0
1
2
3
4
5
6
7
SELECT
COUNT (DISTINCT user_id)
FROM `bettersteps.analytics_166108814.events_*`
SELECT
COUNT (DISTINCT (concat (user_id, session_id)))
FROM `bettersteps.analytics_166108814.events_*`
Niestety te obliczenia mogę zastosować tylko dla użytkowników, którzy mają przypisane user_id.
Wymiary niestandardowe
Żeby móc działać w BQ, również na danych użytkowników bez przypisanego user_id możemy wykorzystać wymiary niestandardowe, które również są przekazywane do Google Analytics dla sesji bez wyrażonej zgody analytics_storage.
Ze względów prawnych nie powinniśmy po stronie użytkownika ustawiać żadnych znaczników, które doprowadzą do jego rozpoznania, więc w przypadku braku user id musimy zrezygnować z metryki użytkowników w Big Query.
Możemy jednak stworzyć wymiar, który zastąpi nam session id i pozwoli powiązać zdarzenia pochodzące z tej samej sesji.
Jako nasze niestandardowe session_id wykorzystamy timestamp rozpoczęcia sesji. W tym celu musimy w GTM stworzyć niestandardowy tag HTML, który zapisze nam do session storage aktualny timestamp:
0
1
2
3
4
5
<script>
var session_start = Date.now();
sessionStorage.setItem('session_start',
session_start);
</script>
Ponieważ chcemy uruchamiać ten tag tylko raz na sesję, musimy stworzyć zmienną, która przechwytuje wartość session_start z session storage. Do tego zrobimy niestandardową zmienną javascript:
0
1
2
3
4
function() {
var s = sessionStorage.getItem('session_start');
return s;
}
Regułę uruchamiającą nasz tag skonfigurujemy w taki sposób aby, robić to tylko wtedy kiedy parametr w session storage jeszcze nie istnieje:
Ostatnim krokiem w GTM jest dodanie tej zmiennej do konfiguracji w naszym tagu GA4:
Oczywiście, jeżeli używamy zmiennej ustawień konfiguracji możemy to zrobić również tam.
Ponieważ ten parametr jest nam potrzebny na potrzeby obliczeń w BQ nie musimy go konfigurować w interfejsie Google Analytics 4.
To co jest tutaj bardzo ważne to, że może się zdarzyć tak, że ta sama wartość session_start wystąpi faktycznie dla więcej niż jednej sesji, ale jest to nasze uproszczenie stworzone na potrzeby raportowania.
Dzięki temu, możemy z dużą dozą prawdopodobieństwa łączyć zdarzenia pochodzące z jednej sesji za pomocą tego parametru oraz wykorzystać go do obliczania liczby sesji w BQ dla sesji bez wyrażonej zgody analytics_storage.
0
1
2
3
4
5
SELECT
COUNT (DISTINCT (select value.int_value
from unnest(event_params)
where key = "session_start"))
FROM `bettersteps.analytics_166108814.events_*`
Końcowe wnioski
Mimo, że dane w Big Query dla sesji bez wyrażonej zgody analytics_storage są mocno okrojone, nadal możemy wykonywać raportowanie oraz analizy na ich podstawie. Jest to nieco bardziej skomplikowane, a dla użytkowników niezalogowanych wymaga dodatkowego tagowania. Nie mniej jednak warto to zrobić, bo zyskujemy dokładniejsze dane, które pokazują nam prawdziwy obraz ruchu na naszej stronie oraz pozwalają wysnuć dokładniejsze wnioski.
Źródła:
Działania tagów w zależności od stanu zgody: https://support.google.com/analytics/answer/9976101?hl=pl&sjid=1091137706529052351-EU
Modelowanie behawioralne: https://support.google.com/analytics/answer/11161109