Centraliser ses campagnes Google Ads, Meta et Bing dans Looker Studio avec Windsor.ai et BigQuery

mise en place d'un dashboard marketing

L’objectif : un dashboard centralisé, à jour et accessible partout

Avec plusieurs clients à gérer sur Google Ads, Meta et Microsoft, je passais beaucoup de temps à jongler entre les interfaces et à compiler des exports à la main. J’avais besoin d’une plateforme où rassembler les résultats de toutes les campagnes, tous canaux confondus.

L’objectif était double : gagner du temps sur le reporting et, surtout, repérer plus vite les baisses ou hausses de performance — sans attendre un export mensuel pour s’apercevoir qu’une campagne a décroché.

J’ai donc décidé de me lancer dans la construction un dashboard qui se met à jour automatiquement, accessible à tout moment, que ce soit pour un point client ou le suivi quotidien.

Pourquoi Windsor.ai, BigQuery et Looker Studio

Pour ce type de projet, plusieurs approches étaient possibles, avec trois choix à faire : comment importer les données, où les stocker, et avec quel outil les afficher. Je me suis arrêté sur Windsor.ai pour l’import, BigQuery pour le stockage, et Looker Studio pour le dashboard.

Windsor.ai comme connecteur : contrairement aux connecteurs natifs de Looker Studio, Windsor centralise plusieurs plateformes (Dans mon cas : Google Ads, Meta, Microsoft, GA4, LinkedIn) dans un format homogène, sans avoir à gérer une intégration différente pour chaque source. C’est un gain de temps considérable dès qu’on dépasse 2-3 plateformes.

BigQuery comme couche intermédiaire : brancher Windsor directement sur Looker Studio est possible, mais ça limite fortement ce qu’on peut faire avec les données — pas de transformation, pas d’historisation propre, pas de logique métier (segmentation, KPIs calculés). En passant par BigQuery, les données brutes sont stockées, transformées via des vues SQL, et le dashboard se contente d’afficher un résultat déjà propre. C’est aussi ce qui permet de gérer plusieurs clients avec la même architecture, en dupliquant simplement les vues.

Looker Studio pour restituer les données : gratuit, natif à l’écosystème Google, et suffisant pour la plupart des besoins de reporting client — Dans mon cas, je n’ai pas besoin d’un outil de BI plus lourd type Power BI.

Étape 1 : connecter les sources avec Windsor.ai

Créer le dataset et les tables dans BigQuery

Avant d’importer les données à partir de Windsor, il faut que la destination existe côté Google Cloud. Ça passe par trois étapes :

  1. Créer un projet BigQuery (ou utiliser un projet existant) dans la console Google Cloud, avec l’API BigQuery activée.
  2. Créer un dataset dédié — je l’ai nommé ads_data — qui accueille toutes les tables liées à l’import Windsor. Si vous avez plusieurs clients, je vous conseille de créer un dataset pour chacun pour garder une architecture.
  3. Laisser Windsor créer les tables automatiquement lors du premier import : une fois le dataset renseigné dans la configuration Windsor, l’outil génère lui-même la table brute et la peuple à chaque synchronisation, sans avoir à définir le schéma manuellement.

Creation ensemble de données Big Querry

C’est cette table brute, une fois alimentée, qui sert de point de départ à la structuration en vues (ads_segmented, ads_kpis…) détaillée à l’étape suivante.

Configuration des connecteurs Windsor

Une fois le compte Windsor.ai créé, la connexion des sources se fait plateforme par plateforme : on autorise l’accès aux différents comptes publicitaires et analytics, via une authentification OAuth classique. Windsor propose ensuite de choisir les champs à importer (impressions, clics, coût, conversions…) et la fréquence de synchronisation.

Pour mes rapports, j’importe par défaut : Date, source, dépenses, impressions, clics, conversions, campaign id et les labels de campagne. Avec ces KPIs, j’ai les infos nécessaires pour faire le suivi hebdomadaire. Les métriques calculées (CPC, CPA et taux de conversion) sont calculés directement dans Looker Studio.

Création tache import Windsor.ai

Une fois les connecteurs configurés, les données remontent automatiquement dans une table unique, prêtes à être exploitées côté BigQuery.

Étape 2 : structurer les données dans BigQuery

