Guilda WorkDevelopers

INTEGRACIÓN

Webhooks

Recibe notificaciones en tiempo real de eventos en tu cuenta, firmadas con HMAC.

HMAC-SHA256 3 reintentos 4 eventos

Los webhooks te avisan en el momento en que pasa algo relevante — una tarea que se finaliza, una cita que se reserva — en vez de tener que consultar la API periódicamente para ver si algo cambió.

Configuración

Da de alta un webhook desde el Backoffice (sección «Webhooks») indicando la URL de destino y a qué eventos te suscribes, o por MCP con webhooks_crear(url, eventos_suscritos, tenant=None). El secreto devuelto (para verificar la firma de cada entrega) solo se enseña esa vez — apúntalo, no se puede volver a leer después.

json
{
  "id": 7,
  "tenant_id": null,
  "url": "https://tuservidor.com/webhooks/guilda",
  "eventos": ["tarea.finalizada", "nota.creada"],
  "secreto": "3f8a...solo-se-enseña-una-vez",
  "activo": 1
}

Formato del payload

json
{
  "evento": "tarea.finalizada",
  "datos": {
    "tarea_id": 42,
    "nombre": "Reunión de seguimiento",
    "duracion_segundos": 2460
  }
}

Cabeceras de cada entrega

CabeceraContenido
X-Guilda-EventNombre del evento, p. ej. tarea.finalizada.
X-Guilda-Signaturesha256=<hex> — HMAC-SHA256 del cuerpo, ver abajo.

Verificar la firma

La firma es un HMAC-SHA256 calculado sobre el cuerpo crudo tal cual se envía, usando el secreto de ese webhook como clave — mismo esquema que GitHub/Stripe, no uno propio. Recalcúlala y compárala con X-Guilda-Signature antes de procesar el evento; hazlo siempre sobre el cuerpo recibido tal cual, nunca sobre un JSON reserializado (el orden de las claves o los espacios pueden cambiar, y la firma no coincidiría aunque el contenido sea «el mismo»).

python
import hashlib
import hmac

def firma_valida(cuerpo_crudo: bytes, cabecera_recibida: str, secreto: str) -> bool:
    esperada = "sha256=" + hmac.new(secreto.encode(), cuerpo_crudo, hashlib.sha256).hexdigest()
    return hmac.compare_digest(cabecera_recibida, esperada)

Reintentos

Si tu endpoint no responde con un código 2xx, la entrega se reintenta hasta 3 veces con espera (inmediato, +30s, +5min) antes de darla por fallida. Cada intento queda registrado — el log de entregas (con el código HTTP o el error de cada uno) es visible desde el Backoffice, para depurar un webhook que no está respondiendo.

Catálogo de eventos

EventoSe dispara cuando...
tarea.finalizadaSe finaliza una tarea con duración (ver Modelos de datos).
nota.creadaSe crea una nota — no se dispara al editarla, solo al crearla.
cita.reservadaSe crea una reserva de Cal.diy vía citas_crear_reserva.
correo.mensaje_nuevoUna sincronización de correo trae mensajes nuevos (uno por sincronización con novedades, no uno por mensaje).
Solo estos cuatro eventos de negocio concretos emiten un webhook — no hay un evento por cada escritura de db.py, sería ruido en el uso diario normal del registro de actividad.

Gestión por MCP

ToolDescripción
webhooks_listar(tenant=None)Lista los webhooks configurados (sin el secreto).
webhooks_crear(url, eventos_suscritos, tenant=None)Da de alta un webhook nuevo.
webhooks_borrar(webhook_id)Borra un webhook (y su historial de entregas).