Le regroupement des canaux traduit les combinaisons brutes source/medium UTM en catégories lisibles par les équipes métier : Recherche organique, Social payant, Direct, Email. L’interface GA4 applique ces regroupements automatiquement en utilisant les règles par défaut de Google. Dans un projet dbt, vous devez répliquer cette logique — et une macro est la bonne abstraction.
Pourquoi une macro
Le regroupement des canaux est nécessaire à au moins deux endroits : le modèle intermédiaire d’événements sessionisés et potentiellement tout mart incluant l’attribution par canal. Répéter le CASE statement signifierait plusieurs points de maintenance. Une macro appelle la logique une seule fois et génère le SQL partout où elle est référencée.
La macro prend des références de colonnes (pas des valeurs) comme arguments, ce qui est le pattern standard dbt pour les macros génératrices de SQL :
-- macros/ga4/default_channel_grouping.sql
{% macro default_channel_grouping(source_column, medium_column) %} CASE -- Direct WHEN {{ source_column }} IS NULL OR {{ source_column }} = '(direct)' OR {{ source_column }} = '(none)' THEN 'Direct'
-- Recherche payante WHEN REGEXP_CONTAINS({{ medium_column }}, r'^(cpc|ppc|paidsearch)$') OR ({{ source_column }} = 'google' AND {{ medium_column }} = 'sem') THEN 'Paid Search'
-- Social payant WHEN REGEXP_CONTAINS({{ medium_column }}, r'^(paidsocial|paid-social|paid_social)$') OR (REGEXP_CONTAINS({{ source_column }}, r'facebook|instagram|linkedin|twitter|tiktok') AND REGEXP_CONTAINS({{ medium_column }}, r'^(cpc|ppc|paid)')) THEN 'Paid Social'
-- Display WHEN REGEXP_CONTAINS({{ medium_column }}, r'^(display|cpm|banner)$') THEN 'Display'
-- Recherche organique WHEN {{ medium_column }} = 'organic' OR REGEXP_CONTAINS({{ source_column }}, r'google|bing|yahoo|duckduckgo|baidu') AND {{ medium_column }} = 'organic' THEN 'Organic Search'
-- Social organique WHEN REGEXP_CONTAINS({{ source_column }}, r'facebook|instagram|linkedin|twitter|tiktok|pinterest|youtube') AND ({{ medium_column }} IS NULL OR {{ medium_column }} IN ('social', 'referral', '(none)')) THEN 'Organic Social'
-- Email WHEN REGEXP_CONTAINS({{ medium_column }}, r'^(email|e-mail|e_mail)$') THEN 'Email'
-- Affiliation WHEN REGEXP_CONTAINS({{ medium_column }}, r'^(affiliate|affiliates)$') THEN 'Affiliates'
-- Référent WHEN {{ medium_column }} = 'referral' THEN 'Referral'
-- Autre ELSE 'Other' END{% endmacro %}Utilisation dans le modèle sessionisé :
{{ default_channel_grouping('session__source_final', 'session__medium_final') }} AS session__channel_groupingL’ordre du CASE est important
Le CASE statement est évalué de haut en bas, la première correspondance gagne. L’ordre ici encode des décisions de priorité :
- Direct en premier — Une source nulle est toujours Direct, avant toute logique basée sur le medium
- Payant avant organique — Le medium
cpcest classifié comme Recherche payante avant que la règle Recherche organique ne puisse attraper une source Google - Medium Social payant d’abord, puis source + medium — Les équipes utilisant
paidsocialcomme medium sont classifiées directement ; les équipes utilisant le mediumcpcavec des sources de réseaux sociaux sont attrapées par la deuxième condition - Social organique vérifie source + medium non payant — Attrape facebook/instagram avec medium social/referral, mais pas s’ils ont un medium payant (déjà attrapé ci-dessus)
- Référent en dernier — Passe après toutes les autres classifications de canal
Changer cet ordre change le résultat. Si vous mettez Référent avant Social organique, certains trafics de référence sociale seront classifiés comme Référent plutôt que Social organique.
Où le regroupement des canaux diverge de l’interface GA4
Votre macro ne correspondra pas exactement à l’interface GA4. L’interface utilise le jeu complet de règles de regroupement des canaux de Google, plus complexe et incluant une logique spécifique aux plateformes que Google ne publie pas entièrement. Attendez-vous à des différences dans le segment « Autre ».
Les points de divergence les plus courants :
Recherche payante de marque vs hors marque. Google Ads peut taguer les campagnes avec des signaux branded ou non-branded, et l’interface peut distinguer ces derniers comme des canaux séparés. Votre macro classe les deux comme Recherche payante.
Cross-network et Performance Max. Les types de campagnes plus récents peuvent utiliser des valeurs de medium non couvertes par les patterns regex standard. Lorsque vous voyez du trafic atterrir dans « Autre » que vous savez être payant, vérifiez les valeurs brutes source/medium et ajoutez des conditions correspondantes.
YouTube. YouTube peut apparaître à la fois comme Social organique (vues organiques YouTube) et Vidéo payante (publicités YouTube payantes avec medium video). Le regex attrape YouTube dans Social organique ; assurez-vous que vos campagnes YouTube payantes utilisent un medium comme cpc ou paid pour être attrapées par les règles Social payant ou Display en premier.
Alignement avec vos conventions UTM
La macro encode des hypothèses sur votre taxonomie UTM. Si votre équipe utilise paid-social comme convention de medium pour les publicités sociales, le regex r'^(paidsocial|paid-social|paid_social)$' le couvre. Si vous utilisez quelque chose de non standard comme social_paid, il tombera dans « Autre ».
Avant de déployer, exécutez une requête de validation :
SELECT session__source, session__medium, session__channel_grouping, COUNT(*) AS sessionsFROM mrt__analytics__sessionsWHERE session__channel_grouping = 'Other'GROUP BY 1, 2, 3ORDER BY 4 DESCLIMIT 50Tout volume de sessions significatif dans « Autre » avec des sources reconnaissables mérite une investigation. Soit votre nommage UTM ne correspond pas aux patterns attendus (un problème de convention de nommage), soit la macro a besoin d’une condition supplémentaire.
Tester la sortie
Ajoutez un test accepted_values à la colonne dans votre YAML :
- name: session__channel_grouping tests: - accepted_values: values: - 'Direct' - 'Organic Search' - 'Paid Search' - 'Paid Social' - 'Organic Social' - 'Email' - 'Referral' - 'Display' - 'Affiliates' - 'Other'Ce test avertira (ou générera une erreur, selon la sévérité) si la macro génère un nom de canal inattendu. Utile comme garde-fou contre les futures modifications qui introduiraient une faute de frappe ou une nouvelle catégorie de canal sans mettre à jour la liste des valeurs acceptées.