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
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
# Modelo: Tráfego Direto (Cloudflare Native)
|
|
2
|
+
> Infoproduto / Lançamento sem formulário de lead na página — usuário clica direto no botão e vai para checkout externo.
|
|
3
|
+
> Plataformas: GA4 · Google Ads · Meta (Facebook) Ads · TikTok Ads
|
|
4
|
+
> Infraestrutura: **Cloudflare Workers + D1** (100% Native)
|
|
5
|
+
|
|
6
|
+
**Quando usar este modelo:**
|
|
7
|
+
- Página de vendas / VSL sem formulário (sem captura de email/telefone na própria página)
|
|
8
|
+
- Compra realizada em plataforma externa (Hotmart, Kiwify, Kirvano, Eduzz, etc.) que envia webhook
|
|
9
|
+
- Fluxo: Visitante chega → `track_user_id` gerado → dados de sessão salvos no D1 → clica no botão → vai para checkout com `user_id` na URL → webhook de compra chega com o `user_id` → D1 recupera fbp/fbc/ttp/geo
|
|
10
|
+
|
|
11
|
+
**Diferença dos outros modelos:**
|
|
12
|
+
- **Nenhum dado de usuário (email/telefone) é capturado na página** — usa `track_user_id` anônimo
|
|
13
|
+
- Prefixo `cdp_uid` para o identificador gerado no primeiro acesso
|
|
14
|
+
- Tags de PageView e InitiateCheckout são enviadas via Fetch para o Worker (não pixels diretos)
|
|
15
|
+
- URL modificada ao clicar no botão de compra: passa `track_user_id` como parâmetro
|
|
16
|
+
- **D1** faz lookup pelo `user_id` (não por email)
|
|
17
|
+
- **Sem Google Ads Offline Conversion** (requer email capturado antes da compra)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ Browser: Página de Vendas / VSL │
|
|
26
|
+
│
|
|
27
|
+
│ 1. cdpTrack.generateId() → gera cdp_uid │
|
|
28
|
+
│ 2. cdpTrack.track('PageView', {...}) → Worker │
|
|
29
|
+
│ 3. Botão Clique → inject cdp_uid na URL │
|
|
30
|
+
│ 4. cdpTrack.track('InitiateCheckout', {...}) → Worker │
|
|
31
|
+
└─────────────────────────────────────────────────────────────┘
|
|
32
|
+
│
|
|
33
|
+
▼
|
|
34
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
35
|
+
│ Cloudflare Worker (Quantum Tier) │
|
|
36
|
+
│
|
|
37
|
+
│ Endpoint: /api/tracking (Same-Domain) │
|
|
38
|
+
│ - Recebe eventos do browser │
|
|
39
|
+
│ - Salva sessão no D1 (fbp, fbc, ttp, UTMs) │
|
|
40
|
+
│ - Despacha para APIs: Meta, GA4, TikTok │
|
|
41
|
+
│
|
|
42
|
+
│ Endpoint: /api/wh/{plataforma} │
|
|
43
|
+
│ - Recebe webhooks de compra (Hotmart, Kiwify...) │
|
|
44
|
+
│ - D1 lookup pelo user_id │
|
|
45
|
+
│ - Envia Purchase CAPI/MP v1.3 │
|
|
46
|
+
└─────────────────────────────────────────────────────────────┘
|
|
47
|
+
│
|
|
48
|
+
▼
|
|
49
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
50
|
+
│ Cloudflare D1 (SQLite) │
|
|
51
|
+
│
|
|
52
|
+
│ Tabela: identity_graph │
|
|
53
|
+
│ - cdp_uid (primary key) │
|
|
54
|
+
│ - fbp, fbc, ttp (cookies) │
|
|
55
|
+
│ - utm_source, utm_medium, utm_campaign │
|
|
56
|
+
│ - ip, user_agent │
|
|
57
|
+
│ - first_seen, last_seen │
|
|
58
|
+
└─────────────────────────────────────────────────────────────┘
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 📘 EVENTOS PRINCIPAIS
|
|
64
|
+
|
|
65
|
+
| Evento | Gatilho | Dados Enviados |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| **PageView** | Carregamento da página | IP, User-Agent, URL, Cookies (fbp, fbc, ttp) |
|
|
68
|
+
| **InitiateCheckout** | Clique no botão de compra (link externo) | `cdp_uid`, `checkout_url`, `utm` (se disponível) |
|
|
69
|
+
| **Purchase** | Webhook da plataforma (via Worker) | `transaction_id`, `value`, `currency`, `cdp_uid`, D1 lookup data |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
74
|
+
|
|
75
|
+
### 1.1 SDK de Rastreamento (Header)
|
|
76
|
+
```html
|
|
77
|
+
<!-- Inserir no <head> -->
|
|
78
|
+
<script src="/js/cdpTrack.js" async></script>
|
|
79
|
+
<script>
|
|
80
|
+
window.cdpConfig = {
|
|
81
|
+
workerUrl: '/api/tracking', // Same-Domain (furtivo)
|
|
82
|
+
metaId: 'SEU_PIXEL_ID',
|
|
83
|
+
ga4Id: 'G-XXXXXXXX',
|
|
84
|
+
tiktokId: 'C4XXXXXXXXXXXXXXX',
|
|
85
|
+
};
|
|
86
|
+
</script>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 1.2 Geração de cdp_uid (First Access)
|
|
90
|
+
```javascript
|
|
91
|
+
// Inserir no início do <body> (primeiro script)
|
|
92
|
+
<script>
|
|
93
|
+
(function() {
|
|
94
|
+
// Gera cdp_uid se não existir (1 ano de expiração)
|
|
95
|
+
const existing = document.cookie.match(/cdp_uid=([^;]+)/);
|
|
96
|
+
if (!existing) {
|
|
97
|
+
const uid = 'usr_' + Math.random().toString(36).substring(2, 10) + Date.now();
|
|
98
|
+
const expiry = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toUTCString();
|
|
99
|
+
document.cookie = `cdp_uid=${encodeURIComponent(uid)}; expires=${expiry}; path=/; SameSite=Lax`;
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
</script>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 1.3 PageView (Carregamento da Página)
|
|
106
|
+
```javascript
|
|
107
|
+
// Após carregamento inicial
|
|
108
|
+
<script>
|
|
109
|
+
window.addEventListener('DOMContentLoaded', async () => {
|
|
110
|
+
const cdp_uid = document.cookie.match(/cdp_uid=([^;]+)/)?.[1] || '';
|
|
111
|
+
|
|
112
|
+
await cdpTrack.track('PageView', {
|
|
113
|
+
cdp_uid,
|
|
114
|
+
page_url: window.location.href,
|
|
115
|
+
page_title: document.title
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
</script>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 1.4 InitiateCheckout + Injeção de cdp_uid
|
|
122
|
+
```javascript
|
|
123
|
+
// Captura cliques em botões de checkout externo
|
|
124
|
+
<script>
|
|
125
|
+
document.addEventListener('click', async (e) => {
|
|
126
|
+
const link = e.target.closest('a[href]');
|
|
127
|
+
if (!link) return;
|
|
128
|
+
|
|
129
|
+
const href = link.href.toLowerCase();
|
|
130
|
+
const platforms = ['hotmart.com', 'kiwify.com', 'kirvano.com', 'eduzz.com'];
|
|
131
|
+
const isCheckout = platforms.some(p => href.includes(p));
|
|
132
|
+
|
|
133
|
+
if (isCheckout) {
|
|
134
|
+
e.preventDefault(); // Previne redirecionamento imediato
|
|
135
|
+
|
|
136
|
+
const cdp_uid = document.cookie.match(/cdp_uid=([^;]+)/)?.[1] || '';
|
|
137
|
+
|
|
138
|
+
// Dispara InitiateCheckout
|
|
139
|
+
await cdpTrack.track('InitiateCheckout', {
|
|
140
|
+
cdp_uid,
|
|
141
|
+
checkout_platform: platforms.find(p => href.includes(p)),
|
|
142
|
+
original_url: href
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Injeta cdp_uid na URL (xcod/sck/src conforme plataforma)
|
|
146
|
+
const url = new URL(href);
|
|
147
|
+
|
|
148
|
+
if (href.includes('hotmart.com')) {
|
|
149
|
+
url.searchParams.set('xcod', cdp_uid);
|
|
150
|
+
} else if (href.includes('kiwify.com')) {
|
|
151
|
+
url.searchParams.set('sck', cdp_uid);
|
|
152
|
+
} else if (href.includes('kirvano.com')) {
|
|
153
|
+
url.searchParams.set('src', cdp_uid);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Redireciona para o checkout
|
|
157
|
+
window.location.href = url.toString();
|
|
158
|
+
}
|
|
159
|
+
}, { capture: true });
|
|
160
|
+
</script>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## ⚡ PASSO 2: SERVIDOR (CLOUDFLARE WORKER)
|
|
166
|
+
|
|
167
|
+
### 2.1 Handler Principal (Same-Domain)
|
|
168
|
+
```javascript
|
|
169
|
+
// worker.js
|
|
170
|
+
|
|
171
|
+
export default {
|
|
172
|
+
async fetch(request, env, ctx) {
|
|
173
|
+
const url = new URL(request.url);
|
|
174
|
+
const cors = {
|
|
175
|
+
'Access-Control-Allow-Origin': '*',
|
|
176
|
+
'Access-Control-Allow-Methods': 'POST, OPTIONS',
|
|
177
|
+
'Access-Control-Allow-Headers': 'Content-Type',
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
if (request.method === 'OPTIONS') {
|
|
181
|
+
return new Response(null, { headers: cors });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Endpoint principal de tracking
|
|
185
|
+
if (url.pathname === '/api/tracking') {
|
|
186
|
+
return handleTracking(request, env, ctx);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Endpoint de webhooks de plataformas
|
|
190
|
+
if (url.pathname.startsWith('/api/wh/')) {
|
|
191
|
+
return handleWebhook(request, env, url);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return new Response('Not Found', { status: 404 });
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
async function handleTracking(request, env, ctx) {
|
|
199
|
+
const body = await request.json();
|
|
200
|
+
const cf = request.cf || {};
|
|
201
|
+
const ip = cf.colo === 'XX' ? '8.8.8.8' : request.headers.get('CF-Connecting-IP');
|
|
202
|
+
|
|
203
|
+
// Captura cookies do request
|
|
204
|
+
const fbp = request.headers.get('Cookie')?.match(/_fbp=([^;]+)/)?.[1];
|
|
205
|
+
const fbc = request.headers.get('Cookie')?.match(/_fbc=([^;]+)/)?.[1];
|
|
206
|
+
const ttp = request.headers.get('Cookie')?.match(/_ttp=([^;]+)/)?.[1];
|
|
207
|
+
|
|
208
|
+
const sessionData = {
|
|
209
|
+
cdp_uid: body.cdp_uid,
|
|
210
|
+
fbp,
|
|
211
|
+
fbc,
|
|
212
|
+
ttp,
|
|
213
|
+
ip,
|
|
214
|
+
user_agent: request.headers.get('User-Agent'),
|
|
215
|
+
utm_source: getUtm('utm_source'),
|
|
216
|
+
utm_medium: getUtm('utm_medium'),
|
|
217
|
+
utm_campaign: getUtm('utm_campaign'),
|
|
218
|
+
utm_content: getUtm('utm_content'),
|
|
219
|
+
utm_term: getUtm('utm_term'),
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// Salva/Atualiza no D1
|
|
223
|
+
await saveSession(env.DB, sessionData);
|
|
224
|
+
|
|
225
|
+
// Dispatch não-bloqueante para APIs
|
|
226
|
+
ctx.waitUntil(dispatchEvents(body, sessionData, env));
|
|
227
|
+
|
|
228
|
+
return new Response(JSON.stringify({ success: true }), {
|
|
229
|
+
headers: { ...cors, 'Content-Type': 'application/json' }
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function saveSession(DB, data) {
|
|
234
|
+
await DB.prepare(`
|
|
235
|
+
INSERT INTO identity_graph (cdp_uid, fbp, fbc, ttp, ip, user_agent,
|
|
236
|
+
utm_source, utm_medium, utm_campaign, utm_content, utm_term, last_seen)
|
|
237
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
238
|
+
ON CONFLICT(cdp_uid) DO UPDATE SET
|
|
239
|
+
fbp = excluded.fbp,
|
|
240
|
+
fbc = excluded.fbc,
|
|
241
|
+
ttp = excluded.ttp,
|
|
242
|
+
ip = excluded.ip,
|
|
243
|
+
last_seen = datetime('now')
|
|
244
|
+
`).bind(
|
|
245
|
+
data.cdp_uid, data.fbp, data.fbc, data.ttp, data.ip, data.user_agent,
|
|
246
|
+
data.utm_source, data.utm_medium, data.utm_campaign, data.utm_content, data.utm_term
|
|
247
|
+
).run();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async function dispatchEvents(eventBody, sessionData, env) {
|
|
251
|
+
const { event_name } = eventBody;
|
|
252
|
+
|
|
253
|
+
if (event_name === 'PageView') {
|
|
254
|
+
await Promise.all([
|
|
255
|
+
dispatchMeta(event_name, sessionData, env, {}),
|
|
256
|
+
dispatchGA4('page_view', sessionData, env, {}),
|
|
257
|
+
dispatchTikTok('PageView', sessionData, env, {}),
|
|
258
|
+
]);
|
|
259
|
+
} else if (event_name === 'InitiateCheckout') {
|
|
260
|
+
await Promise.all([
|
|
261
|
+
dispatchMeta('InitiateCheckout', sessionData, env, {
|
|
262
|
+
content_name: eventBody.checkout_platform
|
|
263
|
+
}),
|
|
264
|
+
dispatchGA4('begin_checkout', sessionData, env, {}),
|
|
265
|
+
dispatchTikTok('InitiateCheckout', sessionData, env, {}),
|
|
266
|
+
]);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### 2.2 Webhook Handler (Hotmart, Kiwify, Kirvano)
|
|
272
|
+
```javascript
|
|
273
|
+
async function handleWebhook(request, env, url) {
|
|
274
|
+
const body = await request.json();
|
|
275
|
+
|
|
276
|
+
// Extrai cdp_uid conforme plataforma
|
|
277
|
+
let cdp_uid;
|
|
278
|
+
|
|
279
|
+
if (url.pathname.includes('hotmart')) {
|
|
280
|
+
cdp_uid = body.data?.purchase?.order_bump_parent_purchase || body.xcod;
|
|
281
|
+
} else if (url.pathname.includes('kiwify')) {
|
|
282
|
+
cdp_uid = body.order_ref || body.sck;
|
|
283
|
+
} else if (url.pathname.includes('kirvano')) {
|
|
284
|
+
cdp_uid = body.src;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!cdp_uid) {
|
|
288
|
+
console.error('cdp_uid not found in webhook');
|
|
289
|
+
return new Response('Missing cdp_uid', { status: 400 });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// D1 Lookup: recupera dados da sessão original
|
|
293
|
+
const session = await env.DB.prepare(
|
|
294
|
+
'SELECT * FROM identity_graph WHERE cdp_uid = ?'
|
|
295
|
+
).bind(cdp_uid).first();
|
|
296
|
+
|
|
297
|
+
if (!session) {
|
|
298
|
+
console.error('Session not found in D1');
|
|
299
|
+
return new Response('Session not found', { status: 404 });
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const purchaseData = {
|
|
303
|
+
transaction_id: body.data?.purchase?.transaction || body.transaction_id,
|
|
304
|
+
value: body.data?.purchase?.price?.value || body.value,
|
|
305
|
+
currency: body.data?.purchase?.price?.currency_value || body.currency,
|
|
306
|
+
email: body.data?.buyer?.email || body.email,
|
|
307
|
+
phone: body.data?.buyer?.checkout_phone || body.phone,
|
|
308
|
+
...session // D1 data (fbp, fbc, ttp, UTMs, IP)
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// Dispatch Purchase para APIs
|
|
312
|
+
await Promise.all([
|
|
313
|
+
dispatchMeta('Purchase', purchaseData, env, {}),
|
|
314
|
+
dispatchGA4('purchase', purchaseData, env, {
|
|
315
|
+
transaction_id: purchaseData.transaction_id,
|
|
316
|
+
value: purchaseData.value,
|
|
317
|
+
currency: purchaseData.currency
|
|
318
|
+
}),
|
|
319
|
+
dispatchTikTok('CompletePayment', purchaseData, env, {}),
|
|
320
|
+
]);
|
|
321
|
+
|
|
322
|
+
return new Response('OK', { status: 200 });
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 2.3 Meta CAPI v22.0
|
|
327
|
+
```javascript
|
|
328
|
+
async function dispatchMeta(eventName, data, env, customData = {}) {
|
|
329
|
+
if (!env.META_ACCESS_TOKEN || !env.META_PIXEL_ID) return;
|
|
330
|
+
|
|
331
|
+
const emailHash = data.email ? await sha256(data.email.toLowerCase().trim()) : null;
|
|
332
|
+
const phoneHash = data.phone ? await sha256('55' + data.phone.replace(/\D/g, '')) : null;
|
|
333
|
+
|
|
334
|
+
const payload = {
|
|
335
|
+
data: [{
|
|
336
|
+
event_name: eventName,
|
|
337
|
+
event_time: Math.floor(Date.now() / 1000),
|
|
338
|
+
event_id: data.transaction_id || crypto.randomUUID(),
|
|
339
|
+
event_source_url: data.page_url || '',
|
|
340
|
+
action_source: 'website',
|
|
341
|
+
user_data: {
|
|
342
|
+
em: emailHash ? [emailHash] : undefined,
|
|
343
|
+
ph: phoneHash ? [phoneHash] : undefined,
|
|
344
|
+
fbp: data.fbp,
|
|
345
|
+
fbc: data.fbc,
|
|
346
|
+
client_ip_address: data.ip,
|
|
347
|
+
client_user_agent: data.user_agent,
|
|
348
|
+
external_id: data.cdp_uid ? [await sha256(data.cdp_uid)] : undefined,
|
|
349
|
+
},
|
|
350
|
+
custom_data: {
|
|
351
|
+
value: data.value || 0,
|
|
352
|
+
currency: data.currency || 'BRL',
|
|
353
|
+
...customData
|
|
354
|
+
}
|
|
355
|
+
}]
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
const res = await fetch(
|
|
359
|
+
`https://graph.facebook.com/v22.0/${env.META_PIXEL_ID}/events?access_token=${env.META_ACCESS_TOKEN}`,
|
|
360
|
+
{
|
|
361
|
+
method: 'POST',
|
|
362
|
+
headers: { 'Content-Type': 'application/json' },
|
|
363
|
+
body: JSON.stringify(payload)
|
|
364
|
+
}
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
if (!res.ok) {
|
|
368
|
+
console.error('Meta CAPI Error:', await res.text());
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### 2.4 GA4 Measurement Protocol
|
|
374
|
+
```javascript
|
|
375
|
+
async function dispatchGA4(eventName, data, env, eventData = {}) {
|
|
376
|
+
if (!env.GA4_ID || !env.GA4_API_SECRET) return;
|
|
377
|
+
|
|
378
|
+
const payload = {
|
|
379
|
+
client_id: data.cdp_uid, // Usa cdp_uid como client_id
|
|
380
|
+
user_id: data.cdp_uid,
|
|
381
|
+
events: [{
|
|
382
|
+
name: eventName,
|
|
383
|
+
params: {
|
|
384
|
+
page_location: data.page_url || '',
|
|
385
|
+
page_title: data.page_title || '',
|
|
386
|
+
...eventData
|
|
387
|
+
}
|
|
388
|
+
}]
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
const res = await fetch(
|
|
392
|
+
`https://www.google-analytics.com/mp/collect?measurement_id=${env.GA4_ID}&api_secret=${env.GA4_API_SECRET}`,
|
|
393
|
+
{
|
|
394
|
+
method: 'POST',
|
|
395
|
+
headers: { 'Content-Type': 'application/json' },
|
|
396
|
+
body: JSON.stringify(payload)
|
|
397
|
+
}
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
if (!res.ok) {
|
|
401
|
+
console.error('GA4 Error:', await res.text());
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### 2.5 TikTok Events API v1.3
|
|
407
|
+
```javascript
|
|
408
|
+
async function dispatchTikTok(eventName, data, env, eventData = {}) {
|
|
409
|
+
if (!env.TIKTOK_PIXEL_ID || !env.TIKTOK_ACCESS_TOKEN) return;
|
|
410
|
+
|
|
411
|
+
const payload = {
|
|
412
|
+
pixel_code: env.TIKTOK_PIXEL_ID,
|
|
413
|
+
event: eventName,
|
|
414
|
+
event_id: data.transaction_id || crypto.randomUUID(),
|
|
415
|
+
timestamp: new Date().toISOString(),
|
|
416
|
+
context: {
|
|
417
|
+
ad: {
|
|
418
|
+
callback: data.ttp
|
|
419
|
+
},
|
|
420
|
+
page: {
|
|
421
|
+
url: data.page_url || '',
|
|
422
|
+
referrer: document.referrer || ''
|
|
423
|
+
},
|
|
424
|
+
user: {
|
|
425
|
+
ip_address: data.ip,
|
|
426
|
+
user_agent: data.user_agent,
|
|
427
|
+
external_id: data.cdp_uid
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
properties: {
|
|
431
|
+
value: data.value || 0,
|
|
432
|
+
currency: data.currency || 'BRL',
|
|
433
|
+
...eventData
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
const res = await fetch(
|
|
438
|
+
'https://business-api.tiktok.com/open_api/v1.3/event/track/',
|
|
439
|
+
{
|
|
440
|
+
method: 'POST',
|
|
441
|
+
headers: {
|
|
442
|
+
'Content-Type': 'application/json',
|
|
443
|
+
'Access-Token': env.TIKTOK_ACCESS_TOKEN
|
|
444
|
+
},
|
|
445
|
+
body: JSON.stringify(payload)
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
if (!res.ok) {
|
|
450
|
+
console.error('TikTok Error:', await res.text());
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### 2.6 Helpers
|
|
456
|
+
```javascript
|
|
457
|
+
async function sha256(value) {
|
|
458
|
+
if (!value) return null;
|
|
459
|
+
const encoder = new TextEncoder();
|
|
460
|
+
const data = encoder.encode(value);
|
|
461
|
+
const hash = await crypto.subtle.digest('SHA-256', data);
|
|
462
|
+
return Array.from(new Uint8Array(hash)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function getUtm(param) {
|
|
466
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
467
|
+
return urlParams.get(param) || '';
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## 📊 PASSO 3: SCHEMA D1
|
|
474
|
+
|
|
475
|
+
```sql
|
|
476
|
+
-- Tabela principal (já definida no Server Agent)
|
|
477
|
+
CREATE TABLE IF NOT EXISTS identity_graph (
|
|
478
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
479
|
+
cdp_uid TEXT UNIQUE NOT NULL,
|
|
480
|
+
fbp TEXT,
|
|
481
|
+
fbc TEXT,
|
|
482
|
+
ttp TEXT,
|
|
483
|
+
ga_client_id TEXT,
|
|
484
|
+
external_id TEXT,
|
|
485
|
+
first_utm TEXT,
|
|
486
|
+
heat_score_avg INTEGER DEFAULT 0,
|
|
487
|
+
visit_count INTEGER DEFAULT 1,
|
|
488
|
+
last_seen TEXT DEFAULT (datetime('now')),
|
|
489
|
+
created_at TEXT DEFAULT (datetime('now'))
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
CREATE INDEX IF NOT EXISTS idx_cdp_uid ON identity_graph(cdp_uid);
|
|
493
|
+
CREATE INDEX IF NOT EXISTS idx_fbp ON identity_graph(fbp);
|
|
494
|
+
CREATE INDEX IF NOT EXISTS idx_fbc ON identity_graph(fbc);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## ✅ CHECKLIST DE VERIFICAÇÃO
|
|
500
|
+
|
|
501
|
+
### Browser
|
|
502
|
+
- [ ] cdp_uid gerado no primeiro acesso e persistido por 1 ano
|
|
503
|
+
- [ ] PageView disparado via Fetch para `/api/tracking`
|
|
504
|
+
- [ ] InitiateCheckout disparado antes do redirecionamento
|
|
505
|
+
- [ ] cdp_uid injetado na URL do checkout (xcod/sck/src)
|
|
506
|
+
- [ ] UTMs capturados e salvos no D1
|
|
507
|
+
|
|
508
|
+
### Cloudflare Worker
|
|
509
|
+
- [ ] Endpoint `/api/tracking` configurado como Route no Cloudflare
|
|
510
|
+
- [ ] Endpoint `/api/wh/{plataforma}` para webhooks
|
|
511
|
+
- [ ] Salvar sessão no D1 com todos os cookies
|
|
512
|
+
- [ ] D1 lookup pelo cdp_uid ao receber webhook
|
|
513
|
+
- [ ] Meta CAPI v22.0 endpoint correto
|
|
514
|
+
- [ ] TikTok Events API v1.3 endpoint correto
|
|
515
|
+
- [ ] GA4 Measurement Protocol configurado
|
|
516
|
+
|
|
517
|
+
### Plataformas Externas
|
|
518
|
+
- [ ] Hotmart webhook configurado para `/api/wh/hotmart`
|
|
519
|
+
- [ ] Kiwify webhook configurado para `/api/wh/kiwify`
|
|
520
|
+
- [ ] Kirvano webhook configurado para `/api/wh/kirvano`
|
|
521
|
+
- [ ] cdp_uid sendo recebido no webhook (xcod/sck/src)
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## 🔄 FLUXO COMPLETO
|
|
526
|
+
|
|
527
|
+
```
|
|
528
|
+
1. Visitante acessa a página de vendas
|
|
529
|
+
└── JS: gera cdp_uid → salva cookie (1 ano)
|
|
530
|
+
└── JS: dispara PageView → /api/tracking
|
|
531
|
+
└── Worker: salva sessão no D1 (fbp, fbc, ttp, UTMs, IP)
|
|
532
|
+
└── Worker: dispatch → Meta, GA4, TikTok (PageView)
|
|
533
|
+
|
|
534
|
+
2. Visitante clica no botão de compra
|
|
535
|
+
└── JS: intercepta clique → previne redirecionamento
|
|
536
|
+
└── JS: dispara InitiateCheckout → /api/tracking
|
|
537
|
+
└── Worker: atualiza sessão no D1
|
|
538
|
+
└── Worker: dispatch → Meta, GA4, TikTok (InitiateCheckout)
|
|
539
|
+
└── JS: injeta cdp_uid na URL (xcod/sck/src)
|
|
540
|
+
└── JS: redireciona para checkout externo
|
|
541
|
+
|
|
542
|
+
3. Usuário compra na plataforma externa (Hotmart/Kiwify/Kirvano)
|
|
543
|
+
└── Plataforma envia webhook → /api/wh/{plataforma}
|
|
544
|
+
└── Worker: extrai cdp_uid do webhook (xcod/sck/src)
|
|
545
|
+
└── Worker: D1 lookup → recupera fbp, fbc, ttp, UTMs, IP
|
|
546
|
+
└── Worker: dispatch → Meta Purchase CAPI (v22.0)
|
|
547
|
+
└── Worker: dispatch → GA4 Purchase (MP)
|
|
548
|
+
└── Worker: dispatch → TikTok CompletePayment (v1.3)
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## ⚠️ NOTAS IMPORTANTES
|
|
554
|
+
|
|
555
|
+
- **Mesmo-Domain Protocol**: O Worker DEVE roda no mesmo domínio do site para evitar CORS e bloqueios
|
|
556
|
+
- **Deduplicação**: O `event_id` deve ser único para cada evento (usar `crypto.randomUUID()` ou similar)
|
|
557
|
+
- **Hashing**: SHA256 deve ser feito no Worker usando `crypto.subtle.digest` (WebCrypto API)
|
|
558
|
+
- **Privacidade**: Nunca logar email/telefone em texto claro no console do Worker
|
|
559
|
+
- **Webhook Seguro**: Validar `cdp_uid` existe no D1 antes de processar purchase
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## 🚀 DEPLOY DO ZERO (Resumo)
|
|
564
|
+
|
|
565
|
+
1. **Criar Worker**: `npx wrangler init cdp-edge-td`
|
|
566
|
+
2. **Configurar D1**: `npx wrangler d1 create cdp-edge-td-db`
|
|
567
|
+
3. **Aplicar Schema**: `npx wrangler d1 execute cdp-edge-td-db --file=schema.sql`
|
|
568
|
+
4. **Configurar Secrets**:
|
|
569
|
+
```bash
|
|
570
|
+
wrangler secret put META_ACCESS_TOKEN
|
|
571
|
+
wrangler secret put META_PIXEL_ID
|
|
572
|
+
wrangler secret put GA4_ID
|
|
573
|
+
wrangler secret put GA4_API_SECRET
|
|
574
|
+
wrangler secret put TIKTOK_PIXEL_ID
|
|
575
|
+
wrangler secret put TIKTOK_ACCESS_TOKEN
|
|
576
|
+
```
|
|
577
|
+
5. **Deploy**: `npx wrangler deploy`
|
|
578
|
+
6. **Configurar Route**: Cloudflare Dashboard → Workers & Pages → Routes → `seusite.com/api/*` → Worker
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
*Este modelo é 100% Cloudflare Native e elimina qualquer dependência de GTM, Stape ou servidores externos.*
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Modelo: Inscrição em Webinar (Cloudflare Native)
|
|
2
|
+
|
|
3
|
+
Este modelo é destinado a páginas de inscrição em webinars, focando na captura de leads e no início da jornada de conteúdo ao vivo.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
8
|
+
|
|
9
|
+
O rastreamento segue o fluxo de registro e confirmação:
|
|
10
|
+
1. **Página de Inscrição**: Captura de dados pessoais e disparo do evento `CompleteRegistration`.
|
|
11
|
+
2. **Servidor (Worker)**: Hashing SHA-256 e persistência no banco D1.
|
|
12
|
+
3. **Database (D1)**: Armazena o lead com a categoria de webinar para segmentação futura.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📘 EVENTOS PRINCIPAIS
|
|
17
|
+
|
|
18
|
+
| Evento | Gatilho | PII (Dados Pessoais) |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **PageView** | Acesso à página | Dados de navegação |
|
|
21
|
+
| **CompleteRegistration** | Sucesso na inscrição | E-mail, Telefone, Nome |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
26
|
+
|
|
27
|
+
### 1.1 Captura de Inscrição
|
|
28
|
+
Este código deve ser vinculado ao evento de sucesso do formulário de inscrição.
|
|
29
|
+
|
|
30
|
+
```javascript
|
|
31
|
+
document.querySelector('#form-webinar').addEventListener('submit', async (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
|
|
34
|
+
const registrationData = {
|
|
35
|
+
email: e.target.email.value,
|
|
36
|
+
phone: e.target.phone.value,
|
|
37
|
+
webinar_id: 'webinar_lancamento_01',
|
|
38
|
+
event_id: cdpTrack.generateId()
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Envio para o Worker
|
|
42
|
+
await cdpTrack.track('CompleteRegistration', registrationData);
|
|
43
|
+
|
|
44
|
+
e.target.submit();
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## ⚡ PASSO 2: SERVIDOR (CLOUDFLARE WORKER)
|
|
51
|
+
|
|
52
|
+
O Worker executa:
|
|
53
|
+
- **Hashing**: Proteção de dados via SHA-256.
|
|
54
|
+
- **D1 Store**: Gravação do lead e vinculação de UTMs para análise de ROI.
|
|
55
|
+
- **API Dispatch**: Envio para Meta CAPI (v22.0) e TikTok Events API (v1.3).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## ✅ VALIDAÇÃO TÉCNICA
|
|
60
|
+
|
|
61
|
+
- **Deduplicação**: Verifique se o `event_id` é único.
|
|
62
|
+
- **Match Quality**: Conferir se e-mail e telefone estão sendo enviados hasheados pelo servidor.
|
|
63
|
+
- **Persistência**: O lead deve aparecer no D1 com o identificador do webinar correspondente.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP Edge — Configuração do Projeto
|
|
3
|
+
*
|
|
4
|
+
* Este arquivo é a única fonte de verdade para configuração do SDK.
|
|
5
|
+
* Copie e ajuste para cada projeto implementado.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const CONFIG = {
|
|
11
|
+
// ── Endpoint do Cloudflare Worker ────────────────────────────────────────────
|
|
12
|
+
// Same-domain: evita ad-blockers e CORS.
|
|
13
|
+
// Em produção: seu-dominio.com.br/api/tracking (Worker roteado)
|
|
14
|
+
// Em dev: use o URL do Worker diretamente
|
|
15
|
+
endpoint: '/api/tracking',
|
|
16
|
+
|
|
17
|
+
// ── Plataformas de checkout habilitadas ──────────────────────────────────────
|
|
18
|
+
// Controla quais plataformas recebem passCheckoutParams() automaticamente.
|
|
19
|
+
// Adicione apenas as plataformas usadas no projeto.
|
|
20
|
+
platforms: ['hotmart', 'kiwify', 'eduzz', 'monetizze', 'cartpanda', 'ticto'],
|
|
21
|
+
|
|
22
|
+
// ── Domínio do site ──────────────────────────────────────────────────────────
|
|
23
|
+
// Usado para cookies first-party e CORS.
|
|
24
|
+
siteDomain: '', // Ex: 'meusite.com.br' — deixar vazio para auto-detect
|
|
25
|
+
|
|
26
|
+
// ── Debug mode ───────────────────────────────────────────────────────────────
|
|
27
|
+
// true = loga todos os eventos no console
|
|
28
|
+
// false = silencioso em produção
|
|
29
|
+
debug: false,
|
|
30
|
+
|
|
31
|
+
// ── Consent Mode v2 (LGPD/GDPR) ─────────────────────────────────────────────
|
|
32
|
+
// Padrão: tudo negado. Sites devem chamar cdpTrack.updateConsent() após
|
|
33
|
+
// o usuário aceitar o banner de cookies.
|
|
34
|
+
consent: {
|
|
35
|
+
defaultDenied: true, // inicializa com ad_storage=denied
|
|
36
|
+
urlPassthrough: true, // preserva gclid/fbclid mesmo sem consent
|
|
37
|
+
waitForUpdate: 500, // ms aguardando CMP antes de disparar hits
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// ── Comportamentos automáticos ───────────────────────────────────────────────
|
|
41
|
+
autoCaptureForms: true, // intercepta formulários de lead automaticamente
|
|
42
|
+
passCheckoutParams: true, // adiciona UTMs + userId nos links de checkout
|
|
43
|
+
initBehaviorEngine: true, // carrega rage-click, exit intent, form abandonment
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default CONFIG;
|