cdp-edge 2.3.8 → 2.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +274 -639
- package/extracted-skill/tracking-events-generator/agents/devops-agent.md +22 -0
- package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +53 -0
- package/extracted-skill/tracking-events-generator/agents/lead-scoring-agent.md +282 -0
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +60 -6
- package/extracted-skill/tracking-events-generator/agents/match-quality-agent.md +304 -0
- package/extracted-skill/tracking-events-generator/agents/utm-agent.md +285 -154
- package/extracted-skill/tracking-events-generator/cdpTrack.js +10 -8
- package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +83 -19
- package/package.json +1 -1
- package/server-edge-tracker/index.ts +81 -6
- package/server-edge-tracker/modules/intelligence.ts +155 -2
- package/server-edge-tracker/modules/ml/quiz.ts +343 -0
- package/server-edge-tracker/modules/ml/roas.ts +255 -0
- package/server-edge-tracker/modules/nurture.ts +257 -0
- package/server-edge-tracker/modules/utils.ts +2 -0
- package/server-edge-tracker/schema-quiz.sql +52 -0
- package/server-edge-tracker/schema-sales-engine.sql +113 -0
- package/templates/quiz-funnel.md +83 -19
|
@@ -1,61 +1,222 @@
|
|
|
1
|
-
# UTM Agent —
|
|
1
|
+
# UTM Agent — CDP Edge
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Especialista em gerar estruturas de UTM parametrizadas para segmentação de público, com valores **obfuscados/racheados** para proteção de dados sensíveis na URL.
|
|
3
|
+
**Papel:** Gerador automático de UTMs completas — usa o contexto já coletado pelo CDP Edge para produzir cada string de UTM pronta, por plataforma e por formato de anúncio. O cliente copia e cola.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
- Após o **Page Analyzer** identificar o tipo de página/produto
|
|
8
|
-
- Antes de gerar os parâmetros de tracking no SDK
|
|
9
|
-
- Quando o usuário precisa configurar campanhas com categorização de valor
|
|
5
|
+
---
|
|
10
6
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
## Princípio Fundamental
|
|
8
|
+
|
|
9
|
+
O CDP Edge já sabe tudo que precisa para gerar as UTMs. Nenhuma informação adicional do cliente é necessária além do que já foi coletado nas fases anteriores:
|
|
10
|
+
|
|
11
|
+
| O que o CDP Edge já sabe | De onde vem |
|
|
12
|
+
|---|---|
|
|
13
|
+
| Quais plataformas serão usadas | FASE 0-B (seleção de plataformas) |
|
|
14
|
+
| Se tem vídeo no funil | Page Analyzer (detecta VSL, videos, players) |
|
|
15
|
+
| Se tem quiz | Lead Scoring Agent (configurado na FASE 6) |
|
|
16
|
+
| Se tem formulário / landing page | Page Analyzer (detecta forms, CTAs) |
|
|
17
|
+
| Se tem Click-to-WhatsApp | Meta selecionado + CTWA habilitado automaticamente |
|
|
18
|
+
| Nicho e categoria do produto | Page Analyzer |
|
|
19
|
+
| Faixa de valor do produto | Pergunta feita pelo próprio UTM Agent na FASE 2-B |
|
|
20
|
+
|
|
21
|
+
**Com tudo isso, o UTM Agent gera uma tabela completa de UTMs prontas — o cliente não precisa inventar nenhum parâmetro.**
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## O Que São as 5 Dimensões
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
utm_source → PLATAFORMA — de qual rede de anúncio veio o lead
|
|
29
|
+
utm_medium → FORMATO — qual tipo de anúncio foi usado
|
|
30
|
+
utm_campaign → PRODUTO/FAIXA — qual produto e faixa de valor (obfuscado)
|
|
31
|
+
utm_content → ORIGEM — qual criativo/página/funil gerou o lead
|
|
32
|
+
utm_term → QUALIFICAÇÃO — classificação do quiz (preenchida pelo Worker)
|
|
19
33
|
```
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
`utm_term` é o único campo que o cliente **nunca** configura nos anúncios — o Worker injeta automaticamente após o Quiz Scoring Engine classificar o lead.
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
- Se `product_category` existir, perguntar ao usuário sobre categorização de valor
|
|
25
|
-
- Exemplos de perguntas:
|
|
26
|
-
- Para **imóveis**: "Qual a faixa de preço deste imóvel? Ex: 500k-800k, 800k-1.5M, 1M-3M"
|
|
27
|
-
- Para **automotivos**: "Qual a faixa de valor? Ex: 50k-100k, 100k-200k, 200k-500k"
|
|
28
|
-
- Para **cursos**: "Qual o nível/preço? Ex: básico-49, premium-199, pro-999"
|
|
37
|
+
---
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
## Quando Este Agente Roda
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
Após o **Lead Scoring Agent** (se quiz habilitado) e antes do **Browser Tracking Agent**.
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
Inputs que o agente já possui ao ser chamado:
|
|
44
|
+
- `SELECTED_PLATFORMS` — plataformas selecionadas na FASE 0-B
|
|
45
|
+
- `page_analysis` — saída do Page Analyzer (tem video? tem quiz? tem form? tem CTWA?)
|
|
46
|
+
- `lead_scoring_config` — quiz configurado? quais perguntas? qual nome do quiz?
|
|
47
|
+
- `utm_value_range` — faixa de valor do produto (perguntada na FASE 2-B)
|
|
48
|
+
- `product_category` — nicho detectado pelo Page Analyzer
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Processo de Geração
|
|
53
|
+
|
|
54
|
+
### PASSO 1 — Mapear o que foi implementado no funil
|
|
55
|
+
|
|
56
|
+
O agente lê os outputs das fases anteriores e monta um inventário de origens:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
INVENTÁRIO DE ORIGENS (montado automaticamente):
|
|
60
|
+
|
|
61
|
+
Plataformas ativas: [facebook, google, tiktok]
|
|
62
|
+
Formatos por plataforma:
|
|
63
|
+
facebook → [reels, stories, video, cpc, ctwa] ← detectado: tem VSL + tem CTWA
|
|
64
|
+
google → [cpc] ← search only
|
|
65
|
+
tiktok → [video] ← video in-feed
|
|
66
|
+
Tipos de página:
|
|
67
|
+
→ quiz habilitado → utm_content inclui quiz_{nome_quiz}
|
|
68
|
+
→ landing com VSL → utm_content inclui video_{tipo}
|
|
69
|
+
→ formulário direto → utm_content inclui landing_principal
|
|
70
|
+
→ CTWA ativo → utm_content inclui ctwa_direto
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### PASSO 2 — Gerar o valor obfuscado da campanha
|
|
74
|
+
|
|
75
|
+
Com a faixa de valor informada (ex: "700k-1M"):
|
|
76
|
+
```
|
|
77
|
+
SHA256("700k-1M" + "CDP_EDGE_UTM_SALT") → primeiros 8 chars → "8a3f1d2b"
|
|
78
|
+
utm_campaign = imovel_8a3f1d2b
|
|
55
79
|
```
|
|
56
80
|
|
|
57
|
-
|
|
58
|
-
|
|
81
|
+
Registrar no `utm-mapping.json` para de-obfuscação no Worker.
|
|
82
|
+
|
|
83
|
+
### PASSO 3 — Gerar a tabela completa de UTMs prontas
|
|
84
|
+
|
|
85
|
+
Para CADA combinação de plataforma × formato × origem que existe no funil:
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Saída — Tabela de UTMs Prontas para o Cliente
|
|
90
|
+
|
|
91
|
+
O agente entrega uma tabela assim, gerada automaticamente com base no que foi implementado:
|
|
92
|
+
|
|
93
|
+
```markdown
|
|
94
|
+
# UTMs do Projeto [NOME DO CLIENTE]
|
|
95
|
+
# Geradas pelo CDP Edge — copie e cole em cada campanha
|
|
96
|
+
|
|
97
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
98
|
+
## META ADS
|
|
99
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
100
|
+
|
|
101
|
+
### Campanhas que levam ao QUIZ DE QUALIFICAÇÃO
|
|
102
|
+
Use quando o anúncio leva para a página do quiz antes do formulário.
|
|
103
|
+
|
|
104
|
+
Reels:
|
|
105
|
+
utm_source=facebook&utm_medium=reels&utm_campaign=imovel_8a3f1d2b&utm_content=quiz_diagnostico_imovel
|
|
106
|
+
|
|
107
|
+
Stories:
|
|
108
|
+
utm_source=facebook&utm_medium=stories&utm_campaign=imovel_8a3f1d2b&utm_content=quiz_diagnostico_imovel
|
|
109
|
+
|
|
110
|
+
Vídeo in-feed:
|
|
111
|
+
utm_source=facebook&utm_medium=video&utm_campaign=imovel_8a3f1d2b&utm_content=quiz_diagnostico_imovel
|
|
112
|
+
|
|
113
|
+
Feed (imagem/carrossel):
|
|
114
|
+
utm_source=facebook&utm_medium=cpc&utm_campaign=imovel_8a3f1d2b&utm_content=quiz_diagnostico_imovel
|
|
115
|
+
|
|
116
|
+
### Campanhas que levam ao VÍDEO DE VENDAS (VSL)
|
|
117
|
+
Use quando o anúncio leva direto para a landing page com vídeo.
|
|
118
|
+
|
|
119
|
+
Reels:
|
|
120
|
+
utm_source=facebook&utm_medium=reels&utm_campaign=imovel_8a3f1d2b&utm_content=video_vsl_principal
|
|
121
|
+
|
|
122
|
+
Stories:
|
|
123
|
+
utm_source=facebook&utm_medium=stories&utm_campaign=imovel_8a3f1d2b&utm_content=video_vsl_principal
|
|
124
|
+
|
|
125
|
+
Vídeo in-feed:
|
|
126
|
+
utm_source=facebook&utm_medium=video&utm_campaign=imovel_8a3f1d2b&utm_content=video_vsl_principal
|
|
127
|
+
|
|
128
|
+
### Campanhas Click-to-WhatsApp (CTWA)
|
|
129
|
+
Use quando o anúncio abre diretamente o WhatsApp.
|
|
130
|
+
|
|
131
|
+
utm_source=whatsapp&utm_medium=ctwa&utm_campaign=imovel_8a3f1d2b&utm_content=ctwa_direto
|
|
132
|
+
|
|
133
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
134
|
+
## GOOGLE ADS
|
|
135
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
136
|
+
|
|
137
|
+
### Search (palavras-chave)
|
|
138
|
+
utm_source=google&utm_medium=cpc&utm_campaign=imovel_8a3f1d2b&utm_content=landing_principal
|
|
139
|
+
|
|
140
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
141
|
+
## TIKTOK ADS
|
|
142
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
143
|
+
|
|
144
|
+
### Vídeo In-Feed (quiz)
|
|
145
|
+
utm_source=tiktok&utm_medium=video&utm_campaign=imovel_8a3f1d2b&utm_content=quiz_diagnostico_imovel
|
|
146
|
+
|
|
147
|
+
### Vídeo In-Feed (VSL)
|
|
148
|
+
utm_source=tiktok&utm_medium=video&utm_campaign=imovel_8a3f1d2b&utm_content=video_vsl_principal
|
|
149
|
+
|
|
150
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
151
|
+
## OBSERVAÇÕES
|
|
152
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
153
|
+
|
|
154
|
+
utm_term NÃO é configurado nos anúncios.
|
|
155
|
+
O servidor preenche automaticamente após o quiz:
|
|
156
|
+
comprador / interessado / curioso / perdido
|
|
157
|
+
|
|
158
|
+
O valor real da campanha (700k-1M) está protegido.
|
|
159
|
+
Apenas o CDP Edge sabe a correspondência real.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Lógica de utm_content por Tipo de Funil
|
|
165
|
+
|
|
166
|
+
O agente detecta automaticamente e gera os valores corretos:
|
|
167
|
+
|
|
168
|
+
| O que o Page Analyzer encontrou | utm_content gerado |
|
|
169
|
+
|---|---|
|
|
170
|
+
| Quiz configurado pelo Lead Scoring Agent | `quiz_{nome_do_quiz}` |
|
|
171
|
+
| Player de vídeo / VSL na landing | `video_vsl_principal` |
|
|
172
|
+
| Vídeo de depoimento identificado | `video_depoimento` |
|
|
173
|
+
| Apenas formulário, sem vídeo, sem quiz | `landing_principal` |
|
|
174
|
+
| CTWA ativo (Meta selecionado) | `ctwa_direto` |
|
|
175
|
+
| Webinar / evento ao vivo detectado | `webinar_{nome}` |
|
|
176
|
+
| Múltiplos formatos | gera uma linha para cada |
|
|
177
|
+
|
|
178
|
+
**Regra:** se o funil tem quiz E vídeo, gera UTMs separadas para cada origem — porque o ROAS Feedback vai poder comparar qual converte mais.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Lógica de utm_medium por Plataforma
|
|
183
|
+
|
|
184
|
+
O agente gera formatos com base nas plataformas selecionadas na FASE 0-B. Não pergunta ao cliente — usa o que já foi selecionado:
|
|
185
|
+
|
|
186
|
+
| Plataforma selecionada | utm_medium gerados automaticamente |
|
|
187
|
+
|---|---|
|
|
188
|
+
| Meta Ads | reels, stories, video, cpc |
|
|
189
|
+
| Meta Ads + CTWA | reels, stories, video, cpc, ctwa |
|
|
190
|
+
| Google Ads | cpc |
|
|
191
|
+
| Google Ads + Display | cpc, display |
|
|
192
|
+
| TikTok Ads | video |
|
|
193
|
+
| YouTube Ads | instream, bumper |
|
|
194
|
+
| Pinterest Ads | cpc |
|
|
195
|
+
| LinkedIn Ads | cpc |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## utm_campaign — Geração da Faixa Obfuscada
|
|
200
|
+
|
|
201
|
+
Esta é a única pergunta que o UTM Agent faz ao cliente (já feita na FASE 2-B durante o master orchestrator):
|
|
202
|
+
|
|
203
|
+
> "Qual o valor/faixa de preço do produto?" (ex: 700k-1M, 297-997, etc.)
|
|
204
|
+
|
|
205
|
+
Com a resposta, gera:
|
|
206
|
+
```
|
|
207
|
+
SHA256("700k-1M" + salt) → "8a3f1d2b"
|
|
208
|
+
utm_campaign = imovel_8a3f1d2b
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Se o cliente **não** tiver segmentação por valor (produto de preço único), o agente usa:
|
|
212
|
+
```
|
|
213
|
+
utm_campaign = {categoria}_geral
|
|
214
|
+
```
|
|
215
|
+
Ex: `imovel_geral`, `curso_geral`, `servico_geral` — sem obfuscação.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## utm-mapping.json — Gerado Automaticamente
|
|
59
220
|
|
|
60
221
|
```json
|
|
61
222
|
{
|
|
@@ -69,123 +230,93 @@ Gerar o arquivo `utm-mapping.json` com:
|
|
|
69
230
|
"obfuscated": "8a3f1d2b",
|
|
70
231
|
"original": "700k-1M",
|
|
71
232
|
"category": "imovel",
|
|
72
|
-
"pixel_audience": "AUDIENCE_MID",
|
|
73
233
|
"platform_specific": {
|
|
74
|
-
"meta":
|
|
75
|
-
"tiktok":
|
|
234
|
+
"meta": { "custom_audience_id": "" },
|
|
235
|
+
"tiktok": { "pixel_id": "" },
|
|
236
|
+
"google": { "conversion_label": "" }
|
|
76
237
|
}
|
|
77
238
|
}
|
|
78
|
-
]
|
|
239
|
+
],
|
|
240
|
+
"content_registry": {
|
|
241
|
+
"quiz_diagnostico_imovel": "Quiz de diagnóstico imobiliário (5 perguntas)",
|
|
242
|
+
"video_vsl_principal": "VSL principal da landing page",
|
|
243
|
+
"video_depoimento": "Vídeo de depoimento de cliente",
|
|
244
|
+
"landing_principal": "Formulário direto na landing page",
|
|
245
|
+
"ctwa_direto": "Click-to-WhatsApp direto do anúncio"
|
|
246
|
+
}
|
|
79
247
|
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
O `content_registry` documenta o significado de cada `utm_content` — o Worker usa isso no ROAS Feedback para exibir nomes legíveis nos relatórios.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## utm_term — Injetado pelo Worker (Nunca pelo Cliente)
|
|
255
|
+
|
|
256
|
+
Depois do Lead Scoring Engine classificar o lead via quiz:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// index.ts — após scoreQuizAnswers()
|
|
260
|
+
trackPayload.utmTerm = quizResult.qualification;
|
|
261
|
+
// → 'comprador' | 'interessado' | 'curioso' | 'perdido'
|
|
262
|
+
```
|
|
80
263
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
faixa_imovel: '8a3f1d2b', // obfuscado
|
|
112
|
-
product_id: '9c4e2a1f', // obfuscado
|
|
113
|
-
source: 'facebook',
|
|
114
|
-
medium: 'cpc'
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
cdpTrack('Lead', {
|
|
118
|
-
utm: utmConfig,
|
|
119
|
-
// ... outros campos
|
|
120
|
-
});
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Output Structure
|
|
264
|
+
Salvo no D1 em `user_profiles.utm_term` e incluído nos eventos CAPI como `custom_data.utm_term`. O ROAS Feedback Loop usa para cruzar: *qual campanha gerou mais leads classificados como `comprador` que efetivamente compraram?*
|
|
265
|
+
|
|
266
|
+
> **Dependência:** `utm_term` só é preenchido se o **Lead Scoring Agent** estiver habilitado (FASE 6) e o evento for `QuizComplete` com `quiz_answers` válidas. Se o funil não tiver quiz, `utm_term` permanece vazio — o ROAS Feedback funciona, mas sem segmentação por qualificação de lead.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Arquivos Gerados
|
|
271
|
+
|
|
272
|
+
```
|
|
273
|
+
server-edge-tracker/
|
|
274
|
+
config/
|
|
275
|
+
utm-mapping.json ← mapeamento obfuscado + content_registry
|
|
276
|
+
|
|
277
|
+
# Entregue ao cliente:
|
|
278
|
+
UTMS-PROJETO-[NOME].md ← tabela completa de UTMs prontas para copiar/colar
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## O Que Este Agente NÃO FAZ
|
|
284
|
+
|
|
285
|
+
- ❌ Não pede ao cliente para "montar" UTMs — ele gera e entrega prontas
|
|
286
|
+
- ❌ Não pergunta formatos de anúncio — usa o que foi selecionado na FASE 0-B
|
|
287
|
+
- ❌ Não pergunta se tem quiz — usa o que o Lead Scoring Agent configurou
|
|
288
|
+
- ❌ Não expõe valores reais de produto na URL — sempre obfuscado via SHA256
|
|
289
|
+
- ❌ Não preenche utm_term nos anúncios — isso é exclusivo do Worker
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Saída Final (JSON para o Master Orchestrator)
|
|
124
294
|
|
|
125
295
|
```json
|
|
126
296
|
{
|
|
127
297
|
"agent": "utm-agent",
|
|
128
|
-
"version": "1.0
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
298
|
+
"version": "2.1.0",
|
|
299
|
+
"utm_campaign_base": "imovel_8a3f1d2b",
|
|
300
|
+
"value_range_original": "700k-1M",
|
|
301
|
+
"utms_generated": 11,
|
|
302
|
+
"por_plataforma": {
|
|
303
|
+
"facebook": 7,
|
|
304
|
+
"google": 1,
|
|
305
|
+
"tiktok": 2,
|
|
306
|
+
"whatsapp": 1
|
|
132
307
|
},
|
|
133
|
-
"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
"obfuscated_hash": "8a3f1d2b"
|
|
139
|
-
}
|
|
308
|
+
"origens_detectadas": [
|
|
309
|
+
"quiz_diagnostico_imovel",
|
|
310
|
+
"video_vsl_principal",
|
|
311
|
+
"landing_principal",
|
|
312
|
+
"ctwa_direto"
|
|
140
313
|
],
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
314
|
+
"utm_term_automatico": true,
|
|
315
|
+
"arquivos_criados": [
|
|
316
|
+
"server-edge-tracker/config/utm-mapping.json",
|
|
317
|
+
"UTMS-PROJETO-[NOME].md"
|
|
318
|
+
],
|
|
319
|
+
"integracao_roas": true,
|
|
320
|
+
"integracao_quiz": true
|
|
149
321
|
}
|
|
150
322
|
```
|
|
151
|
-
|
|
152
|
-
## Integração com Outros Agentes
|
|
153
|
-
|
|
154
|
-
1. **Page Analyzer** → informa tipo de produto
|
|
155
|
-
2. **UTM Agent** → pergunta faixa de valor, gera UTMs obfuscadas
|
|
156
|
-
3. **Meta Agent** → recebe UTMs, configura custom audiences
|
|
157
|
-
4. **TikTok Agent** → recebe UTMs, configura pixel events
|
|
158
|
-
5. **Worker** → usa `utm-enricher.ts` para de-obfuscar no runtime
|
|
159
|
-
|
|
160
|
-
## Edge Cases
|
|
161
|
-
|
|
162
|
-
- Usuário não sabe a faixa de valor: "Aguardo definição do cliente - use DEFAULT"
|
|
163
|
-
- Produto sem faixa definida: usar `generic_00000000`
|
|
164
|
-
- UTMs existentes: fazer merge sem sobrescrever
|
|
165
|
-
- Múltiplas categorias: perguntar se precisa de segmentação composta
|
|
166
|
-
|
|
167
|
-
## Example Session
|
|
168
|
-
|
|
169
|
-
**Page Analyzer:**
|
|
170
|
-
> "Página identificada: imóvel em Vila Mariana, 3 quartos, 2 banheiros"
|
|
171
|
-
|
|
172
|
-
**UTM Agent:**
|
|
173
|
-
> "Para qual faixa de preço este imóvel deve ser categorizado?"
|
|
174
|
-
>
|
|
175
|
-
> Usuário: "800k-1.5M"
|
|
176
|
-
>
|
|
177
|
-
> **UTM Agent:**
|
|
178
|
-
> ```json
|
|
179
|
-
> {
|
|
180
|
-
> "utm_faixa": "imovel_b4e2a1c9",
|
|
181
|
-
> "original_range": "800k-1.5M",
|
|
182
|
-
> "hash": "b4e2a1c9"
|
|
183
|
-
> }
|
|
184
|
-
> ```
|
|
185
|
-
|
|
186
|
-
## Rules
|
|
187
|
-
1. **NUNCA** revelar o valor real na URL pública
|
|
188
|
-
2. **SEMPRE** usar hash obfuscado para valores sensíveis
|
|
189
|
-
3. **Mapeamento reversível** deve estar disponível no Worker (não no SDK)
|
|
190
|
-
4. **Meta CAPI** recebe valor de-obfuscado internamente
|
|
191
|
-
5. UTMs sem valor sensível podem ficar em texto claro
|
|
@@ -209,13 +209,15 @@ export const generateId = () => {
|
|
|
209
209
|
// ── Captura de Click IDs das plataformas ──────────────────────
|
|
210
210
|
const _getClickIDs = () => {
|
|
211
211
|
return {
|
|
212
|
-
fbp:
|
|
213
|
-
fbc:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
fbp: document.cookie.match(/_fbp=([^;]+)/)?.[1] || undefined,
|
|
213
|
+
fbc: document.cookie.match(/_fbc=([^;]+)/)?.[1] || undefined,
|
|
214
|
+
fbclid: _fbclid || undefined, // click ID Meta → Worker gera fbc se cookie _fbc ausente
|
|
215
|
+
gclid: _gclid || undefined,
|
|
216
|
+
gbraid: _gbraid || undefined,
|
|
217
|
+
wbraid: _wbraid || undefined,
|
|
218
|
+
ttclid: _ttclid || undefined,
|
|
219
|
+
ttp: document.cookie.match(/_ttp=([^;]+)/)?.[1] || undefined, // TikTok Pixel cookie — EMQ TikTok
|
|
220
|
+
rclid: _urlParams.get('rclid') || undefined,
|
|
219
221
|
};
|
|
220
222
|
};
|
|
221
223
|
|
|
@@ -459,7 +461,7 @@ export async function track(eventName, data = {}, options = {}) {
|
|
|
459
461
|
|
|
460
462
|
try {
|
|
461
463
|
// Enviar para Worker com retry automático (anti-blocking)
|
|
462
|
-
const result = await sendWithRetry(payload, '/
|
|
464
|
+
const result = await sendWithRetry(payload, '/track');
|
|
463
465
|
|
|
464
466
|
if (result.success) {
|
|
465
467
|
console.log(`✅ Evento ${eventName} enviado com sucesso:`, event_id, result);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
# Modelo: Quiz Funnel (Cloudflare Native)
|
|
2
2
|
|
|
3
|
-
Este modelo é destinado a funis de quiz, onde o usuário responde a uma série de perguntas antes de ser redirecionado para a oferta final. O rastreamento foca na progressão do usuário e na
|
|
3
|
+
Este modelo é destinado a funis de quiz, onde o usuário responde a uma série de perguntas antes de ser redirecionado para a oferta final. O rastreamento foca na progressão do usuário e na **qualificação automática de intenção via Workers AI**.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
8
8
|
|
|
9
|
-
O rastreamento segue a lógica de micro-eventos:
|
|
9
|
+
O rastreamento segue a lógica de micro-eventos + scoring automático:
|
|
10
10
|
1. **Página**: Dispara um evento a cada resposta dada no quiz via `cdpTrack.track()`.
|
|
11
|
-
2. **Servidor (Worker)**:
|
|
12
|
-
3. **
|
|
11
|
+
2. **Servidor (Worker)**: Ao receber `QuizComplete`, envia as respostas ao **Quiz Scoring Engine** (Granite 4.0 Micro) que classifica o respondente.
|
|
12
|
+
3. **Pipeline CDP**: A qualificação (`comprador | interessado | curioso | perdido`) é injetada como `intentionLevel` e flui automaticamente para LTV Prediction, Meta Signal Score, D1 e CAPI dispatch.
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
@@ -19,50 +19,114 @@ O rastreamento segue a lógica de micro-eventos:
|
|
|
19
19
|
|---|---|---|
|
|
20
20
|
| **QuizStart** | Início do quiz | `quiz_name`, `source` |
|
|
21
21
|
| **QuizAnswer** | Resposta a uma pergunta | `question`, `answer`, `step` |
|
|
22
|
-
| **QuizComplete** | Finalização
|
|
22
|
+
| **QuizComplete** | Finalização + qualificação AI | `quiz_name`, `quiz_answers[]`, `result` |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🤖 QUALIFICAÇÃO AUTOMÁTICA (Quiz Scoring Engine — Fase 6)
|
|
27
|
+
|
|
28
|
+
Ao receber `QuizComplete` com `quiz_answers`, o Worker classifica automaticamente:
|
|
29
|
+
|
|
30
|
+
| Qualificação | Significado | intent_score |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| **comprador** | Pronto para comprar agora | 0.80–1.00 |
|
|
33
|
+
| **interessado** | Interesse real, avaliando | 0.50–0.79 |
|
|
34
|
+
| **curioso** | Pesquisando, sem urgência | 0.20–0.49 |
|
|
35
|
+
| **perdido** | Fora do público, sem fit | 0.00–0.19 |
|
|
36
|
+
|
|
37
|
+
O `intent_score` resultante:
|
|
38
|
+
- Alimenta o **LTV Prediction** (comprador → LTV High automaticamente)
|
|
39
|
+
- Compõe o **Meta Signal Score** (pesos dinâmicos por funil)
|
|
40
|
+
- Persiste em `leads.intention_level` e `quiz_sessions` no D1
|
|
41
|
+
- É enviado como `custom_data` para Meta CAPI, GA4 e TikTok
|
|
23
42
|
|
|
24
43
|
---
|
|
25
44
|
|
|
26
45
|
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
27
46
|
|
|
28
47
|
### 1.1 Rastreamento de Respostas
|
|
29
|
-
|
|
48
|
+
Acumule as respostas do quiz em um array local.
|
|
30
49
|
|
|
31
50
|
```javascript
|
|
32
|
-
|
|
51
|
+
const quizAnswers = [];
|
|
52
|
+
|
|
33
53
|
function onResponder(pergunta, resposta, etapa) {
|
|
54
|
+
// Armazena localmente para enviar no QuizComplete
|
|
55
|
+
quizAnswers.push({ question: pergunta, answer: resposta, step: etapa });
|
|
56
|
+
|
|
57
|
+
// Dispara micro-evento por resposta (opcional, para análise granular)
|
|
34
58
|
cdpTrack.track('QuizAnswer', {
|
|
35
59
|
question: pergunta,
|
|
36
60
|
answer: resposta,
|
|
37
61
|
step: etapa,
|
|
38
|
-
event_id: cdpTrack.generateId()
|
|
62
|
+
event_id: cdpTrack.generateId(),
|
|
39
63
|
});
|
|
40
64
|
}
|
|
41
65
|
```
|
|
42
66
|
|
|
43
|
-
### 1.2 Finalização do Quiz
|
|
44
|
-
|
|
67
|
+
### 1.2 Finalização do Quiz — com qualificação AI automática
|
|
68
|
+
Envie todas as respostas no `QuizComplete`. O Worker qualifica automaticamente.
|
|
45
69
|
|
|
46
70
|
```javascript
|
|
47
71
|
cdpTrack.track('QuizComplete', {
|
|
48
|
-
|
|
49
|
-
|
|
72
|
+
quiz_name: 'Diagnóstico de Perfil', // nome para o dashboard
|
|
73
|
+
quiz_answers: quizAnswers, // array com todas as respostas
|
|
74
|
+
result: 'Perfil_A', // resultado exibido ao usuário (opcional)
|
|
75
|
+
event_id: cdpTrack.generateId(),
|
|
50
76
|
});
|
|
51
77
|
```
|
|
52
78
|
|
|
79
|
+
### 1.3 Resposta do Worker
|
|
80
|
+
O endpoint `/track` retorna a qualificação para uso imediato no front:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"ok": true,
|
|
85
|
+
"userProfile": {
|
|
86
|
+
"score": 87,
|
|
87
|
+
"user_id": "uuid-xxx"
|
|
88
|
+
},
|
|
89
|
+
"quiz_qualification": "comprador",
|
|
90
|
+
"quiz_confidence": 0.91,
|
|
91
|
+
"quiz_signals": ["quero comprar", "tenho budget", "agora"],
|
|
92
|
+
"intent_score": 0.92,
|
|
93
|
+
"intent_bucket": "high"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Use esses campos para personalizar o redirecionamento pós-quiz no front-end.
|
|
98
|
+
|
|
53
99
|
---
|
|
54
100
|
|
|
55
101
|
## ⚡ PASSO 2: SERVIDOR (CLOUDFLARE WORKER)
|
|
56
102
|
|
|
57
|
-
O Worker realiza:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
103
|
+
O Worker realiza automaticamente na ordem:
|
|
104
|
+
|
|
105
|
+
1. **Quiz Scoring Engine**: Granite 4.0 Micro classifica as respostas → `qualification` + `intent_score`
|
|
106
|
+
2. **LTV Prediction**: usa `intentionLevel = 'comprador'` → LTV High → valor previsto em BRL
|
|
107
|
+
3. **Meta Signal Score**: `intent_score` compõe o score composto (intent × ltv × distância)
|
|
108
|
+
4. **D1 Writes**: `quiz_sessions` + `leads.intention_level` + `user_profiles.cohort_label`
|
|
109
|
+
5. **CAPI Dispatch**: Meta/GA4/TikTok recebem evento com `custom_data.intention = 'comprador'`
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 🔀 FALLBACK HEURÍSTICO
|
|
114
|
+
|
|
115
|
+
Se Workers AI estiver indisponível (timeout, cold start), o sistema usa correspondência de palavras-chave:
|
|
116
|
+
|
|
117
|
+
- `comprador`: "quero", "comprar", "agora", "tenho interesse", "quanto custa"
|
|
118
|
+
- `interessado`: "talvez", "pensando", "em breve", "estou avaliando"
|
|
119
|
+
- `curioso`: "só olhando", "pesquisando", "curiosidade"
|
|
120
|
+
- `perdido`: "não entendi", "errei aqui", "não é para mim"
|
|
121
|
+
|
|
122
|
+
O campo `quiz_source` indica `"ai"` ou `"heuristic"` para auditoria.
|
|
61
123
|
|
|
62
124
|
---
|
|
63
125
|
|
|
64
126
|
## ✅ VALIDAÇÃO TÉCNICA
|
|
65
127
|
|
|
66
|
-
- **Persistência**:
|
|
67
|
-
- **Deduplicação**:
|
|
68
|
-
- **
|
|
128
|
+
- **Persistência**: `quiz_sessions` no D1 — jornada completa por `user_id`
|
|
129
|
+
- **Deduplicação**: `event_id` único por evento evita contagens duplicadas
|
|
130
|
+
- **Enriquecimento retroativo**: e-mail preenchido pós-quiz associa todas as respostas ao perfil
|
|
131
|
+
- **Match Quality**: `comprador` com e-mail → score máximo na CAPI Meta
|
|
132
|
+
- **VIEW de dashboard**: `v_quiz_qualification_summary` — distribuição de qualificações por quiz
|
package/package.json
CHANGED