cdp-edge 1.2.0 β 1.3.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 +153 -306
- package/bin/cdp-edge.js +71 -61
- package/contracts/agent-versions.json +682 -0
- package/contracts/api-versions.json +372 -368
- package/contracts/types.ts +81 -0
- package/dist/commands/analyze.js +52 -52
- package/dist/commands/infra.js +54 -54
- package/dist/commands/install.js +26 -3
- package/dist/commands/server.js +174 -174
- package/dist/commands/setup.js +332 -100
- package/dist/commands/validate.js +248 -84
- package/dist/index.js +12 -12
- package/dist/sdk/cdpTrack.js +2095 -0
- package/dist/sdk/cdpTrack.min.js +64 -0
- package/dist/sdk/install-snippet.html +10 -0
- package/docs/whatsapp-ctwa.md +5 -4
- package/extracted-skill/tracking-events-generator/INTEGRACAO-COMPLETA.md +89 -0
- package/extracted-skill/tracking-events-generator/MELHORIAS-IMPLEMENTADAS.md +101 -0
- package/extracted-skill/tracking-events-generator/advanced-matching.js +364 -364
- package/extracted-skill/tracking-events-generator/agents/ab-ltv-agent.md +196 -0
- package/extracted-skill/tracking-events-generator/agents/ab-testing-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/attribution-agent.md +41 -41
- package/extracted-skill/tracking-events-generator/agents/bidding-agent.md +347 -0
- package/extracted-skill/tracking-events-generator/agents/bing-agent.md +40 -50
- package/extracted-skill/tracking-events-generator/agents/browser-tracking.md +174 -74
- package/extracted-skill/tracking-events-generator/agents/code-guardian-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/compliance-agent.md +25 -5
- package/extracted-skill/tracking-events-generator/agents/dashboard-agent.md +10 -10
- package/extracted-skill/tracking-events-generator/agents/database-agent.md +43 -42
- package/extracted-skill/tracking-events-generator/agents/debug-agent.md +22 -22
- package/extracted-skill/tracking-events-generator/agents/devops-agent.md +232 -0
- package/extracted-skill/tracking-events-generator/agents/domain-setup-agent.md +23 -9
- package/extracted-skill/tracking-events-generator/agents/email-agent.md +28 -1
- package/extracted-skill/tracking-events-generator/agents/evo-crm-agent.md +244 -0
- package/extracted-skill/tracking-events-generator/agents/fingerprint-agent.md +206 -1
- package/extracted-skill/tracking-events-generator/agents/fraud-detection-agent.md +143 -0
- package/extracted-skill/tracking-events-generator/agents/google-agent.md +128 -2
- package/extracted-skill/tracking-events-generator/agents/intelligence-agent.md +191 -31
- package/extracted-skill/tracking-events-generator/agents/lead-scoring-agent.md +282 -0
- package/extracted-skill/tracking-events-generator/agents/linkedin-agent.md +145 -34
- package/extracted-skill/tracking-events-generator/agents/localization-agent.md +1 -1
- package/extracted-skill/tracking-events-generator/agents/ltv-predictor-agent.md +5 -5
- package/extracted-skill/tracking-events-generator/agents/master-feedback-loop.md +81 -21
- package/extracted-skill/tracking-events-generator/agents/master-orchestrator.md +428 -190
- package/extracted-skill/tracking-events-generator/agents/match-quality-agent.md +304 -0
- package/extracted-skill/tracking-events-generator/agents/memory-agent.json +25 -109
- package/extracted-skill/tracking-events-generator/agents/memory-agent.md +190 -15
- package/extracted-skill/tracking-events-generator/agents/meta-agent.md +10 -2
- package/extracted-skill/tracking-events-generator/agents/ml-clustering-agent.md +749 -0
- package/extracted-skill/tracking-events-generator/agents/page-analyzer.md +21 -4
- package/extracted-skill/tracking-events-generator/agents/performance-agent.md +41 -31
- package/extracted-skill/tracking-events-generator/agents/performance-optimization-agent.md +18 -8
- package/extracted-skill/tracking-events-generator/agents/pinterest-agent.md +14 -6
- package/extracted-skill/tracking-events-generator/agents/premium-tracking-intelligence-agent.md +7 -7
- package/extracted-skill/tracking-events-generator/agents/r2-setup-agent.md +16 -8
- package/extracted-skill/tracking-events-generator/agents/reddit-agent.md +15 -7
- package/extracted-skill/tracking-events-generator/agents/security-enterprise-agent.md +157 -48
- package/extracted-skill/tracking-events-generator/agents/server-tracking.md +35 -35
- package/extracted-skill/tracking-events-generator/agents/spotify-agent.md +15 -7
- package/extracted-skill/tracking-events-generator/agents/tiktok-agent.md +73 -2
- package/extracted-skill/tracking-events-generator/agents/tracking-plan-agent.md +104 -9
- package/extracted-skill/tracking-events-generator/agents/utm-agent.md +322 -0
- package/extracted-skill/tracking-events-generator/agents/validator-agent.md +13 -9
- package/extracted-skill/tracking-events-generator/agents/webhook-agent.md +112 -4
- package/extracted-skill/tracking-events-generator/agents/whatsapp-agent.md +58 -5
- package/extracted-skill/tracking-events-generator/agents/whatsapp-ctwa-setup-agent.md +26 -18
- package/extracted-skill/tracking-events-generator/agents/youtube-agent.md +152 -37
- package/extracted-skill/tracking-events-generator/anti-blocking.js +285 -285
- package/extracted-skill/tracking-events-generator/cdpTrack.js +642 -641
- package/extracted-skill/tracking-events-generator/contracts/api-versions.json +14 -10
- package/extracted-skill/tracking-events-generator/engagement-scoring.js +226 -226
- package/extracted-skill/tracking-events-generator/evals/evals.json +235 -235
- package/extracted-skill/tracking-events-generator/integration-test.js +497 -497
- package/extracted-skill/tracking-events-generator/knowledge-base.md +172 -0
- package/extracted-skill/tracking-events-generator/micro-events.js +992 -992
- package/extracted-skill/tracking-events-generator/models/lancamento-imobiliario.md +344 -0
- package/extracted-skill/tracking-events-generator/models/pinterest/conversions-api-template.js +144 -144
- package/extracted-skill/tracking-events-generator/models/pinterest/event-mappings.json +48 -48
- package/extracted-skill/tracking-events-generator/models/pinterest/tag-template.js +28 -28
- package/extracted-skill/tracking-events-generator/models/quiz-funnel.md +83 -19
- package/extracted-skill/tracking-events-generator/models/reddit/conversions-api-template.js +205 -205
- package/extracted-skill/tracking-events-generator/models/reddit/event-mappings.json +56 -56
- package/extracted-skill/tracking-events-generator/models/reddit/pixel-template.js +19 -19
- package/extracted-skill/tracking-events-generator/models/scenarios/behavior-engine.js +425 -425
- package/extracted-skill/tracking-events-generator/route-intent-capture.js +222 -0
- package/extracted-skill/tracking-events-generator/tracking.config.js +3 -3
- package/package.json +89 -75
- package/scripts/build-sdk.js +106 -0
- package/server-edge-tracker/.client.env.example +14 -0
- package/server-edge-tracker/INSTALAR.md +222 -23
- package/server-edge-tracker/SEGMENTATION-DOCS.md +513 -0
- package/server-edge-tracker/config/utm-mapping.json +64 -0
- package/server-edge-tracker/deploy-client.cjs +76 -0
- package/server-edge-tracker/index.ts +1230 -0
- package/server-edge-tracker/migrate-v7.sql +64 -0
- package/server-edge-tracker/modules/db.ts +710 -0
- package/server-edge-tracker/modules/dispatch/crm.ts +382 -0
- package/server-edge-tracker/modules/dispatch/ga4.ts +72 -0
- package/server-edge-tracker/modules/dispatch/meta.ts +143 -0
- package/server-edge-tracker/modules/dispatch/platforms.ts +255 -0
- package/server-edge-tracker/modules/dispatch/tiktok.ts +107 -0
- package/server-edge-tracker/modules/dispatch/whatsapp.ts +296 -0
- package/server-edge-tracker/modules/intelligence.ts +589 -0
- package/server-edge-tracker/modules/ml/bidding.ts +247 -0
- package/server-edge-tracker/modules/ml/fraud.ts +302 -0
- package/server-edge-tracker/modules/ml/logistic.ts +226 -0
- package/server-edge-tracker/modules/ml/ltv.ts +531 -0
- package/server-edge-tracker/modules/ml/matchquality.ts +232 -0
- package/server-edge-tracker/modules/ml/quiz.ts +343 -0
- package/server-edge-tracker/modules/ml/roas.ts +255 -0
- package/server-edge-tracker/modules/ml/segmentation.ts +407 -0
- package/server-edge-tracker/modules/nurture.ts +257 -0
- package/server-edge-tracker/modules/utils.ts +311 -0
- package/server-edge-tracker/modules/utm/utm-enricher.ts +231 -0
- package/server-edge-tracker/schema-ab-ltv.sql +97 -0
- package/server-edge-tracker/schema-bidding.sql +86 -0
- package/server-edge-tracker/schema-fraud.sql +90 -0
- package/server-edge-tracker/schema-indexes.sql +67 -0
- package/server-edge-tracker/schema-ltv-feedback.sql +11 -0
- package/server-edge-tracker/schema-quiz.sql +52 -0
- package/server-edge-tracker/schema-sales-engine.sql +113 -0
- package/server-edge-tracker/schema-segmentation.sql +219 -0
- package/server-edge-tracker/schema-utm.sql +82 -0
- package/server-edge-tracker/schema.sql +281 -265
- package/server-edge-tracker/types.ts +275 -0
- package/server-edge-tracker/wrangler.toml +140 -85
- package/templates/lancamento-imobiliario.md +344 -0
- package/templates/multi-step-checkout.md +3 -4
- package/templates/pinterest/conversions-api-template.js +144 -144
- package/templates/pinterest/event-mappings.json +48 -48
- package/templates/pinterest/tag-template.js +28 -28
- package/templates/quiz-funnel.md +83 -19
- package/templates/reddit/conversions-api-template.js +205 -205
- package/templates/reddit/event-mappings.json +56 -56
- package/templates/reddit/pixel-template.js +12 -39
- package/templates/scenarios/behavior-engine.js +45 -22
- package/docs/PixelBuilder-Documentacao-Completa (2).docx +0 -0
- package/docs/installation.md +0 -155
- package/docs/quick-start.md +0 -185
- package/extracted-skill/tracking-events-generator/agents/crm-integration-agent.md +0 -1419
- package/extracted-skill/tracking-events-generator/agents/intelligence-scheduling.md +0 -643
- package/server-edge-tracker/worker.js +0 -2574
|
@@ -1,285 +1,285 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ANTI-BLOCKING STRATEGY - CDP Edge (Quantum Tier)
|
|
3
|
-
*
|
|
4
|
-
* Sistema para maximizar resiliΓͺncia contra ad-blockers e garantir
|
|
5
|
-
* que o tracking funcione mesmo em ambientes hostis.
|
|
6
|
-
*
|
|
7
|
-
* @version 1.0.0
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// ββ Guards ββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
11
|
-
const isBrowser = typeof window !== 'undefined';
|
|
12
|
-
|
|
13
|
-
// ββ ConfiguraΓ§Γ΅es de Anti-Blocking βββββββββββββββββββββ
|
|
14
|
-
|
|
15
|
-
const ANTI_BLOCKING_CONFIG = {
|
|
16
|
-
// Mesmo domΓnio evita bloqueios de CORS e ad-blockers
|
|
17
|
-
endpoint: '/
|
|
18
|
-
|
|
19
|
-
// Retries com exponential backoff
|
|
20
|
-
maxRetries: 3,
|
|
21
|
-
retryDelays: [1000, 3000, 6000], // 1s, 3s, 6s
|
|
22
|
-
|
|
23
|
-
// Fallback para Beacon API (quando fetch falha)
|
|
24
|
-
useBeaconFallback: true,
|
|
25
|
-
|
|
26
|
-
// First-party cookies (ad-block proof)
|
|
27
|
-
cookieDuration: 60 * 60 * 24 * 365, // 365 dias
|
|
28
|
-
cookieDomain: '', // SerΓ‘ definido dinamicamente
|
|
29
|
-
|
|
30
|
-
// Detectar ad-blockers
|
|
31
|
-
detectAdBlocker: true,
|
|
32
|
-
adBlockerBaitClass: 'adsbox adbanner pub_300x250',
|
|
33
|
-
|
|
34
|
-
// Lightweight code (evitar patterns de bloqueio)
|
|
35
|
-
minify: false, // Opcional: usar cΓ³digo minificado em produΓ§Γ£o
|
|
36
|
-
noConsoleLogs: false, // Opcional: remover console.logs em produΓ§Γ£o
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
// ββ DetecΓ§Γ£o de Ad-Blocker βββββββββββββββββββββββββ
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Detecta se um ad-blocker estΓ‘ ativo
|
|
43
|
-
*
|
|
44
|
-
* @returns {boolean} True se ad-blocker detectado
|
|
45
|
-
*/
|
|
46
|
-
function detectAdBlocker() {
|
|
47
|
-
if (!isBrowser || !ANTI_BLOCKING_CONFIG.detectAdBlocker) return false;
|
|
48
|
-
|
|
49
|
-
// MΓ©todo 1: Criar elemento com classe comum de ads
|
|
50
|
-
const baitElement = document.createElement('div');
|
|
51
|
-
baitElement.innerHTML = ' ';
|
|
52
|
-
baitElement.className = ANTI_BLOCKING_CONFIG.adBlockerBaitClass;
|
|
53
|
-
baitElement.style.cssText = 'position: absolute; top: -1000px; left: -1000px;';
|
|
54
|
-
document.body.appendChild(baitElement);
|
|
55
|
-
|
|
56
|
-
const isBlocked = getComputedStyle(baitElement).display === 'none';
|
|
57
|
-
|
|
58
|
-
document.body.removeChild(baitElement);
|
|
59
|
-
|
|
60
|
-
// MΓ©todo 2: Verificar se bloqueia requests de tracking
|
|
61
|
-
try {
|
|
62
|
-
const testPixel = new Image();
|
|
63
|
-
testPixel.src = '/pixel-test.png?t=' + Date.now();
|
|
64
|
-
testPixel.onload = () => console.log('β
Pixel nΓ£o bloqueado');
|
|
65
|
-
testPixel.onerror = () => console.warn('β οΈ Pixel pode estar bloqueado');
|
|
66
|
-
} catch (error) {
|
|
67
|
-
console.warn('β οΈ Erro ao testar pixel:', error);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return isBlocked;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// ββ ResiliΓͺncia de Envio βββββββββββββββββββββββββββββ
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Envia dados com retry automΓ‘tico (exponential backoff)
|
|
77
|
-
*
|
|
78
|
-
* @param {object} data - Dados para enviar
|
|
79
|
-
* @param {string} endpoint - Endpoint de destino
|
|
80
|
-
* @returns {Promise} Promise com resultado
|
|
81
|
-
*/
|
|
82
|
-
async function sendWithRetry(data, endpoint = ANTI_BLOCKING_CONFIG.endpoint) {
|
|
83
|
-
if (!isBrowser) return { success: false, error: 'Not in browser' };
|
|
84
|
-
|
|
85
|
-
let lastError = null;
|
|
86
|
-
|
|
87
|
-
for (let attempt = 0; attempt < ANTI_BLOCKING_CONFIG.maxRetries; attempt++) {
|
|
88
|
-
try {
|
|
89
|
-
// Tenta enviar via fetch
|
|
90
|
-
const response = await fetch(endpoint, {
|
|
91
|
-
method: 'POST',
|
|
92
|
-
headers: {
|
|
93
|
-
'Content-Type': 'application/json',
|
|
94
|
-
},
|
|
95
|
-
body: JSON.stringify(data),
|
|
96
|
-
keepalive: true, // Garante envio mesmo se usuΓ‘rio fechar aba
|
|
97
|
-
credentials: 'same-origin', // First-party cookies
|
|
98
|
-
cache: 'no-cache' // Evitar cache de requests de tracking
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
if (response.ok) {
|
|
102
|
-
console.log(`β
Envio bem-sucedido (tentativa ${attempt + 1})`);
|
|
103
|
-
return await response.json();
|
|
104
|
-
} else {
|
|
105
|
-
const errorText = await response.text();
|
|
106
|
-
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
107
|
-
}
|
|
108
|
-
} catch (error) {
|
|
109
|
-
lastError = error;
|
|
110
|
-
console.warn(`β οΈ Tentativa ${attempt + 1} falhou:`, error.message);
|
|
111
|
-
|
|
112
|
-
// Se nΓ£o for a ΓΊltima tentativa, aguarda antes de retry
|
|
113
|
-
if (attempt < ANTI_BLOCKING_CONFIG.maxRetries - 1) {
|
|
114
|
-
const delay = ANTI_BLOCKING_CONFIG.retryDelays[attempt];
|
|
115
|
-
console.log(`β³ Aguardando ${delay}ms antes de retry...`);
|
|
116
|
-
await sleep(delay);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Todas as tentativas falharam
|
|
122
|
-
console.error('β Todas as tentativas de envio falharam:', lastError);
|
|
123
|
-
|
|
124
|
-
// Fallback: Beacon API
|
|
125
|
-
if (ANTI_BLOCKING_CONFIG.useBeaconFallback && navigator.sendBeacon) {
|
|
126
|
-
console.log('π Tentando Beacon API como fallback...');
|
|
127
|
-
const beaconSuccess = navigator.sendBeacon(endpoint, JSON.stringify(data));
|
|
128
|
-
|
|
129
|
-
if (beaconSuccess) {
|
|
130
|
-
console.log('β
Beacon API bem-sucedido');
|
|
131
|
-
return { success: true, method: 'beacon' };
|
|
132
|
-
} else {
|
|
133
|
-
console.error('β Beacon API tambΓ©m falhou');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return { success: false, error: lastError?.message, attempts: ANTI_BLOCKING_CONFIG.maxRetries };
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* FunΓ§Γ£o utilitΓ‘ria de delay
|
|
142
|
-
*/
|
|
143
|
-
function sleep(ms) {
|
|
144
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// ββ First-Party Cookies (Ad-Block Proof) βββββββββββββββ
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Define cookie first-party (nΓ£o bloqueado por ad-blockers)
|
|
151
|
-
*
|
|
152
|
-
* @param {string} name - Nome do cookie
|
|
153
|
-
* @param {string} value - Valor do cookie
|
|
154
|
-
* @param {number} maxAge - Tempo de vida em segundos
|
|
155
|
-
*/
|
|
156
|
-
function setFirstPartyCookie(name, value, maxAge = ANTI_BLOCKING_CONFIG.cookieDuration) {
|
|
157
|
-
if (!isBrowser) return;
|
|
158
|
-
|
|
159
|
-
// Extrair domΓnio atual (para umbrella domain)
|
|
160
|
-
const currentDomain = window.location.hostname;
|
|
161
|
-
const rootDomain = currentDomain.split('.').slice(-2).join('.'); // ex: example.com
|
|
162
|
-
|
|
163
|
-
const cookieOptions = [
|
|
164
|
-
`${name}=${value}`,
|
|
165
|
-
`max-age=${maxAge}`,
|
|
166
|
-
'path=/',
|
|
167
|
-
`domain=.${rootDomain}`, // Umbrella domain para subdomΓnios
|
|
168
|
-
'SameSite=Lax',
|
|
169
|
-
'Secure'
|
|
170
|
-
].join('; ');
|
|
171
|
-
|
|
172
|
-
document.cookie = cookieOptions;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* ObtΓ©m cookie first-party
|
|
177
|
-
*
|
|
178
|
-
* @param {string} name - Nome do cookie
|
|
179
|
-
* @returns {string|null} Valor do cookie ou null
|
|
180
|
-
*/
|
|
181
|
-
function getFirstPartyCookie(name) {
|
|
182
|
-
if (!isBrowser) return null;
|
|
183
|
-
|
|
184
|
-
const value = `; ${document.cookie}`;
|
|
185
|
-
const parts = value.split(`; ${name}=`);
|
|
186
|
-
|
|
187
|
-
if (parts.length === 2) {
|
|
188
|
-
return parts.pop().split(';').shift();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return null;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// ββ Lightweight Code (Evitar Patterns de Bloqueio) βββββββββ
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Verifica se cΓ³digo deve ser minificado (evitar palavras-chave de ad-blockers)
|
|
198
|
-
*
|
|
199
|
-
* @returns {boolean} True se deve minificar
|
|
200
|
-
*/
|
|
201
|
-
function shouldMinifyCode() {
|
|
202
|
-
return ANTI_BLOCKING_CONFIG.minify && isBrowser;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Remove console.logs se configurado (evitar detecΓ§Γ£o)
|
|
207
|
-
*
|
|
208
|
-
* @param {boolean} remove - Remove console.logs?
|
|
209
|
-
*/
|
|
210
|
-
function configureConsoleLogs(remove = ANTI_BLOCKING_CONFIG.noConsoleLogs) {
|
|
211
|
-
if (!isBrowser || !remove) return;
|
|
212
|
-
|
|
213
|
-
// Sobrescrever console com funΓ§Γ΅es vazias
|
|
214
|
-
const noop = () => {};
|
|
215
|
-
console.log = noop;
|
|
216
|
-
console.warn = noop;
|
|
217
|
-
console.error = noop;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ββ Same-Domain Protocol (Anti-Adblock) βββββββββββββ
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Verifica se endpoint estΓ‘ no mesmo domΓnio
|
|
224
|
-
*
|
|
225
|
-
* @param {string} endpoint - Endpoint para verificar
|
|
226
|
-
* @returns {boolean} True se mesmo domΓnio
|
|
227
|
-
*/
|
|
228
|
-
function isSameDomain(endpoint) {
|
|
229
|
-
if (!isBrowser) return true;
|
|
230
|
-
|
|
231
|
-
const endpointUrl = new URL(endpoint, window.location.href);
|
|
232
|
-
return endpointUrl.hostname === window.location.hostname;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// ββ InicializaΓ§Γ£o ββββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Inicializa sistema de anti-blocking
|
|
239
|
-
*/
|
|
240
|
-
function initAntiBlocking() {
|
|
241
|
-
if (!isBrowser) return;
|
|
242
|
-
|
|
243
|
-
console.log('π‘οΈ Inicializando Anti-Blocking System...');
|
|
244
|
-
|
|
245
|
-
// 1. Detectar ad-blocker
|
|
246
|
-
const adBlockerActive = detectAdBlocker();
|
|
247
|
-
if (adBlockerActive) {
|
|
248
|
-
console.warn('β οΈ Ad-Blocker detectado - usando estratΓ©gias de resiliΓͺncia');
|
|
249
|
-
// Enviar evento de ad-blocker detectado
|
|
250
|
-
if (typeof cdpTrack !== 'undefined' && cdpTrack.track) {
|
|
251
|
-
cdpTrack.track('adblocker_detected', {
|
|
252
|
-
user_agent: navigator.userAgent,
|
|
253
|
-
timestamp: Date.now()
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// 2. Configurar first-party cookies
|
|
259
|
-
const userId = getFirstPartyCookie('_cdp_uid');
|
|
260
|
-
if (!userId) {
|
|
261
|
-
const newUserId = `${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
262
|
-
setFirstPartyCookie('_cdp_uid', newUserId);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// 3. Configurar console logs (se necessΓ‘rio)
|
|
266
|
-
if (ANTI_BLOCKING_CONFIG.noConsoleLogs) {
|
|
267
|
-
configureConsoleLogs(true);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
console.log('β
Anti-Blocking System inicializado');
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// ββ ExportaΓ§Γ΅es ββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
274
|
-
|
|
275
|
-
export {
|
|
276
|
-
sendWithRetry,
|
|
277
|
-
detectAdBlocker,
|
|
278
|
-
setFirstPartyCookie,
|
|
279
|
-
getFirstPartyCookie,
|
|
280
|
-
isSameDomain,
|
|
281
|
-
configureConsoleLogs,
|
|
282
|
-
shouldMinifyCode,
|
|
283
|
-
ANTI_BLOCKING_CONFIG,
|
|
284
|
-
initAntiBlocking
|
|
285
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* ANTI-BLOCKING STRATEGY - CDP Edge (Quantum Tier)
|
|
3
|
+
*
|
|
4
|
+
* Sistema para maximizar resiliΓͺncia contra ad-blockers e garantir
|
|
5
|
+
* que o tracking funcione mesmo em ambientes hostis.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ββ Guards ββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
11
|
+
const isBrowser = typeof window !== 'undefined';
|
|
12
|
+
|
|
13
|
+
// ββ ConfiguraΓ§Γ΅es de Anti-Blocking βββββββββββββββββββββ
|
|
14
|
+
|
|
15
|
+
const ANTI_BLOCKING_CONFIG = {
|
|
16
|
+
// Mesmo domΓnio evita bloqueios de CORS e ad-blockers
|
|
17
|
+
endpoint: '/track',
|
|
18
|
+
|
|
19
|
+
// Retries com exponential backoff
|
|
20
|
+
maxRetries: 3,
|
|
21
|
+
retryDelays: [1000, 3000, 6000], // 1s, 3s, 6s
|
|
22
|
+
|
|
23
|
+
// Fallback para Beacon API (quando fetch falha)
|
|
24
|
+
useBeaconFallback: true,
|
|
25
|
+
|
|
26
|
+
// First-party cookies (ad-block proof)
|
|
27
|
+
cookieDuration: 60 * 60 * 24 * 365, // 365 dias
|
|
28
|
+
cookieDomain: '', // SerΓ‘ definido dinamicamente
|
|
29
|
+
|
|
30
|
+
// Detectar ad-blockers
|
|
31
|
+
detectAdBlocker: true,
|
|
32
|
+
adBlockerBaitClass: 'adsbox adbanner pub_300x250',
|
|
33
|
+
|
|
34
|
+
// Lightweight code (evitar patterns de bloqueio)
|
|
35
|
+
minify: false, // Opcional: usar cΓ³digo minificado em produΓ§Γ£o
|
|
36
|
+
noConsoleLogs: false, // Opcional: remover console.logs em produΓ§Γ£o
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// ββ DetecΓ§Γ£o de Ad-Blocker βββββββββββββββββββββββββ
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Detecta se um ad-blocker estΓ‘ ativo
|
|
43
|
+
*
|
|
44
|
+
* @returns {boolean} True se ad-blocker detectado
|
|
45
|
+
*/
|
|
46
|
+
function detectAdBlocker() {
|
|
47
|
+
if (!isBrowser || !ANTI_BLOCKING_CONFIG.detectAdBlocker) return false;
|
|
48
|
+
|
|
49
|
+
// MΓ©todo 1: Criar elemento com classe comum de ads
|
|
50
|
+
const baitElement = document.createElement('div');
|
|
51
|
+
baitElement.innerHTML = ' ';
|
|
52
|
+
baitElement.className = ANTI_BLOCKING_CONFIG.adBlockerBaitClass;
|
|
53
|
+
baitElement.style.cssText = 'position: absolute; top: -1000px; left: -1000px;';
|
|
54
|
+
document.body.appendChild(baitElement);
|
|
55
|
+
|
|
56
|
+
const isBlocked = getComputedStyle(baitElement).display === 'none';
|
|
57
|
+
|
|
58
|
+
document.body.removeChild(baitElement);
|
|
59
|
+
|
|
60
|
+
// MΓ©todo 2: Verificar se bloqueia requests de tracking
|
|
61
|
+
try {
|
|
62
|
+
const testPixel = new Image();
|
|
63
|
+
testPixel.src = '/pixel-test.png?t=' + Date.now();
|
|
64
|
+
testPixel.onload = () => console.log('β
Pixel nΓ£o bloqueado');
|
|
65
|
+
testPixel.onerror = () => console.warn('β οΈ Pixel pode estar bloqueado');
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.warn('β οΈ Erro ao testar pixel:', error);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return isBlocked;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ββ ResiliΓͺncia de Envio βββββββββββββββββββββββββββββ
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Envia dados com retry automΓ‘tico (exponential backoff)
|
|
77
|
+
*
|
|
78
|
+
* @param {object} data - Dados para enviar
|
|
79
|
+
* @param {string} endpoint - Endpoint de destino
|
|
80
|
+
* @returns {Promise} Promise com resultado
|
|
81
|
+
*/
|
|
82
|
+
async function sendWithRetry(data, endpoint = ANTI_BLOCKING_CONFIG.endpoint) {
|
|
83
|
+
if (!isBrowser) return { success: false, error: 'Not in browser' };
|
|
84
|
+
|
|
85
|
+
let lastError = null;
|
|
86
|
+
|
|
87
|
+
for (let attempt = 0; attempt < ANTI_BLOCKING_CONFIG.maxRetries; attempt++) {
|
|
88
|
+
try {
|
|
89
|
+
// Tenta enviar via fetch
|
|
90
|
+
const response = await fetch(endpoint, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: {
|
|
93
|
+
'Content-Type': 'application/json',
|
|
94
|
+
},
|
|
95
|
+
body: JSON.stringify(data),
|
|
96
|
+
keepalive: true, // Garante envio mesmo se usuΓ‘rio fechar aba
|
|
97
|
+
credentials: 'same-origin', // First-party cookies
|
|
98
|
+
cache: 'no-cache' // Evitar cache de requests de tracking
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (response.ok) {
|
|
102
|
+
console.log(`β
Envio bem-sucedido (tentativa ${attempt + 1})`);
|
|
103
|
+
return await response.json();
|
|
104
|
+
} else {
|
|
105
|
+
const errorText = await response.text();
|
|
106
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
lastError = error;
|
|
110
|
+
console.warn(`β οΈ Tentativa ${attempt + 1} falhou:`, error.message);
|
|
111
|
+
|
|
112
|
+
// Se nΓ£o for a ΓΊltima tentativa, aguarda antes de retry
|
|
113
|
+
if (attempt < ANTI_BLOCKING_CONFIG.maxRetries - 1) {
|
|
114
|
+
const delay = ANTI_BLOCKING_CONFIG.retryDelays[attempt];
|
|
115
|
+
console.log(`β³ Aguardando ${delay}ms antes de retry...`);
|
|
116
|
+
await sleep(delay);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Todas as tentativas falharam
|
|
122
|
+
console.error('β Todas as tentativas de envio falharam:', lastError);
|
|
123
|
+
|
|
124
|
+
// Fallback: Beacon API
|
|
125
|
+
if (ANTI_BLOCKING_CONFIG.useBeaconFallback && navigator.sendBeacon) {
|
|
126
|
+
console.log('π Tentando Beacon API como fallback...');
|
|
127
|
+
const beaconSuccess = navigator.sendBeacon(endpoint, JSON.stringify(data));
|
|
128
|
+
|
|
129
|
+
if (beaconSuccess) {
|
|
130
|
+
console.log('β
Beacon API bem-sucedido');
|
|
131
|
+
return { success: true, method: 'beacon' };
|
|
132
|
+
} else {
|
|
133
|
+
console.error('β Beacon API tambΓ©m falhou');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return { success: false, error: lastError?.message, attempts: ANTI_BLOCKING_CONFIG.maxRetries };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* FunΓ§Γ£o utilitΓ‘ria de delay
|
|
142
|
+
*/
|
|
143
|
+
function sleep(ms) {
|
|
144
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ββ First-Party Cookies (Ad-Block Proof) βββββββββββββββ
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Define cookie first-party (nΓ£o bloqueado por ad-blockers)
|
|
151
|
+
*
|
|
152
|
+
* @param {string} name - Nome do cookie
|
|
153
|
+
* @param {string} value - Valor do cookie
|
|
154
|
+
* @param {number} maxAge - Tempo de vida em segundos
|
|
155
|
+
*/
|
|
156
|
+
function setFirstPartyCookie(name, value, maxAge = ANTI_BLOCKING_CONFIG.cookieDuration) {
|
|
157
|
+
if (!isBrowser) return;
|
|
158
|
+
|
|
159
|
+
// Extrair domΓnio atual (para umbrella domain)
|
|
160
|
+
const currentDomain = window.location.hostname;
|
|
161
|
+
const rootDomain = currentDomain.split('.').slice(-2).join('.'); // ex: example.com
|
|
162
|
+
|
|
163
|
+
const cookieOptions = [
|
|
164
|
+
`${name}=${value}`,
|
|
165
|
+
`max-age=${maxAge}`,
|
|
166
|
+
'path=/',
|
|
167
|
+
`domain=.${rootDomain}`, // Umbrella domain para subdomΓnios
|
|
168
|
+
'SameSite=Lax',
|
|
169
|
+
'Secure'
|
|
170
|
+
].join('; ');
|
|
171
|
+
|
|
172
|
+
document.cookie = cookieOptions;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* ObtΓ©m cookie first-party
|
|
177
|
+
*
|
|
178
|
+
* @param {string} name - Nome do cookie
|
|
179
|
+
* @returns {string|null} Valor do cookie ou null
|
|
180
|
+
*/
|
|
181
|
+
function getFirstPartyCookie(name) {
|
|
182
|
+
if (!isBrowser) return null;
|
|
183
|
+
|
|
184
|
+
const value = `; ${document.cookie}`;
|
|
185
|
+
const parts = value.split(`; ${name}=`);
|
|
186
|
+
|
|
187
|
+
if (parts.length === 2) {
|
|
188
|
+
return parts.pop().split(';').shift();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// ββ Lightweight Code (Evitar Patterns de Bloqueio) βββββββββ
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Verifica se cΓ³digo deve ser minificado (evitar palavras-chave de ad-blockers)
|
|
198
|
+
*
|
|
199
|
+
* @returns {boolean} True se deve minificar
|
|
200
|
+
*/
|
|
201
|
+
function shouldMinifyCode() {
|
|
202
|
+
return ANTI_BLOCKING_CONFIG.minify && isBrowser;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Remove console.logs se configurado (evitar detecΓ§Γ£o)
|
|
207
|
+
*
|
|
208
|
+
* @param {boolean} remove - Remove console.logs?
|
|
209
|
+
*/
|
|
210
|
+
function configureConsoleLogs(remove = ANTI_BLOCKING_CONFIG.noConsoleLogs) {
|
|
211
|
+
if (!isBrowser || !remove) return;
|
|
212
|
+
|
|
213
|
+
// Sobrescrever console com funΓ§Γ΅es vazias
|
|
214
|
+
const noop = () => {};
|
|
215
|
+
console.log = noop;
|
|
216
|
+
console.warn = noop;
|
|
217
|
+
console.error = noop;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ββ Same-Domain Protocol (Anti-Adblock) βββββββββββββ
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Verifica se endpoint estΓ‘ no mesmo domΓnio
|
|
224
|
+
*
|
|
225
|
+
* @param {string} endpoint - Endpoint para verificar
|
|
226
|
+
* @returns {boolean} True se mesmo domΓnio
|
|
227
|
+
*/
|
|
228
|
+
function isSameDomain(endpoint) {
|
|
229
|
+
if (!isBrowser) return true;
|
|
230
|
+
|
|
231
|
+
const endpointUrl = new URL(endpoint, window.location.href);
|
|
232
|
+
return endpointUrl.hostname === window.location.hostname;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// ββ InicializaΓ§Γ£o ββββββββββββββββββββββββββββββββββββββββββββ
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Inicializa sistema de anti-blocking
|
|
239
|
+
*/
|
|
240
|
+
function initAntiBlocking() {
|
|
241
|
+
if (!isBrowser) return;
|
|
242
|
+
|
|
243
|
+
console.log('π‘οΈ Inicializando Anti-Blocking System...');
|
|
244
|
+
|
|
245
|
+
// 1. Detectar ad-blocker
|
|
246
|
+
const adBlockerActive = detectAdBlocker();
|
|
247
|
+
if (adBlockerActive) {
|
|
248
|
+
console.warn('β οΈ Ad-Blocker detectado - usando estratΓ©gias de resiliΓͺncia');
|
|
249
|
+
// Enviar evento de ad-blocker detectado
|
|
250
|
+
if (typeof cdpTrack !== 'undefined' && cdpTrack.track) {
|
|
251
|
+
cdpTrack.track('adblocker_detected', {
|
|
252
|
+
user_agent: navigator.userAgent,
|
|
253
|
+
timestamp: Date.now()
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// 2. Configurar first-party cookies
|
|
259
|
+
const userId = getFirstPartyCookie('_cdp_uid');
|
|
260
|
+
if (!userId) {
|
|
261
|
+
const newUserId = `${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
|
|
262
|
+
setFirstPartyCookie('_cdp_uid', newUserId);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// 3. Configurar console logs (se necessΓ‘rio)
|
|
266
|
+
if (ANTI_BLOCKING_CONFIG.noConsoleLogs) {
|
|
267
|
+
configureConsoleLogs(true);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
console.log('β
Anti-Blocking System inicializado');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ββ ExportaΓ§Γ΅es ββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
274
|
+
|
|
275
|
+
export {
|
|
276
|
+
sendWithRetry,
|
|
277
|
+
detectAdBlocker,
|
|
278
|
+
setFirstPartyCookie,
|
|
279
|
+
getFirstPartyCookie,
|
|
280
|
+
isSameDomain,
|
|
281
|
+
configureConsoleLogs,
|
|
282
|
+
shouldMinifyCode,
|
|
283
|
+
ANTI_BLOCKING_CONFIG,
|
|
284
|
+
initAntiBlocking
|
|
285
|
+
};
|