Saltar al contenido principal

Webhooks

Los webhooks permiten recibir notificaciones automáticas en tu servidor cuando ocurren eventos en Luuk. A diferencia de la API (donde tú consultas los datos), con webhooks Luuk envía los datos a tu URL en tiempo real.

API vs Webhooks

CaracterísticaAPI (Pull)Webhooks (Push)
DirecciónTú consultas a LuukLuuk envía a tu servidor
Tiempo realNo (consultas periódicas)Sí (inmediato)
UsoExtraer datos masivos, reportesNotificaciones, automatización
Requiere servidorNoSí (URL HTTPS accesible)
AutenticaciónSession TokenFirma HMAC-SHA256

Ambos sistemas son complementarios. Usa la API para extraer datos históricos y webhooks para reaccionar a eventos en tiempo real.

Eventos Disponibles

EventoDescripciónCuándo se dispara
formulario.completadoProceso completadoUn usuario finaliza un proceso
hilo.creadoHilo creadoSe inicia un nuevo hilo de trabajo
checkpoint.respondidoCheckpoint respondidoSe responde un checkpoint del proceso
seguimiento.vencidoSeguimiento vencidoUn hallazgo supera su plazo
seguimiento.por_vencerSeguimiento por vencerUn hallazgo está próximo a vencer
posta.transferidaPosta transferidaSe transfiere responsabilidad entre grupos

Configurar Webhooks

Los webhooks se configuran desde el panel de administración en Webhooks (menú lateral).

Requisitos:

  • Perfil Administrador o Intermedio
  • URL de destino con HTTPS (obligatorio)

Pasos:

  1. Ir a la sección Webhooks en el menú lateral
  2. Click en Nuevo webhook
  3. Ingresar nombre descriptivo y URL HTTPS de destino
  4. Seleccionar los eventos que deseas recibir
  5. Click en Crear
  6. Guardar el secret que se muestra (solo se muestra una vez)

Verificar Firma (HMAC-SHA256)

Cada envío incluye un header X-Luuk-Signature con la firma HMAC-SHA256 del body. Verifica esta firma para asegurar que el request proviene de Luuk.

Node.js:

const crypto = require('crypto');

function verificarFirma(body, signature, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(body, 'utf8')
    .digest('hex');
  return hash === signature;
}

// En tu endpoint:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-luuk-signature'];
  const bodyString = JSON.stringify(req.body);

  if (!verificarFirma(bodyString, signature, process.env.LUUK_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Firma inválida' });
  }

  // Procesar evento...
  console.log('Evento:', req.body.evento);
  console.log('Datos:', req.body.datos);
  res.status(200).json({ ok: true });
});

Python:

import hmac
import hashlib

def verificar_firma(body: str, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode('utf-8'),
        body.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

# En tu endpoint (Flask):
@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Luuk-Signature')
    body = request.get_data(as_text=True)

    if not verificar_firma(body, signature, os.environ['LUUK_WEBHOOK_SECRET']):
        return jsonify(error='Firma inválida'), 401

    data = request.get_json()
    print(f"Evento: {data['evento']}")
    return jsonify(ok=True), 200

Estructura del Payload

Cada webhook envía un POST con el siguiente formato:

{
  "evento": "formulario.completado",
  "timestamp": "2026-03-12T15:30:00.000Z",
  "clienteId": "abc123",
  "datos": {
    "formularioId": "xyz789",
    "formularioNombre": "Inspección Diaria",
    "hiloId": "hilo_456",
    "correlativo": 1234,
    "usuario": "Juan Pérez",
    "fecha": "2026-03-12T15:30:00.000Z"
  }
}

Headers enviados:

HeaderDescripción
Content-Typeapplication/json
X-Luuk-SignatureFirma HMAC-SHA256 del body
X-Luuk-EventNombre del evento
X-Luuk-DeliveryID único del envío

Gestionar Webhooks

Desde el panel puedes:

  • Pausar/Activar: Detener temporalmente un webhook sin eliminarlo
  • Editar: Cambiar nombre, URL o eventos suscritos
  • Test: Enviar un evento de prueba para verificar tu endpoint
  • Detalle: Ver historial de envíos con códigos de respuesta
  • Eliminar: Eliminar webhook y todo su historial

Mejores Prácticas

  1. Responder rápido: Tu endpoint debe responder con 200 en menos de 10 segundos
  2. Verificar firma: Siempre validar X-Luuk-Signature antes de procesar
  3. Idempotencia: Tu endpoint debe manejar envíos duplicados sin problemas
  4. HTTPS obligatorio: Solo se permiten URLs con certificado SSL válido
  5. Guardar el secret: Se muestra una sola vez al crear el webhook

Solución de Problemas

El webhook no llega:

  • Verificar que el webhook está Activo en el panel
  • Verificar que tu URL es accesible desde internet
  • Revisar el historial de envíos en Detalle para ver códigos de error

Error 401/403 en tu servidor:

  • Verificar que tu endpoint acepta POST sin autenticación adicional
  • Revisar firewalls o middleware que puedan bloquear el request

Payload vacío:

  • Verificar que tu servidor parsea correctamente application/json
  • Revisar los logs de tu servidor web