Les données importées à partir de Windsor sont d’abord stockées dans ads_raw. Je les fais ensuite transiter dans trois vues successives pour enrichir les données :

  • ads_segmented enrichit chaque ligne brute avec la segmentation métier — langue, type de campagne, site — extraite des labels de campagne, sans changer le niveau de détail.
  • ads_kpis agrège cette donnée enrichie par jour, source et segment, en passant d’un détail ligne par ligne à des totaux consolidés.
  • ads_suivi_unpivot recalcule les totaux sur des périodes glissantes (7 jours, 14 jours, 28 jours, mois dernier, 6 derniers mois – les références pour mes rapports) et restructure en lignes pour que Looker Studio puisse les afficher facilement.

Chaque vue s’appuie sur la précédente : la chaîne est linéaire, ce qui permet de la déboguer étape par étape plutôt que de tout gérer dans une seule requête complexe.

La table brute (ads_raw)

C’est la table que Windsor alimente automatiquement à chaque synchronisation — une ligne par jour, par campagne, par plateforme, avec les champs bruts définis à la configuration du connecteur.

Segmentation par canal/campagne (ads_segmented)

Dans cette vue j’enrichis chaque ligne avec la segmentation extraite des labels de campagne.

J’utilise les labels pour catégoriser mes campagnes par langue, type de campagne, mots-clés etc.


CREATE VIEW `mon_projet.mon_client.ads_segmented` AS
SELECT
  date,
  source,
  campaign_id,
  campaign,
  COALESCE(cost, CAST(spend AS FLOAT64)) AS cost,
  CAST(impressions AS FLOAT64) AS impressions,
  CAST(clicks AS FLOAT64) AS clicks,
  CAST(conversions AS FLOAT64) AS conversions,
  REGEXP_EXTRACT(campaign_labels, r'lang:([a-z]+)') AS langue,
  REGEXP_EXTRACT(campaign_labels, r'type:([a-z]+)') AS type_campagne,
  REGEXP_EXTRACT(campaign_labels, r'site:([a-z0-9]+)') AS site
FROM `mon_projet.mon_client.ads_raw`

Deux points de vigilance ici, tirés de l’expérience :

  • Le coût : selon la plateforme, Windsor peut router la dépense vers spend plutôt que cost — le COALESCE évite de perdre des données.
  • Le typage : les champs importés arrivent parfois en BIGNUMERIC, un type que Looker Studio ne reconnaît pas comme métrique. Un CAST(… AS FLOAT64) à ce niveau règle le problème une bonne fois pour toutes.

Vue des KPIs consolidés (ads_kpis)

Cette vue agrège ads_segmented par jour, source et segment :


CREATE VIEW `mon_projet.mon_client.ads_kpis` AS
SELECT
  date,
  source,
  langue,
  type_campagne,
  site,
  SUM(impressions) AS impressions,
  SUM(clicks) AS clicks,
  SUM(cost) AS cost,
  SUM(conversions) AS conversions
FROM `mon_projet.mon_client.ads_segmented`
GROUP BY date, source, langue, type_campagne, site

Les métriques comme le CPC ou le CPA ne sont volontairement pas calculées ici : les calculer directement dans Looker Studio (via SUM(cost)/SUM(clicks)) évite qu’elles soient faussées par l’agrégation — un ratio pré-calculé en amont se retrouve additionné plutôt que recalculé dès qu’on l’affiche sur plusieurs lignes.

Unpivot pour le reporting temporel (ads_suivi_unpivot)

Dernière étape : recalculer les totaux sur des périodes glissantes, puis les transformer en lignes plutôt qu’en colonnes pour que Looker Studio les exploite facilement.


CREATE VIEW `mon_projet.mon_client.ads_suivi_unpivot` AS
WITH base AS (
  SELECT
    source, langue, type_campagne, site,
    SUM(IF(date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY), cost, 0)) AS cost_7d,
    SUM(IF(date >= DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY), conversions, 0)) AS conversions_7d,
    SUM(IF(date >= DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH)
           AND date < DATE_TRUNC(CURRENT_DATE(), MONTH), cost, 0)) AS cost_m1, SUM(IF(date >= DATE_TRUNC(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH)
           AND date < DATE_TRUNC(CURRENT_DATE(), MONTH), conversions, 0)) AS conversions_m1
    -- ... même logique pour 14j, 28j, 6 mois
  FROM `mon_projet.mon_client.ads_kpis`
  GROUP BY source, langue, type_campagne, site
)
SELECT source, langue, type_campagne, site, periode, cost, conversions
FROM base
UNPIVOT (
  (cost, conversions) FOR periode IN (
    (cost_7d, conversions_7d) AS '7 derniers jours',
    (cost_m1, conversions_m1) AS 'Mois dernier'
    -- ... autres périodes
  )
)

Point important : la période « mois dernier » exclut volontairement le mois en cours via DATE_TRUNC — sinon, un mois encore incomplet fausserait la comparaison avec les mois précédents.

