Saltar al contenido principal

Flujo de Sesión — Crimoo Copilot

Cómo se establece la conexión entre el dashboard y el copilot que aparece en el sitio del cliente.

Componentes involucrados​

ComponenteRepoRol
Dashboardui-angularEl operador abre la sesión desde aquí
Backendnode-apiGestiona sesiones, sirve /gtm.js, SSE
Copilot UICrimooCopilot-frontApp React que corre dentro del iframe en el sitio del cliente

Requisito previo​

El sitio del cliente debe tener instalado un tag en GTM que cargue el script del backend:

GET https://api.crimoo.com/gtm.js

Sin este tag, el copilot no puede aparecer en el sitio.

Flujo completo​

Ciclo de vida de tokens​

Estado de sesión (SessionStateService)​

El estado se mantiene en memoria en node-api. No sobrevive reinicios del servidor.

Importante: El timeout solo aplica a sesiones en estado connected o error. Las sesiones pending nunca hacen timeout — quedan como zombies si el copilot nunca cargó.

Endpoints de sesión​

MétodoPathAuthDescripción
POST/api/sessionsJWTCrear sesión, retorna initToken
POST/api/sessions/claimNoCanjear initToken → activationToken
POST/api/sessions/:id/heartbeatactivationTokenMantener sesión activa
POST/api/sessions/:id/disconnectactivationTokenDesconexión explícita
GET/api/sessions/:id/streamNoSSE — stream de estado en tiempo real
GET/gtm.jsNoScript loader que inyecta el iframe

SSE — Stream de estado​

El dashboard se suscribe vía EventSource a /api/sessions/:id/stream. El backend emite eventos con nombre status:

event: status
data: {"status":"connected"}

Estados posibles: pending · connected · disconnected · error

El SessionStreamService (Angular) reconecta automáticamente con backoff exponencial (máx. 5 intentos).

Depuración — El copilot no aparece​

Si los logs muestran ciclos de subscribe/unsubscribe en SSE pero nunca ✅ Session marked as CONNECTED:

  1. GTM no disparó — verificar que el tag esté activo en el container del cliente
  2. initToken expirado — el token dura 120s; si la claim llega tarde, la UI del copilot muestra "sesión expirada"
  3. COPILOT_URL mal configurada — el iframe apunta a una URL inaccesible; verificar variable de entorno COPILOT_URL en node-api
  4. Sesión zombie en pending — el timeout no limpia sesiones pending; solo connected y error