Relatórios de marketing educacional raramente dependem de uma única plataforma.
Quando o objetivo é acompanhar a divulgação de cursos para professores, normalmente precisamos responder a perguntas que atravessam diferentes sistemas:
quantos e-mails foram enviados;
quantas pessoas abriram as mensagens;
quantos cliques foram registrados pela plataforma de automação;
quantos usuários efetivamente chegaram ao site;
quais elementos da peça geraram tráfego;
quantas inscrições foram concluídas;
quais cursos, botões, imagens ou textos contribuíram mais para a conversão.
Foi esse o cenário encontrado na construção de um relatório para acompanhamento de cursos educacionais da Vivo Telefônica.
O projeto exigiu a combinação de dados do Mautic, Google Analytics 4, Google Sheets e Looker Studio, com diferentes padrões históricos de UTMs e níveis distintos de granularidade.
O desafio de cruzar Mautic e GA4
O Mautic apresenta uma visão do disparo de e-mail.
Entre os campos disponíveis estavam:
email_id
email_name
publish_up
sent_count
read_count
read_tax
clicks
click_tax
click_to_open_tax
email_id
email_name
publish_up
sent_count
read_count
read_tax
clicks
click_tax
click_to_open_tax
email_id
email_name
publish_up
sent_count
read_count
read_tax
clicks
click_tax
click_to_open_tax
Já o GA4 registra o comportamento posterior ao clique:
Nome da campanha manual da sessão
Conteúdo do anúncio manual da sessão
Termo manual da sessão
ID da campanha da sessão
Total de usuários
Sessões
Eventos principais
Nome da campanha manual da sessão
Conteúdo do anúncio manual da sessão
Termo manual da sessão
ID da campanha da sessão
Total de usuários
Sessões
Eventos principais
Nome da campanha manual da sessão
Conteúdo do anúncio manual da sessão
Termo manual da sessão
ID da campanha da sessão
Total de usuários
Sessões
Eventos principais
O principal desafio era que as duas fontes não utilizavam uma chave técnica comum.
No Mautic, o e-mail aparecia com nomes como:
[AQS2026] E-mail 58 D1 - Do trap ao texto
[AQS2026] E-mail 58 D2 - Do trap ao texto
[AQS2026] E-mail 60 - D1
[AQS2026] E-mail 58 D1 - Do trap ao texto
[AQS2026] E-mail 58 D2 - Do trap ao texto
[AQS2026] E-mail 60 - D1
[AQS2026] E-mail 58 D1 - Do trap ao texto
[AQS2026] E-mail 58 D2 - Do trap ao texto
[AQS2026] E-mail 60 - D1
No GA4, a identificação podia aparecer em diferentes parâmetros:
email_58_trap_texto_d1
email_58_trap_texto_d2
email_60_ideias_ferias_d1
email_58_trap_texto_d1
email_58_trap_texto_d2
email_60_ideias_ferias_d1
email_58_trap_texto_d1
email_58_trap_texto_d2
email_60_ideias_ferias_d1
Em campanhas antigas, o número do e-mail estava dentro de utm_campaign.
Em campanhas mais recentes, estava em utm_content.
Em outros casos, o identificador completo da peça estava em utm_term.
Portanto, não bastava conectar as fontes. Era necessário construir uma camada de normalização.
Criação de uma chave comum
A primeira etapa foi extrair o número do e-mail no Mautic.
No Looker Studio, utilizamos:
REGEXP_EXTRACT(
LOWER(email_name),
"e-?mail[^0-9]*([0-9]+)"
)
REGEXP_EXTRACT(
LOWER(email_name),
"e-?mail[^0-9]*([0-9]+)"
)
REGEXP_EXTRACT(
LOWER(email_name),
"e-?mail[^0-9]*([0-9]+)"
)
Esse campo transforma:
[AQS2026] E-mail 58 D2 - Do trap ao texto
[AQS2026] E-mail 58 D2 - Do trap ao texto
[AQS2026] E-mail 58 D2 - Do trap ao texto
em:
Em seguida, extraímos a variação do disparo:
IFNULL(
REGEXP_EXTRACT(
LOWER(email_name),
"(d[0-9]+)"
),
"d1"
)IFNULL(
REGEXP_EXTRACT(
LOWER(email_name),
"(d[0-9]+)"
),
"d1"
)IFNULL(
REGEXP_EXTRACT(
LOWER(email_name),
"(d[0-9]+)"
),
"d1"
)Com isso:
E-mail 58 D2 → d2
E-mail 60 D1 → d1
E-mail 61 → d1
E-mail 58 D2 → d2
E-mail 60 D1 → d1
E-mail 61 → d1
E-mail 58 D2 → d2
E-mail 60 D1 → d1
E-mail 61 → d1
Os disparos antigos sem indicação explícita de variação foram tratados como d1, conforme a regra operacional definida pelo cliente.
A chave final do Mautic passou a ser:
CONCAT(
"email_",
Número do e-mail,
"_",
Variação do e-mail
)
CONCAT(
"email_",
Número do e-mail,
"_",
Variação do e-mail
)
CONCAT(
"email_",
Número do e-mail,
"_",
Variação do e-mail
)
Resultado:
email_58_d1
email_58_d2
email_60_d1
email_58_d1
email_58_d2
email_60_d1
email_58_d1
email_58_d2
email_60_d1
Normalização dos dados do GA4
No GA4, a lógica precisava contemplar diferentes gerações de parametrização.
O número do e-mail poderia estar em:
conteúdo manual da sessão;
termo manual da sessão;
nome da campanha manual da sessão.
A fórmula utilizada foi:
CASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*email[_-]?[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"email[_-]?([0-9]+)"
)
ELSE NULL
ENDCASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*email[_-]?[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"email[_-]?([0-9]+)"
)
ELSE NULL
ENDCASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*email_[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"email_([0-9]+)"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*email[_-]?[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"email[_-]?([0-9]+)"
)
ELSE NULL
ENDA variação do e-mail foi tratada de maneira semelhante:
CASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*[_-]d[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"d[0-9]+"
)
WHEN Número do e-mail GA4 IS NOT NULL
THEN "d1"
ELSE NULL
ENDCASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*[_-]d[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"d[0-9]+"
)
WHEN Número do e-mail GA4 IS NOT NULL
THEN "d1"
ELSE NULL
ENDCASE
WHEN REGEXP_MATCH(
LOWER(Conteúdo do anúncio manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Conteúdo do anúncio manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Termo manual da sessão),
".*_d[0-9]+$"
)
THEN REGEXP_EXTRACT(
LOWER(Termo manual da sessão),
"(d[0-9]+)$"
)
WHEN REGEXP_MATCH(
LOWER(Nome da campanha manual da sessão),
".*[_-]d[0-9]+.*"
)
THEN REGEXP_EXTRACT(
LOWER(Nome da campanha manual da sessão),
"d[0-9]+"
)
WHEN Número do e-mail GA4 IS NOT NULL
THEN "d1"
ELSE NULL
ENDA chave final do GA4 foi criada com:
CONCAT(
"email_",
Número do e-mail GA4,
"_",
Variação do e-mail GA4
)
CONCAT(
"email_",
Número do e-mail GA4,
"_",
Variação do e-mail GA4
)
CONCAT(
"email_",
Número do e-mail GA4,
"_",
Variação do e-mail GA4
)
Assim, as duas fontes passaram a compartilhar valores como:
Mautic: email_58_d1
GA4: email_58_d1
Mautic: email_58_d1
GA4: email_58_d1
Mautic: email_58_d1
GA4: email_58_d1
Como seria essa lógica em SQL
Caso a transformação fosse executada em BigQuery, PostgreSQL ou outra camada intermediária, a lógica poderia ser estruturada desta forma.
Normalização do Mautic
SELECT
email_id,
email_name,
publish_up,
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant,
CONCAT(
'email_',
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
),
'_',
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
)
) AS email_key,
CAST(
REGEXP_REPLACE(sent_count, r'\s+', '')
AS INT64
) AS sent_count_clean,
CAST(
REGEXP_REPLACE(read_count, r'\s+', '')
AS INT64
) AS read_count_clean,
CAST(
REGEXP_REPLACE(clicks, r'\s+', '')
AS INT64
) AS clicks_clean
FROM mautic_emails;SELECT
email_id,
email_name,
publish_up,
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant,
CONCAT(
'email_',
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
),
'_',
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
)
) AS email_key,
CAST(
REGEXP_REPLACE(sent_count, r'\s+', '')
AS INT64
) AS sent_count_clean,
CAST(
REGEXP_REPLACE(read_count, r'\s+', '')
AS INT64
) AS read_count_clean,
CAST(
REGEXP_REPLACE(clicks, r'\s+', '')
AS INT64
) AS clicks_clean
FROM mautic_emails;SELECT
email_id,
email_name,
publish_up,
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant,
CONCAT(
'email_',
REGEXP_EXTRACT(
LOWER(email_name),
r'e-?mail[^0-9]*([0-9]+)'
),
'_',
COALESCE(
REGEXP_EXTRACT(
LOWER(email_name),
r'(d[0-9]+)'
),
'd1'
)
) AS email_key,
CAST(
REGEXP_REPLACE(sent_count, r'\s+', '')
AS INT64
) AS sent_count_clean,
CAST(
REGEXP_REPLACE(read_count, r'\s+', '')
AS INT64
) AS read_count_clean,
CAST(
REGEXP_REPLACE(clicks, r'\s+', '')
AS INT64
) AS clicks_clean
FROM mautic_emails;Normalização do GA4
SELECT
session_manual_campaign_name,
session_manual_ad_content,
session_manual_term,
session_campaign_id,
total_users,
sessions,
key_events,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions;SELECT
session_manual_campaign_name,
session_manual_ad_content,
session_manual_term,
session_campaign_id,
total_users,
sessions,
key_events,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions;SELECT
session_manual_campaign_name,
session_manual_ad_content,
session_manual_term,
session_campaign_id,
total_users,
sessions,
key_events,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions;Construção da chave do GA4
WITH normalized_ga4 AS (
SELECT
*,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions
)
SELECT
*,
CONCAT(
'email_',
email_number,
'_',
email_variant
) AS email_key
FROM normalized_ga4;WITH normalized_ga4 AS (
SELECT
*,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions
)
SELECT
*,
CONCAT(
'email_',
email_number,
'_',
email_variant
) AS email_key
FROM normalized_ga4;WITH normalized_ga4 AS (
SELECT
*,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'email_([0-9]+)'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'email[_-]?([0-9]+)'
)
) AS email_number,
COALESCE(
REGEXP_EXTRACT(
LOWER(session_manual_ad_content),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_term),
r'(d[0-9]+)$'
),
REGEXP_EXTRACT(
LOWER(session_manual_campaign_name),
r'(d[0-9]+)'
),
'd1'
) AS email_variant
FROM ga4_sessions
)
SELECT
*,
CONCAT(
'email_',
email_number,
'_',
email_variant
) AS email_key
FROM normalized_ga4;Cruzamento entre Mautic e GA4
SELECT
m.email_id,
m.email_name,
m.publish_up,
m.sent_count_clean,
m.read_count_clean,
m.clicks_clean,
g.session_campaign_id AS element,
g.total_users,
g.sessions,
g.key_events
FROM mautic_normalized AS m
LEFT JOIN ga4_normalized AS g
ON m.email_key = g.email_key;
SELECT
m.email_id,
m.email_name,
m.publish_up,
m.sent_count_clean,
m.read_count_clean,
m.clicks_clean,
g.session_campaign_id AS element,
g.total_users,
g.sessions,
g.key_events
FROM mautic_normalized AS m
LEFT JOIN ga4_normalized AS g
ON m.email_key = g.email_key;
SELECT
m.email_id,
m.email_name,
m.publish_up,
m.sent_count_clean,
m.read_count_clean,
m.clicks_clean,
g.session_campaign_id AS element,
g.total_users,
g.sessions,
g.key_events
FROM mautic_normalized AS m
LEFT JOIN ga4_normalized AS g
ON m.email_key = g.email_key;
O problema dos números importados como texto
Outro desafio apareceu na importação do CSV do Mautic.
Os números utilizavam espaço como separador de milhar:
126 670
99 670
5 459
4 564
126 670
99 670
5 459
4 564
126 670
99 670
5 459
4 564
Ao transformar diretamente esses campos em número, o Looker Studio retornava null.
A solução foi manter os campos originais como texto e criar campos calculados limpos:
CAST(
REGEXP_REPLACE(sent_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(sent_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(sent_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(read_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(read_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(read_count, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(clicks, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(clicks, "\\s", "")
AS NUMBER
)
CAST(
REGEXP_REPLACE(clicks, "\\s", "")
AS NUMBER
)
Os novos campos foram nomeados como:
Enviados
Aberturas
Cliques
Enviados
Aberturas
Cliques
Enviados
Aberturas
Cliques
Essa camada evitou erros de tipagem e permitiu utilizar corretamente as agregações.
Duas combinações para duas granularidades
Um dos principais cuidados do projeto foi não tentar resolver tudo com uma única combinação.
Os dados do Mautic existem no nível do disparo:
E-mail 58 D1
99.670 enviados
4.564 aberturas
331 cliques
E-mail 58 D1
99.670 enviados
4.564 aberturas
331 cliques
E-mail 58 D1
99.670 enviados
4.564 aberturas
331 cliques
Os dados do GA4 podem existir no nível do elemento:
botao_02
botao_01
texto_01
botao_03
img_01
botao_02
botao_01
texto_01
botao_03
img_01
botao_02
botao_01
texto_01
botao_03
img_01
Por isso, estruturamos duas combinações.
Combinação 1: visão consolidada por disparo
A primeira combinação mostra:
Nome do e-mail
Data do disparo
Enviados
Aberturas
Taxa de abertura
Cliques
CTOR
Usuários
Sessões
Conversões
Nome do e-mail
Data do disparo
Enviados
Aberturas
Taxa de abertura
Cliques
CTOR
Usuários
Sessões
Conversões
Nome do e-mail
Data do disparo
Enviados
Aberturas
Taxa de abertura
Cliques
CTOR
Usuários
Sessões
Conversões
Ela responde:
qual foi o desempenho geral do disparo;
quantas pessoas chegaram ao site;
quantas inscrições foram registradas;
quais e-mails tiveram melhor resultado.
Combinação 2: detalhamento por elemento
A segunda combinação abre cada e-mail em seus respectivos destinos ou elementos.
Exemplo:
E-mail 58 D1
botao_02
botao_01
texto_01
botao_03
img_01E-mail 58 D1
botao_02
botao_01
texto_01
botao_03
img_01E-mail 58 D1
botao_02
botao_01
texto_01
botao_03
img_01O elemento é identificado pelo campo correspondente ao utm_id, registrado no GA4 como ID da campanha da sessão.
A tabela dinâmica apresenta:
Assunto da peça
Elemento
Enviados
Aberturas
Cliques
Taxa de abertura
CTOR
Usuários
Conversões
Assunto da peça
Elemento
Enviados
Aberturas
Cliques
Taxa de abertura
CTOR
Usuários
Conversões
Assunto da peça
Elemento
Enviados
Aberturas
Cliques
Taxa de abertura
CTOR
Usuários
Conversões
Essa visão permite observar, por exemplo:
E-mail 58 D1
botao_02
45 usuários
14 conversões
botao_01
40 usuários
10 conversões
texto_01
28 usuários
4 conversões
botao_03
15 usuários
0 conversões
img_01
6 usuários
0 conversões
E-mail 58 D1
botao_02
45 usuários
14 conversões
botao_01
40 usuários
10 conversões
texto_01
28 usuários
4 conversões
botao_03
15 usuários
0 conversões
img_01
6 usuários
0 conversões
E-mail 58 D1
botao_02
45 usuários
14 conversões
botao_01
40 usuários
10 conversões
texto_01
28 usuários
4 conversões
botao_03
15 usuários
0 conversões
img_01
6 usuários
0 conversões
Como evitar métricas duplicadas
Enviados, aberturas e cliques do Mautic pertencem ao disparo inteiro.
Se fossem somados em cada botão, os totais ficariam incorretos.
Por isso, no detalhamento, utilizamos:
Enviados → MAX
Aberturas → MAX
Cliques → MAX
Taxa de abertura → MAX
CTOR → MAX
Enviados → MAX
Aberturas → MAX
Cliques → MAX
Taxa de abertura → MAX
CTOR → MAX
Enviados → MAX
Aberturas → MAX
Cliques → MAX
Taxa de abertura → MAX
CTOR → MAX
Já os dados do GA4 são agregados por elemento:
Usuários → SUM
Conversões → SUM
Usuários → SUM
Conversões → SUM
Usuários → SUM
Conversões → SUM
Essa diferença é fundamental.
O Mautic informa que o e-mail teve 331 cliques totais.
O GA4 informa como os usuários identificados se distribuíram entre botões, imagens, textos e outros destinos.
Os 331 cliques não pertencem individualmente a cada botão.
Eles são o contexto geral do disparo.
Métricas calculadas
A taxa de abertura por disparo foi calculada como:
CASE
WHEN Enviados > 0
THEN Aberturas / Enviados
ELSE 0
END
CASE
WHEN Enviados > 0
THEN Aberturas / Enviados
ELSE 0
END
CASE
WHEN Enviados > 0
THEN Aberturas / Enviados
ELSE 0
END
O CTOR foi calculado como:
CASE
WHEN Aberturas > 0
THEN Cliques / Aberturas
ELSE 0
END
CASE
WHEN Aberturas > 0
THEN Cliques / Aberturas
ELSE 0
END
CASE
WHEN Aberturas > 0
THEN Cliques / Aberturas
ELSE 0
END
Para scorecards consolidados, o cálculo deve considerar a proporção entre os totais:
SUM(Aberturas) / SUM(Enviados)
SUM(Aberturas) / SUM(Enviados)
SUM(Aberturas) / SUM(Enviados)
SUM(Cliques) / SUM(Enviados)
SUM(Cliques) / SUM(Enviados)
SUM(Cliques) / SUM(Enviados)
SUM(Cliques) / SUM(Aberturas)
SUM(Cliques) / SUM(Aberturas)
SUM(Cliques) / SUM(Aberturas)
Isso evita a chamada média das médias.
Um disparo de 5 mil contatos não deve ter o mesmo peso de um disparo de 120 mil contatos no indicador geral.
Arquitetura final
A estrutura consolidada ficou assim:
Mautic
↓
Exportação CSV
↓
Google Sheets
↓
Normalização dos campos
↓
Chave email_número_variação
↓
Looker Studio
↓
Combinação com GA4
↓
Resumo por disparo
+
Detalhamento por elementoMautic
↓
Exportação CSV
↓
Google Sheets
↓
Normalização dos campos
↓
Chave email_número_variação
↓
Looker Studio
↓
Combinação com GA4
↓
Resumo por disparo
+
Detalhamento por elementoMautic
↓
Exportação CSV
↓
Google Sheets
↓
Normalização dos campos
↓
Chave email_número_variação
↓
Looker Studio
↓
Combinação com GA4
↓
Resumo por disparo
+
Detalhamento por elementoO GA4 complementa o processo:
UTM Campaign
UTM Content
UTM Term
UTM ID
↓
Número do e-mail
Variação
Elemento
↓
Usuários
Sessões
ConversõesUTM Campaign
UTM Content
UTM Term
UTM ID
↓
Número do e-mail
Variação
Elemento
↓
Usuários
Sessões
ConversõesUTM Campaign
UTM Content
UTM Term
UTM ID
↓
Número do e-mail
Variação
Elemento
↓
Usuários
Sessões
ConversõesO que esse relatório entrega para a tomada de decisão
O resultado não é apenas um painel de métricas.
Ele permite responder perguntas operacionais e estratégicas:
qual e-mail teve maior alcance;
qual disparo apresentou maior taxa de abertura;
qual mensagem gerou mais cliques;
qual peça levou mais usuários ao site;
qual curso recebeu mais tráfego;
qual botão gerou mais inscrições;
quais elementos tiveram tráfego, mas não converteram;
quais campanhas precisam de ajustes de texto, posição ou chamada para ação;
quais padrões devem ser replicados nos próximos disparos.
A importância de uma taxonomia de UTMs
O projeto também reforçou a importância de manter uma estrutura padronizada.
O padrão futuro adotado deve seguir uma lógica semelhante a:
utm_campaign=ec_2026_julho
utm_content=email_63_nome_da_peca_d1
utm_term=segmentacao_ou_contexto
utm_id=botao_01
utm_campaign=ec_2026_julho
utm_content=email_63_nome_da_peca_d1
utm_term=segmentacao_ou_contexto
utm_id=botao_01
utm_campaign=ec_2026_julho
utm_content=email_63_nome_da_peca_d1
utm_term=segmentacao_ou_contexto
utm_id=botao_01
Exemplo:
utm_source=mautic
utm_medium=email
utm_campaign=ec_2026_julho
utm_content=email_63_competencias_digitais_d1
utm_term=ec_aquisicao
utm_id=botao_01
utm_source=mautic
utm_medium=email
utm_campaign=ec_2026_julho
utm_content=email_63_competencias_digitais_d1
utm_term=ec_aquisicao
utm_id=botao_01
utm_source=mautic
utm_medium=email
utm_campaign=ec_2026_julho
utm_content=email_63_competencias_digitais_d1
utm_term=ec_aquisicao
utm_id=botao_01
Esse padrão permite separar claramente:
Campanha
Peça
Segmentação
Elemento
Campanha
Peça
Segmentação
Elemento
Campanha
Peça
Segmentação
Elemento
Quanto mais estável for a taxonomia, menor será o custo de manutenção do relatório e maior será a confiabilidade das análises.
Como a Ad Rock trabalha com múltiplas fontes
Projetos de dados não se resumem a escolher gráficos.
Antes da visualização, é necessário compreender:
a origem de cada campo;
a granularidade de cada fonte;
a forma como as métricas são agregadas;
os padrões históricos;
as regras de nomenclatura;
as limitações de cada plataforma;
os possíveis riscos de duplicação.
Na Ad Rock, trabalhamos a partir da lógica do dado.
O processo envolve:
Diagnóstico
Normalização
Criação de chaves
Tratamento de tipos
Combinação de fontes
Validação
Modelagem
Visualização
Análise
Diagnóstico
Normalização
Criação de chaves
Tratamento de tipos
Combinação de fontes
Validação
Modelagem
Visualização
Análise
Diagnóstico
Normalização
Criação de chaves
Tratamento de tipos
Combinação de fontes
Validação
Modelagem
Visualização
Análise
Essa abordagem transforma dados fragmentados em uma estrutura confiável para decisões de marketing, audiência, aquisição e conversão.
O objetivo não é apenas mostrar quantos e-mails foram enviados.
É conectar o disparo à navegação, a navegação ao elemento clicado e o elemento ao resultado final.
É assim que relatórios deixam de ser apenas painéis e passam a funcionar como instrumentos de decisão.
Precisa de serviços assim?