Skip to content

Commit 9dfdbd4

Browse files
Align default channel groupings with GA4 docs (Velir#282)
* Align default channel groupings with GA4 docs * rename unit test class * replace curly quotes with straight quotes --------- Co-authored-by: Adam Ribaudo <[email protected]>
1 parent 3a7fb3c commit 9dfdbd4

File tree

5 files changed

+404
-115
lines changed

5 files changed

+404
-115
lines changed

macros/default_channel_grouping.sql

Lines changed: 128 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,148 @@
1-
-- Inspired by https://github.com/llooker/ga_four_block_dev/blob/master/views/sessions.view.lkml
21
-- Google's documentation is here: https://support.google.com/analytics/answer/9756891?hl=en
32
-- source_category Excel file can be downloaded from the above link and may change over time
4-
5-
{% macro default_channel_grouping(source, medium, source_category) %}
6-
{{ return(adapter.dispatch('default_channel_grouping', 'ga4')(source, medium, source_category)) }}
3+
{% macro default_channel_grouping(source, medium, source_category, campaign) %}
4+
{{ return(adapter.dispatch('default_channel_grouping', 'ga4')(source, medium, source_category, campaign)) }}
75
{% endmacro %}
86

9-
{% macro default__default_channel_grouping(source, medium, source_category) %}
10-
case
11-
when
12-
(
13-
{{source}} is null
7+
{% macro default__default_channel_grouping(source, medium, source_category, campaign) %}
8+
case
9+
-- Direct: Source exactly matches "(direct)" AND Medium is one of ("(not set)", "(none)")
10+
when (
11+
{{source}} is null
1412
and {{medium}} is null
1513
)
1614
or (
1715
{{source}} = '(direct)'
1816
and ({{medium}} = '(none)' or {{medium}} = '(not set)')
19-
)
17+
)
2018
then 'Direct'
21-
when
22-
(
23-
REGEXP_CONTAINS({{source}}, r"^(facebook|instagram|pinterest|reddit|twitter|linkedin)") = true
24-
or {{source_category}} = 'SOURCE_CATEGORY_SOCIAL'
19+
20+
-- Cross-network: Campaign Name contains "cross-network"
21+
when REGEXP_CONTAINS({{campaign}}, r"cross-network")
22+
then 'Cross-network'
23+
24+
-- Paid Shopping:
25+
-- (Source matches a list of shopping sites
26+
-- OR
27+
-- Campaign Name matches regex ^(.*(([^a-df-z]|^)shop|shopping).*)$)
28+
-- AND
29+
-- Medium matches regex ^(.*cp.*|ppc|retargeting|paid.*)$
30+
when (
31+
{{source_category}} = 'SOURCE_CATEGORY_SHOPPING'
32+
or REGEXP_CONTAINS({{campaign}}, r"^(.*(([^a-df-z]|^)shop|shopping).*)$")
2533
)
26-
and REGEXP_CONTAINS({{medium}}, r"^(.*cp.*|ppc|retargeting|paid.*)$") = true
27-
then 'Paid Social'
28-
when
29-
REGEXP_CONTAINS({{source}}, r"^(facebook|instagram|pinterest|reddit|twitter|linkedin)") = true
30-
or {{medium}} in ("social","social-network","social-media","sm","social network","social media")
31-
or {{source_category}} = 'SOURCE_CATEGORY_SOCIAL'
32-
then 'Organic Social'
33-
when
34-
REGEXP_CONTAINS({{medium}}, r"email|e-mail|e_mail|e mail") = true
35-
or REGEXP_CONTAINS({{source}}, r"email|e-mail|e_mail|e mail") = true
36-
then 'Email'
37-
when
38-
REGEXP_CONTAINS({{medium}}, r"affiliate|affiliates") = true
39-
then 'Affiliates'
40-
when
41-
{{source_category}} = 'SOURCE_CATEGORY_SHOPPING'
42-
and REGEXP_CONTAINS({{medium}},r"^(.*cp.*|ppc|paid.*)$")
34+
and REGEXP_CONTAINS({{medium}},r"^(.*cp.*|ppc|retargeting|paid.*)$")
4335
then 'Paid Shopping'
44-
when
45-
({{source_category}} = 'SOURCE_CATEGORY_VIDEO' AND REGEXP_CONTAINS({{medium}},r"^(.*cp.*|ppc|paid.*)$"))
46-
or {{source}} = 'dv360_video'
36+
37+
-- Paid Search:
38+
-- Source matches a list of search sites
39+
-- AND
40+
-- Medium matches regex ^(.*cp.*|ppc|retargeting|paid.*)$
41+
when {{source_category}} = 'SOURCE_CATEGORY_SEARCH'
42+
and REGEXP_CONTAINS({{medium}}, r"^(.*cp.*|ppc|retargeting|paid.*)$")
43+
then 'Paid Search'
44+
45+
-- Paid Social:
46+
-- Source matches a regex list of social sites
47+
-- AND
48+
-- Medium matches regex ^(.*cp.*|ppc|retargeting|paid.*)$
49+
when {{source_category}} = 'SOURCE_CATEGORY_SOCIAL'
50+
and REGEXP_CONTAINS({{medium}}, r"^(.*cp.*|ppc|retargeting|paid.*)$")
51+
then 'Paid Social'
52+
53+
-- Paid Video:
54+
-- Source matches a list of video sites
55+
-- AND
56+
-- Medium matches regex ^(.*cp.*|ppc|retargeting|paid.*)$
57+
when {{source_category}} = 'SOURCE_CATEGORY_VIDEO'
58+
and REGEXP_CONTAINS({{medium}},r"^(.*cp.*|ppc|retargeting|paid.*)$")
4759
then 'Paid Video'
48-
when
49-
REGEXP_CONTAINS({{medium}}, r"^(display|cpm|banner)$")
50-
or {{source}} = 'dv360_display'
60+
61+
-- Display:
62+
-- Medium is one of ("display", "banner", "expandable", "interstitial", "cpm")
63+
when {{medium}} in ('display', 'banner', 'expandable', 'interstitial', 'cpm')
5164
then 'Display'
52-
when
53-
{{source_category}} = 'SOURCE_CATEGORY_SEARCH'
54-
and REGEXP_CONTAINS({{medium}}, r"^(.*cp.*|ppc|retargeting|paid.*)$")
55-
then 'Paid Search'
56-
when
57-
REGEXP_CONTAINS({{medium}}, r"^(cpv|cpa|cpp|content-text)$")
58-
then 'Other Advertising'
59-
when
60-
{{medium}} = 'organic' or {{source_category}} = 'SOURCE_CATEGORY_SEARCH'
61-
then 'Organic Search'
62-
when
63-
{{source_category}} = 'SOURCE_CATEGORY_VIDEO'
64-
or REGEXP_CONTAINS({{medium}}, r"^(.*video.*)$")
65-
then 'Organic Video'
66-
when
67-
{{source_category}} = 'SOURCE_CATEGORY_SHOPPING'
65+
66+
-- Paid Other:
67+
-- Medium matches regex ^(.*cp.*|ppc|retargeting|paid.*)$
68+
when REGEXP_CONTAINS({{medium}}, r"^(.*cp.*|ppc|retargeting|paid.*)$")
69+
then 'Paid Other'
70+
71+
-- Organic Shopping:
72+
-- Source matches a list of shopping sites
73+
-- OR
74+
-- Campaign name matches regex ^(.*(([^a-df-z]|^)shop|shopping).*)$
75+
when {{source_category}} = 'SOURCE_CATEGORY_SHOPPING'
76+
or REGEXP_CONTAINS({{campaign}}, r"^(.*(([^a-df-z]|^)shop|shopping).*)$")
6877
then 'Organic Shopping'
69-
when
70-
{{medium}} in ("referral", "app", "link")
78+
79+
-- Organic Social:
80+
-- Source matches a regex list of social sites
81+
-- OR
82+
-- Medium is one of ("social", "social-network", "social-media", "sm", "social network", "social media")
83+
when {{source_category}} = 'SOURCE_CATEGORY_SOCIAL'
84+
or {{medium}} in ("social","social-network","social-media","sm","social network","social media")
85+
then 'Organic Social'
86+
87+
-- Organic Video:
88+
-- Source matches a list of video sites
89+
-- OR
90+
-- Medium matches regex ^(.*video.*)$
91+
when {{source_category}} = 'SOURCE_CATEGORY_VIDEO'
92+
or REGEXP_CONTAINS({{medium}}, r"^(.*video.*)$")
93+
then 'Organic Video'
94+
95+
-- Organic Search:
96+
-- Source matches a list of search sites
97+
-- OR
98+
-- Medium exactly matches organic
99+
when {{source_category}} = 'SOURCE_CATEGORY_SEARCH' or {{medium}} = 'organic'
100+
then 'Organic Search'
101+
102+
-- Referral:
103+
-- Medium is one of ("referral", "app", or "link")
104+
when {{medium}} in ("referral", "app", "link")
71105
then 'Referral'
72-
when
73-
{{medium}} = 'audio'
106+
107+
-- Email:
108+
-- Source = email|e-mail|e_mail|e mail
109+
-- OR
110+
-- Medium = email|e-mail|e_mail|e mail
111+
when REGEXP_CONTAINS({{source}}, r"email|e-mail|e_mail|e mail")
112+
or REGEXP_CONTAINS({{medium}}, r"email|e-mail|e_mail|e mail")
113+
then 'Email'
114+
115+
-- Affiliates:
116+
-- Medium = affiliate
117+
when {{medium}} = 'affiliate'
118+
then 'Affiliates'
119+
120+
-- Audio:
121+
-- Medium exactly matches audio
122+
when {{medium}} = 'audio'
74123
then 'Audio'
75-
when
76-
{{medium}} = 'sms'
77-
or {{source}} = 'sms'
124+
125+
-- SMS:
126+
-- Source exactly matches sms
127+
-- OR
128+
-- Medium exactly matches sms
129+
when {{source}} = 'sms'
130+
or {{medium}} = 'sms'
78131
then 'SMS'
79-
when
80-
REGEXP_CONTAINS({{medium}}, r"(mobile|notification|push$)") or {{source}} = 'firebase'
81-
then 'Push Notifications'
82-
else '(Other)'
83-
end
132+
133+
-- Mobile Push Notifications:
134+
-- Medium ends with "push"
135+
-- OR
136+
-- Medium contains "mobile" or "notification"
137+
-- OR
138+
-- Source exactly matches "firebase"
139+
when REGEXP_CONTAINS({{medium}}, r"push$")
140+
or REGEXP_CONTAINS({{medium}}, r"mobile|notification")
141+
or {{source}} = 'firebase'
142+
then 'Mobile Push Notifications'
143+
144+
-- Unassigned is the value Analytics uses when there are no other channel rules that match the event data.
145+
else 'Unassigned'
146+
end
84147

85148
{% endmacro %}

models/staging/stg_ga4__sessions_traffic_sources.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
with session_events as (
2-
select
2+
select
33
session_key
44
,event_timestamp
55
,events.event_source
@@ -17,11 +17,11 @@ with session_events as (
1717
set_default_channel_grouping as (
1818
select
1919
*
20-
,{{ga4.default_channel_grouping('event_source','event_medium','source_category')}} as default_channel_grouping
20+
,{{ga4.default_channel_grouping('event_source','event_medium','source_category', 'event_campaign')}} as default_channel_grouping
2121
from session_events
2222
),
2323
session_source as (
24-
select
24+
select
2525
session_key
2626
,COALESCE(FIRST_VALUE((CASE WHEN event_source <> '(direct)' THEN event_source END) IGNORE NULLS) OVER (session_window), '(direct)') AS session_source
2727
,COALESCE(FIRST_VALUE((CASE WHEN event_source <> '(direct)' THEN COALESCE(event_medium, '(none)') END) IGNORE NULLS) OVER (session_window), '(none)') AS session_medium

models/staging/stg_ga4__sessions_traffic_sources_daily.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
with session_events as (
21-
select
21+
select
2222
client_key
2323
,session_partition_key
2424
,event_date_dt as session_partition_date
@@ -42,11 +42,11 @@ with session_events as (
4242
set_default_channel_grouping as (
4343
select
4444
*
45-
,{{ga4.default_channel_grouping('event_source','event_medium','source_category')}} as default_channel_grouping
45+
,{{ga4.default_channel_grouping('event_source','event_medium','source_category', 'event_campaign')}} as default_channel_grouping
4646
from session_events
4747
),
4848
first_session_source as (
49-
select
49+
select
5050
client_key
5151
,session_partition_key
5252
,session_partition_date
@@ -63,13 +63,13 @@ first_session_source as (
6363
),
6464
find_non_direct_session_partition_key as (
6565

66-
select
66+
select
6767
*
6868
,if(session_source <> '(direct)', session_partition_key, null) as non_direct_session_partition_key --provide the session_partition_key only if source is not direct. Useful for last non-direct attribution modeling
6969
from first_session_source
7070
)
7171

72-
select
72+
select
7373
client_key
7474
,session_partition_key
7575
,session_partition_date

seeds/ga4_source_categories.csv

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ crackle.com,SOURCE_CATEGORY_VIDEO
170170
cross.tv,SOURCE_CATEGORY_SOCIAL
171171
crunchyroll,SOURCE_CATEGORY_SOCIAL
172172
crunchyroll.com,SOURCE_CATEGORY_SOCIAL
173-
cse.google.com,SOURCE_CATEGORY_SEARCH
174173
curiositystream,SOURCE_CATEGORY_VIDEO
175174
curiositystream.com,SOURCE_CATEGORY_VIDEO
176175
cyworld,SOURCE_CATEGORY_SOCIAL
@@ -314,9 +313,7 @@ goodreads.com,SOURCE_CATEGORY_SOCIAL
314313
google,SOURCE_CATEGORY_SEARCH
315314
google+,SOURCE_CATEGORY_SOCIAL
316315
google-play,SOURCE_CATEGORY_SEARCH
317-
google.com,SOURCE_CATEGORY_SEARCH
318316
googlegroups.com,SOURCE_CATEGORY_SOCIAL
319-
googlemybusiness,SOURCE_CATEGORY_SEARCH
320317
googleplus,SOURCE_CATEGORY_SOCIAL
321318
govloop,SOURCE_CATEGORY_SOCIAL
322319
govloop.com,SOURCE_CATEGORY_SOCIAL
@@ -398,6 +395,7 @@ l.facebook.com,SOURCE_CATEGORY_SOCIAL
398395
l.instagram.com,SOURCE_CATEGORY_SOCIAL
399396
l.messenger.com,SOURCE_CATEGORY_SOCIAL
400397
last.fm,SOURCE_CATEGORY_SOCIAL
398+
lens.google.com,SOURCE_CATEGORY_SEARCH
401399
librarything,SOURCE_CATEGORY_SOCIAL
402400
librarything.com,SOURCE_CATEGORY_SOCIAL
403401
lifestream.aol.com,SOURCE_CATEGORY_SOCIAL
@@ -431,7 +429,6 @@ m.twitch.tv,SOURCE_CATEGORY_VIDEO
431429
m.vk.com,SOURCE_CATEGORY_SOCIAL
432430
m.yelp.com,SOURCE_CATEGORY_SOCIAL
433431
m.youtube.com,SOURCE_CATEGORY_VIDEO
434-
mail.google.com,SOURCE_CATEGORY_SEARCH
435432
mail.rambler.ru,SOURCE_CATEGORY_SEARCH
436433
mail.yandex.ru,SOURCE_CATEGORY_SEARCH
437434
malaysia.search.yahoo.com,SOURCE_CATEGORY_SEARCH
@@ -555,6 +552,7 @@ pinterest.se,SOURCE_CATEGORY_SOCIAL
555552
pixiv.net,SOURCE_CATEGORY_SOCIAL
556553
pl.pinterest.com,SOURCE_CATEGORY_SOCIAL
557554
pl.search.yahoo.com,SOURCE_CATEGORY_SEARCH
555+
play.google.com,SOURCE_CATEGORY_SEARCH
558556
playahead.se,SOURCE_CATEGORY_SOCIAL
559557
player.twitch.tv,SOURCE_CATEGORY_VIDEO
560558
player.vimeo.com,SOURCE_CATEGORY_VIDEO
@@ -645,6 +643,7 @@ smartnews.com,SOURCE_CATEGORY_SOCIAL
645643
snapchat,SOURCE_CATEGORY_SOCIAL
646644
snapchat.com,SOURCE_CATEGORY_SOCIAL
647645
so.com,SOURCE_CATEGORY_SEARCH
646+
social,SOURCE_CATEGORY_SOCIAL
648647
sociallife.com.br,SOURCE_CATEGORY_SOCIAL
649648
socialvibe,SOURCE_CATEGORY_SOCIAL
650649
socialvibe.com,SOURCE_CATEGORY_SOCIAL
@@ -710,6 +709,7 @@ tripadvisor,SOURCE_CATEGORY_SOCIAL
710709
tripadvisor.com,SOURCE_CATEGORY_SOCIAL
711710
trombi,SOURCE_CATEGORY_SOCIAL
712711
trombi.com,SOURCE_CATEGORY_SOCIAL
712+
trustpilot,SOURCE_CATEGORY_SOCIAL
713713
tudou,SOURCE_CATEGORY_SOCIAL
714714
tudou.com,SOURCE_CATEGORY_SOCIAL
715715
tuenti,SOURCE_CATEGORY_SOCIAL

0 commit comments

Comments
 (0)