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.
Files changed (128) hide show
  1. package/README.md +367 -0
  2. package/bin/cdp-edge.js +61 -0
  3. package/contracts/api-versions.json +368 -0
  4. package/dist/commands/analyze.js +52 -0
  5. package/dist/commands/infra.js +54 -0
  6. package/dist/commands/install.js +168 -0
  7. package/dist/commands/server.js +174 -0
  8. package/dist/commands/setup.js +123 -0
  9. package/dist/commands/validate.js +84 -0
  10. package/dist/index.js +12 -0
  11. package/docs/CI-CD-SETUP.md +217 -0
  12. package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
  13. package/docs/events-reference.md +359 -0
  14. package/docs/installation.md +155 -0
  15. package/docs/quick-start.md +185 -0
  16. package/docs/sdk-reference.md +371 -0
  17. package/docs/whatsapp-ctwa.md +209 -0
  18. package/extracted-skill/tracking-events-generator/INDEX.md +94 -0
  19. package/extracted-skill/tracking-events-generator/INSTALACAO-CDPEDGE.md +58 -0
  20. package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +594 -0
  21. package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +412 -0
  22. package/extracted-skill/tracking-events-generator/Premium-Tracking-Intelligence-Resumo.md +333 -0
  23. package/extracted-skill/tracking-events-generator/SKILL.md +257 -0
  24. package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -0
  25. package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +54 -0
  26. package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +1304 -0
  27. package/extracted-skill/tracking-events-generator/agents/bing-agent.md +76 -0
  28. package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +264 -0
  29. package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +149 -0
  30. package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +2077 -0
  31. package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +1419 -0
  32. package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +456 -0
  33. package/extracted-skill/tracking-events-generator/agents/database-agent.md +667 -0
  34. package/extracted-skill/tracking-events-generator/agents/debug-agent.md +1455 -0
  35. package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +224 -0
  36. package/extracted-skill/tracking-events-generator/agents/email-agent.md +61 -0
  37. package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +52 -0
  38. package/extracted-skill/tracking-events-generator/agents/google-agent.md +109 -0
  39. package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +365 -0
  40. package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +643 -0
  41. package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +62 -0
  42. package/extracted-skill/tracking-events-generator/agents/localization-agent.md +55 -0
  43. package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +59 -0
  44. package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +900 -0
  45. package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +1922 -0
  46. package/extracted-skill/tracking-events-generator/agents/memory-agent.json +109 -0
  47. package/extracted-skill/tracking-events-generator/agents/memory-agent.md +703 -0
  48. package/extracted-skill/tracking-events-generator/agents/meta-agent.md +110 -0
  49. package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +255 -0
  50. package/extracted-skill/tracking-events-generator/agents/performance-agent.md +1157 -0
  51. package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +1432 -0
  52. package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +310 -0
  53. package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +849 -0
  54. package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +250 -0
  55. package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +313 -0
  56. package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +1752 -0
  57. package/extracted-skill/tracking-events-generator/agents/server-tracking.md +1188 -0
  58. package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +383 -0
  59. package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +111 -0
  60. package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +364 -0
  61. package/extracted-skill/tracking-events-generator/agents/validator-agent.md +267 -0
  62. package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +69 -0
  63. package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +76 -0
  64. package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +699 -0
  65. package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +422 -0
  66. package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -0
  67. package/extracted-skill/tracking-events-generator/cdpTrack.js +641 -0
  68. package/extracted-skill/tracking-events-generator/contracts/api-versions.json +368 -0
  69. package/extracted-skill/tracking-events-generator/docs/guia-cloudflare-iniciante.md +107 -0
  70. package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -0
  71. package/extracted-skill/tracking-events-generator/evals/evals.json +235 -0
  72. package/extracted-skill/tracking-events-generator/integration-test.js +497 -0
  73. package/extracted-skill/tracking-events-generator/knowledge-base.md +2894 -0
  74. package/extracted-skill/tracking-events-generator/micro-events.js +992 -0
  75. package/extracted-skill/tracking-events-generator/models/captura-de-lead.md +78 -0
  76. package/extracted-skill/tracking-events-generator/models/captura-lead-evento-externo.md +99 -0
  77. package/extracted-skill/tracking-events-generator/models/checkout-proprio.md +111 -0
  78. package/extracted-skill/tracking-events-generator/models/multi-step-checkout.md +672 -0
  79. package/extracted-skill/tracking-events-generator/models/pagina-obrigado.md +55 -0
  80. package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -0
  81. package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -0
  82. package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -0
  83. package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +68 -0
  84. package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -0
  85. package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -0
  86. package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -0
  87. package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -0
  88. package/extracted-skill/tracking-events-generator/models/scenarios/real-estate-logic.md +50 -0
  89. package/extracted-skill/tracking-events-generator/models/scenarios/sales-page-logic.md +50 -0
  90. package/extracted-skill/tracking-events-generator/models/trafego-direto.md +582 -0
  91. package/extracted-skill/tracking-events-generator/models/webinar-registration.md +63 -0
  92. package/extracted-skill/tracking-events-generator/tracking.config.js +46 -0
  93. package/extracted-skill/tracking-events-generator/walkthrough.md +26 -0
  94. package/package.json +75 -0
  95. package/server-edge-tracker/INSTALAR.md +328 -0
  96. package/server-edge-tracker/migrate-new-db.sql +137 -0
  97. package/server-edge-tracker/migrate-v2.sql +16 -0
  98. package/server-edge-tracker/migrate-v3.sql +6 -0
  99. package/server-edge-tracker/migrate-v4.sql +18 -0
  100. package/server-edge-tracker/migrate-v5.sql +17 -0
  101. package/server-edge-tracker/migrate-v6.sql +24 -0
  102. package/server-edge-tracker/migrate.sql +111 -0
  103. package/server-edge-tracker/schema.sql +265 -0
  104. package/server-edge-tracker/worker.js +2574 -0
  105. package/server-edge-tracker/wrangler.toml +85 -0
  106. package/templates/afiliado-sem-landing.md +312 -0
  107. package/templates/captura-de-lead.md +78 -0
  108. package/templates/captura-lead-evento-externo.md +99 -0
  109. package/templates/checkout-proprio.md +111 -0
  110. package/templates/install/.claude/commands/cdp.md +1 -0
  111. package/templates/install/CLAUDE.md +65 -0
  112. package/templates/linkedin/tag-template.js +46 -0
  113. package/templates/multi-step-checkout.md +673 -0
  114. package/templates/pagina-obrigado.md +55 -0
  115. package/templates/pinterest/conversions-api-template.js +144 -0
  116. package/templates/pinterest/event-mappings.json +48 -0
  117. package/templates/pinterest/tag-template.js +28 -0
  118. package/templates/quiz-funnel.md +68 -0
  119. package/templates/reddit/conversions-api-template.js +205 -0
  120. package/templates/reddit/event-mappings.json +56 -0
  121. package/templates/reddit/pixel-template.js +46 -0
  122. package/templates/scenarios/behavior-engine.js +402 -0
  123. package/templates/scenarios/real-estate-logic.md +50 -0
  124. package/templates/scenarios/sales-page-logic.md +50 -0
  125. package/templates/spotify/pixel-template.js +46 -0
  126. package/templates/trafego-direto.md +582 -0
  127. package/templates/vsl-page.md +292 -0
  128. 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;