NAiOSOmni
omnichatv0.8.0Conecta WhatsApp y Telegram a NAiOS. Dashboard con KPIs y gráficas, inbox unificado, auto-reply IA con tools, agentes verticales, modo simulación demo y multi-tenant.
Descripción
OmniChat convierte cualquier canal de mensajería en una interfaz a NAiOS. Vincula WhatsApp Personal (Baileys, vía QR), WhatsApp Business Platform oficial (Meta Cloud API) o Telegram Bot. Incluye dashboard con KPIs auto-calculados + gráficas (línea, donut, heatmap), inbox unificado en tiempo real (SSE), auto-respuesta IA con tool-calling, 14 herramientas (generar/editar imágenes, transcribir audio, mandar email, consultar KB, crear presentaciones/landings/forms, guardar pedidos estructurados...), 5 modos de canal (cerrado, whitelist, blacklist, cliente, gateway de adquisición), modo SIMULACIÓN para demos donde el cliente elige qué agente probar, comandos por self-chat (/on, /off, /pause, /ai), self-link via /claim para que tus clientes registrados usen su propio contexto NAiOS, onboarding gateway con magic-link login, AGENTES VERTICALES: bots especializados (pedidos a domicilio, leads inmobiliarios, reservas restaurante, etc.) con prompt + variables de negocio + JSON schema de captura, generados por IA-wizard, con CRM integrado, auto-recovery del worker tras pérdida de sesión y reconexión sin re-vincular cuando las credenciales siguen válidas.
Funcionalidades (26)
Vincula tu número como dispositivo via QR o código. Soporta grupos. Worker process aislado.
Conexión oficial con Meta Cloud API. Cero riesgo de ban, plantillas, webhooks HMAC verificados.
Bot oficial vía Bot API. Token de @BotFather, sin riesgo, gratis. Soporta grupos y media.
Lista de conversaciones + thread + composer. SSE push, multimedia visual (imágenes, audios, vídeos).
Loop tool-calling: 12 herramientas listas (generar/editar imágenes, audios, KB, email, presentaciones...).
Typing indicator escalado por longitud, jitter aleatorio, cool-down post-respuesta manual del owner.
Cerrado, whitelist, blacklist, cliente, gateway. Configurable visualmente.
Convierte tu canal en funnel: cualquier desconocido invitado a crear cuenta gratis NAiOS con magic-link.
Users registrados pueden vincular su WhatsApp con /claim email + /code. Bot usa SU prompt y SUS tokens.
Override por peer: force-on/off, prompt custom, pausa, todo desde UI.
Editor visual por día con franjas horarias, modo OOO con mensaje custom.
Cuotas msg/min/hora/día, detección automática de bursts, protege contra bans.
/on /off /pause /status /test /prompt /ai /help desde tu propio self-chat.
6 plantillas: restaurante, soporte, inmobiliaria, salón, ventas B2B, asistente personal.
Endpoint con totales y stats por canal, errores, mensajes/día, sesiones activas.
Crea bots especializados (pedidos, leads, reservas) describiendo en lenguaje natural — la IA genera prompt, campos y email.
Los pedidos se guardan en BD con JSON Schema. Vista CRM con filtros, estados, edición, notas, export CSV.
Aviso por email + WhatsApp al teléfono vinculado cuando llega un pedido nuevo. Confirmación automática al cliente.
Cada nuevo registro dispara POST firmado con HMAC-SHA256 a tu URL externa (Zapier, Make, n8n, CRM). Retry exponencial + log de entregas.
4 columnas (nuevo / contactado / completado / archivado) con arrastrar y soltar entre estados. Toggle tabla/Kanban persistido.
Diagrama interactivo generado por IA a partir del prompt — visualiza turnos, decisiones, herramientas y campos capturados. Zoom/pan + export SVG.
Tab principal con KPIs, gráficas (Chart.js: línea/donut/barras + heatmap D3), actividad reciente unificada y health-check con acciones.
Home con KPIs auto-calculados (mensajes, pedidos, conversión, tokens) + line chart 30d entrantes/salientes + donut estados + heatmap hora×día + top canales/agentes + alertas de salud.
Pone un canal en modo demo: el cliente elige entre los agentes que tú habilites. 5 textos editables, comandos /exit /cambiar /menu /help, records marcados con flag is_simulation.
Tras pérdida de sesión WhatsApp Web (cierre server-side, límite de 4 dispositivos, reinicio del server) el worker se rearranca solo reusando el auth_blob guardado. Botón 'Reconectar' explícito si el auto falla.
Picker de contactos integrado: agenda sincronizada (wa-personal) o peers vistos. En Bandeja primero eliges canal y luego contacto, te lleva al thread vacío listo para escribir.
Changelog
- MODO SIMULACIÓN — toggle por canal con multi-select de agentes permitidos, 5 textos editables (menú/intro/confirm/invalid/exit), comandos /exit /cambiar /menu /help, estado per-peer (chosen_agent_id + phase + session_started_at), historial scoped por session_started_at para evitar contaminación de persona al cambiar agente
- Tabla nueva omnichat_simulation_state + columnas en omnichat_channel_settings + flag is_simulation en omnichat_agent_records
- DASHBOARD global del plugin sustituye la home /plugins/omnichat/ — KPIs auto-calculados (mensajes con delta vs período anterior, pedidos nuevos + stale-24h, conversión, tokens consumidos), line chart 30d entrantes/salientes, donut estados, heatmap hora×día, top canales y top agentes, feed pedidos recientes, alertas calculadas (canales caídos, pedidos sin contactar, fallos webhook 1h)
- Endpoint /api/dashboard?range=24h|7d|30d con todas las agregaciones SQL en una request, refresh cada 30s
- Sidebar restructure: Dashboard como primer ítem, listado de canales movido a /channels, eliminadas mini-stats redundantes con el dashboard
- Auto-recovery — restoreAll() ahora también revive canales unlinked con auth_blob+identifier válidos al arrancar el plugin (cubre cierre server-side de WhatsApp Web, límite de 4 dispositivos, server restart)
- Botón Reconectar (icono refresh) en card de canales unlinked con sesión válida — reusa auth_blob sin escanear QR
- Worker fix — wasPaired check ahora consulta la BD (identifier IS NOT NULL) en vez del in-memory sock.authState.creds.registered, que Baileys flipea a false en cierres server-side
- Friendly status_detail en cards: 'unpaired_close: connectionClosed' → ocultado para canales unlinked (el botón Vincular ya comunica), 'loggedOut: ...' → 'Sesión cerrada desde WhatsApp', etc.
- Agent detail UX overhaul — sub-tabs verticales (Identidad / Comportamiento / Captura / Integraciones) reemplazan el scroll plano de 9 cards
- Sticky save bar con indicador 'Cambios sin guardar' (animación pulse) + beforeunload warning
- Tools agrupadas por categoría (🖼 Multimedia / 📚 Conocimiento / 📦 Captura / 📤 Outputs) con cards visuales: icono semántico, título amable, nombre técnico discreto, toggle iOS-style, border accent verde cuando ON, badges 'Obligatorio' / 'Plugin no instalado'
- KB collections como sub-panel anidado bajo lookup_kb (no card hermano) — cards con icono+color de la colección, doc_count chip, auto-select si hay 1 sola, warning si lookup_kb ON pero 0 marcadas, empty state con CTA a /plugins/knowledge-base
- Endpoint /api/agents/tools-catalog ahora devuelve available + missing[] por tool consultando el plugin loader
- Botón 'Editar agente' shortcut en settings del canal cuando hay agent_id activo — link directo a /plugins/omnichat/agents/<id>
- Picker de Nuevo chat en Bandeja (tab Conversaciones) — modal 2-pasos canal+contacto, deep-link a inbox con ?openPeer=<id>
- Inbox: parser de ?openPeer=<id>&peerName&peerType al cargar — abre thread automáticamente (existente o sintético) y limpia URL con replaceState
- Filtro 'Solo reales / Todos / Solo simulación' en pestaña Pedidos + badge 🧪 sim en cards/filas
- Bug fix — getRecentMessages comparaba ts SQLite ('YYYY-MM-DD HH:MM:SS') vs sinceTs ISO ('YYYY-MM-DDTHH:MM:SSZ') con string ASCII, ' ' < 'T' rompía el filtro siempre. Ahora usa datetime() en ambos lados
- Bug fix — endpoint /api/agents/kb-collections usaba this.pluginLoader que nunca se asignaba; ahora resuelve con this.app.get('pluginLoader') lazy en request-time
- Bug fix — JS del records.ejs reventaba en modo embed por addEventListener sobre null en hub-conv-q; añadido optional chaining
- Bug fix — outerHTML en renderDetail del slide-over panel borraba el id del span al re-renderizar status pill, segundo cambio de estado fallaba con 'Cannot read properties of null'; reemplazado por className+textContent
- Bug fix — bug de especificidad CSS body.oc-shell-body (1,1,1) > .oc-shell-body (1,1,0) hacía que el grid mobile siguiera con sidebar 240px reservada; sidebar oculta pero el main solo recibía viewport-240px de ancho
- Mobile responsive — viewport meta en las 7 vistas con <head>, KPI grid 2-col en mobile (minmax 200px → 150px), heatmap labels density adapta a width, padding-left para burger en agent dashboard, sidebar bottom padding para que footer 'Inicio NAiOS' no caiga bajo el chrome del browser
- Toggle del card de canal con label 'Bot' explícito + tooltip — evita confusión con conexión
- CSRF middleware: eliminados console.log de debug que saturaban el log en cada switch de chat
- Reconciliación condicional — _reconcileOrphanFiles solo se llama cuando el conv loaded tiene mensajes con generation marker sin file_url (antes se llamaba en cada switch sin cesar)
- Composer con adjuntos: 📎 file picker multi-archivo + drag-and-drop overlay + Ctrl+V paste
- Backend multer endpoint hasta 5 archivos × 50MB con auto-detect MIME → image/video/audio/document
- Smart caption: 1ª imagen/video lleva el texto como caption, los demás van sin
- Worker wa-personal extendido: handlers nativos para audio (ptt) y video con caption
- Hub unificado en Bandeja: tab 'Conversaciones' agrega chats de TODOS los canales
- Filtro por canal con chips clickables + counters por canal en header
- Endpoint /api/inbox/conversations con merge cross-channel + search global
- Slide-over thread con composer integrado (responde sin salir del Hub)
- Avatares en lista del Hub + thread head consistente con inbox individual
- Mobile: lista colapsa al thread al seleccionar conversación
- Bug fix: imágenes outbound del bot ya no se pierden por race condition con el echo de Baileys (BOT_SENT_IDS dedup)
- Avatares de perfil: fetch desde Baileys via sock.profilePictureUrl, descarga + cache local
- Worker IPC: fetchAvatar (single) + bulkFetchAvatars (throttled ~5/sec)
- DB: omnichat_synced_contacts.avatar_local_path + avatar_fetched_at + helpers upsertAvatar/getAvatar
- Endpoint GET /api/channels/:id/avatar/:peerId con ETag caching y refresh automático >7d
- Endpoint POST /refresh-avatars para bulk manual
- Helper ocAvatar() reusable con fallback a icono Phosphor si no hay foto
- Integración: lista de conversaciones (36px) + thread header (40px) + combobox contactos (28px)
- Botón 📸 Avatares junto a 📲 Agenda en contact picker (solo wa-personal)
- Card de canal refactorizado: status pill uniforme con icono+label (sin más raw 'error'/'unlinked')
- Toggle ON/OFF inline en el card (bot_enabled directo, sin entrar a Ajustes)
- Menú ⋮ contextual con Ajustes / Ver log / Re-vincular / Eliminar
- Acción primaria contextual al estado (Inbox / Vincular / Reconectar)
- Tab nuevo 📜 Log con tabla en tiempo real, filtros (tiempo/nivel/categoría/search), live tail SSE, export CSV, clear
- Servicio LogService que escribe BD + emite SSE + console fallback
- Instrumentación: connection lifecycle, auto-reply decisions, tool calls, webhook deliveries, rate-limit bursts
- Retención automática 30 días + endpoints GET/DELETE /api/channels/:id/logs
- Card oc-card-bot-off opacidad reducida + sufijo '(bot off)' al título
- Combobox de contactos reusable (ocPeerCombobox) — dropdown con búsqueda, fallback manual, exclude list
- Pestaña Contactos reescrita: combobox sustituye input peer_id, auto-rellena nombre
- Overrides existentes renderizados como cards con avatar + chip de política + borde semántico
- Click en card 'editar' → formulario inline pre-rellenado con valores actuales (no más borrar+recrear)
- Cache compartida del peer pool entre Acceso (whitelist/blacklist) y Contactos (overrides)
- Combobox excluye automáticamente peers que ya tienen override (evita duplicados)
- Sincronización opt-in de la libreta WhatsApp (Baileys): reads sock.contacts + suscripción a contacts.upsert para incremental
- Tabla omnichat_synced_contacts + bulkUpsert con transacción + ON CONFLICT preserva nombres no vacíos
- Worker IPC syncContacts + handler async + emit contacts.snapshot
- Nuevo método driver.requestContactsSync() simétrico a sendMessage
- POST /api/channels/:id/sync-contacts (manual trigger) y GET /synced-contacts
- UI contact picker: botón 📲 Agenda solo visible para wa-personal, modal de consent privacy-first la 1ª vez
- Merge inteligente seen-peers + synced-contacts (deduped por peer_id), tags visuales 'agenda'/'manual'
- Sort: peers con mensajes primero por recencia, luego sincronizados alfabéticamente
- Telegram + Cloud API: botón oculto (no exponen agenda)
- Bug fix: JOIN cross-DB users → omnichat fallaba; ahora se hidrata naios_user_email en 2-step
- Contact picker visual para whitelist/blacklist — sustituye textarea de peer_ids
- Split panel En la lista | Disponibles, búsqueda en vivo, click para mover
- Color semántico verde para whitelist, rojo para blacklist (previene errores)
- Endpoint /api/channels/:id/seen-peers con last_msg_preview y actividad relativa
- Modal 'Añadir manualmente' con preview del formato (auto @s.whatsapp.net si solo dígitos)
- Backward compatible con almacenamiento legacy newline-separated
- Scoping privacy-first del KB por agente: cada agente puede ser limitado a colecciones específicas
- Tool lookup_kb lee agent.kb_collections; si está vacío, no consulta nada (evita filtrar info confidencial)
- Búsqueda paralela en colecciones autorizadas + merge top-K por similarity
- UI agent detail: sub-sección 'Colecciones de KB autorizadas' aparece al activar lookup_kb
- Endpoint /api/agents/kb-collections proxy a knowledge-base con detección de plugin no instalado
- Nuevo método público KB.getCollectionsForUser({userId}) simétrico a searchAsUser/addDocAsUser
- Dashboard del agente como tab por defecto (sustituye Estadísticas)
- Endpoint /api/agents/:id/dashboard con 6+ aggregations en una sola llamada (cache 60s)
- 5 KPIs: total, hoy (vs ayer), 7 días (vs anterior), por atender, tiempo medio cierre
- 3 gráficas Chart.js (línea por día / donut por estado / barras top campo adaptativo)
- Heatmap D3 actividad hora × día de la semana
- Activity feed unificado: registros + entregas webhook ordenados temporalmente
- Health-check con 5+ validaciones y enlace 'arreglar' por cada problema
- Chart.js v4 lazy-loaded desde CDN solo en este tab
- Visor de flujo del agente: D3 + dagre renderiza JSON generado por IA a partir del prompt
- GET /api/agents/:id/flow con cache por hash del prompt (si no cambió, sirve cache instantáneo)
- Nuevo tab 📊 Flujo en detalle del agente con zoom/pan, export SVG, modo JSON debug
- 6 tipos de nodo (start/message/input/decision/tool/end/error) con paleta coordinada al tema slate/green
- D3 v7 + dagre cargados lazy desde CDN solo al activar el tab
- Webhooks salientes por agente: URL + HMAC-SHA256 secret + retry exponencial (1s/5s/30s) + log de entregas
- POST /api/agents/:id/webhook/test (ping de prueba sin retry) y /webhook/deliveries (auditoría)
- Vista Kanban en Bandeja con 4 columnas y drag-drop entre estados (Sortable.js, optimistic update)
- Toggle tabla/Kanban con preferencia persistida en localStorage
- UI agent detail: card 'Webhook' con generar secret + test ping + tabla de entregas en vivo
- Tabla omnichat_webhook_deliveries para debugging
- Etiquetas dinámicas por agente: record_label_singular/plural (Pedido/Reserva/Ticket/Cita/Lead/etc.)
- Wizard IA propone los labels automáticamente según el caso de uso
- UI usa el label del agente en cards, headers, confirms y notificaciones (email + WhatsApp owner)
- Top nav renombrado: 'Pedidos' → 'Bandeja' (neutro, cubre todos los géneros)
- Agentes verticales: bots especializados (gasoil, restaurante, inmobiliaria…) con prompt + vars de negocio + JSON Schema de captura
- AI Wizard: describe tu bot en lenguaje natural y la IA genera el agente completo (prompt, campos, email template, tools)
- Tool save_agent_record con validación contra data_schema y schema dinámico (LLM ve los campos exactos a pedir)
- Tool send_confirmation_email con plantilla del agente + sustitución {{vars}}
- Sustitución {{vars}} en prompts (resolve template-vars helper)
- Vista CRM /records: tabla, filtros, detalle slide-over, edit, status workflow, bulk actions, CSV export
- Notificación al dueño por email + WhatsApp al recibir pedido nuevo
- Per-channel agent selector + UI agentes con grid + on/off
- Inbox responsive mobile + menú ⋮ por conversación con 4 acciones
- Scrollbars temáticos slate/green
- DB: omnichat_agents, omnichat_agent_records (+ active_agent_id en channel_settings)
- Telegram Bot driver oficial (Bot API)
- 5 tools nuevas: generate_image_transparent, generate_music, create_presentation, create_landing, create_form
- Métricas endpoint para superadmin
- Settings UI v2 con tabs modernos + editores visuales (business_hours, OOO, rate_limit)
- Templates de prompts (restaurante, soporte, inmobiliaria...)
- Test suite Node native (29 tests)
- Profile wizard para users gateway (cambiar email/password provisional)
- Identity enrichment: badge NAiOS en inbox para peers vinculados
- SSE en inbox (push real-time vs polling)
- Visualización multimedia en thread (img/audio/video)
- Hardening: rate limiter, anti-spam burst, business hours, out-of-office
- Gateway mode real: onboarding NAiOS via WhatsApp + magic-link login
- Self-link /claim email + /code XXXXXX para users registrados
- Multi-tenant en tool ctx (identity.user_id usa contexto de SU workspace)
- Per-peer overrides UI (force_on/off, custom_prompt)
- Token bypass admin/superadmin
- Tools framework con audience (admin/public) + plugin requirements
- Tools: generate_image, send_email, lookup_kb, edit_image, remove_bg, transcribe_audio, analyze_image
- ctx.invokePlugin para llamadas cross-plugin
- Comando /ai para chat IA con tools desde self-chat
- Notify pre-task ("🎨 Generando imagen...")
- WhatsApp Cloud API driver (Meta oficial)
- Refactor Baileys a worker process (child_process.fork + IPC)
- Auto-reply IA + comandos /off /on /pause /status /test /prompt
- Inbox unificado básico
- Channel modes (closed/whitelist/blacklist/customer/gateway)
- Identity resolution con omnichat_known_peers
- Per-peer lock + queueing (race fix)
- Scaffold inicial
- Channel adapter interface
- Driver wa-personal Baileys (in-process)
- DB schema (8 tablas)
- Pairing por QR + código
- Vista base