← Volver al catálogo
AutomatizacionesReferenciaIntermedioGratis

OpenClaw Webhooks — Integración con agentes IA

Skill de referencia para recibir y verificar webhooks del gateway OpenClaw, con ejemplos listos en Express y FastAPI para construir servicios externos que reaccionen a eventos de agentes IA.

Descargar skill (.zip)

Descarga abierta · sin registro · para Node.js, Python, Express

// resultado_de_ejemplo

// Generated with: openclaw-webhooks skill // https://github.com/hookdeck/webhook-skills // // FlowDesk CRM — Webhook Handler para Agentes IA OpenClaw // Cliente: FlowDesk CRM (SaaS B2B para PYMEs) // Generado por CULTIVA IA — https://cultivaia.com // ----------------------------------------------------------

const express = require('express'); const crypto = require('crypto');

const app = express(); const PORT = process.env.PORT || 3000;

// ─── 1. VERIFICACIÓN DE TOKEN ─────────────────────────────────────────────────

/**

  • Verifica el token Bearer enviado por OpenClaw Gateway.
  • Soporta dos formatos de cabecera:
  • Authorization: Bearer
  • x-openclaw-token:
  • Usa timingSafeEqual para prevenir timing attacks. */ function verifyOpenClawWebhook(authHeader, xTokenHeader, secret) { const token = extractToken(authHeader, xTokenHeader); if (!token || !secret) return false;

try { return crypto.timingSafeEqual( Buffer.from(token), Buffer.from(secret) ); } catch { return false; } }

function extractToken(authHeader, xTokenHeader) { if (xTokenHeader) return xTokenHeader; if (authHeader && authHeader.startsWith('Bearer ')) return authHeader.slice(7); return null; }

// ─── 2. LOGGER ESTRUCTURADO ───────────────────────────────────────────────────

function log(level, event, data = {}) { console.log(JSON.stringify({ ts: new Date().toISOString(), level, service: 'flowdesk-openclaw-handler', event, ...data, })); }

// ─── 3. PROCESAMIENTO DE EVENTOS (ASYNC) ─────────────────────────────────────

/**

  • Procesa un evento de agente IA de forma asíncrona.
  • FlowDesk lo usa para:
    • Generar respuestas borrador de soporte al cliente
    • Resumir conversaciones largas
    • Enrutar tickets según prioridad detectada por la IA */ async function processAgentEvent(payload) { const { message, name, agentId, sessionKey, wakeMode, channel, to } = payload;

log('info', 'agent.processing', { agentId: agentId || 'default', name: name || 'FlowDesk Agent', sessionKey, wakeMode: wakeMode || 'now', deliveryChannel: channel || 'slack', recipient: to, messagePreview: message?.slice(0, 80), });

// Aquí iría la lógica de negocio de FlowDesk: // - Consultar ticket en BD por sessionKey // - Enriquecer el mensaje con contexto del cliente // - Almacenar el jobId de OpenClaw para trazabilidad

log('info', 'agent.queued', { sessionKey, note: 'Agente IA encolado — respuesta será entregada via Slack al equipo de soporte', }); }

/**

  • Procesa un evento de wake (sistema).
  • FlowDesk lo usa para:
    • Notificar al agente de nuevos correos entrantes
    • Alertar sobre SLAs próximos a vencer
    • Refrescar contexto del cliente en la sesión del agente */ async function processWakeEvent(payload) { const { text, mode } = payload;

log('info', 'wake.processing', { mode: mode || 'now', eventText: text, });

// Lógica: registrar el evento en tabla agent_events para auditoría log('info', 'wake.recorded', { note: 'Evento sistema registrado en BD' }); }

// ─── 4. RUTAS WEBHOOK ─────────────────────────────────────────────────────────

// Middleware de autenticación reutilizable function authenticateOpenClaw(req, res, next) { const authHeader = req.headers['authorization']; const xToken = req.headers['x-openclaw-token']; const secret = process.env.OPENCLAW_HOOK_TOKEN;

if (!verifyOpenClawWebhook(authHeader, xToken, secret)) { log('warn', 'auth.failed', { ip: req.ip, path: req.path, hasAuth: !!authHeader, hasXToken: !!xToken, }); return res.status(401).json({ error: 'Token inválido o ausente' }); }

next(); }

