Arquitectura del Gateway
Arquitectura del gateway WebSocket, componentes y flujos de cliente.
Última actualización: 2026-01-22
Visión General
- Un gateway de larga duración posee todas las interfaces de mensajería (via WhatsApp
Baileys, GrammY Telegram, Slack, Discord, Signal, iMessage, WebChat).
- Los clientes del plano de control (app macOS, CLI, Web UI, automatización) se conectan al
gateway via WebSocket en el host configurado (predeterminado
''127.0.0.1:18789'').
- Los Nodos (macOS/iOS/Android/headless) también se conectan via WebSocket, pero
usan una declaración explícita en mayúsculas/comando ''role: node''.
- Un gateway por host; este es el único lugar donde se abren las sesiones de WhatsApp.
Componentes y Flujo
#
Gateway (Daemon)
- Mantiene conexiones de proveedor.
- Expone API WS tipada (solicitudes, respuestas, eventos enviados por servidor).
- Valida tramas entrantes contra esquemas JSON.
- Emite eventos ''agent'', ''chat'', ''presence'', ''health'', ''heartbeat'', ''cron'', etc.
#
Clientes (app mac / CLI / Web admin)
- Una conexión WS por cliente.
- Envía solicitudes (''health'', ''status'', ''send'', ''agent'', ''system-presence'').
- Se suscribe a eventos (''tick'', ''agent'', ''presence'', ''shutdown'').
#
Nodos (macOS / iOS / Android / headless)
- Se conectan al ''mismo servidor WS'' usando ''role: node''.
- Proporcionan identidad de dispositivo en ''connect''; el emparejamiento es ''basado en dispositivo'' (rol ''node'') y
la aprobación existe en el almacén de emparejamiento de dispositivos.
- Expone comandos como ''canvas.*'', ''camera.*'', ''screen.record'', ''location.get''.
Detalles del protocolo:
#
Web Chat
- UI estática para historial de chat y envío usando la API WS del Gateway.
- En configuraciones remotas, se conecta via el mismo túnel SSH/Tailscale que otros
clientes.
Ciclo de Vida de Conexión (Cliente Único)
Client Gateway
| |
|| (or res error + close)
| (payload=hello-ok carries snapshot: presence + health)
| |
|< event:presence -----| (final: {runId,status,summary})
| |Protocolo de Cable (Resumen)
- Transporte: WebSocket, tramas de texto con cargas JSON.
- La primera trama ''debe'' ser ''connect''.
- Después del handshake:
- Solicitudes: ''{type:"req", id, method, params}'' → ''{type:"res", id, ok, payload|error}''
- Eventos: ''{type:"event", event, payload, seq?, stateVersion?}''
- Si ''OPENCLAW_GATEWAY_TOKEN'' (o ''--token'') está configurado, ''connect.params.auth.token''
debe coincidir o el socket se cerrará.
- Los métodos con efectos secundarios (''send'', ''agent'') requieren claves de idempotencia
para reintentos seguros; el servidor mantiene un caché de desduplicación de corta duración.
Emparejamiento + Confianza Local
- Todos los clientes WS (operadores + nodos) incluyen ''identidad de dispositivo'' en ''connect''.
- Los nuevos IDs de dispositivo requieren aprobación de emparejamiento; el gateway emite un token de dispositivo
para conexiones subsiguientes.
- Las conexiones locales (loopback o dirección tailnet propia del host del gateway) pueden
ser auto-aprobadas para mantener la UX del mismo host fluida.
- Las conexiones ''no locales'' deben firmar el nonce ''connect.challenge'' y requieren
aprobación explícita.
- La autenticación del gateway (''gateway.auth.*'') aún aplica a ''todas'' las conexiones, locales o
remotas. Detalles: ''Protocolo del Gateway'', ''Emparejamiento'', ''Seguridad''.
Tipos de Protocolo y Generación de Código
- Los esquemas TypeBox definen el protocolo.
- Los esquemas JSON se generan a partir de estos esquemas.
- Los modelos Swift se generan a partir de esquemas JSON.
Acceso Remoto
- Preferido: Tailscale o VPN.
- Alternativo: túnel SSH
''ssh -N -L 18789:127.0.0.1:18789 user@host''
- El mismo handshake + tokens de auth aplican sobre el túnel.
- TLS + pinning opcional pueden habilitarse para WS en configuración remota.
Instantánea Operacional
- Inicio: ''openclaw gateway'' (primer plano, logs a stdout).
- Salud: ''health'' sobre WS (también incluido en ''hello-ok'').
- Supervisión: launchd/systemd para reinicio automático.
Invariantes
- Solo un gateway por host controla una sesión de Baileys.
- El handshake es obligatorio; cualquier trama no-JSON o que no sea connect primero es cierre forzado.
- Los eventos no se retransmiten; los clientes deben recuperar huecos.