CBCTHubCBCTHub
PreciosBlogAyuda
 
 
Volver al blog
webhooksapireal-timedevelopersintegration

Webhooks vs polling: notificaciones de exámenes en tiempo real para flujos de imagen dental

CBCTHub·24 de junio de 2026

Toda integración de imagen dental termina enfrentando la misma pregunta arquitectónica: ¿cómo se entera la app del dentista derivador de que una tomografía CBCT está lista? Si tu respuesta es "hacemos polling a la API cada 30 segundos", estás introduciendo latencia, gastando invocaciones serverless y descargando baterías de móvil. Hay un mejor camino por defecto — webhooks event-driven con verificación HMAC y reintentos idempotentes — y este post argumenta por qué deberías cambiar.

Los dos patrones en un párrafo

Polling significa que tu código pregunta "¿ya está listo?" en un temporizador. Webhooks significa que CBCTHub llama a tu endpoint en el instante en que ocurre el evento. Polling es pull, webhooks es push. Ambos funcionan. Tienen perfiles de costo, latencia y operación muy distintos.

Comparación lado a lado

DimensiónPolling (cada 30 s)Webhooks
Latencia mediana15 s (mitad del intervalo)< 1 s
Latencia peor caso30 s + presupuesto de reintentossegundos, con reintentos encima
Invocaciones cloud por 100 exámenes (subida de 10 min)~2.000~100
Impacto en batería móvilAlto — despierta la radio cada cicloNinguno — el servidor empuja
Detrás de firewall / en laptopFunciona sin problemaRequiere URL pública
DepurabilidadTrivial — repites cualquier requestNecesita logs de entrega + replay
Contrapresión (backpressure)Natural — tú controlas la frecuenciaEl proveedor debe implementar colas

Para flujos típicos entre PMS y CBCTHub donde quieres que la app del dentista se actualice en el segundo exacto en que el examen está listo, los webhooks ganan en todas las dimensiones que importan al usuario final.

Cuándo el polling todavía tiene sentido

Los webhooks no son una religión. Recurre al polling cuando:

  • Estás depurando localmente y no quieres montar un túnel ngrok o Cloudflare hacia tu laptop.
  • Tu sistema no puede exponer una URL pública — por ejemplo, un PMS legacy desplegado en la LAN de la clínica sin IP pública ni proxy inverso.
  • Procesas resultados en batch — un cron nocturno que importa los exámenes del día funciona perfecto con polling.
  • El evento es raro y ya haces polling en un trigger UX (por ejemplo, cuando el usuario abre la lista de exámenes).

Todo lo demás — notificaciones en tiempo real al dentista, relays de push móvil, pantallas de estado en la sala de espera — pertenece a webhooks.

Cómo firma CBCTHub los webhooks

Cada entrega de webhook incluye dos cabeceras:

  • X-CBCTHub-Signature: HMAC-SHA256 del cuerpo crudo del request, firmado con el secreto que viste una sola vez cuando creaste la subscripción.
  • X-CBCTHub-Delivery: un ID único de este intento de entrega. Úsalo como tu clave de idempotencia.

Verifica la firma antes de hacer cualquier otra cosa. Si falla la verificación, responde 401 y registra el intento — o el secreto está mal configurado o alguien busca una vulnerabilidad.

Verificación en Node.js / Express

import crypto from 'crypto';
import express from 'express';

const app = express();

app.post(
  '/cbcthub/webhook',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const sig = req.header('X-CBCTHub-Signature') ?? '';
    const expected = crypto
      .createHmac('sha256', process.env.CBCTHUB_WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    if (
      sig.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
    ) {
      return res.status(401).send('firma inválida');
    }

    const deliveryId = req.header('X-CBCTHub-Delivery');
    const event = JSON.parse(req.body.toString());

    // Idempotencia — devuelve 200 si ya procesaste esta entrega
    if (await deliveries.has(deliveryId)) return res.status(200).send('duplicada');
    await deliveries.add(deliveryId);

    await handleEvent(event); // tu lógica de negocio
    return res.status(200).send('ok');
  }
);

Verificación en Python / FastAPI

import hmac, hashlib, os
from fastapi import FastAPI, Request, HTTPException

app = FastAPI()
SECRET = os.environ['CBCTHUB_WEBHOOK_SECRET'].encode()

