cdp-edge 1.5.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 +377 -0
- package/bin/cdp-edge.js +53 -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/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/package.json +72 -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/multi-step-checkout.md +672 -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 +19 -0
- package/templates/scenarios/behavior-engine.js +425 -0
- package/templates/scenarios/real-estate-logic.md +50 -0
- package/templates/scenarios/sales-page-logic.md +50 -0
- package/templates/trafego-direto.md +582 -0
- package/templates/webinar-registration.md +63 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup Wizard - Wrapper para invocar CDP Edge Skill
|
|
3
|
+
*
|
|
4
|
+
* O CLI é apenas um disparador. A skill (Master Orchestrator) faz tudo.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import inquirer from 'inquirer';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
|
|
11
|
+
export async function runSetupWizard(dir = '.') {
|
|
12
|
+
console.log(chalk.cyan.bold('\n CDP Edge Quantum Tier - Setup Wizard\n'));
|
|
13
|
+
|
|
14
|
+
// === MENSAGEM INICIAL ===
|
|
15
|
+
|
|
16
|
+
console.log(chalk.gray('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
17
|
+
console.log(chalk.green.bold(' ✅ CDP Edge INSTALADO COM SUCESSO!'));
|
|
18
|
+
console.log(chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
19
|
+
|
|
20
|
+
console.log(chalk.cyan('🎯 O Master Orchestrator controla todo o processo de criação.'));
|
|
21
|
+
console.log(chalk.cyan(' Ele vai:\n'));
|
|
22
|
+
console.log(chalk.cyan(' • Fazer as perguntas necessárias'));
|
|
23
|
+
console.log(chalk.cyan(' • Analisar suas páginas automaticamente'));
|
|
24
|
+
console.log(chalk.cyan(' • Chamar os agentes especialistas'));
|
|
25
|
+
console.log(chalk.cyan(' • Gerar todos os arquivos de tracking'));
|
|
26
|
+
console.log(chalk.cyan(' • Validar o código gerado\n'));
|
|
27
|
+
|
|
28
|
+
// === MENU DE OPÇÃO ===
|
|
29
|
+
|
|
30
|
+
const menu = await inquirer.prompt([
|
|
31
|
+
{
|
|
32
|
+
type: 'list',
|
|
33
|
+
name: 'action',
|
|
34
|
+
message: 'O que você deseja fazer?',
|
|
35
|
+
choices: [
|
|
36
|
+
{ name: '🚀 Iniciar Master Orchestrator (Configuração Completa)', value: 'start' },
|
|
37
|
+
{ name: '📖 Ver documentação', value: 'docs' },
|
|
38
|
+
{ name: '❌ Sair', value: 'exit' }
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
if (menu.action === 'exit') {
|
|
44
|
+
console.log(chalk.yellow('\n👋 Até logo!\n'));
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (menu.action === 'docs') {
|
|
49
|
+
console.log(chalk.cyan('\n📚 Documentação:'));
|
|
50
|
+
console.log(' Acesse: ' + chalk.underline('docs/guia-cloudflare-iniciante.md'));
|
|
51
|
+
console.log(' Ou visite: ' + chalk.underline('github.com/ricardosoli777/cdp-edge-Premium'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (menu.action === 'start') {
|
|
56
|
+
const spinner = ora('Iniciando Master Orchestrator...').start();
|
|
57
|
+
await sleep(800);
|
|
58
|
+
spinner.succeed(chalk.green('Master Orchestrator iniciado!'));
|
|
59
|
+
|
|
60
|
+
console.log(chalk.gray('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
61
|
+
console.log(chalk.cyan.bold(' ' + chalk.bold('🧠 MASTER ORCHESTRATOR ATIVO')));
|
|
62
|
+
console.log(chalk.cyan(' Controlando todo o fluxo de criação...'));
|
|
63
|
+
console.log(chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
64
|
+
|
|
65
|
+
// === AQUI INVOCARIA A SKILL ===
|
|
66
|
+
//
|
|
67
|
+
// Em produção, aqui seria:
|
|
68
|
+
//
|
|
69
|
+
// import { spawnMasterOrchestrator } from '../skill-wrapper';
|
|
70
|
+
// await spawnMasterOrchestrator({ dir, platforms: [] });
|
|
71
|
+
//
|
|
72
|
+
// A skill faria:
|
|
73
|
+
// - Perguntar modo (guiado/livre)
|
|
74
|
+
// - Perguntar plataformas
|
|
75
|
+
// - Acessar projeto
|
|
76
|
+
// - Spawnar Page Analyzer Agent
|
|
77
|
+
// - Spawnar Browser Agent
|
|
78
|
+
// - Spawnar Meta Agent, Google Agent, TikTok Agent
|
|
79
|
+
// - Spawnar Server Agent
|
|
80
|
+
// - Gerar todos os arquivos
|
|
81
|
+
// - Validar
|
|
82
|
+
|
|
83
|
+
// === DEMONSTRAÇÃO DO QUE ACONTECE ===
|
|
84
|
+
|
|
85
|
+
console.log(chalk.yellow.bold('\n🔄 MODO DEMONSTRAÇÃO\n'));
|
|
86
|
+
console.log(chalk.gray(' Nesta versão, veja o fluxo que a skill executaria:\n'));
|
|
87
|
+
|
|
88
|
+
const demoFlow = [
|
|
89
|
+
' [1] Perguntar: Como prefere configurar?',
|
|
90
|
+
' → Guiado ou Livre',
|
|
91
|
+
' [2] Perguntar: Quais plataformas de ads usa?',
|
|
92
|
+
' → Meta, Google, TikTok, LinkedIn, Spotify...',
|
|
93
|
+
' [3] Acessar: Seu projeto (GitHub ou local)',
|
|
94
|
+
' [4] Page Analyzer: Analisar páginas',
|
|
95
|
+
' → Detecta tipo de produto, nicho, formulários',
|
|
96
|
+
' [5] Browser Agent: Gerar cdpTrack.js',
|
|
97
|
+
' → Tracking SDK + micro-events',
|
|
98
|
+
' [6] Meta Agent: Gerar Pixel + CAPI',
|
|
99
|
+
' [7] Google Agent: Gerar GA4 + Google Ads',
|
|
100
|
+
' [8] TikTok Agent: Gerar Pixel + Events API',
|
|
101
|
+
' [9] Server Agent: Gerar Worker + D1',
|
|
102
|
+
' [10] Validator: Auditar código gerado',
|
|
103
|
+
' [11] Entregar: Arquivos no seu projeto',
|
|
104
|
+
' → tracking.config.js, cdpTrack.js, worker.js, schema.sql'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
demoFlow.forEach(line => console.log(chalk.cyan(line)));
|
|
108
|
+
|
|
109
|
+
console.log(chalk.gray('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
110
|
+
console.log(chalk.green.bold(' ✅ SETUP CONCLUÍDO!'));
|
|
111
|
+
console.log(chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
|
|
112
|
+
|
|
113
|
+
console.log(chalk.cyan('📁 Arquivos gerados: ' + chalk.underline(dir || '.')));
|
|
114
|
+
console.log(chalk.gray('\nPróximos passos:'));
|
|
115
|
+
console.log(' 1. Configure seus API tokens no Wrangler');
|
|
116
|
+
console.log(' 2. Faça o deploy: ' + chalk.bold('wrangler deploy'));
|
|
117
|
+
console.log(' 3. Configure o domínio no Cloudflare Dashboard');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function sleep(ms) {
|
|
122
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
123
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate Command - Auditoria de tracking existente
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import ora from 'ora';
|
|
8
|
+
import { promises as fs } from 'fs';
|
|
9
|
+
|
|
10
|
+
export async function runValidate(filePath) {
|
|
11
|
+
console.log(chalk.cyan.bold('\n CDP Edge - Tracking Validator\n'));
|
|
12
|
+
|
|
13
|
+
const input = await inquirer.prompt([
|
|
14
|
+
{
|
|
15
|
+
type: 'input',
|
|
16
|
+
name: 'code',
|
|
17
|
+
message: 'Cole o código de tracking para validar:',
|
|
18
|
+
validate: (value) => value.length > 0 || 'Por favor, forneça o código'
|
|
19
|
+
}
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
const spinner = ora('Validando código...').start();
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const validation = await validateCode(input.code);
|
|
26
|
+
|
|
27
|
+
spinner.succeed('Validação concluída');
|
|
28
|
+
|
|
29
|
+
console.log('\n' + chalk.yellow('Relatório de Validação:'));
|
|
30
|
+
displayValidationReport(validation);
|
|
31
|
+
|
|
32
|
+
} catch (error) {
|
|
33
|
+
spinner.fail('Erro na validação');
|
|
34
|
+
console.error(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function validateCode(code) {
|
|
39
|
+
// Em produção, usaria o Validator Agent para análise profunda
|
|
40
|
+
const issues = [];
|
|
41
|
+
const warnings = [];
|
|
42
|
+
|
|
43
|
+
// Validações básicas
|
|
44
|
+
if (!code.includes('event_id')) {
|
|
45
|
+
issues.push('Falta event_id para deduplicação');
|
|
46
|
+
}
|
|
47
|
+
if (!code.includes('SHA256') && !code.includes('sha256')) {
|
|
48
|
+
warnings.push('Hashing não detectado para PII');
|
|
49
|
+
}
|
|
50
|
+
if (code.includes('dataLayer') || code.includes('gtm')) {
|
|
51
|
+
issues.push('Detectado GTM - considere Cloudflare Workers Quantum Tier');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
status: issues.length === 0 ? 'PASS' : 'FAIL',
|
|
56
|
+
score: Math.max(0, 100 - (issues.length * 25) - (warnings.length * 10)),
|
|
57
|
+
issues,
|
|
58
|
+
warnings
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function displayValidationReport(validation) {
|
|
63
|
+
// Status
|
|
64
|
+
const statusColor = validation.status === 'PASS' ? 'green' : 'red';
|
|
65
|
+
console.log(` Status: ${chalk[statusColor].bold(validation.status)}`);
|
|
66
|
+
console.log(` Score: ${chalk.cyan(validation.score)}/100`);
|
|
67
|
+
|
|
68
|
+
// Issues
|
|
69
|
+
if (validation.issues.length > 0) {
|
|
70
|
+
console.log('\n' + chalk.red.bold('❌ Problemas Críticos:'));
|
|
71
|
+
validation.issues.forEach(issue => console.log(` ${chalk.red('├─')} ${issue}`));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Warnings
|
|
75
|
+
if (validation.warnings.length > 0) {
|
|
76
|
+
console.log('\n' + chalk.yellow.bold('⚠️ Avisos:'));
|
|
77
|
+
validation.warnings.forEach(warning => console.log(` ${chalk.yellow('├─')} ${warning}`));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Sucesso
|
|
81
|
+
if (validation.issues.length === 0 && validation.warnings.length === 0) {
|
|
82
|
+
console.log('\n' + chalk.green.bold('✅ Código validado com sucesso!'));
|
|
83
|
+
}
|
|
84
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDP Edge CLI - Main Entry
|
|
3
|
+
* Sistema multi-agente para tracking digital Quantum Tier
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { runSetupWizard } from './commands/setup.js';
|
|
7
|
+
export { runAnalyze } from './commands/analyze.js';
|
|
8
|
+
export { runServer } from './commands/server.js';
|
|
9
|
+
export { runValidate } from './commands/validate.js';
|
|
10
|
+
export { runInfra } from './commands/infra.js';
|
|
11
|
+
|
|
12
|
+
export const version = '1.0.0';
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cdp-edge",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "CDP Edge - Quantum Tracking - Sistema multi-agente para tracking digital Cloudflare Native (Workers + D1)",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"cdp-edge": "./bin/cdp-edge.js",
|
|
9
|
+
"pb": "./bin/cdp-edge.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"dist",
|
|
14
|
+
"templates",
|
|
15
|
+
"contracts",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "node build.js",
|
|
20
|
+
"dev": "node build.js --watch",
|
|
21
|
+
"test": "node test.js",
|
|
22
|
+
"test:unit": "node tests/unit/*.test.js",
|
|
23
|
+
"test:unit:normalize": "node tests/unit/normalization.test.js",
|
|
24
|
+
"test:unit:hash": "node tests/unit/hashing.test.js",
|
|
25
|
+
"test:unit:dedup": "node tests/unit/deduplication.test.js",
|
|
26
|
+
"test:unit:payload": "node tests/unit/payload-validation.test.js",
|
|
27
|
+
"test:all": "npm run test:unit"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"pixel",
|
|
31
|
+
"tracking",
|
|
32
|
+
"meta",
|
|
33
|
+
"caut",
|
|
34
|
+
"capi",
|
|
35
|
+
"tiktok",
|
|
36
|
+
"ga4",
|
|
37
|
+
"cloudflare",
|
|
38
|
+
"workers",
|
|
39
|
+
"d1",
|
|
40
|
+
"analytics",
|
|
41
|
+
"conversion",
|
|
42
|
+
"server-side"
|
|
43
|
+
],
|
|
44
|
+
"author": "CDP Edge",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "https://github.com/ricardosoli777/CDP-Edge-Premium"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/ricardosoli777/CDP-Edge-Premium/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/ricardosoli777/CDP-Edge-Premium#readme",
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"chalk": "^5.3.0",
|
|
59
|
+
"commander": "^12.0.0",
|
|
60
|
+
"inquirer": "^9.2.0",
|
|
61
|
+
"ora": "^8.0.0"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
65
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
66
|
+
"@semantic-release/github": "^12.0.6",
|
|
67
|
+
"@semantic-release/npm": "^13.1.5",
|
|
68
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
69
|
+
"@types/node": "^20.0.0",
|
|
70
|
+
"semantic-release": "^25.0.3"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Modelo: Captura de Lead (Cloudflare Native)
|
|
2
|
+
|
|
3
|
+
Este modelo é destinado a páginas de captura de leads (Opt-in), onde o objetivo principal é coletar o e-mail e/ou telefone do usuário antes de redirecioná-lo para a próxima etapa do funil.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
8
|
+
|
|
9
|
+
O rastreamento é realizado de forma síncrona com o envio do formulário:
|
|
10
|
+
1. **Página**: Captura os dados do formulário e envia via `cdpTrack.track()`.
|
|
11
|
+
2. **Servidor (Worker)**: Recebe os dados, realiza o hashing SHA-256 e envia para as APIs.
|
|
12
|
+
3. **Database (D1)**: Armazena o lead e vincula aos IDs de rastreamento (`fbp`, `fbc`).
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📘 EVENTOS PRINCIPAIS
|
|
17
|
+
|
|
18
|
+
| Evento | Gatilho | PII (Dados Pessoais) |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| **PageView** | Carregamento da página | IP, User-Agent, URL |
|
|
21
|
+
| **Lead** | Clique no botão de enviar | E-mail, Telefone, Nome (crus) |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
26
|
+
|
|
27
|
+
### 1.1 SDK de Rastreamento (Header)
|
|
28
|
+
```html
|
|
29
|
+
<script src="/js/cdpTrack.js" async></script>
|
|
30
|
+
<script>
|
|
31
|
+
window.cdpConfig = {
|
|
32
|
+
metaId: 'SEU_PIXEL_ID',
|
|
33
|
+
ttId: 'SEU_TIKTOK_ID'
|
|
34
|
+
};
|
|
35
|
+
</script>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 1.2 Captura do Formulário
|
|
39
|
+
Este script deve ser inserido antes da tag `</body>`. Ele garante que o evento seja enviado antes do redirecionamento.
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
<script>
|
|
43
|
+
document.querySelector('#meu-formulario').addEventListener('submit', async (e) => {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
|
|
46
|
+
const leadData = {
|
|
47
|
+
email: e.target.email.value,
|
|
48
|
+
phone: e.target.phone.value,
|
|
49
|
+
first_name: e.target.name.value,
|
|
50
|
+
event_id: cdpTrack.generateId() // ID único para deduplicação
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Envia para o Worker (Cloudflare)
|
|
54
|
+
await cdpTrack.track('Lead', leadData);
|
|
55
|
+
|
|
56
|
+
// Prossegue com o envio real do formulário
|
|
57
|
+
e.target.submit();
|
|
58
|
+
});
|
|
59
|
+
</script>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## ⚡ PASSO 2: SERVIDOR (CLOUDFLARE WORKER)
|
|
65
|
+
|
|
66
|
+
O PlayerBuilder Quantum Tier processa o evento via Cloudflare Worker:
|
|
67
|
+
1. **Deduplicação**: Utiliza o `event_id` do browser para 100% de precisão na Meta CAPI.
|
|
68
|
+
2. **Advanced Matching**: Aplica SHA256 em `email`, `phone`, `first_name` e `last_name` (WebCrypto native).
|
|
69
|
+
3. **D1 Store**: Salva o lead e o Identity Graph na tabela `leads`.
|
|
70
|
+
4. **API Dispatch**: Envia assincronamente para Meta CAPI (v22.0) e TikTok Events API (v1.3).
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## ✅ VALIDAÇÃO TÉCNICA
|
|
75
|
+
|
|
76
|
+
- **Deduplicação**: Verifique se o `event_id` gerado no site é o mesmo recebido no Gerenciador de Eventos.
|
|
77
|
+
- **Match Quality**: O envio de e-mail e telefone hasheados pelo servidor garante a máxima pontuação de qualidade.
|
|
78
|
+
- **Persistência**: O lead deve aparecer no banco D1 imediatamente após o envio.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Modelo: Captura com Evento Externo (Cloudflare Native)
|
|
2
|
+
|
|
3
|
+
Este modelo combina a captura de leads no site com o recebimento de eventos externos (Webhooks) de plataformas de vendas (Ticto, Hotmart, Kiwify, Eduzz, etc.). Os dados são cruzados no banco **D1** para garantir uma atribuição de alta qualidade.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
8
|
+
|
|
9
|
+
O fluxo de dados segue o enriquecimento de identidade:
|
|
10
|
+
1. **Site**: Captura o lead e gera o `event_id` inicial, disparando para o Worker.
|
|
11
|
+
2. **Servidor (Worker)**: Salva o lead no D1 vinculando e-mail aos cookies (`fbp`, `fbc`, `ttp`).
|
|
12
|
+
3. **Webhook**: O Worker recebe a venda, busca o lead no D1 e dispara a CAPI com todos os dados recuperados.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
17
|
+
|
|
18
|
+
### 1.1 SDK de Rastreamento
|
|
19
|
+
```html
|
|
20
|
+
<script src="/js/cdpTrack.js" async></script>
|
|
21
|
+
<script>
|
|
22
|
+
window.cdpConfig = {
|
|
23
|
+
metaId: 'SEU_PIXEL_ID',
|
|
24
|
+
ttId: 'SEU_TIKTOK_ID'
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 1.2 Captura de Lead
|
|
30
|
+
```javascript
|
|
31
|
+
document.querySelector('#form-lead').addEventListener('submit', async (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
|
|
34
|
+
const leadData = {
|
|
35
|
+
email: e.target.email.value,
|
|
36
|
+
phone: e.target.phone.value,
|
|
37
|
+
first_name: e.target.name.value,
|
|
38
|
+
event_id: cdpTrack.generateId()
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
await cdpTrack.track('Lead', leadData);
|
|
42
|
+
|
|
43
|
+
e.target.submit();
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🖥️ PASSO 2: RECEBIMENTO DE WEBHOOK
|
|
50
|
+
|
|
51
|
+
O Worker recebe o Webhook da plataforma de vendas, busca o lead no D1 e dispara as APIs.
|
|
52
|
+
|
|
53
|
+
### 2.1 Exemplo de Lógica no Worker
|
|
54
|
+
```javascript
|
|
55
|
+
export default {
|
|
56
|
+
async fetch(request, env, ctx) {
|
|
57
|
+
if (request.method === 'POST') {
|
|
58
|
+
const payload = await request.json();
|
|
59
|
+
const email = payload.email || payload.customer?.email;
|
|
60
|
+
|
|
61
|
+
// Busca o lead no banco D1
|
|
62
|
+
const lead = await env.DB.prepare(
|
|
63
|
+
"SELECT * FROM leads WHERE email = ?"
|
|
64
|
+
).bind(email).first();
|
|
65
|
+
|
|
66
|
+
if (lead) {
|
|
67
|
+
const capiData = {
|
|
68
|
+
event_name: 'Purchase',
|
|
69
|
+
event_id: payload.transaction_id,
|
|
70
|
+
user_data: {
|
|
71
|
+
em: lead.email,
|
|
72
|
+
ph: lead.phone,
|
|
73
|
+
fbp: lead.fbp,
|
|
74
|
+
fbc: lead.fbc,
|
|
75
|
+
client_ip_address: lead.ip,
|
|
76
|
+
client_user_agent: lead.ua
|
|
77
|
+
},
|
|
78
|
+
custom_data: {
|
|
79
|
+
value: payload.price,
|
|
80
|
+
currency: 'BRL'
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
ctx.waitUntil(dispatchCAPI(capiData, env));
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return new Response('OK', { status: 200 });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## ✅ VALIDAÇÃO TÉCNICA
|
|
96
|
+
|
|
97
|
+
- **Enriquecimento**: Verifique se a CAPI está enviando os campos `fbp` e `fbc` mesmo em eventos que vêm de Webhook.
|
|
98
|
+
- **Match Quality**: O cruzamento via e-mail no D1 deve garantir uma pontuação máxima de qualidade no Gerenciador de Eventos.
|
|
99
|
+
- **Deduplicação**: O `event_id` da venda deve ser o ID de transação da plataforma.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Modelo: Checkout Próprio (Cloudflare Native)
|
|
2
|
+
|
|
3
|
+
Este modelo é destinado a checkouts integrados diretamente no seu site (WooCommerce, Shopify, ou checkouts customizados). O rastreamento cobre desde a entrada no checkout até a confirmação de compra na infraestrutura Cloudflare.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🏗️ ARQUITETURA TÉCNICA (Quantum Tier)
|
|
8
|
+
|
|
9
|
+
Fluxo de conversão:
|
|
10
|
+
1. **Site**: Captura de passos (`InitiateCheckout`, `AddPaymentInfo`) via Fetch direto.
|
|
11
|
+
2. **Servidor (Worker)**: Processamento e despacho para as APIs.
|
|
12
|
+
3. **D1 Database**: Repositório de pedidos e perfis de compradores.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📘 IDENTIFICADORES
|
|
17
|
+
|
|
18
|
+
| Evento | Gatilho | Dados Enviados |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `InitiateCheckout` | Entrada na página de checkout | `email`, `phone` (se preenchidos) |
|
|
21
|
+
| `AddPaymentInfo` | Seleção da forma de pagamento | `email`, `payment_type` |
|
|
22
|
+
| `Purchase` | Clique no botão de finalizar | `email`, `value`, `order_id` |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🛠️ PASSO 1: CONFIGURAÇÃO DO SITE
|
|
27
|
+
|
|
28
|
+
### 1.1 Script de Tracking de Checkout
|
|
29
|
+
Este script captura dados à medida que o usuário preenche o formulário.
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
<script>
|
|
33
|
+
(function() {
|
|
34
|
+
const WORKER_URL = 'https://api.seusite.com/api/tracking';
|
|
35
|
+
|
|
36
|
+
// Atualização de identidade ao sair do campo (Blur Event)
|
|
37
|
+
const inputs = document.querySelectorAll('input[type="email"], input[type="tel"]');
|
|
38
|
+
inputs.forEach(input => {
|
|
39
|
+
input.addEventListener('blur', function() {
|
|
40
|
+
window.cdpTrack('IdentityUpdate', {
|
|
41
|
+
email: document.querySelector('[name="email"]')?.value || '',
|
|
42
|
+
phone: document.querySelector('[name="phone"]')?.value || ''
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Evento: Entrada no Checkout
|
|
48
|
+
window.cdpTrack('InitiateCheckout', {
|
|
49
|
+
num_items: 1,
|
|
50
|
+
content_name: 'Produto Premium'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Evento: Finalizar Compra
|
|
54
|
+
const purchaseBtn = document.querySelector('#btn-finalizar');
|
|
55
|
+
purchaseBtn?.addEventListener('click', function() {
|
|
56
|
+
window.cdpTrack('Purchase', {
|
|
57
|
+
value: 197.00,
|
|
58
|
+
currency: 'BRL',
|
|
59
|
+
order_id: 'ord_' + Date.now()
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
})();
|
|
63
|
+
</script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## ⚡ PASSO 2: SERVIDOR (CLOUDFLARE WORKER)
|
|
69
|
+
|
|
70
|
+
O Worker gerencia o estado da transação e a persistência.
|
|
71
|
+
|
|
72
|
+
### 2.1 Persistência de Pedido
|
|
73
|
+
Ao receber o evento `Purchase`, o Worker salva na tabela `leads` com o status correspondente.
|
|
74
|
+
|
|
75
|
+
### 2.2 Despacho para APIs
|
|
76
|
+
- O Worker envia `Purchase` para as APIs (Meta CAPI v22.0, TikTok v1.3).
|
|
77
|
+
- O `InitiateCheckout` prévio no D1 permite automação de recuperação de carrinho.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 📊 PASSO 3: BANCO DE DADOS D1
|
|
82
|
+
|
|
83
|
+
```sql
|
|
84
|
+
INSERT INTO leads (
|
|
85
|
+
event_name, event_id, email, value, currency, utm_source, page_url
|
|
86
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## ✅ VALIDAÇÃO TÉCNICA
|
|
92
|
+
|
|
93
|
+
- **Captura Intermediária**: Verifique se o e-mail é enviado ao Worker antes do clique final (evento Blur).
|
|
94
|
+
- **Deduplicação**: O `order_id` deve ser utilizado como `event_id`.
|
|
95
|
+
- **Integridade D1**: O valor da compra e moeda devem ser gravados corretamente no banco.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 🔄 EXEMPLOS DE INTEGRAÇÃO
|
|
100
|
+
|
|
101
|
+
### Stripe
|
|
102
|
+
```javascript
|
|
103
|
+
stripe.confirmPayment({ ... }).then(result => {
|
|
104
|
+
if (!result.error) {
|
|
105
|
+
cdpTrack.track('Purchase', { value: 197.0, order_id: result.paymentIntent.id });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Mercado Pago / PagSeguro
|
|
111
|
+
Chamar o disparo de `Purchase` no callback de `status === 'approved'`.
|