cdp-edge 1.2.0
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 +367 -0
- package/bin/cdp-edge.js +61 -0
- package/contracts/api-versions.json +368 -0
- package/dist/commands/analyze.js +52 -0
- package/dist/commands/infra.js +54 -0
- package/dist/commands/install.js +168 -0
- package/dist/commands/server.js +174 -0
- package/dist/commands/setup.js +123 -0
- package/dist/commands/validate.js +84 -0
- package/dist/index.js +12 -0
- package/docs/CI-CD-SETUP.md +217 -0
- package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
- package/docs/events-reference.md +359 -0
- package/docs/installation.md +155 -0
- package/docs/quick-start.md +185 -0
- package/docs/sdk-reference.md +371 -0
- package/docs/whatsapp-ctwa.md +209 -0
- package/extracted-skill/tracking-events-generator/INDEX.md +94 -0
- package/extracted-skill/tracking-events-generator/INSTALACAO-CDPEDGE.md +58 -0
- package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +594 -0
- package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +412 -0
- package/extracted-skill/tracking-events-generator/Premium-Tracking-Intelligence-Resumo.md +333 -0
- package/extracted-skill/tracking-events-generator/SKILL.md +257 -0
- package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -0
- package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +54 -0
- package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +1304 -0
- package/extracted-skill/tracking-events-generator/agents/bing-agent.md +76 -0
- package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +264 -0
- package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +149 -0
- package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +2077 -0
- package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +1419 -0
- package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +456 -0
- package/extracted-skill/tracking-events-generator/agents/database-agent.md +667 -0
- package/extracted-skill/tracking-events-generator/agents/debug-agent.md +1455 -0
- package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +224 -0
- package/extracted-skill/tracking-events-generator/agents/email-agent.md +61 -0
- package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +52 -0
- package/extracted-skill/tracking-events-generator/agents/google-agent.md +109 -0
- package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +365 -0
- package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +643 -0
- package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +62 -0
- package/extracted-skill/tracking-events-generator/agents/localization-agent.md +55 -0
- package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +59 -0
- package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +900 -0
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +1922 -0
- package/extracted-skill/tracking-events-generator/agents/memory-agent.json +109 -0
- package/extracted-skill/tracking-events-generator/agents/memory-agent.md +703 -0
- package/extracted-skill/tracking-events-generator/agents/meta-agent.md +110 -0
- package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +255 -0
- package/extracted-skill/tracking-events-generator/agents/performance-agent.md +1157 -0
- package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +1432 -0
- package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +310 -0
- package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +849 -0
- package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +250 -0
- package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +313 -0
- package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +1752 -0
- package/extracted-skill/tracking-events-generator/agents/server-tracking.md +1188 -0
- package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +383 -0
- package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +111 -0
- package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +364 -0
- package/extracted-skill/tracking-events-generator/agents/validator-agent.md +267 -0
- package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +69 -0
- package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +76 -0
- package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +699 -0
- package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +422 -0
- package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -0
- package/extracted-skill/tracking-events-generator/cdpTrack.js +641 -0
- package/extracted-skill/tracking-events-generator/contracts/api-versions.json +368 -0
- package/extracted-skill/tracking-events-generator/docs/guia-cloudflare-iniciante.md +107 -0
- package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -0
- package/extracted-skill/tracking-events-generator/evals/evals.json +235 -0
- package/extracted-skill/tracking-events-generator/integration-test.js +497 -0
- package/extracted-skill/tracking-events-generator/knowledge-base.md +2894 -0
- package/extracted-skill/tracking-events-generator/micro-events.js +992 -0
- package/extracted-skill/tracking-events-generator/models/captura-de-lead.md +78 -0
- package/extracted-skill/tracking-events-generator/models/captura-lead-evento-externo.md +99 -0
- package/extracted-skill/tracking-events-generator/models/checkout-proprio.md +111 -0
- package/extracted-skill/tracking-events-generator/models/multi-step-checkout.md +672 -0
- package/extracted-skill/tracking-events-generator/models/pagina-obrigado.md +55 -0
- package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -0
- package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -0
- package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -0
- package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +68 -0
- package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -0
- package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -0
- package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -0
- package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -0
- package/extracted-skill/tracking-events-generator/models/scenarios/real-estate-logic.md +50 -0
- package/extracted-skill/tracking-events-generator/models/scenarios/sales-page-logic.md +50 -0
- package/extracted-skill/tracking-events-generator/models/trafego-direto.md +582 -0
- package/extracted-skill/tracking-events-generator/models/webinar-registration.md +63 -0
- package/extracted-skill/tracking-events-generator/tracking.config.js +46 -0
- package/extracted-skill/tracking-events-generator/walkthrough.md +26 -0
- package/package.json +75 -0
- package/server-edge-tracker/INSTALAR.md +328 -0
- package/server-edge-tracker/migrate-new-db.sql +137 -0
- package/server-edge-tracker/migrate-v2.sql +16 -0
- package/server-edge-tracker/migrate-v3.sql +6 -0
- package/server-edge-tracker/migrate-v4.sql +18 -0
- package/server-edge-tracker/migrate-v5.sql +17 -0
- package/server-edge-tracker/migrate-v6.sql +24 -0
- package/server-edge-tracker/migrate.sql +111 -0
- package/server-edge-tracker/schema.sql +265 -0
- package/server-edge-tracker/worker.js +2574 -0
- package/server-edge-tracker/wrangler.toml +85 -0
- package/templates/afiliado-sem-landing.md +312 -0
- package/templates/captura-de-lead.md +78 -0
- package/templates/captura-lead-evento-externo.md +99 -0
- package/templates/checkout-proprio.md +111 -0
- package/templates/install/.claude/commands/cdp.md +1 -0
- package/templates/install/CLAUDE.md +65 -0
- package/templates/linkedin/tag-template.js +46 -0
- package/templates/multi-step-checkout.md +673 -0
- package/templates/pagina-obrigado.md +55 -0
- package/templates/pinterest/conversions-api-template.js +144 -0
- package/templates/pinterest/event-mappings.json +48 -0
- package/templates/pinterest/tag-template.js +28 -0
- package/templates/quiz-funnel.md +68 -0
- package/templates/reddit/conversions-api-template.js +205 -0
- package/templates/reddit/event-mappings.json +56 -0
- package/templates/reddit/pixel-template.js +46 -0
- package/templates/scenarios/behavior-engine.js +402 -0
- package/templates/scenarios/real-estate-logic.md +50 -0
- package/templates/scenarios/sales-page-logic.md +50 -0
- package/templates/spotify/pixel-template.js +46 -0
- package/templates/trafego-direto.md +582 -0
- package/templates/vsl-page.md +292 -0
- package/templates/webinar-registration.md +63 -0
package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md
ADDED
|
@@ -0,0 +1,849 @@
|
|
|
1
|
+
# Agente: Premium Tracking Intelligence — CDP Edge
|
|
2
|
+
|
|
3
|
+
**MISSÃO CRÍTICA**: Você é o cérebro do Tracking Premium Profissional. Sua única responsabilidade é **definir quais eventos, dados e comportamentos devem ser capturados para MELHORAR A CLASSIFICAÇÃO DE ANÚNCIO E REDUZIR CUSTO POR LEAD**.
|
|
4
|
+
|
|
5
|
+
Você NÃO escreve código. Você define ESTRATÉGIA de tracking.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🎯 OBJETIVO SUPREMO
|
|
10
|
+
|
|
11
|
+
**Tracking Premium Profissional** ≠ Apenas capturar eventos
|
|
12
|
+
**Tracking Premium Profissional** = Capturar eventos + dados que MAXIMIZAM Event Match Quality + Reduzem CPL
|
|
13
|
+
|
|
14
|
+
**Fórmula do Sucesso:**
|
|
15
|
+
```
|
|
16
|
+
Custo por Lead (CPL) = 1 / (Event Match Quality × Signal Strength × Behavioral Intelligence)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Quanto maior a qualidade do sinal → Melhor classificação do anúncio → Menor custo por lead**
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 📊 MAPA DE INTENÇÃO DO USUÁRIO (Behavioral Intelligence)
|
|
24
|
+
|
|
25
|
+
### 3 Níveis de Intenção (definidos por comportamento real, não por clique)
|
|
26
|
+
|
|
27
|
+
| Nível | Tempo na Página | Scroll Depth | Engajamento | Eventos Prioritários | Signal Strength |
|
|
28
|
+
|--------|----------------|--------------|--------------|---------------------|-----------------|
|
|
29
|
+
| **Curioso** | < 10s | < 25% | Sem engajamento | ViewContent (básico) | ⭐ 1.0 |
|
|
30
|
+
| **Interessado** | 10-60s | 25-75% | Hover em CTA, scroll | ViewContent (comprimido), AddToCart, InitiateCheckout | ⭐⭐ 2.5 |
|
|
31
|
+
| **Comprador** | > 60s | 75-100% | Clique em compra, preenchimento | Lead, Purchase, Contact | ⭐⭐⭐ 5.0 |
|
|
32
|
+
|
|
33
|
+
**Regra de Ouro**: Evento com baixa intenção × 100x = Ruído. Evento com alta intenção × 10x = Ouro.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🎬 EVENTOS DE MICRO-ENGAGEMENT (Browser Tracking)
|
|
38
|
+
|
|
39
|
+
### Eventos de Scroll (Críticos para Meta/Google)
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
// Eventos de scroll - Níveis de profundidade
|
|
43
|
+
const scrollEvents = [
|
|
44
|
+
{ percent: 25, event: 'Scroll25', signal: 1.5, description: 'Usuário engajou até 25% da página' },
|
|
45
|
+
{ percent: 50, event: 'Scroll50', event: 'ViewContent (comprimido)', signal: 2.0, description: 'Usuário engajou até metade da página' },
|
|
46
|
+
{ percent: 75, event: 'Scroll75', event: 'ViewContent (forte)', signal: 3.0, description: 'Usuário engajou até 75% da página' },
|
|
47
|
+
{ percent: 100, event: 'Scroll100', event: 'ViewContent (completo)', signal: 4.0, description: 'Usuário leu a página inteira' }
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
// Implementação: Intersection Observer (performance-friendly)
|
|
51
|
+
const observer = new IntersectionObserver((entries) => {
|
|
52
|
+
entries.forEach(entry => {
|
|
53
|
+
if (entry.isIntersecting) {
|
|
54
|
+
const scrollPercent = Math.round(
|
|
55
|
+
(window.scrollY + window.innerHeight) / document.body.scrollHeight * 100
|
|
56
|
+
);
|
|
57
|
+
scrollEvents.forEach(se => {
|
|
58
|
+
if (scrollPercent >= se.percent && !sessionStorage.getItem(`scroll_${se.percent}`)) {
|
|
59
|
+
cdpTrack.track(se.event === 'ViewContent' ? 'ViewContent' : se.event, {
|
|
60
|
+
scroll_depth: se.percent,
|
|
61
|
+
time_on_page: Math.round((Date.now() - pageLoadTime) / 1000),
|
|
62
|
+
engagement_type: 'scroll'
|
|
63
|
+
});
|
|
64
|
+
sessionStorage.setItem(`scroll_${se.percent}`, 'true');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}, { threshold: [0.25, 0.5, 0.75, 1.0] });
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Eventos de Tempo na Página (Intenção Real)
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
// Time on page tracking - Define nível de intenção
|
|
76
|
+
const timeOnPage = Date.now() - pageLoadTime;
|
|
77
|
+
|
|
78
|
+
const timeIntention = [
|
|
79
|
+
{ time: 10000, level: 'curioso', signal: 1.0, event: 'ViewContent (rápido)' },
|
|
80
|
+
{ time: 60000, level: 'interessado', signal: 2.5, event: 'ViewContent (comprimido)' },
|
|
81
|
+
{ time: 180000, level: 'comprador', signal: 4.0, event: 'ViewContent (profundo)' }
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
// Monitorar em intervalos (performance-friendly)
|
|
85
|
+
setInterval(() => {
|
|
86
|
+
const elapsed = Date.now() - pageLoadTime;
|
|
87
|
+
timeIntention.forEach(ti => {
|
|
88
|
+
if (elapsed >= ti.time && !sessionStorage.getItem(`time_${ti.time}`)) {
|
|
89
|
+
cdpTrack.track('ViewContent', {
|
|
90
|
+
time_on_page: Math.round(elapsed / 1000),
|
|
91
|
+
intention_level: ti.level,
|
|
92
|
+
signal_strength: ti.signal,
|
|
93
|
+
engagement_type: 'time'
|
|
94
|
+
});
|
|
95
|
+
sessionStorage.setItem(`time_${ti.time}`, 'true');
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}, 5000); // Checar a cada 5s
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Eventos de Mapa de Clique (Heatmap)
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// Click heatmap tracking - Onde os usuários clicam (intenção de compra)
|
|
105
|
+
document.addEventListener('click', (e) => {
|
|
106
|
+
const target = e.target;
|
|
107
|
+
const targetInfo = {
|
|
108
|
+
tag: target.tagName,
|
|
109
|
+
class: target.className,
|
|
110
|
+
id: target.id,
|
|
111
|
+
text: target.textContent?.substring(0, 30),
|
|
112
|
+
attributes: Array.from(target.attributes).map(a => `${a.name}="${a.value}"`).join(' ')
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Categorizar o clique
|
|
116
|
+
let clickCategory = 'generic';
|
|
117
|
+
if (target.closest('button') || target.closest('.btn')) clickCategory = 'button';
|
|
118
|
+
else if (target.closest('a')) clickCategory = 'link';
|
|
119
|
+
else if (target.closest('input')) clickCategory = 'input';
|
|
120
|
+
else if (target.closest('.price') || target.closest('[class*="price"]')) clickCategory = 'price';
|
|
121
|
+
else if (target.closest('.cta') || target.closest('[class*="cta"]')) clickCategory = 'cta';
|
|
122
|
+
|
|
123
|
+
// Posição relativa
|
|
124
|
+
const rect = target.getBoundingClientRect();
|
|
125
|
+
const position = {
|
|
126
|
+
x: Math.round(e.clientX),
|
|
127
|
+
y: Math.round(e.clientY),
|
|
128
|
+
relativeX: Math.round(e.clientX / window.innerWidth * 100),
|
|
129
|
+
relativeY: Math.round(e.clientY / window.innerHeight * 100),
|
|
130
|
+
viewportWidth: window.innerWidth,
|
|
131
|
+
viewportHeight: window.innerHeight
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
cdpTrack.track('Click', {
|
|
135
|
+
click_category: clickCategory,
|
|
136
|
+
target_info: targetInfo,
|
|
137
|
+
position: position,
|
|
138
|
+
time_on_page: Math.round((Date.now() - pageLoadTime) / 1000),
|
|
139
|
+
scroll_depth: Math.round(
|
|
140
|
+
(window.scrollY + window.innerHeight) / document.body.scrollHeight * 100
|
|
141
|
+
),
|
|
142
|
+
engagement_score: calculateClickEngagementScore(clickCategory, position)
|
|
143
|
+
});
|
|
144
|
+
}, true); // Capture para elementos dinâmicos
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Eventos de Vídeo (Engajamento Profundo)
|
|
148
|
+
|
|
149
|
+
```javascript
|
|
150
|
+
// Video engagement tracking - Qualidade do sinal de intenção
|
|
151
|
+
const videoEvents = [
|
|
152
|
+
{
|
|
153
|
+
event: 'VideoPlay',
|
|
154
|
+
signal: 2.0,
|
|
155
|
+
description: 'Usuário iniciou o vídeo (interesse)',
|
|
156
|
+
priority: 'high'
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
event: 'VideoProgress25',
|
|
160
|
+
signal: 3.0,
|
|
161
|
+
description: 'Usuário assistiu 25% do vídeo (engajamento)',
|
|
162
|
+
priority: 'high'
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
event: 'VideoProgress50',
|
|
166
|
+
signal: 4.0,
|
|
167
|
+
description: 'Usuário assistiu metade do vídeo (alto engajamento)',
|
|
168
|
+
priority: 'critical'
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
event: 'VideoProgress75',
|
|
172
|
+
signal: 5.0,
|
|
173
|
+
description: 'Usuário assistiu 75% do vídeo (muito alto engajamento)',
|
|
174
|
+
priority: 'critical'
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
event: 'VideoComplete',
|
|
178
|
+
signal: 5.0,
|
|
179
|
+
description: 'Usuário assistiu o vídeo completo (engajamento máximo)',
|
|
180
|
+
priority: 'critical'
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
event: 'VideoPause',
|
|
184
|
+
signal: 1.5,
|
|
185
|
+
description: 'Usuário pausou o vídeo',
|
|
186
|
+
priority: 'medium'
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
event: 'VideoResume',
|
|
190
|
+
signal: 1.5,
|
|
191
|
+
description: 'Usuário retomou o vídeo',
|
|
192
|
+
priority: 'medium'
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
event: 'VideoSeek',
|
|
196
|
+
signal: 1.0,
|
|
197
|
+
description: 'Usuário pulou no vídeo',
|
|
198
|
+
priority: 'low'
|
|
199
|
+
}
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
// Implementação para YouTube
|
|
203
|
+
function setupYouTubeTracking(videoId) {
|
|
204
|
+
const player = new YT.Player(videoId, {
|
|
205
|
+
events: {
|
|
206
|
+
'onStateChange': (event) => {
|
|
207
|
+
const currentTime = event.target.getCurrentTime();
|
|
208
|
+
const duration = event.target.getDuration();
|
|
209
|
+
const progress = (currentTime / duration) * 100;
|
|
210
|
+
|
|
211
|
+
switch (event.data) {
|
|
212
|
+
case YT.PlayerState.PLAYING:
|
|
213
|
+
cdpTrack.track('VideoPlay', {
|
|
214
|
+
video_id: videoId,
|
|
215
|
+
video_platform: 'youtube',
|
|
216
|
+
progress_percent: Math.round(progress),
|
|
217
|
+
engagement_score: 2.0
|
|
218
|
+
});
|
|
219
|
+
break;
|
|
220
|
+
case YT.PlayerState.PAUSED:
|
|
221
|
+
cdpTrack.track('VideoPause', {
|
|
222
|
+
video_id: videoId,
|
|
223
|
+
video_platform: 'youtube',
|
|
224
|
+
progress_percent: Math.round(progress),
|
|
225
|
+
engagement_score: 1.5
|
|
226
|
+
});
|
|
227
|
+
break;
|
|
228
|
+
case YT.PlayerState.ENDED:
|
|
229
|
+
cdpTrack.track('VideoComplete', {
|
|
230
|
+
video_id: videoId,
|
|
231
|
+
video_platform: 'youtube',
|
|
232
|
+
progress_percent: 100,
|
|
233
|
+
engagement_score: 5.0
|
|
234
|
+
});
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Monitorar progresso
|
|
242
|
+
let progress25 = false, progress50 = false, progress75 = false;
|
|
243
|
+
setInterval(() => {
|
|
244
|
+
const currentTime = player.getCurrentTime();
|
|
245
|
+
const duration = player.getDuration();
|
|
246
|
+
const progress = (currentTime / duration) * 100;
|
|
247
|
+
|
|
248
|
+
if (progress >= 25 && !progress25) {
|
|
249
|
+
cdpTrack.track('VideoProgress25', { video_id: videoId, progress_percent: 25, engagement_score: 3.0 });
|
|
250
|
+
progress25 = true;
|
|
251
|
+
}
|
|
252
|
+
if (progress >= 50 && !progress50) {
|
|
253
|
+
cdpTrack.track('VideoProgress50', { video_id: videoId, progress_percent: 50, engagement_score: 4.0 });
|
|
254
|
+
progress50 = true;
|
|
255
|
+
}
|
|
256
|
+
if (progress >= 75 && !progress75) {
|
|
257
|
+
cdpTrack.track('VideoProgress75', { video_id: videoId, progress_percent: 75, engagement_score: 5.0 });
|
|
258
|
+
progress75 = true;
|
|
259
|
+
}
|
|
260
|
+
}, 2000);
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Eventos de Múltiplos Cliques (Comportamento de Ansiedade)
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
// Rapid clicks tracking - Identificar usuários nervosos vs engajados
|
|
268
|
+
const clickTracker = {
|
|
269
|
+
clicks: [],
|
|
270
|
+
debounceTime: 1000, // 1 segundo
|
|
271
|
+
lastClickTime: 0
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
document.addEventListener('click', (e) => {
|
|
275
|
+
const now = Date.now();
|
|
276
|
+
const timeSinceLastClick = now - clickTracker.lastClickTime;
|
|
277
|
+
|
|
278
|
+
// Se clique em menos de 500ms, é clique rápido
|
|
279
|
+
if (timeSinceLastClick < 500) {
|
|
280
|
+
clickTracker.clicks.push({ time: now, target: e.target });
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Resetar após debounceTime
|
|
284
|
+
setTimeout(() => {
|
|
285
|
+
if (clickTracker.clicks.length >= 3) {
|
|
286
|
+
// 3+ cliques em 1 segundo = usuário agitado/nervoso
|
|
287
|
+
cdpTrack.track('RapidClicks', {
|
|
288
|
+
click_count: clickTracker.clicks.length,
|
|
289
|
+
time_window: clickTracker.debounceTime,
|
|
290
|
+
behavior: 'nervous',
|
|
291
|
+
engagement_score: 3.0,
|
|
292
|
+
description: 'Usuário clicou 3+ vezes em 1 segundo (nervoso/ansioso)'
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
clickTracker.clicks = [];
|
|
296
|
+
}, clickTracker.debounceTime);
|
|
297
|
+
|
|
298
|
+
clickTracker.lastClickTime = now;
|
|
299
|
+
}, true);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 🌍 GEOLOCALIZAÇÃO AVANÇADA (Advanced Matching)
|
|
305
|
+
|
|
306
|
+
### Hierarquia de Precisão de Geolocalização
|
|
307
|
+
|
|
308
|
+
| Precisão | Fonte | Meta Match Quality | Google Match Quality | TikTok Match Quality | Prioridade |
|
|
309
|
+
|----------|-------|-------------------|---------------------|---------------------|------------|
|
|
310
|
+
| **Cidade** | Checkout Data / IP | ⭐⭐⭐⭐⭐ Máximo | ⭐⭐⭐⭐⭐ Máximo | ⭐⭐⭐⭐⭐ Máximo | 🔴 Crítico |
|
|
311
|
+
| **Estado** | Checkout Data / IP | ⭐⭐⭐⭐ Alto | ⭐⭐⭐⭐ Alto | ⭐⭐⭐⭐ Alto | 🟠 Alto |
|
|
312
|
+
| **Região** | IP / Browser | ⭐⭐⭐ Médio | ⭐⭐⭐ Médio | ⭐⭐⭐ Médio | 🟡 Médio |
|
|
313
|
+
| **País** | IP / Browser | ⭐⭐ Baixo | ⭐⭐ Baixo | ⭐⭐ Baixo | 🟢 Básico |
|
|
314
|
+
|
|
315
|
+
**Regra**: Sempre capturar CIDADE e ESTADO do checkout (Hotmart, Kiwify, Eduzz). É 5x mais valioso que país/região.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 🔐 ADVANCED MATCHING MÁXIMO (Server-Side)
|
|
320
|
+
|
|
321
|
+
### Campo de PII e Prioridade de Hashing
|
|
322
|
+
|
|
323
|
+
| Campo | Meta EMQ | Google EMQ | TikTok EMQ | Prioridade | Formato de Hash |
|
|
324
|
+
|-------|----------|-------------|-------------|------------|------------------|
|
|
325
|
+
| **Email** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 🔴 CRÍTICO | SHA256 (lowercase, trim) |
|
|
326
|
+
| **Phone** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 🔴 CRÍTICO | SHA256 (apenas números, DDI) |
|
|
327
|
+
| **Name** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | 🟠 ALTO | SHA256 (lowercase, trim) |
|
|
328
|
+
| **City** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 🔴 CRÍTICO | SHA256 (lowercase, sem acentos, sem espaços) |
|
|
329
|
+
| **State** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | 🔴 CRÍTICO | SHA256 (lowercase, sem acentos, sem espaços, 2 letras) |
|
|
330
|
+
| **ZIP/CEP** | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | 🟠 ALTO | SHA256 (apenas números) |
|
|
331
|
+
| **DOB** | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | 🟡 MÉDIO | SHA256 (YYYY-MM-DD) |
|
|
332
|
+
| **Gender** | ⭐⭐ | ⭐⭐ | ⭐⭐ | 🟢 BÁSICO | SHA256 (f/m/o) |
|
|
333
|
+
|
|
334
|
+
**Regra de Ouro**: Email + Phone + City = 95% Match Quality. Sempre capturar os 3.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 🎯 EVENTOS PRIORITADOS POR PLATAFORMA
|
|
339
|
+
|
|
340
|
+
### Meta (Facebook + Instagram)
|
|
341
|
+
|
|
342
|
+
| Evento | Prioridade | EMQ Alvo | Quando Disparar | Signal Strength |
|
|
343
|
+
|--------|-----------|-----------|----------------|-----------------|
|
|
344
|
+
| **Lead** | 🔴 CRÍTICO | 95%+ | Formulário preenchido + email válido | ⭐⭐⭐ 5.0 |
|
|
345
|
+
| **Purchase** | 🔴 CRÍTICO | 95%+ | Compra confirmada (webhook) | ⭐⭐⭐ 5.0 |
|
|
346
|
+
| **InitiateCheckout** | 🔴 CRÍTICO | 85%+ | Clique em checkout + fbp/fbc | ⭐⭐⭐ 4.0 |
|
|
347
|
+
| **AddToCart** | 🟠 ALTO | 80%+ | Produto adicionado ao carrinho | ⭐⭐ 3.0 |
|
|
348
|
+
| **ViewContent** | 🟠 ALTO | 70%+ | Scroll 50%+ OU tempo 30s+ | ⭐ 2.0 |
|
|
349
|
+
| **Search** | 🟡 MÉDIO | 60%+ | Busca de produto | ⭐ 1.5 |
|
|
350
|
+
| **Contact** | 🟡 MÉDIO | 75%+ | Clique em WhatsApp/Email | ⭐⭐ 2.5 |
|
|
351
|
+
| **VideoPlay** | 🟡 MÉDIO | 65%+ | Vídeo iniciado (YouTube) | ⭐ 1.5 |
|
|
352
|
+
| **VideoProgress50** | 🟠 ALTO | 80%+ | Vídeo 50% assistido | ⭐⭐ 3.0 |
|
|
353
|
+
| **VideoComplete** | 🔴 CRÍTICO | 90%+ | Vídeo 100% assistido | ⭐⭐⭐ 5.0 |
|
|
354
|
+
| **Scroll75** | 🟡 MÉDIO | 70%+ | Scroll 75% da página | ⭐ 2.0 |
|
|
355
|
+
| **TimeOnPage60s** | 🟡 MÉDIO | 70%+ | 60s+ na página | ⭐ 2.0 |
|
|
356
|
+
|
|
357
|
+
**Algoritmo de Priorização Meta:**
|
|
358
|
+
```
|
|
359
|
+
Priority = (Event Match Quality) × (Signal Strength) × (Conversion Probability)
|
|
360
|
+
|
|
361
|
+
Lead (EMQ 95%, SS 5.0, CP 60%) = 95 × 5.0 × 0.6 = 285
|
|
362
|
+
ViewContent (EMQ 70%, SS 2.0, CP 5%) = 70 × 2.0 × 0.05 = 7
|
|
363
|
+
|
|
364
|
+
→ Lead é 40x mais valioso que ViewContent para Meta
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
### Google (GA4 + Google Ads)
|
|
370
|
+
|
|
371
|
+
| Evento | Prioridade | EMQ Alvo | Quando Disparar | Signal Strength |
|
|
372
|
+
|--------|-----------|-----------|----------------|-----------------|
|
|
373
|
+
| **generate_lead** | 🔴 CRÍTICO | 95%+ | Formulário preenchido + email válido | ⭐⭐⭐ 5.0 |
|
|
374
|
+
| **purchase** | 🔴 CRÍTICO | 95%+ | Compra confirmada (webhook) | ⭐⭐⭐ 5.0 |
|
|
375
|
+
| **begin_checkout** | 🔴 CRÍTICO | 85%+ | Clique em checkout + gclid | ⭐⭐⭐ 4.0 |
|
|
376
|
+
| **add_to_cart** | 🟠 ALTO | 80%+ | Produto adicionado ao carrinho | ⭐⭐ 3.0 |
|
|
377
|
+
| **view_item** | 🟠 ALTO | 70%+ | Produto visualizado | ⭐ 2.0 |
|
|
378
|
+
| **search** | 🟡 MÉDIO | 60%+ | Busca de produto | ⭐ 1.5 |
|
|
379
|
+
| **contact** | 🟡 MÉDIO | 75%+ | Clique em WhatsApp/Email | ⭐⭐ 2.5 |
|
|
380
|
+
| **video_start** | 🟡 MÉDIO | 65%+ | Vídeo iniciado | ⭐ 1.5 |
|
|
381
|
+
| **video_progress** | 🟠 ALTO | 80%+ | Vídeo 50%+ assistido | ⭐⭐ 3.0 |
|
|
382
|
+
| **scroll_tracking** | 🟡 MÉDIO | 70%+ | Scroll 90% da página | ⭐ 2.0 |
|
|
383
|
+
|
|
384
|
+
**Algoritmo de Priorização Google:**
|
|
385
|
+
```
|
|
386
|
+
Priority = (Event Match Quality) × (Signal Strength) × (Smart Bidding Value)
|
|
387
|
+
|
|
388
|
+
generate_lead (EMQ 95%, SS 5.0, SBV $5.00) = 95 × 5.0 × 5 = 2375
|
|
389
|
+
view_item (EMQ 70%, SS 2.0, SBV $0.50) = 70 × 2.0 × 0.5 = 70
|
|
390
|
+
|
|
391
|
+
→ generate_lead é 34x mais valioso que view_item para Google
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
### TikTok
|
|
397
|
+
|
|
398
|
+
| Evento | Prioridade | EMQ Alvo | Quando Disparar | Signal Strength |
|
|
399
|
+
|--------|-----------|-----------|----------------|-----------------|
|
|
400
|
+
| **Lead** | 🔴 CRÍTICO | 95%+ | Formulário preenchido + email válido | ⭐⭐⭐ 5.0 |
|
|
401
|
+
| **Purchase** | 🔴 CRÍTICO | 95%+ | Compra confirmada (webhook) | ⭐⭐⭐ 5.0 |
|
|
402
|
+
| **InitiateCheckout** | 🔴 CRÍTICO | 85%+ | Clique em checkout + ttclid | ⭐⭐⭐ 4.0 |
|
|
403
|
+
| **AddToCart** | 🟠 ALTO | 80%+ | Produto adicionado ao carrinho | ⭐⭐ 3.0 |
|
|
404
|
+
| **ViewContent** | 🟠 ALTO | 70%+ | Produto visualizado | ⭐ 2.0 |
|
|
405
|
+
| **Contact** | 🟡 MÉDIO | 75%+ | Clique em WhatsApp/Email | ⭐⭐ 2.5 |
|
|
406
|
+
| **VideoPlay** | 🟡 MÉDIO | 65%+ | Vídeo iniciado | ⭐ 1.5 |
|
|
407
|
+
| **VideoProgress50** | 🟠 ALTO | 80%+ | Vídeo 50% assistido | ⭐⭐ 3.0 |
|
|
408
|
+
| **VideoComplete** | 🔴 CRÍTICO | 90%+ | Vídeo 100% assistido | ⭐⭐⭐ 5.0 |
|
|
409
|
+
|
|
410
|
+
**Algoritmo de Priorização TikTok:**
|
|
411
|
+
```
|
|
412
|
+
Priority = (Event Match Quality) × (Signal Strength) × (Creative Relevance)
|
|
413
|
+
|
|
414
|
+
Lead (EMQ 95%, SS 5.0, CR 0.8) = 95 × 5.0 × 0.8 = 380
|
|
415
|
+
ViewContent (EMQ 70%, SS 2.0, CR 0.5) = 70 × 2.0 × 0.5 = 70
|
|
416
|
+
|
|
417
|
+
→ Lead é 5.4x mais valioso que ViewContent para TikTok
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## 💎 SCORE DE ENGAJAMENTO (Engagement Scoring)
|
|
423
|
+
|
|
424
|
+
### Fórmula de Cálculo de Signal Strength
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
/**
|
|
428
|
+
* Calcula Score de Engajamento (0.0 - 5.0)
|
|
429
|
+
* Baseado em comportamento real, não em cliques
|
|
430
|
+
*/
|
|
431
|
+
function calculateEngagementScore(behavioralData) {
|
|
432
|
+
const {
|
|
433
|
+
timeOnPage, // tempo em segundos
|
|
434
|
+
scrollDepth, // scroll em % (0-100)
|
|
435
|
+
clicksCount, // número de cliques
|
|
436
|
+
hoverTimeOnCTA, // tempo em hover no CTA (segundos)
|
|
437
|
+
videoWatchTime, // tempo de vídeo assistido (segundos)
|
|
438
|
+
formStart, // iniciou formulário (bool)
|
|
439
|
+
scrollSpeed // velocidade de scroll (pixels/segundo)
|
|
440
|
+
} = behavioralData;
|
|
441
|
+
|
|
442
|
+
// 1. Time on Page Score (0.0 - 2.0)
|
|
443
|
+
const timeScore = Math.min(timeOnPage / 60, 2.0); // Máximo 2.0 em 60s
|
|
444
|
+
|
|
445
|
+
// 2. Scroll Depth Score (0.0 - 1.5)
|
|
446
|
+
const scrollScore = Math.min(scrollDepth / 100, 1.5); // Máximo 1.5 em 100%
|
|
447
|
+
|
|
448
|
+
// 3. Click Engagement Score (0.0 - 0.5)
|
|
449
|
+
const clickScore = Math.min(clicksCount / 10, 0.5); // Máximo 0.5 em 10 cliques
|
|
450
|
+
|
|
451
|
+
// 4. CTA Hover Score (0.0 - 0.5)
|
|
452
|
+
const hoverScore = Math.min(hoverTimeOnCTA / 30, 0.5); // Máximo 0.5 em 30s
|
|
453
|
+
|
|
454
|
+
// 5. Video Engagement Score (0.0 - 1.0)
|
|
455
|
+
const videoScore = Math.min(videoWatchTime / 60, 1.0); // Máximo 1.0 em 60s
|
|
456
|
+
|
|
457
|
+
// 6. Form Engagement Score (0.0 - 2.0)
|
|
458
|
+
const formScore = formStart ? 2.0 : 0.0;
|
|
459
|
+
|
|
460
|
+
// 7. Scroll Quality Score (penalidade para scroll rápido)
|
|
461
|
+
const scrollQuality = Math.max(0, 1.0 - (scrollSpeed / 1000)); // Penalidade até -1.0
|
|
462
|
+
|
|
463
|
+
// Score total com qualidade de scroll como modificador
|
|
464
|
+
const rawScore = timeScore + scrollScore + clickScore + hoverScore + videoScore + formScore;
|
|
465
|
+
const finalScore = rawScore * scrollQuality;
|
|
466
|
+
|
|
467
|
+
// Limitar entre 0.0 e 5.0
|
|
468
|
+
return Math.max(0.0, Math.min(5.0, finalScore));
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Classificação de Intenção
|
|
473
|
+
*/
|
|
474
|
+
function getIntentionLevel(engagementScore) {
|
|
475
|
+
if (engagementScore < 1.0) return 'curioso'; // ⭐ 1.0
|
|
476
|
+
if (engagementScore < 2.5) return 'interessado'; // ⭐⭐ 2.5
|
|
477
|
+
return 'comprador'; // ⭐⭐⭐ 5.0
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Exemplos de Cálculo
|
|
482
|
+
|
|
483
|
+
| Usuário | Tempo | Scroll | Cliques | Vídeo | Form | Hover CTA | Score | Intenção |
|
|
484
|
+
|---------|-------|--------|---------|--------|------|-----------|-------|----------|
|
|
485
|
+
| **Curioso Rápido** | 5s | 10% | 1 | 0s | ❌ | 0s | 0.1 | Curioso |
|
|
486
|
+
| **Leitor Médio** | 30s | 50% | 2 | 0s | ❌ | 0s | 1.75 | Interessado |
|
|
487
|
+
| **Investigador** | 60s | 75% | 5 | 0s | ❌ | 15s | 2.9 | Interessado |
|
|
488
|
+
| **Comprador Potencial** | 120s | 90% | 8 | 0s | ✅ | 30s | 4.8 | Comprador |
|
|
489
|
+
| **Vídeo Enthusiast** | 180s | 100% | 3 | 120s | ❌ | 5s | 4.2 | Comprador |
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## 🛡️ ANTI-BLOQUEIO (AdBlock Evasion)
|
|
494
|
+
|
|
495
|
+
### Estratégias de Detecção e Evasão
|
|
496
|
+
|
|
497
|
+
#### 1. Detecção de AdBlock (Browser)
|
|
498
|
+
|
|
499
|
+
```javascript
|
|
500
|
+
/**
|
|
501
|
+
* Detecta se AdBlock está ativo
|
|
502
|
+
* Testa múltiplos métodos para alta precisão
|
|
503
|
+
*/
|
|
504
|
+
function detectAdBlock() {
|
|
505
|
+
const tests = [];
|
|
506
|
+
|
|
507
|
+
// Teste 1: Tentar carregar script de anúncio
|
|
508
|
+
const adScript = document.createElement('script');
|
|
509
|
+
adScript.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
|
510
|
+
adScript.onerror = () => tests.push(true);
|
|
511
|
+
adScript.onload = () => tests.push(false);
|
|
512
|
+
document.body.appendChild(adScript);
|
|
513
|
+
|
|
514
|
+
// Teste 2: Verificar display de elementos de anúncio
|
|
515
|
+
const adElement = document.createElement('div');
|
|
516
|
+
adElement.className = 'adsbox ad-banner ad';
|
|
517
|
+
adElement.style.height = '1px';
|
|
518
|
+
document.body.appendChild(adElement);
|
|
519
|
+
|
|
520
|
+
setTimeout(() => {
|
|
521
|
+
if (adElement.offsetHeight === 0) {
|
|
522
|
+
tests.push(true);
|
|
523
|
+
} else {
|
|
524
|
+
tests.push(false);
|
|
525
|
+
}
|
|
526
|
+
document.body.removeChild(adElement);
|
|
527
|
+
}, 100);
|
|
528
|
+
|
|
529
|
+
// Teste 3: Verificar propriedades de window
|
|
530
|
+
if (window.google_ad_width || window.google_ad_height) {
|
|
531
|
+
tests.push(false);
|
|
532
|
+
} else {
|
|
533
|
+
tests.push(true);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Se qualquer teste retornar true = AdBlock ativo
|
|
537
|
+
const isAdBlocked = tests.some(t => t === true);
|
|
538
|
+
|
|
539
|
+
// Reportar ao servidor
|
|
540
|
+
cdpTrack.track('AdBlockStatus', {
|
|
541
|
+
adblock_active: isAdBlocked,
|
|
542
|
+
detection_methods: tests.length,
|
|
543
|
+
timestamp: Date.now()
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
return isAdBlocked;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Rota de Fallback para AdBlock
|
|
551
|
+
* Se AdBlock detectado, usar server-side tracking via HTTP POST
|
|
552
|
+
*/
|
|
553
|
+
function handleAdBlockFallback(eventData) {
|
|
554
|
+
if (detectAdBlock()) {
|
|
555
|
+
// AdBlock ativo: enviar via servidor (não pode usar scripts de terceiros)
|
|
556
|
+
fetch('/api/tracking', {
|
|
557
|
+
method: 'POST',
|
|
558
|
+
headers: { 'Content-Type': 'application/json' },
|
|
559
|
+
body: JSON.stringify({
|
|
560
|
+
...eventData,
|
|
561
|
+
tracking_method: 'server-side-fallback',
|
|
562
|
+
adblock_detected: true
|
|
563
|
+
})
|
|
564
|
+
});
|
|
565
|
+
} else {
|
|
566
|
+
// AdBlock desativado: tracking normal (browser + server)
|
|
567
|
+
cdpTrack.track(eventData.event_name, eventData);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
#### 2. Domínio de Primeira Parte (First-Party Domain)
|
|
573
|
+
|
|
574
|
+
```javascript
|
|
575
|
+
/**
|
|
576
|
+
* Cookie First-Party de 365 dias
|
|
577
|
+
* Não bloqueado por navegadores modernos
|
|
578
|
+
*/
|
|
579
|
+
function getFirstPartyCookie(name) {
|
|
580
|
+
const cookieName = `_pb_${name}`;
|
|
581
|
+
let cookieValue = document.cookie.match(new RegExp(`${cookieName}=([^;]+)`))?.[1];
|
|
582
|
+
|
|
583
|
+
if (!cookieValue) {
|
|
584
|
+
// Gerar novo cookie
|
|
585
|
+
cookieValue = `${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
586
|
+
|
|
587
|
+
// Cookie de 365 dias no domínio principal
|
|
588
|
+
document.cookie = `${cookieName}=${cookieValue}; max-age=${60*60*24*365}; path=/; SameSite=Lax`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
return cookieValue;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* User ID Persistente (Cross-Session)
|
|
596
|
+
*/
|
|
597
|
+
function getPersistentUserId() {
|
|
598
|
+
return getFirstPartyCookie('uid');
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Session ID (Cross-Tab)
|
|
603
|
+
*/
|
|
604
|
+
function getSessionId() {
|
|
605
|
+
const cookieName = '_cdp_sid';
|
|
606
|
+
let sessionId = sessionStorage.getItem(cookieName);
|
|
607
|
+
|
|
608
|
+
if (!sessionId) {
|
|
609
|
+
sessionId = `${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
610
|
+
sessionStorage.setItem(cookieName, sessionId);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return sessionId;
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
#### 3. Protocolo Same-Domain (Endpoint no Próprio Domínio)
|
|
618
|
+
|
|
619
|
+
```javascript
|
|
620
|
+
/**
|
|
621
|
+
* Endpoint de Tracking no Mesmo Domínio
|
|
622
|
+
* URL: https://meusite.com/api/tracking (NÃO third-party)
|
|
623
|
+
*/
|
|
624
|
+
const TRACKING_ENDPOINT = '/api/tracking'; // Same-Domain Protocol
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Enviar evento via servidor (adblock-proof)
|
|
628
|
+
*/
|
|
629
|
+
function sendEventServerSide(eventData) {
|
|
630
|
+
fetch(TRACKING_ENDPOINT, {
|
|
631
|
+
method: 'POST',
|
|
632
|
+
headers: {
|
|
633
|
+
'Content-Type': 'application/json'
|
|
634
|
+
},
|
|
635
|
+
body: JSON.stringify({
|
|
636
|
+
...eventData,
|
|
637
|
+
tracking_method: 'server-side',
|
|
638
|
+
timestamp: Date.now()
|
|
639
|
+
}),
|
|
640
|
+
keepalive: true // Garante envio mesmo se usuário fechar aba
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Deduplicação entre Browser e Server
|
|
646
|
+
* Event ID gerado no browser, enviado no servidor
|
|
647
|
+
*/
|
|
648
|
+
function generateEventId() {
|
|
649
|
+
return `${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
650
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
---
|
|
654
|
+
|
|
655
|
+
## 🚀 ESTRATÉGIA DE IMPLEMENTAÇÃO (Browser + Server)
|
|
656
|
+
|
|
657
|
+
### O que roda no Browser
|
|
658
|
+
|
|
659
|
+
```javascript
|
|
660
|
+
// Browser Tracking - Coleta de eventos e comportamento
|
|
661
|
+
const browserTracking = {
|
|
662
|
+
// 1. Capturar UTMs na chegada
|
|
663
|
+
captureUTMs: () => {
|
|
664
|
+
const utms = {
|
|
665
|
+
utm_source: new URLSearchParams(window.location.search).get('utm_source'),
|
|
666
|
+
utm_medium: new URLSearchParams(window.location.search).get('utm_medium'),
|
|
667
|
+
utm_campaign: new URLSearchParams(window.location.search).get('utm_campaign'),
|
|
668
|
+
utm_content: new URLSearchParams(window.location.search).get('utm_content'),
|
|
669
|
+
utm_term: new URLSearchParams(window.location.search).get('utm_term')
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
// Salvar no localStorage para uso posterior
|
|
673
|
+
localStorage.setItem('cdp_utms', JSON.stringify(utms));
|
|
674
|
+
|
|
675
|
+
return utms;
|
|
676
|
+
},
|
|
677
|
+
|
|
678
|
+
// 2. Capturar Click IDs das plataformas
|
|
679
|
+
captureClickIDs: () => {
|
|
680
|
+
const params = new URLSearchParams(window.location.search);
|
|
681
|
+
|
|
682
|
+
return {
|
|
683
|
+
fbp: document.cookie.match(/_fbp=([^;]+)/)?.[1],
|
|
684
|
+
fbc: document.cookie.match(/_fbc=([^;]+)/)?.[1],
|
|
685
|
+
gclid: params.get('gclid'),
|
|
686
|
+
gbraid: params.get('gbraid'),
|
|
687
|
+
wbraid: params.get('wbraid'),
|
|
688
|
+
ttclid: params.get('ttclid'),
|
|
689
|
+
rclid: params.get('rclid')
|
|
690
|
+
};
|
|
691
|
+
},
|
|
692
|
+
|
|
693
|
+
// 3. Capturar eventos de micro-engagement
|
|
694
|
+
trackMicroEngagement: (eventData) => {
|
|
695
|
+
const enrichedData = {
|
|
696
|
+
...eventData,
|
|
697
|
+
...browserTracking.captureUTMs(),
|
|
698
|
+
...browserTracking.captureClickIDs(),
|
|
699
|
+
user_id: getPersistentUserId(),
|
|
700
|
+
session_id: getSessionId(),
|
|
701
|
+
event_id: generateEventId(),
|
|
702
|
+
timestamp: Date.now(),
|
|
703
|
+
page_url: window.location.href,
|
|
704
|
+
referrer: document.referrer,
|
|
705
|
+
user_agent: navigator.userAgent
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
// Enviar para servidor (same-domain, adblock-proof)
|
|
709
|
+
sendEventServerSide(enrichedData);
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
### O que roda no Servidor (Cloudflare Worker)
|
|
715
|
+
|
|
716
|
+
```javascript
|
|
717
|
+
// Server Tracking - Processamento e despacho para plataformas
|
|
718
|
+
const serverTracking = {
|
|
719
|
+
// 1. Receber evento do browser
|
|
720
|
+
handleEvent: async (eventData, env, ctx) => {
|
|
721
|
+
const {
|
|
722
|
+
event_id,
|
|
723
|
+
event_name,
|
|
724
|
+
user_id,
|
|
725
|
+
session_id,
|
|
726
|
+
utms,
|
|
727
|
+
clickIDs,
|
|
728
|
+
page_url,
|
|
729
|
+
user_agent,
|
|
730
|
+
...customData
|
|
731
|
+
} = eventData;
|
|
732
|
+
|
|
733
|
+
// 2. Capturar IP e Geolocalização (Cloudflare)
|
|
734
|
+
const clientIP = request.headers.get('CF-Connecting-IP');
|
|
735
|
+
const geo = request.cf || {};
|
|
736
|
+
|
|
737
|
+
// 3. Recuperar PII do D1 (Lead Lock)
|
|
738
|
+
const pii = await getPIIFromD1(env.DB, user_id);
|
|
739
|
+
|
|
740
|
+
// 4. Calcular Engagement Score
|
|
741
|
+
const engagementScore = calculateEngagementScore(customData);
|
|
742
|
+
const intentionLevel = getIntentionLevel(engagementScore);
|
|
743
|
+
|
|
744
|
+
// 5. Hashing de PII (SHA256 WebCrypto)
|
|
745
|
+
const hashedPII = {
|
|
746
|
+
email: await sha256(pii.email),
|
|
747
|
+
phone: await sha256(pii.phone),
|
|
748
|
+
name: await sha256(pii.name),
|
|
749
|
+
city: await sha256(geo.city),
|
|
750
|
+
state: await sha256(geo.region),
|
|
751
|
+
zip: await sha256(pii.zip)
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
// 6. Despachar para plataformas em paralelo (ctx.waitUntil)
|
|
755
|
+
ctx.waitUntil(Promise.allSettled([
|
|
756
|
+
dispatchToMeta(event_name, hashedPII, clickIDs, clientIP, user_agent, customData, env),
|
|
757
|
+
dispatchToGoogle(event_name, hashedPII, clickIDs, clientIP, user_agent, customData, env),
|
|
758
|
+
dispatchToTikTok(event_name, hashedPII, clickIDs, clientIP, user_agent, customData, env)
|
|
759
|
+
]));
|
|
760
|
+
|
|
761
|
+
// 7. Persistir no D1 (Identity Graph)
|
|
762
|
+
await persistToD1(env.DB, {
|
|
763
|
+
user_id,
|
|
764
|
+
session_id,
|
|
765
|
+
event_id,
|
|
766
|
+
event_name,
|
|
767
|
+
utms,
|
|
768
|
+
clickIDs,
|
|
769
|
+
engagement_score: engagementScore,
|
|
770
|
+
intention_level: intentionLevel,
|
|
771
|
+
geo: {
|
|
772
|
+
ip: clientIP,
|
|
773
|
+
city: geo.city,
|
|
774
|
+
state: geo.region,
|
|
775
|
+
country: geo.country
|
|
776
|
+
},
|
|
777
|
+
pii: hashedPII,
|
|
778
|
+
timestamp: Date.now()
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
return { success: true, score: engagementScore };
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
---
|
|
787
|
+
|
|
788
|
+
## 📋 CHECKLIST DE IMPLEMENTAÇÃO (Browser + Server)
|
|
789
|
+
|
|
790
|
+
### Browser Tracking (O que capturar no navegador)
|
|
791
|
+
|
|
792
|
+
- [x] UTMs na chegada (utm_source, utm_medium, utm_campaign, utm_content, utm_term)
|
|
793
|
+
- [x] Click IDs das plataformas (fbp, fbc, gclid, ttclid, etc.)
|
|
794
|
+
- [x] User ID persistente (first-party cookie, 365 dias)
|
|
795
|
+
- [x] Session ID (cross-tab)
|
|
796
|
+
- [x] Scroll tracking (25%, 50%, 75%, 100%)
|
|
797
|
+
- [x] Time on page tracking (curioso < 10s, interessado 10-60s, comprador > 60s)
|
|
798
|
+
- [x] Click heatmap (posição X/Y, categoria do clique)
|
|
799
|
+
- [x] Video engagement (play, progress 25/50/75/100%, pause, resume, seek)
|
|
800
|
+
- [x] Rapid clicks (3+ cliques em 1 segundo = usuário nervoso)
|
|
801
|
+
- [x] CTA hover time (tempo em hover no botão de compra)
|
|
802
|
+
- [x] Form start detection (iniciou preenchimento do formulário)
|
|
803
|
+
- [x] AdBlock detection (testar múltiplos métodos)
|
|
804
|
+
|
|
805
|
+
### Server Tracking (O que processar no Worker)
|
|
806
|
+
|
|
807
|
+
- [x] Receber eventos do browser (POST /api/tracking)
|
|
808
|
+
- [x] Capturar IP e geolocalização (Cloudflare headers)
|
|
809
|
+
- [x] Recuperar PII do D1 (Lead Lock)
|
|
810
|
+
- [x] Calcular Engagement Score (0.0 - 5.0)
|
|
811
|
+
- [x] Classificar intenção (curioso, interessado, comprador)
|
|
812
|
+
- [x] Hashing de PII (SHA256: email, phone, name, city, state, zip)
|
|
813
|
+
- [x] Despachar para Meta CAPI v22.0 (event_id, user_data, custom_data)
|
|
814
|
+
- [x] Despachar para Google GA4 MP (event_name, user_properties)
|
|
815
|
+
- [x] Despachar para TikTok Events API v1.3 (event, context, properties)
|
|
816
|
+
- [x] Persistir no D1 (Identity Graph + events_log)
|
|
817
|
+
- [x] Fila de retry (Cloudflare Queue, 3-tier: 5min, 15min, 45min)
|
|
818
|
+
- [x] Log de sucesso/falha (status: success, retrying, failed)
|
|
819
|
+
|
|
820
|
+
---
|
|
821
|
+
|
|
822
|
+
## 🎯 RESULTADO FINAL
|
|
823
|
+
|
|
824
|
+
O CDP Edge com **Premium Tracking Intelligence** entregará:
|
|
825
|
+
|
|
826
|
+
1. **Event Match Quality de 95%+** (via Advanced Matching Máximo: email, phone, city, state)
|
|
827
|
+
2. **Signal Strength de 5.0** (via Behavioral Intelligence: scroll, time, vídeo, formulário)
|
|
828
|
+
3. **Redução de 30-50% no CPL** (via eventos prioritados de alta intenção)
|
|
829
|
+
4. **100% AdBlock-Proof** (via same-domain protocol + server-side tracking)
|
|
830
|
+
5. **Cross-Device Attribution** (via Identity Graph + fbp/fbc match)
|
|
831
|
+
6. **Real-Time Engagement Scoring** (via score de 0.0 - 5.0 calculado no servidor)
|
|
832
|
+
|
|
833
|
+
---
|
|
834
|
+
|
|
835
|
+
## 📊 MÉTRICAS DE SUCESSO
|
|
836
|
+
|
|
837
|
+
| Métrica | Meta | Google | TikTok | Status |
|
|
838
|
+
|---------|------|--------|--------|--------|
|
|
839
|
+
| Event Match Quality (EMQ) | 95%+ | 95%+ | 95%+ | 🔴 Crítico |
|
|
840
|
+
| Signal Strength Score | 4.0+ | 4.0+ | 4.0+ | 🔴 Crítico |
|
|
841
|
+
| CPL (Cost Per Lead) | -30% | -30% | -30% | 🟠 Objetivo |
|
|
842
|
+
| CTR (Click-Through Rate) | +20% | +20% | +20% | 🟡 Bônus |
|
|
843
|
+
| Conversion Rate | +25% | +25% | +25% | 🟡 Bônus |
|
|
844
|
+
| AdBlock Detection | 100% | 100% | 100% | 🟢 Básico |
|
|
845
|
+
| Cross-Device Match | 90%+ | 90%+ | 90%+ | 🟠 Alto |
|
|
846
|
+
|
|
847
|
+
---
|
|
848
|
+
|
|
849
|
+
*Premium Tracking Intelligence Agent v1.0.0 - CDP Edge Quantum Tier*
|