Usar los listeners de eventos de __tcfapi: tutorial para scripts que respetan el consentimiento
Por qué tus scripts deben escuchar, no sondear
Cualquier script que dependa del consentimiento — una etiqueta publicitaria, un cargador de analítica, un wrapper de header bidding — necesita saber dos cosas: si el CMP ya tiene una decisión y cuál es. Un error común es leer una cookie al cargar la página, o sondear el CMP con un temporizador hasta que aparezca algo. Ambos enfoques fallan de forma predecible: el formato de la cookie es interno del CMP y puede cambiar, y el sondeo o se dispara demasiado pronto o hace perder tiempo esperando.
El IAB TCF define una interfaz JavaScript estándar para exactamente este trabajo: la función __tcfapi. Este tutorial repasa los comandos que realmente necesitas, los eventos que recibirás y los errores que aparecen con más frecuencia en producción.
El stub y la cola
Se espera que un CMP de TCF coloque un pequeño stub en la página lo antes posible, antes de que se cargue el script completo del CMP. El stub define window.__tcfapi y pone en cola cualquier llamada hecha antes de que el CMP esté listo. Cuando el CMP termina de cargarse, procesa la cola y responde a cada llamada.
Esto es lo que hace seguro que otros scripts llamen a __tcfapi de inmediato: mientras el stub esté en la página antes que ellos, sus llamadas no se pierden. Si un script lanza un error porque __tcfapi no está definido, el stub falta o se carga demasiado tarde — corrige el orden de carga en lugar de añadir reintentos.
Los comandos que importan
ping
__tcfapi('ping', 2, callback) devuelve un estado básico sin esperar a la decisión del usuario. La respuesta incluye cmpLoaded, un cmpStatus como stub, loading, loaded o error, y un displayStatus con valor visible, hidden o disabled. También informa de gdprApplies una vez conocido. Úsalo para diagnóstico y para decidir si el TCF es relevante para este visitante.
addEventListener
__tcfapi('addEventListener', 2, callback) es el comando que deberían usar la mayoría de las integraciones. El callback recibe un objeto tcData y un indicador de éxito, y se vuelve a llamar cada vez que cambia el estado del consentimiento. Desde el TCF v2.2, esta es la forma recomendada de obtener los datos de consentimiento; el antiguo comando getTCData quedó obsoleto.
removeEventListener
Cada objeto tcData lleva un listenerId. Pásalo a __tcfapi('removeEventListener', 2, callback, listenerId) cuando tu script ya no necesite actualizaciones — por ejemplo, un cargador de un solo uso que ya ha tomado su decisión.
Cómo leer eventStatus
El campo clave de tcData es eventStatus. Tiene tres valores:
tcloaded— el CMP encontró una decisión almacenada válida y no se mostrará ningún banner. Puedes actuar sobre los datos de inmediato.cmpuishown— se está mostrando el banner. Los datos reflejan cualquier estado previo, pero el usuario puede estar a punto de cambiarlo.useractioncomplete— el usuario acaba de hacer o confirmar una elección. Actúa sobre los datos nuevos.
Un cargador típico espera a tcloaded o a useractioncomplete y luego comprueba los propósitos y proveedores que necesita. Ignora cmpuishown, salvo quizá para registrar que apareció un banner.
Comprobar propósitos y proveedores
Dentro de tcData, el consentimiento y el interés legítimo se exponen como objetos indexados por ID:
tcData.purpose.consents[1]— consentimiento para el propósito 1 (almacenamiento en el dispositivo).tcData.purpose.legitimateInterests[7]— estado del interés legítimo para el propósito 7.tcData.vendor.consents[ID]ytcData.vendor.legitimateInterests[ID]— estado por proveedor, usando el ID del proveedor en la Global Vendor List.tcData.gdprApplies— si el CMP determinó que el RGPD se aplica a este visitante. Si esfalse, tu script debe seguir su lógica ajena al TCF.tcData.tcString— la cadena codificada, que pasas a los socios que la esperan.
Comprueba tanto el propósito como el proveedor. Un consentimiento de propósito sin consentimiento de proveedor, o al revés, no basta para que la mayoría de los proveedores traten datos.
Iframes y llamadas entre frames
Los anuncios y widgets suelen ejecutarse dentro de iframes que no pueden ver el __tcfapi de la página padre. El TCF lo resuelve con un protocolo postMessage: el CMP añade a la página superior un frame llamado __tcfapiLocator, y el código dentro de un iframe puede localizarlo, enviar un mensaje __tcfapiCall y recibir una respuesta __tcfapiReturn. La mayoría de los SDK publicitarios ya lo hacen. Si escribes tu propio código de iframe, implementa el mismo patrón en lugar de leer cookies entre frames.
Errores comunes y cómo detectarlos
- Actuar sobre
cmpuishown. Los scripts que se cargan en cuanto se dispara cualquier callback se ejecutarán antes de que el usuario decida. Filtra poreventStatus. - Quitar el listener demasiado pronto. Si lo quitas tras el primer callback, te perderás un
useractioncompleteposterior y nunca cargarás. - Ignorar las retiradas. Los scripts persistentes deben seguir escuchando y detenerse o reconfigurarse cuando se retira el consentimiento.
- Ignorar
gdprApplies. Fuera de las regiones TCF, los objetos de propósitos pueden estar vacíos; tratarlo como “sin consentimiento” puede apagar ingresos que tienes permitido generar. - No comprobar el indicador de éxito. Cuando
successes false, regístralo; suele indicar una configuración rota del CMP.
Probar tu integración
En la consola del navegador, llama a __tcfapi('ping', 2, console.log) para confirmar que el CMP está presente; luego registra un listener con console.log como callback y recorre el banner. Deberías ver cmpuishown seguido de useractioncomplete en una primera visita, y tcloaded al recargar. Repite con aceptar todo, rechazar todo y una selección personalizada, y confirma que tu script se comporta correctamente en cada caso.
Puntos clave
- Usa
__tcfapien lugar de leer las cookies del CMP o sondear. - Asegúrate de que el stub del CMP se carga antes que cualquier script que llame a la API.
- Usa
addEventListenery actúa solo contcloadedouseractioncomplete. - Comprueba tanto el estado del propósito como el del proveedor, y respeta
gdprApplies. - Usa el patrón postMessage de
__tcfapiLocatordentro de los iframes.