WebChatV2/docs/N8N_CONTRACT.md

4.4 KiB

Contrato de integración con n8n — WebChatV2

El frontend hace un POST al webhook de n8n con el mensaje del usuario y el historial, y espera una respuesta JSON con el texto del asistente y, opcionalmente, KeyNotes (resumen / To-Do) que se insertan automáticamente en el panel derecho y que el usuario puede editar después.

1. Configuración de la URL

La URL del webhook se resuelve en tiempo de ejecución (no se "hornea" al compilar), para que puedas cambiarla sin reconstruir la imagen Docker:

  1. public/config.js → define window.APP_CONFIG.N8N_WEBHOOK_URL (prioridad alta).
  2. Si no existe, se usa la variable de entorno VITE_N8N_WEBHOOK_URL (definida al compilar).

En Docker, edita el archivo config.js servido por nginx (o monta un volumen sobre /usr/share/nginx/html/config.js) y recarga la página.

2. Request — POST {N8N_WEBHOOK_URL}

Content-Type: application/json

{
  "themeId": "theme_abc123",
  "subThemeId": "sub_def456",
  "themeTitle": "Tema Principal",
  "subThemeTitle": "Subtema 1",
  "history": [
    { "role": "user", "content": "Hola" },
    { "role": "assistant", "content": "¿En qué puedo ayudarte?" }
  ],
  "message": "Explícame cómo funciona esto"
}
Campo Tipo Descripción
themeId string ID del MainTheme activo. Útil para guardar contexto en n8n/DB.
subThemeId string ID del SubTheme activo (la conversación actual).
themeTitle string Título del tema (legible).
subThemeTitle string Título del subtema (legible).
history array Mensajes previos {role, content} (orden cronológico).
message string Texto que el usuario acaba de escribir (NO está incluido en history).

role es "user" | "assistant".

3. Response — 200 OK (JSON)

{
  "reply": "Respuesta en **Markdown** del asistente…",
  "keyNotes": [
    {
      "type": "summary",
      "title": "Resumen de la conversación",
      "content": "Puntos clave tratados…"
    },
    {
      "type": "todo",
      "title": "Tareas pendientes",
      "items": [
        { "text": "Revisar la documentación", "done": false },
        { "text": "Configurar el webhook", "done": true }
      ]
    }
  ]
}

Reglas

  • reply (obligatorio, string): texto de respuesta. Se renderiza como Markdown (soporta GFM: listas, tablas, bloques de código, etc.).
  • keyNotes (opcional, array): notas que se añaden al SubTheme activo con source: "n8n". El usuario puede editarlas/eliminarlas libremente.

Tipos de KeyNote

type Requiere
summary title + content (string, Markdown plano)
todo title + items[] con { text: string, done?: boolean }
free title + content

done es opcional y por defecto false.

4. Errores y timeouts

  • Cualquier status HTTP fuera del rango 2xx se trata como error y se marca el mensaje como status: "error". El usuario puede pulsar Reintentar.
  • Timeout por defecto: 120 s. La solicitud puede cancelarse con el botón Detener (usa AbortController), lo que aborta el fetch hacia n8n.

5. Ejemplo de workflow n8n (orientativo)

Webhook (POST /webhook/chat)
  → Set (extraer body.message, body.history, body.themeTitle…)
  → [tu LLM / lógica]
  → Set (construir JSON { reply, keyNotes })
  → Respond to Webhook (JSON, 200)

En n8n usa el nodo Respond to Webhook con Respond With: JSON y en Response Body pega el objeto { "reply": ..., "keyNotes": [...] }.

6. Evolución futura (streaming / persistencia en DB)

  • Streaming: el contrato queda preparado para añadir SSE (text/event-stream) más adelante sin romper la UI (el indicador "escribiendo…" ya existe).
  • Persistencia: el estado vive hoy en localStorage. Para sincronizar con una DB vía n8n, añade endpoints GET/POST /webhook/state y reemplaza el adapter en src/store/persistence.ts (punto único de intercambio).