@saulwade/swl-ses 2.4.3 → 2.5.1
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/CLAUDE.md +194 -241
- package/README.md +600 -597
- package/agentes/_intent-spec.md +73 -73
- package/agentes/_propose-step.md +90 -90
- package/agentes/abogado-diablo-swl.md +145 -0
- package/agentes/accesibilidad-wcag-swl.md +690 -690
- package/agentes/arquitecto-swl.md +267 -267
- package/agentes/auto-evolucion-swl.md +908 -908
- package/agentes/backend-api-swl.md +1 -1
- package/agentes/backend-csharp-swl.md +420 -420
- package/agentes/backend-go-swl.md +390 -390
- package/agentes/backend-java-swl.md +281 -281
- package/agentes/backend-node-swl.md +1 -1
- package/agentes/backend-python-swl.md +1 -1
- package/agentes/backend-rust-swl.md +364 -364
- package/agentes/backend-workers-swl.md +482 -482
- package/agentes/cloud-infra-swl.md +509 -509
- package/agentes/consolidador-swl.md +541 -541
- package/agentes/datos-swl.md +1 -1
- package/agentes/depurador-swl.md +352 -352
- package/agentes/devops-ci-swl.md +400 -400
- package/agentes/disenador-ui-swl.md +569 -569
- package/agentes/documentador-swl.md +345 -345
- package/agentes/frontend-angular-swl.md +621 -621
- package/agentes/frontend-css-swl.md +716 -716
- package/agentes/frontend-react-swl.md +692 -692
- package/agentes/frontend-swl.md +496 -496
- package/agentes/frontend-tailwind-swl.md +826 -826
- package/agentes/gh-fix-ci-swl.md +6 -1
- package/agentes/implementador-swl.md +1 -1
- package/agentes/investigador-swl.md +432 -432
- package/agentes/investigador-ux-swl.md +505 -505
- package/agentes/llm-apps-swl.md +1 -1
- package/agentes/migrador-swl.md +442 -442
- package/agentes/mobile-android-swl.md +511 -511
- package/agentes/mobile-cross-swl.md +541 -541
- package/agentes/mobile-ios-swl.md +502 -502
- package/agentes/mobile-testing-swl.md +302 -302
- package/agentes/nemesis-auditor-swl.md +285 -285
- package/agentes/notificador-swl.md +1 -1
- package/agentes/observabilidad-swl.md +438 -438
- package/agentes/pagos-swl.md +310 -310
- package/agentes/perfilador-usuario-swl.md +321 -321
- package/agentes/planificador-swl.md +399 -399
- package/agentes/producto-prd-swl.md +589 -589
- package/agentes/red-team-swl.md +218 -218
- package/agentes/release-manager-swl.md +590 -590
- package/agentes/rendimiento-swl.md +713 -713
- package/agentes/resolutor-build-swl.md +10 -1
- package/agentes/revisor-angular-swl.md +278 -278
- package/agentes/revisor-codigo-swl.md +1 -1
- package/agentes/revisor-csharp-swl.md +264 -264
- package/agentes/revisor-go-swl.md +259 -259
- package/agentes/revisor-java-swl.md +257 -257
- package/agentes/revisor-kotlin-swl.md +273 -273
- package/agentes/revisor-nextjs-swl.md +281 -281
- package/agentes/revisor-php-swl.md +271 -271
- package/agentes/revisor-react-swl.md +278 -278
- package/agentes/revisor-rust-swl.md +346 -346
- package/agentes/revisor-seguridad-swl.md +399 -399
- package/agentes/revisor-swift-swl.md +268 -268
- package/agentes/revisor-typescript-swl.md +346 -346
- package/agentes/sre-swl.md +1 -1
- package/agentes/tdd-qa-swl.md +393 -393
- package/bin/lib/bot-comandos.js +1 -1
- package/bin/swl-ses.js +6 -0
- package/comandos/swl/adoptar-proyecto.md +14 -2
- package/comandos/swl/configurar-ci.md +8 -1
- package/comandos/swl/deuda-codigo.md +97 -97
- package/comandos/swl/discutir-fase.md +22 -118
- package/comandos/swl/fix.md +118 -0
- package/comandos/swl/nuevo-proyecto.md +54 -3
- package/comandos/swl/predecir.md +32 -2
- package/comandos/swl/seguridad.md +189 -0
- package/comandos/swl/status.md +5 -3
- package/habilidades/aprendizaje-continuo/SKILL.md +3 -1
- package/habilidades/discutir-fase/SKILL.md +84 -81
- package/habilidades/discutir-fase/recursos/plantilla-contexto.md +136 -0
- package/habilidades/doc-sync/SKILL.md +3 -1
- package/habilidades/doubt-driven-review/SKILL.md +15 -1
- package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
- package/habilidades/estructura-proyecto-claude/SKILL.md +11 -2
- package/habilidades/harness-claude-code/SKILL.md +3 -1
- package/habilidades/instalar-sistema/SKILL.md +3 -1
- package/habilidades/meta-reglas-extendido/SKILL.md +92 -0
- package/habilidades/meta-reglas-extendido/recursos/analisis-previo-tareas-grandes.md +186 -0
- package/habilidades/meta-reglas-extendido/recursos/analizar-directorios-antes-de-escribir.md +235 -0
- package/habilidades/meta-reglas-extendido/recursos/api-diseno.md +413 -0
- package/habilidades/meta-reglas-extendido/recursos/arquitectura.md +491 -0
- package/habilidades/meta-reglas-extendido/recursos/arreglar-al-detectar.md +264 -0
- package/habilidades/meta-reglas-extendido/recursos/debatir-antes-de-aceptar.md +152 -0
- package/habilidades/meta-reglas-extendido/recursos/git-workflow.md +259 -0
- package/habilidades/meta-reglas-extendido/recursos/gobernanza.md +291 -0
- package/habilidades/meta-reglas-extendido/recursos/memoria-consolidada.md +263 -0
- package/habilidades/meta-reglas-extendido/recursos/seguridad-agentes.md +443 -0
- package/habilidades/meta-reglas-extendido/recursos/sesiones-paralelas.md +190 -0
- package/habilidades/meta-reglas-extendido/recursos/sin-duplicacion-reglas-globales.md +179 -0
- package/habilidades/meta-reglas-extendido/recursos/skills-estandar.md +394 -0
- package/habilidades/meta-reglas-extendido/recursos/usar-code-review-graph.md +156 -0
- package/habilidades/meta-reglas-extendido/recursos/usar-context7.md +236 -0
- package/habilidades/meta-reglas-extendido/recursos/usar-sistema-swl.md +253 -0
- package/habilidades/meta-reglas-extendido/recursos/verificar-citas-normativas.md +527 -0
- package/habilidades/meta-skills-estandar/SKILL.md +3 -1
- package/habilidades/nuevo-proyecto/SKILL.md +20 -3
- package/habilidades/php-experto/SKILL.md +10 -3
- package/habilidades/{filament-admin/SKILL.md → php-experto/recursos/filament-admin.md} +23 -39
- package/habilidades/prevencion-sobreingenieria/recursos/soluciones-nativas.md +166 -166
- package/habilidades/prevencion-sobreingenieria/recursos/variables-residuales-post-refactor.md +85 -85
- package/habilidades/proceso-debate-adversarial/recursos/personas.md +5 -4
- package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -0
- package/hooks/check-update.js +19 -10
- package/hooks/contexto-subagente.js +68 -68
- package/hooks/degradacion-instintos.js +1 -1
- package/hooks/extraccion-aprendizajes.js +2 -2
- package/hooks/lib/briefing.js +3 -3
- package/hooks/lib/nudge-tracker.js +1 -1
- package/hooks/lib/otlp-exporter.js +1 -1
- package/hooks/lib/webhook-dedup.js +1 -1
- package/hooks/session-briefing.js +1 -1
- package/llms.txt +6 -6
- package/manifiestos/canonical-hashes.json +713 -52
- package/manifiestos/hooks-config.json +469 -469
- package/manifiestos/invariantes-criticos.json +30 -30
- package/manifiestos/modulos.json +168 -135
- package/manifiestos/perfiles.json +0 -2
- package/manifiestos/skills-lock.json +49 -56
- package/package.json +7 -5
- package/plantillas/github-workflows/README.md +15 -1
- package/plantillas/github-workflows/swl-devsecops.yml +70 -0
- package/plugin.json +5 -5
- package/reglas/analisis-previo-tareas-grandes.md +30 -156
- package/reglas/analizar-directorios-antes-de-escribir.md +30 -211
- package/reglas/api-diseno.md +28 -398
- package/reglas/arquitectura.md +35 -456
- package/reglas/arreglar-al-detectar.md +30 -230
- package/reglas/debatir-antes-de-aceptar.md +30 -143
- package/reglas/docs.md +7 -0
- package/reglas/estilo-codigo.md +9 -0
- package/reglas/fragmentos-compartidos.md +6 -0
- package/reglas/git-workflow.md +44 -240
- package/reglas/gobernanza.md +23 -262
- package/reglas/memoria-consolidada.md +34 -228
- package/reglas/performance.md +8 -0
- package/reglas/pruebas.md +12 -0
- package/reglas/seguridad-agentes.md +37 -418
- package/reglas/seguridad.md +12 -0
- package/reglas/sesiones-paralelas.md +29 -162
- package/reglas/sin-duplicacion-reglas-globales.md +25 -166
- package/reglas/skills-estandar.md +23 -373
- package/reglas/usar-code-review-graph.md +31 -140
- package/reglas/usar-context7.md +30 -208
- package/reglas/usar-sistema-swl.md +47 -242
- package/reglas/verificar-citas-normativas.md +47 -537
- package/scripts/actualizar.js +253 -253
- package/scripts/audit-tools/auditar-relleno-inventario.js +145 -0
- package/scripts/auditar-clases-conocidas.js +106 -0
- package/scripts/bootstrap-instintos.js +2 -2
- package/scripts/canario-hooks.js +166 -0
- package/scripts/cli/configurar-ci.js +2 -1
- package/scripts/evidencia-valor.js +93 -0
- package/scripts/field-report.js +1 -1
- package/scripts/generar-comandos.js +143 -0
- package/scripts/generar-inventario.js +236 -23
- package/scripts/generar-matriz-lenguajes.js +1 -1
- package/scripts/instalador.js +15 -1
- package/scripts/lib/configurar-ci.js +10 -3
- package/scripts/lib/diary-entry.js +3 -1
- package/scripts/lib/drift-detector.js +1 -1
- package/scripts/lib/evidencia-valor.js +189 -0
- package/scripts/lib/expandir-targets.js +71 -71
- package/scripts/lib/frontmatter-md.js +63 -0
- package/scripts/lib/parsear-opciones.js +2 -0
- package/scripts/lib/prune-componentes.js +180 -0
- package/scripts/lib/reglas-globales-conocidas.json +16 -2
- package/scripts/lib/scoring-instintos.js +2 -2
- package/scripts/lib/toml-merge.js +204 -204
- package/scripts/lib/transformadores/claude.js +1 -1
- package/scripts/lib/transformadores/codex.js +1 -1
- package/scripts/lib/transformadores/copilot.js +1 -1
- package/scripts/lib/transformadores/cursor.js +1 -1
- package/scripts/lib/transformadores/gemini.js +22 -2
- package/scripts/lib/transformadores/opencode.js +1 -1
- package/scripts/mcp-server/auth.js +105 -105
- package/scripts/mcp-server/cache.js +106 -106
- package/scripts/prune.js +102 -0
- package/scripts/publicar.js +18 -2
- package/scripts/tui/pantallas/inspect.js +175 -175
- package/scripts/tui/pantallas/uninstall-wizard.js +210 -210
- package/scripts/tui/pantallas/update-wizard.js +234 -234
- package/scripts/tui/pantallas/welcome.js +189 -189
- package/habilidades/paid-media-tracking/SKILL.md +0 -269
- package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +0 -220
- package/habilidades/paid-media-tracking/recursos/google-ads-api.md +0 -215
- package/habilidades/tracking-measurement/SKILL.md +0 -239
- package/habilidades/tracking-measurement/recursos/consent-mode.md +0 -231
- package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +0 -216
- package/habilidades/tracking-measurement/recursos/meta-capi.md +0 -262
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
# Consent Mode v2: GDPR, CCPA e integración con CMPs
|
|
2
|
-
|
|
3
|
-
## Qué es Consent Mode v2
|
|
4
|
-
|
|
5
|
-
Consent Mode v2 es un mecanismo de Google que permite a los tags de Google
|
|
6
|
-
(GA4, Google Ads, Floodlight) adaptar su comportamiento según el consentimiento
|
|
7
|
-
del usuario. Introducido en 2024 como requisito para mantener la personalización
|
|
8
|
-
de anuncios en el EEE y UK.
|
|
9
|
-
|
|
10
|
-
### Los 4 parámetros de consentimiento
|
|
11
|
-
|
|
12
|
-
| Parámetro | Controla |
|
|
13
|
-
|-----------|----------|
|
|
14
|
-
| `analytics_storage` | Cookies de medición (GA4: `_ga`, `_ga_*`) |
|
|
15
|
-
| `ad_storage` | Cookies de publicidad (Google Ads, Floodlight) |
|
|
16
|
-
| `ad_user_data` | Envío de datos de usuario a Google para publicidad |
|
|
17
|
-
| `ad_personalization` | Remarketing y personalización de anuncios |
|
|
18
|
-
|
|
19
|
-
Cuando un parámetro está `denied`, Google no almacena cookies pero sí
|
|
20
|
-
registra eventos "sin cookies" (pings anónimos) para el modelado estadístico.
|
|
21
|
-
|
|
22
|
-
## Implementación base con gtag
|
|
23
|
-
|
|
24
|
-
El código de Consent Mode debe ejecutarse ANTES del snippet de GTM o gtag.
|
|
25
|
-
El orden importa: si GTM carga primero, puede crear cookies antes del consentimiento.
|
|
26
|
-
|
|
27
|
-
```html
|
|
28
|
-
<!-- 1. Snippet de Consent Mode — ANTES de GTM -->
|
|
29
|
-
<script>
|
|
30
|
-
window.dataLayer = window.dataLayer || [];
|
|
31
|
-
function gtag(){dataLayer.push(arguments);}
|
|
32
|
-
|
|
33
|
-
gtag('consent', 'default', {
|
|
34
|
-
analytics_storage: 'denied',
|
|
35
|
-
ad_storage: 'denied',
|
|
36
|
-
ad_user_data: 'denied',
|
|
37
|
-
ad_personalization: 'denied',
|
|
38
|
-
wait_for_update: 500, // ms para esperar la respuesta del CMP
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
gtag('set', 'ads_data_redaction', true); // Redactar URLs de click si denied
|
|
42
|
-
gtag('set', 'url_passthrough', true); // Pasar info de click en URL para atribución
|
|
43
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<!-- 2. Snippet de GTM — DESPUÉS de Consent Mode -->
|
|
46
|
-
<script>
|
|
47
|
-
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
48
|
-
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
49
|
-
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
50
|
-
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
51
|
-
})(window,document,'script','dataLayer','GTM-XXXXXXX');
|
|
52
|
-
</script>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Actualizar consentimiento tras decisión del usuario
|
|
56
|
-
|
|
57
|
-
```javascript
|
|
58
|
-
// Llamar después de que el usuario acepta en el banner del CMP
|
|
59
|
-
function otorgarConsentimiento(opciones) {
|
|
60
|
-
gtag('consent', 'update', {
|
|
61
|
-
analytics_storage: opciones.analytics ? 'granted' : 'denied',
|
|
62
|
-
ad_storage: opciones.publicidad ? 'granted' : 'denied',
|
|
63
|
-
ad_user_data: opciones.publicidad ? 'granted' : 'denied',
|
|
64
|
-
ad_personalization: opciones.publicidad ? 'granted' : 'denied',
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Llamar cuando el usuario rechaza todo
|
|
69
|
-
function rechazarConsentimiento() {
|
|
70
|
-
gtag('consent', 'update', {
|
|
71
|
-
analytics_storage: 'denied',
|
|
72
|
-
ad_storage: 'denied',
|
|
73
|
-
ad_user_data: 'denied',
|
|
74
|
-
ad_personalization: 'denied',
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Integración con CMPs
|
|
80
|
-
|
|
81
|
-
### Cookiebot
|
|
82
|
-
|
|
83
|
-
Cookiebot dispara el evento `CookiebotOnAccept` / `CookiebotOnDecline`.
|
|
84
|
-
Integración directa disponible en GTM como template oficial de la galería.
|
|
85
|
-
|
|
86
|
-
```javascript
|
|
87
|
-
// Listener para Cookiebot
|
|
88
|
-
window.addEventListener('CookiebotOnAccept', function() {
|
|
89
|
-
gtag('consent', 'update', {
|
|
90
|
-
analytics_storage: Cookiebot.consent.statistics ? 'granted' : 'denied',
|
|
91
|
-
ad_storage: Cookiebot.consent.marketing ? 'granted' : 'denied',
|
|
92
|
-
ad_user_data: Cookiebot.consent.marketing ? 'granted' : 'denied',
|
|
93
|
-
ad_personalization: Cookiebot.consent.marketing ? 'granted' : 'denied',
|
|
94
|
-
});
|
|
95
|
-
}, false);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### OneTrust
|
|
99
|
-
|
|
100
|
-
OneTrust usa categorías de cookies mapeadas a grupos:
|
|
101
|
-
|
|
102
|
-
| Grupo OneTrust | Parámetro Consent Mode |
|
|
103
|
-
|---------------|----------------------|
|
|
104
|
-
| `C0002` (Performance) | `analytics_storage` |
|
|
105
|
-
| `C0004` (Targeting) | `ad_storage`, `ad_user_data`, `ad_personalization` |
|
|
106
|
-
|
|
107
|
-
```javascript
|
|
108
|
-
// Template GTM disponible en: OneTrust > GTM Integration
|
|
109
|
-
// O implementación manual:
|
|
110
|
-
window.OneTrust?.OnConsentChanged(function(event) {
|
|
111
|
-
const activas = event.detail;
|
|
112
|
-
gtag('consent', 'update', {
|
|
113
|
-
analytics_storage: activas.includes('C0002') ? 'granted' : 'denied',
|
|
114
|
-
ad_storage: activas.includes('C0004') ? 'granted' : 'denied',
|
|
115
|
-
ad_user_data: activas.includes('C0004') ? 'granted' : 'denied',
|
|
116
|
-
ad_personalization: activas.includes('C0004') ? 'granted' : 'denied',
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
### Usercentrics
|
|
122
|
-
|
|
123
|
-
Usercentrics expone el objeto `UC_UI` y el evento `ucEvent`:
|
|
124
|
-
|
|
125
|
-
```javascript
|
|
126
|
-
window.addEventListener('ucEvent', function(e) {
|
|
127
|
-
if (e.detail?.event === 'consent_status') {
|
|
128
|
-
const servicios = e.detail;
|
|
129
|
-
gtag('consent', 'update', {
|
|
130
|
-
analytics_storage: servicios['Google Analytics'] ? 'granted' : 'denied',
|
|
131
|
-
ad_storage: servicios['Google Ads'] ? 'granted' : 'denied',
|
|
132
|
-
ad_user_data: servicios['Google Ads'] ? 'granted' : 'denied',
|
|
133
|
-
ad_personalization: servicios['Google Ads'] ? 'granted' : 'denied',
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
## Modelado de conversiones en GA4
|
|
140
|
-
|
|
141
|
-
Cuando `analytics_storage` o `ad_storage` está `denied`, GA4 no puede
|
|
142
|
-
atribuir conversiones directamente. Google utiliza ML para estimar las
|
|
143
|
-
conversiones faltantes basándose en usuarios con consentimiento similar.
|
|
144
|
-
|
|
145
|
-
**Condiciones para que el modelado funcione**:
|
|
146
|
-
- Mínimo 1,000 conversiones observables por semana.
|
|
147
|
-
- Tasa de consentimiento > 0% (si nadie acepta, no hay datos base).
|
|
148
|
-
- Consent Mode implementado correctamente (los pings anónimos llegan).
|
|
149
|
-
|
|
150
|
-
**Verificar que los pings llegan**: En GA4 > Admin > Data streams > tu stream >
|
|
151
|
-
Measurement Protocol. Debe mostrar eventos incluso de usuarios sin consentimiento
|
|
152
|
-
(aparecen como eventos anónimos sin `client_id`).
|
|
153
|
-
|
|
154
|
-
## GDPR: base legal por tipo de tracking
|
|
155
|
-
|
|
156
|
-
| Tipo de tracking | Base legal posible | Requiere banner |
|
|
157
|
-
|-----------------|-------------------|-----------------|
|
|
158
|
-
| Analytics de medición interna | Interés legítimo (debatible) | Sí, en la mayoría de países |
|
|
159
|
-
| Analytics para mejora de producto | Interés legítimo | Sí |
|
|
160
|
-
| Retargeting / remarketing | Consentimiento explícito | Sí, siempre |
|
|
161
|
-
| Conversiones para optimización de anuncios | Consentimiento explícito | Sí, siempre |
|
|
162
|
-
|
|
163
|
-
**Práctica recomendada**: usar consentimiento explícito para todo tracking
|
|
164
|
-
publicitario y analítico. El interés legítimo es cuestionable y está siendo
|
|
165
|
-
restringido en interpretaciones recientes del GDPR.
|
|
166
|
-
|
|
167
|
-
**Registro de consentimiento**: almacenar en base de datos:
|
|
168
|
-
- Fecha y hora de la decisión
|
|
169
|
-
- Versión de la política de privacidad aceptada
|
|
170
|
-
- Opciones específicas seleccionadas por el usuario
|
|
171
|
-
- IP anonimizada (últimos 2 octetos a 0)
|
|
172
|
-
|
|
173
|
-
## CCPA: opt-out en lugar de opt-in
|
|
174
|
-
|
|
175
|
-
En California (CCPA), el modelo es inverso al GDPR: tracking activo por
|
|
176
|
-
defecto, con obligación de ofrecer opt-out.
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
// URL de opt-out requerida por CCPA
|
|
180
|
-
// El usuario llega desde el enlace "No vender mi información personal"
|
|
181
|
-
if (new URLSearchParams(location.search).has('ccpa_opt_out')) {
|
|
182
|
-
gtag('consent', 'update', {
|
|
183
|
-
ad_storage: 'denied',
|
|
184
|
-
ad_user_data: 'denied',
|
|
185
|
-
ad_personalization: 'denied',
|
|
186
|
-
});
|
|
187
|
-
// Persistir la preferencia en localStorage
|
|
188
|
-
localStorage.setItem('ccpa_opt_out', 'true');
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Al cargar la página, verificar opt-out previo
|
|
192
|
-
if (localStorage.getItem('ccpa_opt_out') === 'true') {
|
|
193
|
-
gtag('consent', 'update', {
|
|
194
|
-
ad_storage: 'denied',
|
|
195
|
-
ad_user_data: 'denied',
|
|
196
|
-
ad_personalization: 'denied',
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
**US Privacy String**: formato `1YNN` (versión 1, aviso notificado, opt-out no,
|
|
202
|
-
LSPA no). Incluir en requests de publicidad si se usa un ad server compatible.
|
|
203
|
-
|
|
204
|
-
## Verificación con Consent Mode Inspector
|
|
205
|
-
|
|
206
|
-
En Chrome DevTools > Application > Cookies:
|
|
207
|
-
- Antes de aceptar: no deben existir `_ga`, `_ga_*`, `_gcl_*`, `_fbp`
|
|
208
|
-
- Después de aceptar analytics: `_ga` y `_ga_MEASUREMENTID` deben aparecer
|
|
209
|
-
- Después de aceptar publicidad: `_gcl_au` (Google Ads) debe aparecer
|
|
210
|
-
|
|
211
|
-
En la consola del browser:
|
|
212
|
-
```javascript
|
|
213
|
-
// Ver estado actual del consentimiento
|
|
214
|
-
window.dataLayer.filter(e => e[0] === 'consent')
|
|
215
|
-
// Debe mostrar el 'default' y los 'update' aplicados
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Con la extensión **Consent Mode Inspector** de Google (Chrome Web Store):
|
|
219
|
-
muestra en tiempo real el estado de cada parámetro y los cambios al interactuar
|
|
220
|
-
con el banner de consentimiento.
|
|
221
|
-
|
|
222
|
-
## Checklist de cumplimiento pre-lanzamiento
|
|
223
|
-
|
|
224
|
-
- [ ] Consent Mode inicializado ANTES del snippet de GTM
|
|
225
|
-
- [ ] Default: los 4 parámetros en `denied`
|
|
226
|
-
- [ ] Banner de CMP visible en primera visita para usuarios del EEE
|
|
227
|
-
- [ ] `gtag('consent', 'update', ...)` se ejecuta al aceptar/rechazar
|
|
228
|
-
- [ ] Sin cookies `_ga`, `_fbp` antes del consentimiento (verificar en DevTools)
|
|
229
|
-
- [ ] Registro de consentimiento almacenado en base de datos
|
|
230
|
-
- [ ] Enlace "No vender mi información" visible en footer (para CCPA)
|
|
231
|
-
- [ ] Política de privacidad actualizada con tecnologías de tracking usadas
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
# GTM: dataLayer avanzado, triggers, variables y server-side
|
|
2
|
-
|
|
3
|
-
## Arquitectura de GTM
|
|
4
|
-
|
|
5
|
-
GTM funciona con tres conceptos fundamentales que se relacionan en orden:
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
Trigger (cuándo) ──► Tag (qué hacer) ──► Variable (con qué datos)
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Un **trigger** detecta un evento en la página. Una **tag** se dispara cuando
|
|
12
|
-
el trigger se activa. Las **variables** proveen los datos que la tag necesita.
|
|
13
|
-
|
|
14
|
-
### Workspace y versiones
|
|
15
|
-
|
|
16
|
-
- El **workspace** es el entorno de trabajo en progreso (sin publicar).
|
|
17
|
-
- Cada **versión** es un snapshot publicado con nombre, fecha y descripción.
|
|
18
|
-
- Crear una versión antes de cada cambio relevante: `Versión > Nueva versión`.
|
|
19
|
-
- En producción usar siempre un contenedor publicado, nunca el workspace.
|
|
20
|
-
- Ambientes (`Environments`): crear uno por stage (dev, staging, prod) para
|
|
21
|
-
probar sin afectar el contenedor de producción.
|
|
22
|
-
|
|
23
|
-
## Variables
|
|
24
|
-
|
|
25
|
-
### Variables built-in
|
|
26
|
-
|
|
27
|
-
GTM incluye variables activables sin configuración extra:
|
|
28
|
-
|
|
29
|
-
| Variable | Valor |
|
|
30
|
-
|----------|-------|
|
|
31
|
-
| `Page URL` | URL completa de la página actual |
|
|
32
|
-
| `Page Path` | Solo el path: `/productos/sku-001` |
|
|
33
|
-
| `Click URL` | URL del elemento clickeado |
|
|
34
|
-
| `Click Text` | Texto del elemento clickeado |
|
|
35
|
-
| `Click Classes` | Clases CSS del elemento clickeado |
|
|
36
|
-
| `Form URL` | URL de acción del formulario enviado |
|
|
37
|
-
| `Scroll Depth Threshold` | Porcentaje de scroll alcanzado |
|
|
38
|
-
|
|
39
|
-
Activarlas en: Variables > Built-In Variables > Configure.
|
|
40
|
-
|
|
41
|
-
### Variables personalizadas de dataLayer
|
|
42
|
-
|
|
43
|
-
Para leer valores del objeto `ecommerce` del dataLayer:
|
|
44
|
-
|
|
45
|
-
- Tipo: **Data Layer Variable**
|
|
46
|
-
- Nombre de variable: `ecommerce.transaction_id` (notación de punto)
|
|
47
|
-
- Versión del dataLayer: **Version 2** (siempre para GA4)
|
|
48
|
-
- Nombre de la variable en GTM: `{{DL - ecommerce.transaction_id}}`
|
|
49
|
-
|
|
50
|
-
Convención de naming para variables de dataLayer: `{{DL - ruta.al.valor}}`.
|
|
51
|
-
|
|
52
|
-
### Variables de JavaScript personalizado
|
|
53
|
-
|
|
54
|
-
Para lógica más compleja (formateo, cálculos, lectura de cookies):
|
|
55
|
-
|
|
56
|
-
```javascript
|
|
57
|
-
// Variable: {{JS - GA Client ID}}
|
|
58
|
-
function() {
|
|
59
|
-
var cookie = document.cookie.match(/_ga=([^;]+)/);
|
|
60
|
-
if (!cookie) return undefined;
|
|
61
|
-
var parts = cookie[1].split('.');
|
|
62
|
-
return parts.slice(-2).join('.');
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
// Variable: {{JS - FBC Cookie}}
|
|
68
|
-
function() {
|
|
69
|
-
var match = document.cookie.match(/_fbc=([^;]+)/);
|
|
70
|
-
return match ? match[1] : undefined;
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Triggers
|
|
75
|
-
|
|
76
|
-
### Tipos de trigger más usados
|
|
77
|
-
|
|
78
|
-
**All Pages (Pageview)**: Se dispara en cada carga de página. Base para GA4
|
|
79
|
-
Configuration tag. Siempre presente en todo contenedor.
|
|
80
|
-
|
|
81
|
-
**Custom Event**: Se dispara cuando `dataLayer.push({ event: 'nombre' })`
|
|
82
|
-
coincide con el nombre configurado. Usar para eventos de e-commerce.
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
Trigger > Custom Event
|
|
86
|
-
Event name: purchase
|
|
87
|
-
(Para capturar todos los eventos custom: usar regex .*)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**Click - All Elements**: Se dispara en cualquier click. Útil para tracking
|
|
91
|
-
de botones sin código JavaScript adicional.
|
|
92
|
-
|
|
93
|
-
**Form Submission**: Se dispara al enviar un formulario. Requiere activar
|
|
94
|
-
`Form` en Built-In Variables.
|
|
95
|
-
|
|
96
|
-
**History Change**: Esencial en Single-Page Apps (React, Angular, Vue) donde
|
|
97
|
-
la URL cambia sin recarga completa. Usar en lugar de Pageview para SPAs.
|
|
98
|
-
|
|
99
|
-
### Race conditions en SPAs
|
|
100
|
-
|
|
101
|
-
En aplicaciones de una sola página, el trigger `History Change` puede
|
|
102
|
-
dispararse antes de que el componente actualice el dataLayer. Solución:
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
// Después del cambio de ruta, esperar al siguiente tick
|
|
106
|
-
router.afterEach((to) => {
|
|
107
|
-
setTimeout(() => {
|
|
108
|
-
dataLayer.push({ ecommerce: null });
|
|
109
|
-
dataLayer.push({
|
|
110
|
-
event: 'page_view',
|
|
111
|
-
page_path: to.path,
|
|
112
|
-
page_title: to.meta.title,
|
|
113
|
-
});
|
|
114
|
-
}, 0);
|
|
115
|
-
});
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Alternativa con GTM: usar la variable `{{JS - Page Path}}` con `Page Path`
|
|
119
|
-
built-in, que siempre refleja la URL actual al momento del trigger.
|
|
120
|
-
|
|
121
|
-
## Tags
|
|
122
|
-
|
|
123
|
-
### GA4 Configuration Tag
|
|
124
|
-
|
|
125
|
-
Una sola por contenedor. Se dispara en All Pages.
|
|
126
|
-
|
|
127
|
-
- Tag type: **Google Analytics: GA4 Configuration**
|
|
128
|
-
- Measurement ID: `{{Constant - GA4 Measurement ID}}`
|
|
129
|
-
- Fields to set: `debug_mode` = `true` (solo en workspace de desarrollo)
|
|
130
|
-
|
|
131
|
-
### GA4 Event Tag
|
|
132
|
-
|
|
133
|
-
Una por tipo de evento e-commerce.
|
|
134
|
-
|
|
135
|
-
- Tag type: **Google Analytics: GA4 Event**
|
|
136
|
-
- Configuration Tag: seleccionar la Configuration Tag creada arriba
|
|
137
|
-
- Event Name: `{{DL - event}}` (lee el nombre del evento del dataLayer)
|
|
138
|
-
- Trigger: Custom Event con el nombre del evento
|
|
139
|
-
|
|
140
|
-
Para pasar el objeto `ecommerce` completo:
|
|
141
|
-
- Event Parameters: agregar `items` = `{{DL - ecommerce.items}}`
|
|
142
|
-
- Marcar **Send Ecommerce data**: activado, Source: Data Layer
|
|
143
|
-
|
|
144
|
-
### Conversion Linker
|
|
145
|
-
|
|
146
|
-
Tag obligatoria para Enhanced Conversions y cross-device tracking:
|
|
147
|
-
|
|
148
|
-
- Tag type: **Conversion Linker**
|
|
149
|
-
- Trigger: All Pages
|
|
150
|
-
- Colocar antes que cualquier tag de conversión de Google Ads
|
|
151
|
-
|
|
152
|
-
## GTM Server-Side en Cloud Run
|
|
153
|
-
|
|
154
|
-
El servidor GTM actúa como proxy entre el browser y las plataformas de ads,
|
|
155
|
-
permitiendo enviar datos first-party sin depender de las restricciones del browser.
|
|
156
|
-
|
|
157
|
-
### Setup mínimo
|
|
158
|
-
|
|
159
|
-
1. Crear un contenedor de tipo **Server** en GTM.
|
|
160
|
-
2. Desplegar la imagen `gcr.io/cloud-tagging-10302018/gts-preview:latest`
|
|
161
|
-
en Cloud Run (mínimo 1 instancia siempre activa para latencia).
|
|
162
|
-
3. Configurar el **Server Container URL** en el contenedor browser de GTM.
|
|
163
|
-
4. Verificar que las requests van a `tu-dominio.com/g/collect` en vez de
|
|
164
|
-
directamente a `google-analytics.com`.
|
|
165
|
-
|
|
166
|
-
### Client templates
|
|
167
|
-
|
|
168
|
-
El servidor GTM necesita un **Client** que reciba las requests del browser:
|
|
169
|
-
|
|
170
|
-
- **GA4 Client**: recibe requests del tag GA4 del browser.
|
|
171
|
-
- **Meta Pixel Client**: recibe requests del Meta Pixel del browser.
|
|
172
|
-
|
|
173
|
-
Cada client parsea el payload y lo pone disponible para los tags del servidor.
|
|
174
|
-
|
|
175
|
-
### Tag templates del servidor
|
|
176
|
-
|
|
177
|
-
Los tags del servidor envían datos a las plataformas finales:
|
|
178
|
-
|
|
179
|
-
- **GA4 (server-side)**: usa `measurement_id` y `api_secret` como variables.
|
|
180
|
-
- **Meta CAPI**: usa `pixel_id` y `access_token` como variables de entorno.
|
|
181
|
-
|
|
182
|
-
Ventaja clave: las variables con credenciales viven en el servidor,
|
|
183
|
-
nunca expuestas en el browser.
|
|
184
|
-
|
|
185
|
-
## Modo de depuración
|
|
186
|
-
|
|
187
|
-
### Tag Assistant
|
|
188
|
-
|
|
189
|
-
1. En GTM workspace > Preview: abre Tag Assistant en una nueva pestaña.
|
|
190
|
-
2. Ingresar la URL del sitio y activar la sesión de debug.
|
|
191
|
-
3. El panel izquierdo muestra todos los eventos del dataLayer en orden.
|
|
192
|
-
4. Hacer click en un evento para ver qué tags se dispararon y cuáles no.
|
|
193
|
-
|
|
194
|
-
### GA4 DebugView
|
|
195
|
-
|
|
196
|
-
En GA4 > Admin > DebugView: muestra eventos en tiempo real del browser
|
|
197
|
-
con `debug_mode: true`. Indispensable para validar eventos e-commerce.
|
|
198
|
-
|
|
199
|
-
### Regla de validación antes de pasar a producción
|
|
200
|
-
|
|
201
|
-
1. Verificar en Tag Assistant que cada evento tiene `ecommerce: null` previo.
|
|
202
|
-
2. Confirmar en GA4 DebugView que el evento `purchase` llega con el
|
|
203
|
-
`transaction_id` correcto.
|
|
204
|
-
3. Publicar una versión con nombre descriptivo: `"feat: purchase event GA4"`.
|
|
205
|
-
4. Monitorear GA4 > Realtime durante las primeras 24 horas post-deploy.
|
|
206
|
-
|
|
207
|
-
## Buenas prácticas de naming
|
|
208
|
-
|
|
209
|
-
| Tipo | Convención | Ejemplo |
|
|
210
|
-
|------|-----------|---------|
|
|
211
|
-
| Variable dataLayer | `{{DL - ruta.del.valor}}` | `{{DL - ecommerce.transaction_id}}` |
|
|
212
|
-
| Variable JavaScript | `{{JS - Descripción}}` | `{{JS - GA Client ID}}` |
|
|
213
|
-
| Constante | `{{Constant - Nombre}}` | `{{Constant - GA4 Measurement ID}}` |
|
|
214
|
-
| Trigger custom event | Igual que el nombre del evento | `purchase`, `view_item` |
|
|
215
|
-
| Tag GA4 | `GA4 - Nombre del evento` | `GA4 - Purchase`, `GA4 - Config` |
|
|
216
|
-
| Tag conversión | `Ads - Nombre conversión` | `Ads - Purchase Conversion` |
|