Webhooks frente a llamadas síncronas: cuándo usar cada una para moderar
Bloquear al usuario hasta que termine la moderación no siempre es la respuesta correcta. Un marco de decisión para los patrones síncrono, asíncrono e híbrido.
Una de las primeras decisiones de arquitectura al integrar una API de moderación es si hacer esperar al usuario hasta tener el resultado. La respuesta ingenua es "sí, siempre". La correcta es "depende, y lo más probable es que te convenga combinar las dos cosas".
Moderación síncrona: el guardado espera al veredicto
El flujo: el usuario pulsa enviar → tu backend llama a la API de moderación → esperas la respuesta → si está marcado, lo rechazas; si no, lo guardas y respondes al usuario.
Cuándo conviene:
- Mensajes de chat, comentarios, reseñas: todo lo que otros usuarios ven al instante.
- Registros de cuentas y campos de perfil (nombres visibles, biografías). Limpiar a posteriori sale caro.
- Cualquier sitio donde haya mucho riesgo legal o para la imagen de marca.
El coste: una llamada de moderación en el camino crítico. Si la API es lenta o inestable, tu aplicación también, y por eso importan los tiempos de espera y los reintentos. Cuenta con que, a ojos del usuario, enviar tarde entre 50 y 100 ms más; un proxy ligero en el edge acerca esa llamada a tus usuarios.
Asíncrona con webhooks: guardar primero, moderar después
El flujo: el usuario pulsa enviar → lo guardas al momento en estado "pendiente" → encolas un trabajo de moderación → la API de moderación lo procesa y llama a tu webhook → actualizas el registro según el veredicto.
Cuándo conviene:
- Subidas de imágenes y vídeo. La inferencia es lenta (de cientos de milisegundos a segundos); bloquear la subida da una experiencia pésima.
- Contenido largo como artículos, anuncios o descripciones. El usuario ha pasado 20 minutos escribiendo; no le pongas además un spinner.
- Cualquier contenido oculto por defecto (borradores, subidas privadas) donde "la moderación ocurre antes de publicar" es aceptable.
El coste: tienes que diseñar pensando en el estado pendiente. Tu interfaz tiene que mostrar "en revisión". Tu esquema de base de datos necesita un estado de moderación. Tu endpoint de webhook tiene que ser idempotente y estar firmado. Es trabajo de verdad.
El patrón híbrido (lo que hacen de verdad la mayoría de las plataformas maduras)
Comprobación síncrona barata en el camino crítico + comprobación asíncrona cara en segundo plano.
- El usuario envía. Haces una llamada síncrona rápida contra un modelo ligero, del tipo "¿esto es claramente spam o tóxico con alta confianza?". Tarda menos de 30 ms.
- Si es claramente malo, lo rechazas al momento. La experiencia es muy buena, porque el rechazo es instantáneo y viene con su explicación.
- Si pasa, guardas el contenido como "publicado" y encolas una comprobación profunda asíncrona con un modelo más pesado, análisis de imágenes, correlación entre usuarios, etc.
- Si la comprobación asíncrona marca después el contenido, lo ocultas o lo bajas de posición y, opcionalmente, avisas a un revisor humano.
Así funcionan los chats de videojuegos, los grandes marketplaces y las redes sociales. La llamada síncrona caza lo obvio y se lo explica al usuario; la comprobación asíncrona caza lo más retorcido sin perjudicar la latencia.
Tabla de decisión
El patrón adecuado depende menos de tu stack que de dónde aparece el contenido y de cuánto pesa. Este es el reparto con el que empezaríamos:
| Dónde aparece | Patrón |
|---|---|
| Mensaje de chat (1:1) | Síncrono |
| Comentario público | Síncrono, lo pesado opcionalmente asíncrono |
| Nombre / biografía del perfil | Síncrono |
| Subida de imagen (avatar) | Síncrono (es pequeña) |
| Subida de imagen (galería) | Webhook asíncrono |
| Subida de vídeo | Webhook asíncrono, siempre |
| Post largo / anuncio | Híbrido: comprobación síncrona de palabras clave, revisión profunda asíncrona |
| Fotogramas de una emisión en directo | Síncrono con muestreo agresivo |
Cómo hacer bien los webhooks
Si adoptas la moderación asíncrona, el webhook pasa a ser una pieza crítica de infraestructura. Una lista rápida:
- Verifica las firmas. Todo proveedor de moderación firma sus webhooks; si el tuyo no lo hace, cámbialo. Un endpoint de webhook sin verificar es una puerta abierta para que cualquiera marque contenido como "aprobado".
- Sé idempotente. Los proveedores reintentan. Tu handler tiene que tratar las entregas duplicadas como si no hubieran ocurrido.
- Responde rápido. Confirma la recepción en unos pocos cientos de milisegundos. El trabajo real, hazlo en un job en segundo plano.
- Diseña pensando en el orden. Un veredicto "rechazado" puede llegar después de uno "aprobado" por culpa de los reintentos. Compara siempre las marcas de tiempo; nunca te fíes del orden de llegada.
- Gestiona el caso del webhook que no llega. Si no vuelve nada en N minutos, reconcilia el estado con un job que consulte periódicamente. Los webhooks fallan más de lo que admiten los proveedores.
Un motivo menos evidente para elegir lo síncrono aunque lo asíncrono sea "más rápido"
Hay un motivo relacionado con el comportamiento de los usuarios a favor de la moderación síncrona que los desarrolladores suelen pasar por alto: los usuarios que reciben una respuesta inmediata cambian su comportamiento. Cuando un usuario ve al momento "esto parece spam, reformúlalo", una minoría considerable lo reformula y publica algo correcto. Cuando la respuesta llega 30 segundos después por correo, ya han pasado a otra cosa, frustrados, y con menos ganas de volver a publicar.
Si tienes una comunidad en la que quieres guiar a los usuarios hacia un mejor comportamiento (la mayoría de las comunidades), la moderación síncrona es una funcionalidad, no solo una comodidad de ingeniería.
Sigue leyendo
Moderar comentarios en Express con el SDK de JavaScript
Construye en Express un muro de comentarios que publica, retiene o rechaza cada comentario con su motivo, mant...
Moderar comentarios en Flask con el SDK de Python
Monta un muro de comentarios en Flask que publica, retiene o rechaza cada comentario con su motivo, verifica e...
Moderar comentarios en Laravel con Laratox
Una regla de validación, una facade y un fake: construye en Laravel un muro de comentarios que publica, retien...