/**

  • POST /hooks/agent

  • Recibe solicitudes para ejecutar un turno del agente IA.

  • OpenClaw espera respuesta 202 Accepted rápida; el trabajo es async.

  • Payload esperado:

  • {

  • "message": "El cliente Pablo García reporta que no puede exportar facturas PDF",

  • "name": "SoporteTicket",

  • "agentId": "flowdesk-support-agent",

  • "sessionKey": "ticket:FD-4821",

  • "wakeMode": "now",

  • "deliver": true,

  • "channel": "slack",

  • "to": "#soporte-ia",

  • "model": "openai/gpt-4o-mini",

  • "thinking": "medium",

  • "timeoutSeconds": 60

  • } */ app.post('/hooks/agent', express.json({ limit: '256kb' }), authenticateOpenClaw, async (req, res) => { const payload = req.body;

    // Validación básica del payload if (!payload.message) { log('warn', 'agent.invalid_payload', { reason: 'message requerido' }); return res.status(400).json({ error: 'Campo "message" requerido' }); }

    // Responder inmediatamente (OpenClaw no espera resultado, solo ACK) res.status(202).json({ received: true, queued: true });

    // Procesar en background (no bloquea la respuesta HTTP) processAgentEvent(payload).catch(err => { log('error', 'agent.processing_error', { message: err.message }); }); } );

/**

  • POST /hooks/wake

  • Encola un evento de sistema para que el agente lo procese en su próximo ciclo.

  • OpenClaw espera 200 OK.

  • Payload esperado:

  • {

  • "text": "Nuevo ticket creado: FD-4821 — prioridad alta",

  • "mode": "now"

  • } */ app.post('/hooks/wake', express.json({ limit: '64kb' }), authenticateOpenClaw, async (req, res) => { const payload = req.body;

    if (!payload.text) { log('warn', 'wake.invalid_payload', { reason: 'text requerido' }); return res.status(400).json({ error: 'Campo "text" requerido' }); }

    // Responder inmediatamente res.status(200).json({ received: true });

    // Procesar en background processWakeEvent(payload).catch(err => { log('error', 'wake.processing_error', { message: err.message }); }); } );

// ─── 5. HEALTH CHECK ─────────────────────────────────────────────────────────

app.get('/health', (req, res) => { res.json({ status: 'ok', service: 'flowdesk-openclaw-handler', version: '1.0.0', endpoints: ['/hooks/agent', '/hooks/wake'], }); });

// ─── 6. ARRANQUE ─────────────────────────────────────────────────────────────

app.listen(PORT, () => { log('info', 'server.started', { port: PORT }); if (!process.env.OPENCLAW_HOOK_TOKEN) { log('warn', 'config.missing', { note: 'OPENCLAW_HOOK_TOKEN no configurado — los webhooks serán rechazados', }); } });

module.exports = app; // Para testing

/* ───────────────────────────────────────────────────────────────── VARIABLES DE ENTORNO (.env) ─────────────────────────────────────────────────────────────────

OPENCLAW_HOOK_TOKEN=flowdesk_oc_prod_x7k2m9n4p1q8r5s3 PORT=3000

───────────────────────────────────────────────────────────────── DESARROLLO LOCAL CON TUNNEL ─────────────────────────────────────────────────────────────────

Instalar Hookdeck CLI (una vez)

npm install -g hookdeck-cli

Arrancar el servidor

node server.js

En otra terminal, crear el tunnel

npx hookdeck-cli listen 3000 openclaw --path /hooks/agent

Hookdeck dará una URL pública tipo:

https://hkdk.events/xxxxxxxx

→ Configúrala como webhook URL en el panel de OpenClaw Gateway

───────────────────────────────────────────────────────────────── EJEMPLO CURL — Disparar agente de soporte ─────────────────────────────────────────────────────────────────

curl -X POST http://localhost:3000/hooks/agent
-H "Content-Type: application/json"
-H "Authorization: Bearer flowdesk_oc_prod_x7k2m9n4p1q8r5s3"
-d '{ "message": "El cliente Pablo García (ticket FD-4821) no puede exportar facturas PDF. Sistema: MacOS 14, Chrome 124.", "name": "SoporteTicket", "agentId": "flowdesk-support-agent", "sessionKey": "ticket:FD-4821", "wakeMode": "now", "deliver": true, "channel": "slack", "to": "#soporte-ia", "model": "openai/gpt-4o-mini", "thinking": "medium", "timeoutSeconds": 60 }'

Respuesta esperada: HTTP 202

{ "received": true, "queued": true }

───────────────────────────────────────────────────────────────── EJEMPLO CURL — Evento wake (nuevo ticket) ─────────────────────────────────────────────────────────────────

curl -X POST http://localhost:3000/hooks/wake
-H "Content-Type: application/json"
-H "x-openclaw-token: flowdesk_oc_prod_x7k2m9n4p1q8r5s3"
-d '{ "text": "Nuevo ticket creado: FD-4822 — cliente Enterprise, prioridad ALTA, asignado a soporte-ia", "mode": "now" }'

Respuesta esperada: HTTP 200

{ "received": true }

───────────────────────────────────────────────────────────────── */

// qué_hace

Proporciona código listo para verificar tokens y manejar payloads de webhooks enviados por el gateway de agentes IA OpenClaw.

// cómo_lo_hace

Implementa verificación de token mediante comparación segura (timingSafeEqual / hmac.compare_digest) en Express y FastAPI, con tablas de referencia de endpoints, campos y códigos de respuesta.

// ejemplo_de_uso

Úsala cuando construyes un agente IA que necesita recibir notificaciones asíncronas de OpenClaw. Ej.: verificas el token y procesas el payload de finalización de tarea en tu endpoint FastAPI.

// plataformas

Node.jsPythonExpressFastAPINext.jsHookdeck
Categoría
Automatizaciones
Tipo
Referencia
Nivel
Intermedio
Licencia
MIT
Seguridad
seguro · riesgo bajo
Versión
1.0.0

// opiniones_de_la_comunidad

Opiniones

Cargando opiniones…

// pase_cultiva_ia

Llévate todo el arsenal con el Pase

Todas las skills, prompts y automatizaciones del catálogo en un único archivo, listas para usar: un pago, acceso de por vida y las novedades que añadamos. Sin suscripción.

Pago único · IVA incluido · pago seguro con Stripe.

Acceso inmediato · si no es lo que esperabas, te devolvemos los 10 €.