@app.post('/cbcthub/webhook')
async def webhook(req: Request):
    body = await req.body()
    sig = req.headers.get('x-cbcthub-signature', '')
    expected = hmac.new(SECRET, body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(sig, expected):
        raise HTTPException(401, 'firma invalida')

    delivery_id = req.headers.get('x-cbcthub-delivery')
    event = await req.json()

    if await deliveries.contains(delivery_id):
        return {'status': 'duplicada'}
    await deliveries.add(delivery_id)

    await handle_event(event)
    return {'status': 'ok'}

Idempotencia: la regla que no puedes saltarte

CBCTHub reintenta las entregas que no reciben 2xx, con backoff exponencial hasta por 24 horas. Eso significa que tu endpoint recibirá el mismo evento más de una vez en algún momento, ya sea porque hubo un 5xx o porque la respuesta dio timeout. Usa X-CBCTHub-Delivery como clave de deduplicación en Redis, una tabla de la base de datos o incluso una caché LRU, y responde 200 en el segundo intento sin volver a ejecutar los efectos secundarios.

Test mode: valida sin tocar producción

Genera una API key cbct_test_, registra un webhook contra ella y dispara un evento de prueba desde el dashboard. Los eventos disparados con una key de prueba traen "livemode": false en el payload, así tu código puede rutearlos a una base de staging y seguir corriendo el mismo handler. Es la forma más segura de poner una integración de webhooks en producción sin riesgo de que una entrega real termine en la bandeja equivocada.

Patrón: webhooks → cola durable → workers

El patrón más robusto en producción mantiene pequeño tu handler de webhook: verifica firma, encola, responde 200. Un pool separado de workers consume la cola y hace el trabajo lento. Esto aísla el acuse del webhook de tu lógica de negocio, así un hipo de la base nunca hace que CBCTHub retroceda.

Stacks concretos:

  • Vercel: ruta del webhook → Inngest o QStash → funciones en background.
  • AWS: API Gateway → SQS → consumidores Lambda.
  • Self-hosted: Express → stream de Redis → workers BullMQ.
  • Cloudflare: Worker → Queue → Worker consumidor.

Cuándo elegir qué

Por defecto, webhooks para cualquier evento en tiempo real que mire al usuario. Deja el polling para importaciones nocturnas, herramientas de debug y sistemas legacy on-prem que no aceptan tráfico entrante. El híbrido también vale — muchas integraciones en producción usan ambos, con webhooks como camino principal y un poll diario de reconciliación como red de seguridad.

Conclusión

El polling es la respuesta fácil al inicio y la equivocada a largo plazo. Los webhooks con firma HMAC, handlers idempotentes y una cola pequeña cuestan menos, escalan mejor y dan a los usuarios finales una experiencia en tiempo real. El sistema de entrega de webhooks de CBCTHub está construido para esto — reintentos automáticos, UI de replay, separación de livemode — así que lo único que te queda por construir es el receptor.

Lee la referencia de webhooks · Crea una cuenta gratis

Probar visor gratisVer soluciones

Prueba CBCTHub gratis

Sube, visualiza y comparte examenes DICOM en la nube. Sin instalar nada.

Crear cuenta gratis

Articulos relacionados

Cómo integrar tu software de gestión dental con CBCTHub: tutorial completo de la API

Guía paso a paso para integrar un PMS dental con la API REST de CBCTHub. Sube exámenes, embebe el visor 3D y automatiza la entrega en Node, Python y PHP.

APIs de imagen dental con cumplimiento HIPAA: lista de verificación de seguridad para integraciones en salud de EE. UU.

Lista de 10 puntos para garantizar el cumplimiento HIPAA en cualquier integración de API de imagen dental en EE. UU. Cifrado, BAAs, audit logs, notificación de brechas.

Proteccion de datos de pacientes en Mexico: guia LFPDPPP, INAI y NOM-024 para centros radiologicos dentales

Proteccion de datos de pacientes en Mexico: guia LFPDPPP, INAI y NOM-024 para centros radiologicos dentales

Como cumplir la LFPDPPP, su Reglamento, la NOM-024-SSA3-2012 y la NOM-004 en una clinica de imagen dental. INAI, Aviso de Privacidad, multas en UMA. Como ayuda CBCTHub.

CBCTHubCBCTHub

La plataforma de entrega digital de exámenes CBCT. Procesamiento 100% local.

Disponible enApp Store
Disponible enGoogle Play

Soluciones

Centros radiológicosRadiólogos dentalesVisor CBCT online

Producto

FuncionesPreciosBlogAlternativasAprendeEducaciónNuevoDesarrolladoresAPIDemo

Soporte

Centro de ayudaFAQContactosoporte@cbcthub.comStatus+56 9 7632 9096

Empresa

Acerca deSeguridadTérminos de servicioPolítica de privacidad

Por país

ChileMéxicoColombiaArgentinaPerúEcuadorUruguayEspaña
HIPAA-readyGDPRLGPDLey 21.719

© 2026 CBCTHub. Todos los derechos reservados.

AppLab Software LLC · 1021 E Lincolnway, Cheyenne, WY 82001