Etape 3 : Créer le dashboard Looker Studio

Pour importer les données dans Looker Studio, il suffit d’ajouter une nouvelle source de données via le connecteur BigQuery natif, puis on de sélectionner le projet, le dataset et la vue à connecter — généralement ads_suivi_unpivot, qui contient déjà les périodes de comparaison prêtes à l’emploi.

Ajouter une nouvelle source de données dans Big Query

Des périodes déjà prêtes grâce à ads_suivi_unpivot

Toute la logique de calcul des périodes — 7 derniers jours, 14 derniers jours, 28 derniers jours, mois dernier, 6 derniers mois — a déjà été préparée à l’étape 2, dans la vue ads_suivi_unpivot. Ça veut dire qu’il n’y a rien à recalculer côté Looker Studio : il suffit de filtrer ou de grouper sur le champ periode pour afficher directement la comparaison souhaitée, sans configurer de plage de dates personnalisée à chaque graphique.

C’est ce qui permet, par exemple, de construire un tableau comparant les 7 derniers jours au mois dernier côte à côte, simplement en sélectionnant les deux valeurs de periode correspondantes — sans écrire de logique de date dans Looker Studio lui-même.

Calculer les métriques avec SUM() plutôt que les pré-calculer

Les métriques comme le CPC, le CPA ou le taux de conversion sont calculées directement dans Looker Studio via des champs calculés, par exemple :

CPC = SUM(cost) / SUM(clicks)

Ce choix n’est pas anodin : une métrique pré-calculée dans BigQuery (comme un CPA déjà divisé) se retrouve additionnée plutôt que recalculée dès qu’elle est affichée sur plusieurs lignes agrégées — le total obtenu n’a alors plus de sens. Utiliser SUM() sur les valeurs brutes (coût, clics, conversions) dans le champ calculé garantit que le ratio reste correct, quel que soit le niveau d’agrégation affiché.

Création des tableaux et graphiques

À partir d’ici, tu as tout en main pour créer tes tableaux et graphiques de suivi pour vérifier en temps réel les performances de chaque campagne ou segment de campagne. Voici quelques exemples de tableaux que je vérifie quotidiennement :

  • Évolution du CPA dans le temps — graphique en courbe sur les différentes périodes glissantes (7j, 14j, 28j), pour repérer rapidement une dérive
  • Répartition du budget par plateforme — graphique en secteurs ou barres empilées sur source, pour voir en un coup d’œil où va la dépense
  • Tableau croisé par segment — langue ou type_campagne en dimension, avec CPC/CPA/taux de conversion en métriques calculées, pour comparer les segments entre eux

Résultat : ce que ça change au quotidien

Gain de temps sur le reporting client: Ce qui prenait auparavant plusieurs exports manuels par plateforme et par client se résume désormais à un dashboard toujours à jour, sans intervention manuelle. Le temps libéré est réinvesti dans l’analyse des campagnes plutôt que dans leur compilation.

Détection plus rapide des anomalies de tracking: Avec des données centralisées et comparées sur plusieurs périodes glissantes, une anomalie — une campagne qui décroche, un pic de coût anormal, une conversion qui disparaît — se repère en un coup d’œil, plutôt qu’au détour d’un export mensuel.

Un rapport sur mesure, accessible directement par le client: Cette architecture permet aussi de construire, à partir des mêmes vues, un rapport Looker Studio dédié et partagé directement avec le client — avec ses propres filtres, ses propres segments, sans lui donner accès aux comptes publicitaires ou à BigQuery. Le client garde une vue autonome et à jour sur ses performances, sans dépendre d’un envoi manuel de rapport.

Combien coûte un dashboard marketing centralisé

Sur cette stack, le seul poste de coût réel est Windsor.ai — BigQuery et Looker Studio restent gratuits vu les volumes de données en jeu ici (quelques millions de lignes par mois, largement dans les quotas gratuits de BigQuery).

Pour Windsor, le prix dépend surtout du nombre de comptes publicitaires à connecter. Dans mon cas, avec une quinzaine de clients à gérer et plusieurs comptes par client, je suis sur un abonnement plus élevé, facturé à l’année. Mais pour une seule entreprise qui centralise ses propres campagnes (Google Ads, Meta, Microsoft…), le plan de base à 25€ suffit largement. Il permet de couvrir 75 comptes à partir de 3 sources différentes, ce qui laisse une bonne marge même avec plusieurs plateformes et plusieurs comptes par plateforme.

 

Voilà pour la stack complète — à adapter selon vos plateformes et besoins. Bon reporting !