El tipo de integración JSBOX alimenta el chat del sitio web: los visitantes envían mensajes que aparecen en tu panel de control de Mailoo. Puedes responder desde la consola de chat; los visitantes ven las actualizaciones mediante WebSocket o polling.
::: {.contents local=""} :::
Conceptos
- Tipo de integración:
JSBOX(creado en el panel de control o mediante la API pública con una clave API). - Sesiones: Cada hilo de visitante es una sesión de chat (
sessionPublicIdopaco). El primer mensaje crea una sesión; los mensajes posteriores incluyensessionPublicId. - Clave API: Obligatoria para llamadas del lado del servidor a los webhooks de Mailoo (tu BFF, backend o automatización). Nunca pongas la clave API en JavaScript del navegador.
API pública (X-API-Key)
Las claves restringidas pueden incluir:
webhook.chat-integration-create---POST /api/v1/webhooks/chat/{projectUid}/integrations(crear una integración JSBOX).chat.send-message--- mensajes de chat, historial de sesión y estado de chat bajo/api/v1/webhooks/chat/....
Crear una integración JSBOX
curl -X POST "https://api.mailoo.app/api/v1/webhooks/chat/proj_1/integrations" \\
-H "X-API-Key: YOUR_KEY" \\
-H "Content-Type: application/json" \\
-d '{"name":"Support chat","config":{"allowedOrigins":["https://example.com"]}}'
Enviar un mensaje de visitante (limitado a proyecto + integración):
curl -X POST "https://api.mailoo.app/api/v1/webhooks/chat/{projectUid}/{integrationId}/messages" \\
-H "X-API-Key: YOUR_KEY" \\
-H "Content-Type: application/json" \\
-H "Origin: https://your-site.com" \\
-d '{"content":"Hello","sessionPublicId":"optional-if-continuing"}'
Listar mensajes en una sesión (para polling servidor/BFF):
GET /api/v1/webhooks/chat/{projectUid}/{integrationId}/sessions/{sessionPublicId}/messages?since=ISO8601
Estado de la integración de chat
GET /api/v1/webhooks/chat/{projectUid}/{integrationId}/status
Ruta legada (solo id de integración): POST /api/v1/webhooks/messages/{integrationId} sigue existiendo pero requiere chat.send-message y una integración JSBOX.
Los webhooks públicos de chat comparten el rate limit de la clave API. Cuando se supera, Mailoo responde HTTP 429. El widget @mailoo/chat clasifica eso (y fallos de gateway/red) y muestra un panel de indisponibilidad en lugar del texto crudo de la API --- el host debe pasar unavailableAction (ver chat-widget-nextjs-example{.interpreted-text role="doc"}).
Panel de control (JWT Bearer)
- Sesiones:
GET /api/v1/chat/{integrationId}/sessions---status=OPEN|PENDING|CLOSEDopcional yassignedUserId=<userId>oassignedUserId=unassigned. - Historial:
GET /api/v1/chat/{integrationId}/sessions/{sessionPublicId}/messages - Respuesta del propietario:
POST /api/v1/chat/{integrationId}/sessions/{sessionPublicId}/replycon JSON{"content":"..."}. - Asignar / cerrar:
PATCH /api/v1/chat/{integrationId}/sessions/{sessionPublicId}con{"assignedUserId":"<userId>"|null}(solo miembros del proyecto) o{"action":"close"}.
Las sesiones son OPEN, PENDING o CLOSED. Ajustes del widget JSBOX (config.chatWidget):
- Autorespuesta --- el primer mensaje del visitante en una sesión nueva envía
autoresponder.message;expectedReplyHoursopcional pasa el estado aPENDINGhasta que un operador responda. - Plantillas de respuesta ---
replyTemplates(no plantillas de campaña FORM); la consola las inserta en el cuadro de respuesta. - Seguimiento al cerrar --- con
action: close, se envíancloseFollowUp.messagey/ocloseFollowUp.reviewUrl. Mensajes posteriores del visitante en una sesión cerrada devuelven 409. - Agente IA opcional ---
config.chatWidget.agent(enabled,name,imageMediaIdopcional,kbIntegrationIdBlog del mismo proyecto, markdowninstructions/kbDigestPrompt/kbArticlePrompt,kbFiles). Si está activo, el agente aparece primero en el equipo (idjsbox_chat_agent). La API anteponeinstructions, rellena las plantillas y llama a Wednesday en segundo plano con un digest de KB (solo título + slug); el cuerpo del artículo víaKB_REQUEST:<slug>. Los archivos KB se guardan en S3 y aún no se inyectan al modelo. El widget no habla con Wednesday. Respuestas OUTBOUNDjsbox_chat_agentconsenderName= nombre visible. Asignar detiene el agente. El agente también puede transferir a un humano conHANDOFF_TO_HUMAN:(texto al visitante más brief para operadores); Mailoo fijahandedOffAt, estadoPENDING, guarda el brief como OUTBOUNDmetadata.source: jsbox_chat_agent_handoff(solo dashboard) y omite más turnos del agente. Hace faltaWEDNESDAY_BASE_URL(dev:http://127.0.0.1:4080). - MCP / ajustes de agente ---
GET/PATCH /api/v1/chat/{projectUid}/integrations/{integrationId}/settings(ámbitochat.manageo token MCP) lee/actualiza la misma config saneada del widget y devuelve conteos lifetime de mensajes y sesiones (sin lista de sesiones ni cuerpos). Herramienta MCP:manage_jsbox_integration_settings(vermailoo-mcp{.interpreted-text role="doc"}). Skill de agente (reglas mínimas):configure-chat-mcp{.interpreted-text role="doc"}.
La aplicación web las proxea a través de su BFF bajo las mismas rutas (con autenticación de sesión).
WebSocket
En un host Next.js usando @mailoo/chat, el origen WebSocket del navegador no es una variable de tiempo de compilación NEXT_PUBLIC_*: el servidor lo resuelve en tiempo de ejecución (MAILOO_CHAT_WS_ORIGIN, sino entorno base de chat/API --- consulta getMailooChatWebSocketOrigin).
- Propietario (panel):
/api/v1/chat/ws?integrationId=...&token=<JWT>--- usa el mismo token de acceso queAuthorization: Bearer. - Visitante:
/api/v1/chat/visitor-ws?projectUid=...&integrationId=...&sessionPublicId=...--- sin clave API; la sesión debe existir ya (creada al enviar un mensaje). Prefiere exponer solosessionPublicIdal navegador y validar en tu BFF cuando sea posible.
Para detalles de arquitectura, payloads de eventos, proxy inverso (wss) y consideraciones multi-réplica, consulta chat-websocket-production{.interpreted-text role="doc"}.
Panel (detalle de integración)
En la página de la integración JSBOX, los propietarios del proyecto usan pestañas:
- Widget --- colores de marca, texto de bienvenida, URL de privacidad, posición del launcher (cuatro esquinas más middle-left / middle-right; por defecto bottom-right) y temas.
- Respuestas y automatización --- visibilidad de operadores, autoresponder, plantillas de respuesta y seguimiento al cerrar.
- Agente IA --- ajustes solo del propietario: interruptor, nombre, avatar opcional, Blog KB, ventanas markdown de instrucciones y subida de archivos KB (S3). Los editores pueden abrir la pestaña; solo el propietario guarda. Si está activo, el agente está en el equipo del widget y en Setup → Operators (sin checkbox). El chat flotante de mailoo.app es esta misma JSBOX; el seed de desarrollo activa el agente con nombre, Blog KB y plantillas de prompt (Wednesday +
WEDNESDAY_BASE_URL). - Conexión y ajustes --- biblioteca de imágenes, claves API, snippet de entorno del servidor y eliminación. El
configalmacenado está detrás de Ver JSON de configuración (diálogo de referencia formateado), no como bloque siempre visible.
JSBOX no tiene pestaña Products/contenido: el estado, el recuento de mensajes y la última actividad permanecen en la cabecera. Los editores ven esas métricas de cabecera, Conexión y ajustes y la pestaña Agente IA (interruptor desactivado). Los editores de widget/respuestas siguen siendo solo del propietario.
CORS y allowedOrigins
Las llamadas del navegador a los webhooks de Mailoo pueden enviar una cabecera Origin. Opcionalmente configura orígenes permitidos en la integración JSBOX. Si la lista está vacía, no se verifica Origin (la clave API sigue siendo obligatoria). El campo legado domain en la configuración almacenada permanece como respaldo CORS para filas antiguas pero ya no se recopila en el panel de control.
La posición del launcher se guarda en config.chatWidget.position y se devuelve en el endpoint público widget-config. La ruta de host por defecto (resolveMailooChatHostConfig + MailooSiteChatShell) la aplica siempre vía widgetConfig. Un prop position explícito en MailooSiteChatWidget sigue teniendo prioridad si se define.
Consulta también
chat-widget-nextjs-example{.interpreted-text role="doc"} --- patrón BFF de Next.js y variables de entornochat-websocket-production{.interpreted-text role="doc"} --- comportamiento WebSocket y notas de producción- OpenAPI:
https://api.mailoo.app/docs/v1