API y automatización
Cómo recibir webhooks sin duplicar acciones en flujos de archivos
Guía práctica para diseñar receptores de webhooks idempotentes: validar firmas, registrar eventos, responder rápido y procesar archivos sin duplicar efectos.
El problema: una entrega no siempre equivale a un evento
En un flujo real de archivos, un webhook puede llegar más de una vez, llegar tarde o aparecer en un orden distinto al esperado. Esto no es necesariamente un error de diseño: los reintentos existen para superar cortes de red, caídas temporales del receptor o respuestas HTTP ambiguas. El problema aparece cuando el endpoint trata cada entrega como una acción nueva y vuelve a descargar un archivo, convertirlo, crear un ticket, enviar una notificación o registrar una operación en el ERP.
La primera decisión arquitectónica es separar evento, entrega y efecto secundario. El evento representa algo que ocurrió en la fuente; la entrega es un intento de comunicarlo; el efecto secundario es lo que tu sistema hace como consecuencia. Un receptor robusto no pregunta “¿he recibido esta petición antes?”, sino “¿este evento ya fue aceptado y qué efectos autorizados puede producir todavía?”. Esa distinción es la base de los webhooks idempotentes.
- Riesgo típico: crear dos registros internos para el mismo archivo transformado.
- Riesgo típico: enviar varias notificaciones a clientes por una sola acción Cloud.
- Riesgo típico: sobrescribir una versión nueva con una respuesta tardía de un evento anterior.
Qué debe garantizar tu receptor antes de procesar
Un receptor de webhooks debe garantizar cuatro cosas: autenticidad, trazabilidad, idempotencia y una respuesta HTTP predecible. Autenticidad significa comprobar que el mensaje procede de la fuente esperada y no fue modificado durante el transporte. Trazabilidad significa conservar identificadores, fecha de entrega, estado interno y resultado. Idempotencia significa que una repetición del mismo evento no duplica efectos. La respuesta HTTP indica a la fuente si la entrega fue aceptada o debe tratarse como fallida.
La regla operativa es estricta: primero verificar, después aceptar de forma duradera y solo entonces responder correctamente. Si la transformación, descarga o sincronización con el CRM puede tardar, no la ejecutes dentro de la ventana crítica del webhook. Registra el evento en una tabla o cola transaccional, marca su estado inicial y delega el trabajo pesado a un proceso en segundo plano. Para casos asíncronos, 202 Accepted es una respuesta adecuada cuando la petición fue recibida pero otro proceso la gestionará después.
- Comprobar firma antes de leer o guardar el payload como dato confiable.
- Persistir la aceptación del evento antes de responder con éxito.
- No ejecutar trabajos largos en el hilo principal del endpoint.
- Usar estados internos visibles para soporte y operaciones.
Firma HMAC: no confíes en el payload sin validarlo
La firma es el primer filtro. En Apification, las firmas HMAC están documentadas como mecanismo para verificar la procedencia e integridad del payload. La recomendación operativa es validar la firma HMAC antes de leer o guardar el contenido como si fuera confiable. Si la validación falla, el receptor no debe procesar el evento, no debe disparar descargas y no debe iniciar trabajos internos. Un fallo de firma no es un problema de negocio; es un rechazo de seguridad.
Una verificación robusta no debería depender solo del cuerpo. En especificaciones técnicas de webhooks se recomienda que la firma cubra el identificador, el timestamp y el body, porque el timestamp ayuda a reducir ataques de repetición y puede diferir de la fecha original del evento cuando hay reintentos. En la práctica, tu implementación debe reconstruir exactamente el mensaje firmado según la documentación de la fuente, comparar la firma de forma segura y registrar solo metadatos necesarios para diagnóstico, nunca secretos.
- Rechazar eventos con firma ausente, mal formada o no coincidente.
- Validar el timestamp de entrega según una tolerancia definida por tu equipo.
- No incluir secretos, tokens ni firmas completas en logs compartidos.
- Mantener separados los secretos de webhook por entorno y destino.
Deduplicación práctica con estados persistentes
Para deduplicar, necesitas una clave estable. Una especificación de webhooks contempla un identificador único asociado al evento que permanece igual aunque una entrega fallida se reintente. Ese identificador puede usarse como clave de idempotencia para que el consumidor procese un evento una sola vez, incluso si se recibe por problemas de red, por error o de forma maliciosa. Si tu fuente proporciona también un identificador de entrega, consérvalo para auditoría, pero no lo uses como única clave de evento.
El patrón mínimo es una tabla de eventos con clave única, estado y resultado. Al recibir un webhook válido, intenta insertar el event_id. Si ya existe y está procesado, responde correctamente sin repetir efectos. Si existe en procesando, responde de forma coherente y evita lanzar otro worker. Si está en error, decide si se permite reencolarlo manualmente o tras una política interna. Este enfoque convierte la duplicación de entregas en una consulta de estado, no en una repetición de trabajo.
- Campos recomendados: event_id, delivery_id si existe, tipo, recurso, fecha, estado, intentos internos y último error.
- Estados útiles: recibido, procesando, procesado, error, descartado.
- Restricción clave: índice único sobre el identificador estable del evento.
- Regla de soporte: toda acción manual debe dejar rastro de quién reintentó y cuándo.
Idempotencia aplicada a acciones sobre archivos
Los archivos añaden riesgos específicos. Una misma notificación puede terminar descargando dos veces el mismo recurso, generando dos conversiones o notificando dos URLs distintas para un resultado equivalente. Diseña cada paso con una operación de “crear si no existe” o “avanzar solo si el estado lo permite”. Por ejemplo, crea el registro interno del archivo una sola vez, asocia la versión o el identificador estable del recurso y guarda el resultado de la transformación como un artefacto referenciado, no como una escritura ciega sobre el último valor disponible.
También conviene separar descarga, transformación y notificación. La descarga obtiene el insumo y confirma que corresponde al evento aceptado. La transformación produce una salida controlada, idealmente con un registro de trabajo. La notificación al CRM, ERP o gestor documental se realiza al final y solo si los pasos anteriores llegaron al estado esperado. Si llega un evento tardío, compáralo con fechas, estado e identificadores estables antes de modificar una versión o informar un resultado.
- No sobrescribir versiones sin comprobar el estado actual del recurso interno.
- No enviar notificaciones externas hasta que el resultado esté persistido.
- Guardar el vínculo entre archivo, proyecto Cloud, evento y resultado interno.
- Tratar las transformaciones como trabajos trazables, no como respuestas inmediatas del endpoint.
Reintentos: cuándo aceptar, cuándo fallar y cuándo pausar
Los reintentos son una herramienta, pero también amplifican defectos si el receptor no es idempotente. Apification documenta reintentos automáticos y manuales para fallos temporales de webhooks. Por eso tu endpoint debe distinguir entre “no puedo aceptar el evento” y “ya lo acepté, pero lo procesaré después”. Si la firma es válida y puedes guardar el evento de forma duradera, responde con éxito o con 202 Accepted y deja que tu cola interna gestione el trabajo. Así evitas que una conversión lenta provoque entregas repetidas innecesarias.
Si tu base de datos, cola o almacenamiento de eventos no está disponible, no finjas aceptación. En condiciones temporales del servidor, 503 Service Unavailable es el código adecuado y puede acompañarse de Retry-After cuando tengas una estimación. Los errores 4xx deben reservarse para problemas atribuibles a la petición, como formato inválido o firma rechazada. La consistencia de estas respuestas facilita interpretar el historial de entregas y evita mezclar incidentes de seguridad con saturación operativa.
- Aceptar solo cuando el evento quedó persistido o encolado de forma duradera.
- Devolver error si no puedes registrar el evento y necesitas que la fuente reintente.
- No usar reintentos externos para compensar procesos internos mal diseñados.
- Revisar eventos en error antes de reintentar manualmente para no duplicar efectos.
Cómo encaja Apification en una arquitectura segura
Apification permite integrar Cloud y sus servicios mediante API REST, OpenAPI, webhooks, iframe y JavaScript. Para integraciones servidor a servidor, la API REST permite gestionar recursos Cloud, usuarios, configuración y trabajos de transformación desde el backend. En flujos orientados a eventos, los webhooks firmados ayudan a reaccionar a cambios sin consultar continuamente recursos o trabajos en segundo plano. Apification documenta eventos relacionados con archivos, servicios, formularios, firmas y procesos.
La parte operativa también importa. Apification documenta historial de entregas webhook con URL de destino, fecha, estado y cuerpo de respuesta, además de estadísticas y reintentos automáticos y manuales. También documenta comandos idempotentes mediante una clave estable en escrituras para que los reintentos de red no repitan la acción. En proyectos con archivos grandes, los trabajos asíncronos permiten importar y transformar recursos en segundo plano conservando progreso y errores detallados.
- Usar OpenAPI 3.1 descargable como contrato para esquemas de petición y respuesta.
- Combinar REST API para acciones iniciadas por tu backend y webhooks para cambios relevantes.
- Consultar historial y estadísticas para depurar fallos de entrega sin depender solo de logs internos.
- Aplicar claves idempotentes en escrituras cuando una operación pueda reintentarse.
Ejemplo de implementación operativa
Una arquitectura razonable es: Apification webhook, endpoint verificador, tabla o cola de eventos, worker, API interna o CRM y registro final por archivo o proyecto Cloud. El endpoint valida la firma HMAC, comprueba timestamp y estructura, extrae el identificador estable del evento, intenta insertarlo con una restricción única y responde cuando la aceptación está persistida. El worker toma eventos en estado recibido, los marca como procesando, ejecuta la descarga o consulta necesaria mediante APIs, lanza transformaciones si corresponde y registra el resultado.
Los fallos esperables deben estar definidos antes de producción. Si falla la firma, se rechaza y no se procesa. Si el evento ya existe, se devuelve una respuesta correcta sin repetir el trabajo. Si el CRM está caído, el worker conserva el evento en error o pendiente según tu política interna. Si llega un evento antiguo, se compara contra estado, fechas e identificadores antes de modificar nada. Ningún secreto debe aparecer en logs, parámetros de URL públicas o mensajes de error visibles.
- Checklist previo: firma validada, clave única creada, estados definidos y logs sin secretos.
- Checklist de pruebas: entrega duplicada, entrega tardía, firma inválida, caída de base de datos y caída del CRM.
- Checklist de operación: revisar historial de entregas, eventos en error, reintentos manuales y tiempos de cola.
- Criterio de salida: cada archivo tiene un único resultado destacado o un error explicable y trazable.
Preguntas frecuentes
¿Qué significa que un webhook sea idempotente?
Significa que recibir el mismo evento más de una vez no duplica sus efectos. El receptor usa una clave estable del evento, registra estado y evita repetir descargas, transformaciones o notificaciones ya procesadas.
¿Debo responder 200 o 202 a un webhook?
Responde correctamente solo después de verificar y aceptar el payload de forma duradera. 202 Accepted es útil si el evento quedó recibido pero el procesamiento real continuará de forma asíncrona.
¿Qué hago si la firma HMAC no coincide?
No proceses el payload. Un fallo de firma debe tratarse como rechazo de seguridad: no descargues archivos, no encoles trabajos y no dispares acciones internas basadas en ese contenido.
¿Cómo ayuda Apification en estos flujos?
Apification ofrece integración mediante REST API, OpenAPI y webhooks firmados, con reintentos, historial de entregas, estadísticas y comandos idempotentes para escrituras con clave estable.
Fuentes y lecturas
Documentación consultada para elaborar este artículo.
- Apification — Automatización y webhooks — Apification
- Apification — Integra Apification en tu producto — Apification
- Apification — Automatización de procesos — Apification
- RFC 9110 — HTTP Semantics — RFC Editor
- MDN — HTTP response status codes — MDN Web Docs
- MDN — Idempotency-Key header — MDN Web Docs
- OWASP REST Security Cheat Sheet — OWASP Cheat Sheet Series
- OWASP Web Service Security Cheat Sheet — OWASP Cheat Sheet Series
- Standard Webhooks specification — Standard Webhooks
- Node.js Crypto API — Node.js