← Leksimus

Changelog

Registro de cambios, mejoras y correcciones de Leksimus.

v8.36.0 Studio
  • Release: v.8.36.0
  • Fix
  • + Studio / Vista de moderador / Resumen muestra el canal ajeno - La pestaña Resumen mostraba el preview de stream, las estadísticas y el chat del propio moderador en vez del canal que estaba gestionando (las pestañas Comandos, Overlay, Interacción y Conexiones ya filtraban correctamente por `managedChannel`). Ahora `StreamPreview` y `StreamStatsPanel`/`ChatUsersPanel` reciben el canal moderado cuando aplica, y las secciones "Cuentas vinculadas" y "Funcionalidades por plataforma" (datos de la cuenta propia, irrelevantes al moderar) se ocultan en ese modo. El chat unificado sigue atado al overlay room propio: no hay forma de mostrar el chat del canal ajeno sin un cambio de arquitectura aparte.
  • + Studio / Anuncios globales / No eran visibles para usuarios ni editables por admin - El banner de "Anuncios globales" usaba el cliente API del dashboard de Discord (`/dashboard/api/announcement`) dentro de Studio (Twitch), y solo se montaba en la pestaña Admin (oculta para el resto de usuarios). Además el endpoint `GET /twitch-dashboard/api/announcement` nunca devolvía `isOwner`, así que el botón "Editar" no aparecía ni para el admin. `AnnouncementBanner` ahora acepta el cliente API por prop (`twitchApi` en Studio), el endpoint Twitch incluye `isOwner` en GET y PUT (mismo patrón que el lado Discord), y el banner se renderiza para todos los usuarios de Studio fuera del tab Admin.
  • + Dashboard / Tipografía y contraste / Letra demasiado pequeña en toda la web - La mayoría de textos de UI usaban tamaños literales de Tailwind (`text-[9px]`, `text-[10px]`, `text-[11px]`) en vez de la escala estándar, ilegibles según feedback de usuarios. `index.css` sube esos tamaños (a 11/11.5/12.5px) y `text-xs` (12px → 13px) con reglas globales fuera de cualquier `@layer`, sin tocar componente por componente. También sube la opacidad de `text-white/20` a `/40` para mejorar el contraste de texto secundario sobre fondos casi negros.
  • + Studio / Comandos personalizados / Doble scroll - La lista de comandos personalizados tenía su propio `max-h-[800px] overflow-y-auto` interno, redundante desde que la página completa ya scrollea. Quitado: ahora la lista se extiende junto con el resto del panel.
  • + Studio / Overlay & Alertas / Emojis como iconos - `AlertsPanel` (tipos de evento, controles de overlay, selector de media, nota de cobertura Kick) y el sidebar de Studio (`UnifiedSidebar`) usaban emojis como iconos, contra la convención del proyecto. Reemplazados por SVG inline estilo Feather.
v8.35.0 Studio
  • Release: v.8.35.0
  • Nuevo
  • + Studio / Actividad y participantes / Kick - El panel de estadísticas y el panel de chatters de Kick están disponibles en Studio junto a sus equivalentes de Twitch. `KickStatsPanel` muestra viewers en vivo, pico de sesión, media de sesión, chatters únicos y mensajes totales (polling cada 30 s). `KickChatUsersPanel` lista los chatters activos de Kick con indicador de actividad reciente y filtro por nombre (polling cada 15 s). La sección muestra el badge de Kick en el header solo cuando hay cuenta Kick vinculada.
  • + Studio / Actividad y participantes / Recap del directo - Nuevo panel `StreamRecapPanel` que muestra el resumen de la sesión actual (o la última finalizada) para Twitch y opcionalmente Kick: pico de viewers, media, chatters únicos, mensajes en chat, nuevos seguidores, subs (directos + resubs), y raids con el total de viewers obtenidos por raid. Los raids se pueden desplegar para ver quién raidió y cuántos viewers aportó cada uno. Polling cada 60 s.
  • + Bot / Métricas de sesión / Acumuladores - `DB_StreamSession` añade `viewerSum` (suma acumulada de samples) y `messageCount` (mensajes totales del chat en la sesión). `CRON_StreamWatchtime` pasa de muestrear cada 5 min a cada 1 min y acumula `viewerSum` en cada ciclo para ambas plataformas. `StreamMessageCounter` (nuevo servicio) cuenta mensajes en memoria por plataforma y canal, y los vuelca a `DB_StreamSession` al final de cada ciclo del cron.
  • + Bot / Métricas de sesión / Conteo de mensajes Twitch y Kick - `KickStudioChatService` registra cada mensaje de Kick en `StreamMessageCounter` (contador + chatter activo). `REQ_TwitchOfflineChatRelay` registra cada PRIVMSG de Twitch en el mismo contador mediante `require` lazy para evitar dependencias circulares.
  • + API / Kick Dashboard / Endpoints de stats y chatters - `GET /kick-dashboard/api/stats` devuelve métricas de la sesión activa de Kick (isLive, viewers, pico, media, únicos, mensajes). `GET /kick-dashboard/api/chatters` devuelve los chatters activos en los últimos 30 min, ordenados por última actividad.
  • + API / Twitch Dashboard / Endpoint de recap - `GET /twitch-dashboard/api/session-recap` devuelve el resumen combinado Twitch + Kick: datos de sesión de ambas plataformas, eventos de actividad (follows, subs, raids detallados por raider) consultando `DB_TwitchActivityLog` dentro de la ventana temporal de la sesión.
  • Cambios
  • + Bot / Planes / Tier free activo - `CONF_SubscriptionPlans.json`: `free.available` pasa a `true`. El bot opera con funciones base sin suscripción; se paga para desbloquear funciones avanzadas.
  • + Bot / Planes / Relay Kick→Discord de pago - Nueva clave `chatRelayKickToDiscord` en todos los planes: `false` en free, `true` en suscriber, vip y unlimited.
  • + Bot / Alertas Kick / Gratuitas - `/kickalert` usaba la clave `streamevents` (solo suscriptores), en contradicción con `/streamalert` de Twitch que era gratuita. Clave corregida a `streamAlerts`; las alertas de Kick son ahora gratuitas igual que las de Twitch.
v8.34.0 Studio
  • Release: v.8.34.0
  • Nuevo
  • + Dashboard / Chat unificado / Emotes - El chat unificado renderiza emotes de forma nativa en lugar de mostrarlos como texto. Kick: reemplaza `[emote:{id}:{name}]` por `<img src="https://files.kick.com/emotes/{id}/fullsize">`. Twitch nativas: parsea `twitchEmotesRaw` (formato IRC `id:start-end`) y reemplaza cada posición con `<img src="https://static-cdn.jtvnw.net/emoticons/v2/{id}/default/dark/1.0">`. BTTV global + canal: se obtienen al montar (`api.betterttv.net`) y al recibir el primer `broadcasterId` de Twitch. 7TV global + canal: ídem (`7tv.io`). FFZ canal: se obtiene con el nombre de canal Twitch (`api.frankerfacez.com`). Los emotes de texto (BTTV/7TV/FFZ) se aplican por coincidencia de palabra; cada emote es un `<img>` inline de 20px de alto.
  • Fix
  • + Dashboard / Chat unificado / Badges de Twitch - Los badges de Twitch no se mostraban. Causa: `data.badges` de Twitch llega del WebSocket como string IRC `"moderator/1,subscriber/0"`, y el handler hacía `Array.isArray(data.badges) ? data.badges : []`, que siempre devolvía `[]` para Twitch. Añadida función `parseBadges()` que convierte el string al array `[{type}]` que espera `BadgeChip`. Kick ya enviaba un array, por lo que sus badges seguían funcionando.
v8.33.0 Kick
  • Release: v.8.33.0
  • Nuevo
  • + Bot / Kick / Comandos hardcoded en chat de Kick - Los comandos nativos del bot antes exclusivos del chat de Twitch funcionan ahora también en el chat de Kick. Nuevo módulo `KickHardcodedRouter.js` que adapta el contexto de Kick (badges → badgesStr, relay fake → `sendKickChatAsUser`) y redirige al despacho de cada handler existente sin duplicar lógica: `TW_Quotes` (`!quote`, `!addquote`, `!delquote`), `TW_Shoutout` (`!so`; el mensaje custom llega a Kick, el clip al overlay y el embed a Discord), `TW_Giveaway` (`!sorteo`; crea el sorteo en Discord), `TW_Queue` (`!openlobby`…`!pickplayer`), `TW_JukeboxCommands` (`!music*`), `TW_StreamControl` subset (`!live`, `!traduciron`, `!traduciroff`, `!traducirestado`). Comandos Twitch-only excluidos: `!clip`, `!settitle`, `!setgame`, `!followage`. Flujo en `KickStudioChatService`: `dispatchNativeCommand` → `dispatchKickHardcoded` → `resolveCommandText` (custom).
  • + Dashboard / Comandos nativos / Badge Kick - El catálogo de comandos IRC nativos muestra un badge verde `K` junto a cada comando disponible en Kick. Los 20+ comandos compatibles lo muestran; `!followage`, `!getclip`, `!clip`, `!settitle` no lo llevan.
  • Fix
  • + Dashboard / Widgets de overlay / Editar - El botón "Editar" de los widgets de overlay no abría el formulario. Causa: `SpoilerUrl` se usaba dentro del formulario de edición en `OverlayWidgetsPanel.jsx` sin estar importado; React lanzaba un error de tipo al intentar renderizarlo. Añadido el import faltante.
v8.32.0 Kick
  • Release: v.8.32.0
  • Nuevo
  • + Dashboard / Chat unificado / Badges - Cada mensaje del chat unificado muestra el nivel del usuario con chips de color junto al username: `MOD` (verde), `VIP` (amarillo), `SUB` (lila), `LIVE` (broadcaster, rojo), `BOT` (gris), `OG` (púrpura). Toggle **MOD** en la cabecera del panel. Los badges se extraen del campo `sender.identity.badges` de Pusher y del campo equivalente del webhook, normalizados por `KickProvider` y `KickWebhookController` y propagados a través de `MultichatOverlayService` hasta el WebSocket del dashboard.
  • + Dashboard / Chat unificado / Hora - Toggle **HH:MM** en la cabecera del panel. Muestra la hora de cada mensaje (formato `HH:MM`, locale `es-ES`). El timestamp proviene del campo `created_at` del evento Pusher (`ts`) o del campo `timestamp` del webhook; se propaga por toda la pipeline igual que los badges.
  • + Webhook / Kick / Clave pública dinámica - La firma RSA del webhook de Kick ya no depende solo de la clave hardcodeada. `KickWebhookController` obtiene la clave de `https://api.kick.com/public/v1/public-key` al arrancar y la refresca cada 24 h; si el fetch falla, usa el hardcode como fallback. Protege ante rotaciones de clave sin interrumpir el servicio.
  • Fix
  • + Bot / Kick / Canal Pusher `.v2` - `KickProvider.subscribeChat()` usaba `chatrooms.{chatroomId}` como nombre de canal Pusher. Kick publica los mensajes en `chatrooms.{chatroomId}.v2`; sin el sufijo la conexión se establecía correctamente pero no llegaba ningún evento. Causa de que el chat de Kick no apareciera en el dashboard aunque los logs mostraran `[KickStudioChat] Suscrito`. Ver ERR_0060.
  • + Bot / Kick / LeksID auto-reparación en reconcile - Si el flujo OAuth se completó con `dest=dashboard` en lugar de `dest=link`, el campo `kickUsername` quedaba a `null` en `DB_LeksId` aunque `overlayRoomToken` existiera. `KickStudioChatService.reconcile()` no encontraba el documento y nunca suscribía el canal. Ahora el reconcile detecta estos LeksIDs huérfanos, cruza con `DB_KickOAuth` por `twitchUserId`, repara el campo y suscribe el canal en el mismo ciclo. Ver ERR_0061.
  • Docs
  • + `docs/issues/ERR_0060.md` y `ERR_0061.md` - Registro de los dos bugs de Kick con causa raíz, impacto y checklist de prevención. INDEX actualizado (61 registros, próximo ERR_0062).
  • + `docs/shared/funcional/multicanal.md` - Secciones nuevas: badges/timestamp en Chat unificado, KickStudioChat (canal Pusher `.v2`, normalización, auto-reparación de LeksID), seguridad del webhook (firma RSA, clave dinámica, anti-replay).
v8.31.0 Studio
  • Release: v.8.31.0
  • Nuevo
  • + Dashboard / Reautorización de Twitch - El Studio detecta si el token de Twitch guardado no tiene todos los scopes actuales (compara con `SCOPES_LIST`; el refresh de token **no** concede scopes nuevos) y muestra un banner con botón **"Reautorizar Twitch"** que reinicia el OAuth. `GET /twitch-dashboard/auth/me` pasa a exponer `scopes`, `missingScopes` y `needsReauth`. Necesario para habilitar el envío como streamer (`user:write:chat`) en cuentas ya vinculadas: un scope nuevo no se puede conceder en silencio, requiere consentimiento.
  • Cambios
  • + Twitch / Chat multicanal - Los mensajes que el streamer envía desde el chat multicanal del Studio ahora salen **como el propio streamer** vía la API oficial (Helix `POST /chat/messages`, scope `user:write:chat`), igual que ya hacía Kick con su API. Reemplaza el eco "en nombre de" por IRC: se elimina la conexión IRC-as-streamer, que se caía (`code=1006`) y dejaba envíos fallidos (`sendRaw undefined`) y reenvíos en bucle. Los comandos (`!...`) se siguen procesando con permisos de broadcaster. Nueva función `sendChatMessageAsUser` en `UTIL_TwitchHelix`. Los streamers ya vinculados deben re-autorizar Twitch para conceder el scope nuevo.
  • + Overlay / Capas por Browser Source - El overlay desplegado (`stream/public/overlay/index.html`) acepta `?layer` con tres capas mutuamente excluyentes: `alerts` (solo alertas/tarjetas/contadores), `general` (media excepto el SO: sonidos, imágenes, vídeos, otros clips) y `so` (solo el clip del !so). Sin parámetro se pinta todo (compatibilidad). El clip del !so se marca en el emit con `soClip: true` (`TW_Shoutout`) para enrutarlo a su capa propia. Permite una Browser Source por capa en OBS sin que el SO, la media y las alertas se pisen.
  • Fix
  • + Twitch / !so - El clip del shoutout salía siempre el mismo: `pickShoutoutClip` tomaba el primer clip de Helix, que ordena por **más vistos** (no por fecha), y se quedaba con el top. Ahora baraja la lista (Fisher-Yates) antes de elegir, como el reproductor de clips aleatorios.
  • + Overlay / Indicador de conexion - El punto de estado del WebSocket (`#status`, verde al conectar, fijo arriba a la derecha) ensuciaba el overlay del stream. Queda oculto por defecto; visible solo con `?debug` en la URL del overlay.
v8.30.0 Studio
  • Release: v.8.30.0
  • Nuevo
  • + Leksimus Studio completo - Todas las herramientas de tu canal viven ya en un solo sitio, organizadas por pestañas: comandos nativos y personalizados, cola, alertas, widgets de overlay, TTS, ruleta, extensibles, VIP, traduccion, clips, OBS Overlay y WebSocket, biblioteca de media, moderadores, importar comandos y mas. Las mismas funciones del panel de Twitch, unificadas en Studio.
  • + Comandos en Twitch y Kick - Ahora eliges en que plataformas responde cada comando personalizado. Marca Kick y el comando tambien funciona en tu chat de Kick.
  • + Alerta de "En directo" multiplataforma - Nueva alerta al empezar a transmitir, disponible para Twitch y Kick (es el unico evento que la API de Kick permite). Cada grupo de alertas elige sus plataformas.
  • + Comandos a traves del relay de Discord - Con el chat relayado entre tu plataforma y Discord, los comandos funcionan en ambos sentidos: un comando escrito en el canal de Discord recibe respuesta del bot, y desde tu chat puedes usar `!relay <comando>` para lanzar un comando de Discord (ej. `!relay botinfo`).
  • + SO y clips en su propia capa - Puedes poner el shoutout y los clips en una Browser Source aparte para que no se pisen con tus alertas. Si no tocas nada, todo sigue funcionando igual.
  • Cambios
  • + OBS Relay siempre conectado - El OBS Relay queda fijo en una barra del dashboard y ya no se desconecta al cambiar de pestaña.
v8.29.0 Studio
  • Release: v.8.29.0
  • Nuevo
  • + Leksimus Studio - El dashboard multicanal ahora es **Leksimus Studio**, tu unico panel de streaming para Twitch, Kick y (proximamente) YouTube. Mismo sitio para canal, chat unificado, alertas y overlay, sobre tu identidad LeksID.
  • + Acceso libre - El dashboard deja de ser de pago: cualquier streamer puede entrar y vincular sus cuentas. La parte de pago pasa a limites y funciones avanzadas, no al acceso al panel.
  • Fix
  • + Chat de Kick - Si estabas en plan free no podias vincular Kick, y por eso su chat no aparecia en el dashboard aunque si llegara a Discord. Ya puedes vincularlo, y el chat se activa al instante al hacerlo, sin esperas.
  • + Web - El acceso principal pasa a llamarse "Leksimus Studio" y la web aprovecha mejor las pantallas anchas.
v8.28.0 Streaming
  • Release: v.8.28.0
  • Nuevo
  • + Multicanal / Chat - Ya puedes escribir en tus chats desde el dashboard: nueva barra de envio con selector de plataforma. Los comandos de Twitch (!so, !uptime...) se ejecutan con tus permisos de streamer, y en Kick el mensaje sale con tu identidad real.
  • + Dashboard / Streaming - Navegacion centralizada: un solo dashboard de Streaming con las paginas Comandos, Multicanal y Kick. Eliges la plataforma con la que haces streaming sin saltar entre dashboards separados.
  • + Multicanal - Ahora es una pestaña del dashboard Streaming, con actividad y participantes del canal, complementos como OBS Relay, y tu LeksID protegido (difuminado hasta que lo reveles).
  • Fix
  • + Dashboard - Las paginas de acceso de Twitch y Kick y las Guias de uso ahora tienen el panel de navegacion y la identidad visual de Digital Bite, como el resto del dashboard.
v8.27.1 Fix
  • Release: v.8.27.1
  • Fix
  • + Multicanal / Chat - El chat de Kick no llegaba al chat multicanal del dashboard ni al widget de OBS. Vincular el canal de Kick al LeksID ahora activa automaticamente la suscripcion de chat con Kick; ya no hace falta configurar el relay a Discord ni el mapeo del overlay para ver el chat unificado.
  • + Overlay OBS / Multichat - Corregido un error presente desde v.8.25.0 por el que el widget de chat compartido no recibia los mensajes de Kick cuando el nombre del canal de Kick era distinto al de Twitch. El badge de plataforma se mantiene correcto en todos los casos.
  • + Multicanal - Los mensajes duplicados (cuando el mismo chat llega por dos rutas) se filtran automaticamente.
v8.27.0 Multicanal
  • Release: v.8.27.0
  • Nuevo
  • + Overlay OBS / Multicanal - Nuevo overlay unificado: una sola Browser Source recibe las alertas de todas tus plataformas vinculadas (Twitch, Kick y futuras), cada una con el badge y color de su plataforma. Los overlays de Twitch y Kick siguen funcionando por separado, sin cambios.
  • + Dashboard / Multicanal - Chat multicanal en vivo: los chats de Twitch y Kick aparecen juntos en el dashboard en tiempo real, cada mensaje con el icono y color de su plataforma.
  • + Dashboard / Multicanal - Nueva cabina en vivo: preview del canal con selector Twitch/Kick junto al chat multicanal, en la parte superior del dashboard.
  • + Dashboard / Multicanal - Seccion de overlay unificado con URL para OBS protegida con spoiler, copia en un clic y alertas de prueba por plataforma. El room unificado se activa automaticamente al entrar (requiere plan Suscriber o superior).
  • + Dashboard / Multicanal - Rediseno completo de la pagina: tabla de funcionalidades disponibles por plataforma, modulos multicanal con estado segun cuentas vinculadas y comandos IRC agrupados por categoria.
  • Fix
  • + Dashboard / Multicanal - La pagina adopta la identidad visual de Digital Bite/Leksimus: navegacion unificada, superficies oscuras, rojo de marca como acento e iconos propios en lugar de emojis.
v8.26.0 Kick
  • Release: v.8.26.0
  • Nuevo
  • + Dashboard / Kick - El panel de Kick ahora es operativo: permite ver el canal autorizado, servidores vinculados, estado del canal, alertas de directo, relay de chat a Discord y overlay de chat compartido.
  • + Dashboard / Kick - Se pueden guardar alertas de directo, elegir canal de Discord, rol de mencion, configurar relay Kick -> Discord, enviar pruebas y vincular el chat de Kick al overlay multicanal.
  • + Overlay OBS / Kick - Kick tiene URL y token propios para alertas OBS (`/overlay/alerts.html?platform=kick`), separados del token y la fuente de Twitch.
  • Fix
  • + Dashboard / Kick - El panel adopta la identidad visual de Digital Bite/Leksimus: superficies oscuras y rojo de marca como acento principal.
  • + Dashboard / Kick - El panel ahora usa la navegacion unificada para saltar entre Discord Bot, Twitch IRC, Kick, Multicanal y guias de uso.
  • + Overlay OBS / Alertas - Las alertas de Kick y Twitch quedan filtradas por plataforma para evitar que sonidos o eventos se mezclen entre fuentes.
v8.25.1 Fix
  • Release: v.8.25.1
  • Fix
  • + Bot / Kick / OAuth — Corregido el flujo de autorización OAuth de Kick. El endpoint de introspect no devuelve identidad de usuario y está marcado como deprecated; se reemplaza por la llamada correcta a la API oficial (`GET /public/v1/users`), que devuelve el usuario autenticado con su ID y nombre cuando se usa con scope `user:read`.
v8.25.0 Streaming
  • Release: v.8.25.0
  • Nuevo
  • + Bot / Kick - Las alertas de directo ahora usan la API oficial de Kick cuando esta configurada, con deteccion live/offline mas rapida y fallback legacy si la API oficial no esta disponible.
  • + Bot / Kick - Soporte para webhooks oficiales `livestream.status.updated`: los avisos de directo pueden llegar en tiempo real y comparten la misma logica que el sondeo periodico.
  • + Discord / `/streamextras` - Nuevo comando para activar eventos programados de Discord al ir en vivo, resumen post-stream y consulta de top watchtime.
  • + Bot / Streaming - Nuevo ciclo de vida de directos: sesiones live/offline, pico de viewers, chatters unicos, metricas de actividad y resumen automatico al terminar el stream.
  • + Bot / Twitch / `/twitchpoll` - Gestion de encuestas y predicciones de Twitch desde Discord: crear, terminar, bloquear, resolver o cancelar segun corresponda.
  • + Overlay OBS / Multichat - Los mensajes de Kick pueden aparecer en el widget de chat del overlay junto a Twitch, con badge de plataforma.
  • Config
  • + Nuevas variables para API oficial de Kick, reconciliacion de suscripciones webhook, frecuencia de sondeo Kick, watchtime y multichat overlay.
v8.24.0 Seguridad
  • Release: v.8.24.0
  • Seguridad
  • + Bot / Twitch / webrequest — Refuerzo de seguridad en el sistema de comandos `{webrequest:URL}` y en el proxy de texto. Las peticiones que apunten a direcciones internas o privadas del servidor (loopback, redes privadas, link-local y el endpoint de metadatos) quedan bloqueadas, mientras que cualquier URL pública sigue funcionando exactamente igual.
  • + Bot / Twitch / webrequest — La protección actúa en dos capas: al guardar el comando en el dashboard y en el momento de la petición, validando la dirección real de destino en cada conexión, incluidos los redireccionamientos.
  • + Bot / Seguridad — Los intentos de apuntar un comando a una dirección interna se notifican automáticamente al administrador del bot y quedan registrados para su revisión.
v8.23.0 Dashboard
  • Release: v.8.23.0
  • Nuevo
  • + Dashboard / Twitch - Identidad visual Digital Bite: todos los acentos morado/indigo del dashboard Twitch (`TwitchCommands`, toggles, grids de posicion, badges de tipo evento/overlay, checkboxes VIP) fueron reemplazados por el rojo de marca `#e8001a`.
  • + Dashboard / Twitch - El mock del cockpit en vivo ya reflejaba la identidad visual; ahora los paneles de configuracion tambien son coherentes con la marca.
  • Fix
  • + Bot / Twitch / !so - El clip del ultimo stream ahora se resuelve siempre en fresco: se elimino el cache en memoria de URLs GQL firmadas, que tenia TTL de 10 minutos, y tambien el shuffle de candidatos.
  • + Bot / Twitch / !so - Cada ejecucion de `!so` consulta la API directamente y selecciona el primer clip resolvible a MP4 de la lista devuelta por Helix, ordenada por fecha descendente.
  • + Dashboard / Twitch / !so - Las dimensiones del overlay de clip (`ancho` x `alto`) ahora tienen valor por defecto `480px x 270px` tanto al crear el comando como al cargar una configuracion antigua con campos vacios.
  • + Dashboard / Twitch / !so - Antes el formulario mostraba siempre los inputs en blanco aunque el valor efectivo fuera automatico.
v8.22.0 Jukebox
  • Release: v.8.22.0
  • Nuevo
  • + Dashboard / Twitch / Jukebox — Modo de activación "Ambos": el selector ahora permite habilitar Bits/Cheer y Recompensa de canal simultáneamente. Al elegir "Ambos" se muestran a la vez el input de bits mínimos y el selector de recompensa.
  • + Dashboard / Twitch / Jukebox — Botón ▶ en cada ítem de la cola activa, en estado "En cola" / "Enviada": marca la solicitud como "Sonando" y envía un control play al bridge para iniciar reproducción inmediatamente.
  • + Dashboard / Now Playing — Barra de progreso con interpolación suave: entre polls del bridge, cada 5 s, un timer local de 500 ms avanza la posición para que la barra se mueva de forma continua sin saltos.
  • + Overlay OBS / Now Playing — La plantilla por defecto del widget ahora incluye barra de progreso verde, tiempo actual y duración (`1:23 / 4:06`), con la misma interpolación suave. No requiere Custom HTML.
  • Fix
  • + Dashboard / Twitch / Jukebox — El modo `triggerMode: 'both'` era ignorado en la validación del backend; las solicitudes de bits y recompensa se rechazaban con `trigger_mismatch`. Corregido en `TwitchJukeboxService`.
v8.21.0 Jukebox
  • Release: v.8.21.0
  • Nuevo
  • + Dashboard / Twitch / Jukebox — Nueva sección "Activación de solicitudes" siempre visible en el panel Jukebox. Incluye selector de modo entre Bits/Cheer o Recompensa de canal, campo de bits mínimos con texto explicativo dinámico y selector de recompensa con chip de confirmación. Las opciones avanzadas, como límite de cola, aprobación manual y duplicados, pasan a un bloque colapsable separado.
  • + Music Bridge v1.8.0 — `smtc-generic` anuncia soporte completo de Jukebox con `supportsJukebox: true`. Las solicitudes aprobadas se envían al bridge y quedan en estado "En cola" hasta que el streamer reproduce la canción manualmente en su app de música. El bridge la detecta automáticamente por SMTC al coincidir título y artista.
  • Fix
  • + Dashboard / Now Playing — Corregido el badge de versión del bridge, que mostraba siempre "Bridge v?" porque `getBridgeCapabilities()` devolvía solo el subobjeto `capabilities` sin incluir `clientVersion`, almacenado por separado. Ahora la función retorna `{ ...capabilities, clientVersion }`.
  • + Dashboard / Now Playing — Corregido el badge "Jukebox" en el bloque de capacidades del bridge, que aparecía apagado aunque el Jukebox estuviera activo en la configuración. La causa era que `smtc-generic` reportaba `supportsJukebox: false` al servidor. Queda corregido en Music Bridge v1.8.0.
v8.20.1 Fix
  • Release: v.8.20.1
  • Fix
  • + Bot / Discord — `REQ_CreateRole` y `REQ_CreateThread` crasheaban con `TypeError: Cannot destructure property 'nombre'/'titulo' of 'undefined'` en cada interacción de Discord (menús de self-roles, botones, slash commands). Causa: ambos requisitos tenían `allowedEvents: ['interactionCreate']`, lo que hacía que el REQ_Engine los ejecutara en cada interacción sin el segundo argumento de config. Corregido: `allowedEvents: []` — el REQ_Engine los ignora; los comandos `/createrole` y `/createthread` los siguen llamando directamente con la config resuelta.
  • + Dashboard / Twitch / Canales moderados — Al navegar entre canales moderados, los paneles Alertas de overlay, Extensibles, Ruletas y Streamers VIP no actualizaban sus datos. Dos causas: (1) backend — `/extensibles`, `/ruletas` y `/alerts/*` usaban `getChannel(req)` o `req.dashboardUser.twitchUsername` ignorando el header `X-Managed-Channel`; corregido usando `resolveChannel(req)` en las 18 rutas afectadas. (2) frontend — `AlertsPanel` no recibía `managedChannel` y solo cargaba al montar; `StreamersVIPPanel` y similares tenían una race condition donde el `useEffect` del hijo se ejecutaba antes de que el padre llamara a `setManagedChannel`; corregido con `useLayoutEffect` en `TwitchCommands` para fijar el contexto de canal antes de que cualquier efecto pasivo de hijos se ejecute.
  • + Dashboard / Discord / Self Roles — En modo de despliegue BGW split (Render Web Service + Background Worker separados), crear, editar o eliminar paneles de selfroles desde el dashboard devolvía 503 "Cliente Discord no disponible". Causa arquitectural: `api.js` (Web Service) no tiene cliente Discord; `global.client` es exclusivo del BGW y los procesos no comparten memoria. Solución: se implementa el patrón `UTIL_SignalBus` ya establecido en el proyecto. El WS emite señales `selfrole_create`, `selfrole_update` o `selfrole_delete` a MongoDB (`DB_BotSignal`); el BGW las consume vía polling cada 5 s y ejecuta la operación Discord con `global.client`. En modo monolítico (local / proceso único) la operación sigue siendo directa e inmediata.
v8.20.0 Dashboard
  • Release: v.8.20.0
  • Nuevo
  • + Discord / Roles — Nuevo comando `/createrole`: permite crear un nuevo rol en el servidor especificando nombre, color hex, visibilidad separada en la lista de miembros y si es mencionable. Requiere permiso `ManageRoles`.
  • + Discord / Hilos — Nuevo comando `/createthread`: publica un embed personalizado en un canal y abre automáticamente un hilo sobre ese mensaje. Opciones: título, descripción, nombre del hilo, canal destino, rol a mencionar, color del embed y duración de archivo automático (1h / 1 día / 3 días / 1 semana).
  • + Dashboard / Twitch / VIP temporal — El campo de texto libre "Título exacto de la recompensa" se reemplaza por un selector que carga las recompensas existentes del canal. Al seleccionar una, el campo "Coste" se rellena automáticamente con el valor real configurado en Twitch.
  • + Dashboard / Twitch / Comandos — Modo Chat Compartido migrado de dropdown de 3 opciones a dos checkboxes independientes: "Solo activo en Chat Compartido" y "Desactivar en Chat Compartido". El estado `normal` (sin restricción) se activa cuando ninguno está marcado.
  • Fix
  • ~ Bot / Dashboard / Self Roles — El cliente de Discord (`global.client`) nunca se asignaba en `app.js`, lo que impedía que las rutas del dashboard pudieran acceder a Discord para crear o actualizar mensajes de selfroles. La edición desde el dashboard devolvía 503 "Cliente Discord no disponible". Corregido: `global.client = client` se asigna tras crear el cliente en modo monolítico.
  • ~ Dashboard / Self Roles — Al editar un panel, el título y la descripción del embed se sobrescribían siempre con los valores por defecto en lugar de cargar los valores reales del panel guardado. Corregido en `startEdit`.
  • ~ Dashboard / Self Roles — El título y la descripción del embed no se persistían en MongoDB al crear o actualizar un panel. Ahora se almacenan junto al resto de la configuración.
  • Seguridad
  • ~ Dashboard — Actualización de axios 1.15.0 -> 1.16.1.
v8.19.1 Fix
  • Release: v.8.19.1
  • Fix
  • + Overlay / Alertas / Chat — Los eventos de overlay (alertas Twitch, mensajes de chat, TTS, comandos) dejaron de funcionar tras la migración del dominio a `app.digitalbite.net`. Causa raíz: `OVERLAY_API_URL` apuntaba a `app.digitalbite.net`, por lo que el OverlayEmitter enviaba los POST a `/api/overlay/emit` pasando por Cloudflare. El Bot Fight Mode de Cloudflare detectaba el tráfico Node.js como automatizado y servía un Managed Challenge (HTTP 403) antes de que el request llegara al servidor. Solución: `OVERLAY_API_URL` apunta ahora a `https://leksimus-ws.onrender.com` (URL directa de Render, sin pasar por Cloudflare), mientras que `OVERLAY_PUBLIC_URL` y `OVERLAY_WS_PUBLIC_URL` mantienen `app.digitalbite.net` para el tráfico público de browsers.
v8.19.0 Now Playing
  • Release: v.8.19.0
  • Eliminado
  • + Now Playing — Integraciones server-side de Spotify, Amazon Music (LWA) y Last.fm retiradas por completo. El Music Bridge (lectura SMTC en Windows) ya cubre todos esos reproductores sin OAuth, por lo que se elimina el poll server-side para no exponer credenciales del usuario. Borrados: rutas `/spotify/*` y `/amazon-music/*` del dashboard, `SpotifyOAuthRoutes`/`AmazonOAuthRoutes`, `UTIL_SpotifyApi`/`UTIL_AmazonMusicApi`/`UTIL_LastFmApi`, modelos `DB_SpotifyOAuth`/`DB_AmazonMusicOAuth`, el cron `CRON_NowPlayingPoller` y el campo `lastfmUsername` (modelo + form de widgets). Variables `SPOTIFY_*`, `AMAZON_MUSIC_*` y `LASTFM_*` eliminadas del `.env.example`. El panel Now Playing del dashboard queda con bridge local + configuración del overlay únicamente. Dashboard reconstruido (`dashboard-dist`).
  • Fix
  • + Dashboard — Login de Discord devolvía 404 "Cannot GET /leksimus/dashboard/auth/callback": el `DASHBOARD_DISCORD_REDIRECT_URI` usa el prefijo heredado `/leksimus/...` pero solo estaba montado `/dashboard/auth`. Añadido el shim de compatibilidad `/leksimus/dashboard/auth`, igual que ya existía para el panel Twitch (`/leksimus/twitch-dashboard/auth`). El prefijo `/leksimus` se mantiene de forma intencional como namespace para alojar futuras apps bajo el mismo subdominio.
v8.18.19 Fix
  • Release: v.8.18.19
  • Fix
  • + Render WS — Subdominio bloqueado: todas las rutas (`/health`, `/dashboard/*`, `/overlay/*`) devolvían "Not Found" con cabecera `x-render-routing: blocked-render-subdomain`. El servicio arrancaba correctamente pero Render bloqueaba el tráfico a nivel de edge antes de llegar a Express. Solución: `renderSubdomainPolicy: enabled` en `render.yaml`.
  • + Render WS — `dashboard-dist/` no disponible tras Clear Cache & Deploy: el directorio de build del dashboard no se regeneraba porque el comando de build de Render estaba configurado solo como `yarn install`. `dashboard-dist/` ahora está versionado en git y `render.yaml` incluye `buildCommand: npm install && npm run dashboard:build:ci` para mantener el build actualizado en cada despliegue.
  • + Trazabilidad de arranque: `api.js` y `APIServer.js` ahora emiten `console.log` en los puntos clave del arranque (PORT detectado, MongoDB conectado, servidor escuchando). Visible directamente en los logs de Render sin depender del nivel del logger Winston.
v8.18.18 Fix
  • Release: v.8.18.18
  • Fix
  • + Deploy Render: la v.8.18.17 llegó a producción con un `render.yaml` y un script `build` en `package.json` generados por error durante el proceso de desarrollo, lo que alteró el pipeline de build de Render y dejó `dashboard-dist` sin generar. Ambos cambios revertidos; el proceso de build vuelve al estado de v.8.18.16 (comando configurado vía UI de Render).
v8.18.17 Ruletas
  • Release: v.8.18.17
  • Nuevo
  • + Ruletas — Permiso de comando IRC: el trigger `!ruleta <nombre>` ahora admite restricción de uso. Al activar el comando IRC en el editor de una ruleta, aparece el selector "Permitido para" con las mismas opciones que los comandos custom: Todos, VIP, Suscriptores, Moderadores y Solo yo (streamer). Las ruletas existentes mantienen `Todos` por defecto.
  • + Ruletas — Trigger por evento Twitch (cableado): las ruletas con el trigger "Evento Twitch" activado ahora se giran de verdad cuando el evento ocurre. El EventHub ya procesaba follows, subs, raids y cheers para comandos custom; ahora también invoca `spinRuletaByTwitchEvent` para las ruletas configuradas con ese evento.
  • + Ruletas — Condiciones por evento Twitch: cada tipo de evento puede tener un umbral mínimo opcional. Cheer: mínimo de bits (ya existía el campo, ahora se muestra como "Sin mínimo" cuando vacío). Raid: mínimo de viewers del raid. Subscribe / Resubscribe: tier mínimo (Tier 1 / Tier 2 / Tier 3). Si el evento no supera el umbral configurado, la ruleta no se gira.
v8.18.16 Fix
  • Release: v.8.18.16
  • Fix
  • + Dashboard Now Playing: al guardar configuración avanzada (CSS/HTML/JS personalizado) mientras el Music Bridge estaba conectado y reproduciendo, el overlay mostraba "Sin pista activa" en lugar de la canción activa. `buildWidgetState` para el tipo `now_playing` siempre emitía un estado vacío (`track: ''`, `isPlaying: false`); ahora consulta `getLastTrack()` para incluir la pista en memoria del bridge en el broadcast `widget_update`.
  • + Music Bridge: al cambiar de canción, el overlay perdía el diseño personalizado y revertía al diseño por defecto o a uno usado anteriormente. El servidor cacheaba los settings del widget en el momento de autenticación del bridge; si el usuario guardaba un nuevo CSS/HTML/JS personalizado después de conectar el bridge, el cache quedaba obsoleto y cada `track` event emitía el `widget_update` con los settings viejos. Ahora los settings se leen frescos desde la DB en cada track update.
v8.18.15 Overlay
  • Release: v.8.18.15
  • Fix
  • + Overlay Now Playing: los placeholders `{track}`, `{artist}`, `{album}`, `{albumArt}` e `{isPlaying}` ahora se reemplazan correctamente en el editor HTML personalizado del widget. Antes `renderCustomWidgetHtml` no incluía los campos del estado `now_playing` y los placeholders se quedaban vacíos.
  • Nuevo
  • + Guía de diseño Now Playing (`/docs/overlay/now-playing-guide`): documentación completa para diseñadores web que quieran crear sus propios overlays con los editores CSS, HTML y JS del dashboard. Incluye 3 ejemplos funcionales con vista previa, tablas de referencia del objeto `state`, placeholders disponibles, clases CSS por defecto, instrucciones para Google Fonts y consejos de OBS.
v8.18.14 Fix
  • Release: v.8.18.14
  • Fix
  • + Music Bridge v1.6.2: el nombre del artista ahora se obtiene con fallback: `Artist` → `AlbumArtist` → `Subtitle`. Cubre reproductores que registran el artista en campos alternativos de SMTC (ej. YouTube Music vía Chrome usa `Artist`; otros reproductores pueden usar `AlbumArtist`).
v8.18.13 Music Bridge
  • Release: v.8.18.13
  • Nuevo
  • + Music Bridge v1.6.1: el token del canal se pre-rellena automáticamente al abrir el panel de Configuración. El usuario solo necesita pegarlo una vez; los cambios posteriores (ej. cambiar la fuente de reproducción) no requieren volver a introducirlo.
v8.18.12 Music Bridge
  • Release: v.8.18.12
  • Fix
  • + Music Bridge v1.6.0: reemplazado PowerShell como motor de lectura SMTC por un helper nativo en C# (`smtc-reader.exe`). PowerShell no puede completar `IAsyncOperation<T>` de WinRT cuando se ejecuta como subproceso de Electron porque no tiene message pump; `RequestAsync()` expiraba siempre (SMTC err: timeout). C# usa `await` sobre las API de WinRT directamente (via CsWinRT), que registra callbacks de completado sin necesitar message pump. La detección de reproducción activa (track, artista, álbum, carátula) funciona ahora de forma fiable con cualquier reproductor SMTC.
  • + Music Bridge v1.6.0: `smtc-poller.ps1` simplificado a solo detección de procesos (`-ListApps`). Todo el código WinRT que nunca funcionó en PS ha sido eliminado.
  • Nuevo
  • + Music Bridge v1.6.0: `smtc-reader.exe` soporta modo `--list` (enumera sesiones SMTC activas con nombre amigable, estado y pista actual) y modo poll continuo con `--source <id>` para filtrar por aplicación. Se distribuye como extraResource en el ejecutable portable.
v8.18.11 Music Bridge
  • Release: v.8.18.11
  • Fix
  • + Music Bridge v1.5.3: corregido bug de stale close handlers. Al reconectar, el handler del WebSocket anterior se disparaba emitiendo logs falsos de "Desconectado" inmediatamente después de "Conectado". Cada handler de close ahora verifica que el ws al que pertenece sigue siendo el activo antes de actuar.
  • + Music Bridge v1.5.3: añadido heartbeat WebSocket (ping cada 25 s). Previene que el proxy de Render cierre conexiones idle con código 1006 cuando no hay reproducción activa.
  • + Music Bridge v1.5.3: PowerShell ahora se lanza con el flag -Sta (Single-Threaded Apartment). WinRT requiere STA para despachar IAsyncOperation<T>; sin él, RequestAsync() se bloqueaba indefinidamente en MTA. Este era el motivo por el que SMTC nunca devolvía sesiones al ejecutar el bridge como app Electron (el proceso hijo heredaba MTA).
  • + Music Bridge v1.5.3: la detección SMTC en -List ya no usa sintaxis multilinea para la carga de tipos WinRT, que fallaba con error de parseo en PS5.1 al ejecutarse desde un proceso empaquetado. Cada tipo se carga en una sola línea.
  • + Music Bridge v1.5.3: el bloque -ListApps (detección por proceso) se movió antes de la carga de tipos WinRT. El error de WinRT ya no afecta a -ListApps, que solo usa Get-Process.
  • + Music Bridge v1.5.3: stderr de los subprocesos PowerShell ahora se captura y se muestra en el log de Actividad del bridge. Facilita diagnóstico sin necesidad de abrir una consola separada.
  • Nuevo
  • + Music Bridge v1.5.3: el botón "Detectar" combina sesiones SMTC activas con apps de música conocidas en ejecución. Paso 1 — busca por nombre de proceso (Spotify.exe, Amazon Music.exe, etc.). Paso 2 — busca por título de ventana para cubrir nombres de proceso desconocidos. Si el reproductor está abierto pero aún no en SMTC, aparece igualmente con icono ●. Al seleccionarlo el poller usa matching parcial case-insensitive en el SourceAppUserModelId.
  • + Music Bridge v1.5.3: footer muestra la versión actual del ejecutable (v1.5.3) y un botón que abre digitalbite.net en el navegador del sistema.
  • + Music Bridge v1.5.3: matching de SourceAppId en el poller cambia de igualdad exacta a contains case-insensitive (ej. "amazon" matchea "Amazon Music.exe").
v8.18.10 Fix
  • Release: `leksimus-bot` v.8.18.10
  • Fix
  • + Music Bridge v1.4.0: corregido bug en `smtc-poller.ps1` modo `-List`. `ConvertTo-Json -AsArray` es exclusivo de PowerShell 7+; en PS5.1, el predeterminado en Windows, producia `null` para arrays vacios y un objeto (no array) para un solo elemento. El boton "Detectar" ahora devuelve correctamente el array de fuentes SMTC activas
  • + Music Bridge v1.4.0: `listSources()` en `main.js` normaliza el resultado parseado a array siempre, cubriendo el caso en que PS emita un objeto unico en lugar de array
  • + Dashboard Now Playing: el boton "Descargar LeksimusMusicBridge.exe" y el token del canal ahora se muestran independientemente del estado de conexion del bridge. Antes solo eran visibles cuando el bridge estaba desconectado, impidiendo al usuario copiar el token con el bridge ya conectado
v8.18.9 Overlay
  • Release: `leksimus-bot` v.8.18.9
  • Nuevo
  • + Music Bridge v1.3.0: selector de fuente de reproduccion. En Configuracion, el boton "Detectar" lista todas las sesiones SMTC activas (app, estado, cancion actual). El usuario elige la fuente que quiere trackear. La seleccion se guarda en `config.json` como `sourceAppId`. Si se deja en "Automatico", el bridge usa la primera sesion en estado Playing como antes
  • + Music Bridge v1.3.0: la cabecera muestra la fuente activa seleccionada, por ejemplo "Fuente: Amazon Music"
v8.18.8 Fix
  • Release: `leksimus-bot` v.8.18.8
  • Fix
  • + Music Bridge v1.2.0: reescritura de la funcion Await en `smtc-poller.ps1`. En PowerShell 5.1 el metodo `AsTask<T>` de `WindowsRuntimeSystemExtensions` falla al resolver el overload generico para `IAsyncOperation<T>`, causando que el poller nunca emitiera datos (error silenciado por el try/catch). La nueva implementacion usa polling directo de `IAsyncInfo.Status` sin depender de `AsTask`. El bridge ahora detecta correctamente reproductores SMTC (Amazon Music, Spotify, YouTube Music, VLC, etc.)
v8.18.7 Fix
  • Release: `leksimus-bot` v.8.18.7
  • Fix
  • + Music Bridge v1.1.0: `smtc-poller.ps1` ahora usa `GetSessions()` en lugar de `GetCurrentSession()`. `GetCurrentSession()` solo devuelve la sesión con foco del sistema — si el reproductor está en segundo plano, SMTC no la reportaba. Con `GetSessions()` se itera todas las sesiones y se elige la primera que esté reproduciendo activamente, con fallback a `GetCurrentSession()` si ninguna está en reproducción
  • + Music Bridge v1.1.0: logs de diagnóstico WS — ws.open confirma que el upgrade TCP completó, ws.error muestra el mensaje exacto, ws.close incluye el código de cierre
v8.18.6 Fix
  • Release: `leksimus-bot` v.8.18.6
  • Fix
  • + MusicBridgeWSServer: queries a MongoDB en el handler de auth y track ahora envueltas en try/catch. Sin este fix, un error de DB (e.g., durante cold start de Render) causaba una promesa rechazada sin capturar que podía crashear el proceso en Node ≥15
  • + Music Bridge (exe): añadidos logs de diagnóstico — ws.on('open') confirma que el upgrade TCP se completó, ws.on('error') muestra el mensaje de error exacto, y ws.on('close') incluye el código de cierre. Facilita diagnóstico de problemas de conexión
v8.18.5 Overlay
  • Release: `leksimus-bot` v.8.18.5
  • Nuevo
  • + Music Bridge: ejecutable portable para Windows disponible (`LeksimusMusicBridge-1.0.0.exe`, 67 MB). Construido con `electron-builder` v24.13.3, portable x64
  • + Panel Now Playing: boton "Descargar LeksimusMusicBridge.exe" visible cuando `MUSIC_BRIDGE_DOWNLOAD_URL` esta configurado en el servidor
  • + Variable de entorno `MUSIC_BRIDGE_DOWNLOAD_URL`: URL publica del ejecutable del bridge. Si no se configura, el boton no aparece
  • Fix
  • + URL del overlay en el panel Now Playing: texto demasiado grande. Ahora usa fuente monoespaciada de 10px con truncado correcto
v8.18.4 Overlay
  • Release: `leksimus-bot` v.8.18.4
  • Nuevo
  • + Spotify OAuth: flujo completo de autorizacion para vincular la cuenta Spotify del streamer al canal. Incluye `GET /auth/spotify`, que inicia el flow, `GET /auth/spotify/callback`, que intercambia codigo por tokens, y almacenamiento en `DB_SpotifyOAuth`
  • + Panel Now Playing: seccion "Spotify" con boton Conectar/Desconectar y estado de conexion en tiempo real. Muestra nombre del perfil Spotify y fecha de autorizacion
  • + Poller Now Playing: Spotify anadido como fuente 2, entre Amazon Music y Last.fm. El servidor consulta `GET /me/player/currently-playing` cada 15 s para canales con token vinculado. Bulk query de tokens por tick
  • + Nuevo modelo `DB_SpotifyOAuth`: almacena `accessToken`, `refreshToken`, `expiresAt` y `spotifyUserId` por canal, con refresh automatico
  • + Variables de entorno: `SPOTIFY_CLIENT_ID`, `SPOTIFY_CLIENT_SECRET` y `SPOTIFY_REDIRECT_URI` anadidas al `.env.example`
  • + Dashboard API: nuevos endpoints `GET /spotify/status`, `GET /spotify/auth-url` y `DELETE /spotify/disconnect`
  • + Nota: requiere crear una App en `developer.spotify.com`; gratuito, sin aprobacion de beta
v8.18.3 Overlay
  • Release: `leksimus-bot` v.8.18.3
  • Nuevo
  • + Music Bridge redisenado como aplicacion Electron: ventana pequena (360x520 px) con interfaz propia. El ejecutable se conecta directamente al servidor Leksimus (`wss://leksimus-ws.onrender.com/bridge/music`) sin necesitar que el dashboard este abierto
  • + Music Bridge: autenticacion con token de canal (`overlayRoomToken`). La conexion se valida en el servidor; el bridge no expone ningun puerto local
  • + Music Bridge: overlay de setup en primer uso para ingresar el token de canal. Boton de configuracion accesible en todo momento
  • + Music Bridge: UI con pill de estado (conectado/conectando/error), tarjeta de pista activa (portada + titulo + artista) y log de actividad en tiempo real
  • + Servidor: nuevo `MusicBridgeWSServer.js`; gestiona conexiones de bridges autenticados, cachea el ultimo estado de pista y emite `widget_update` al overlay de OBS cuando cambia la cancion
  • + Dashboard: panel Now Playing redisenado; muestra estado de conexion del bridge consultando `GET /music-bridge/status` cada 5 s. Boton "Copiar token" para facilitar la configuracion del ejecutable
  • + Dashboard API: nuevos endpoints `GET /music-bridge/status` y `GET /music-bridge/config`
  • Eliminado
  • `music-bridge.js` (servidor WebSocket local en Node.js): reemplazado por la arquitectura Electron de conexion directa al servidor
v8.18.2 Overlay
  • Release: `leksimus-bot` v.8.18.2
  • Nuevo
  • + Amazon Music OAuth (LWA): flujo completo de Login with Amazon para vincular cuentas de Amazon Music al canal. Incluye `GET /auth/amazon`, que inicia el flow, `GET /auth/amazon/callback`, que intercambia codigo por tokens, y almacenamiento seguro en `DB_AmazonMusicOAuth`
  • + Panel Now Playing: seccion "Amazon Music" con boton Conectar/Desconectar y estado de conexion en tiempo real
  • + Dashboard API: nuevos endpoints `GET /amazon-music/status`, `GET /amazon-music/auth-url` y `DELETE /amazon-music/disconnect`
  • + Poller Now Playing: refactorizado para soportar multiples fuentes. Prioridad 1: Amazon Music `recentlyPlayed` cuando hay token vinculado. Prioridad 2: Last.fm como fallback. Se activa si hay al menos una fuente configurada
  • + Nuevo modelo `DB_AmazonMusicOAuth`: almacena `accessToken`, `refreshToken`, `expiresAt` y `amazonCustomerId` por canal de Twitch, con refresh automatico
  • + Variables de entorno: `AMAZON_MUSIC_CLIENT_ID`, `AMAZON_MUSIC_CLIENT_SECRET`, `AMAZON_MUSIC_API_KEY` y `AMAZON_MUSIC_REDIRECT_URI` anadidas al `.env.example`
  • + Nota: la integracion con Amazon Music Web API requiere aprobacion de acceso a la beta cerrada de Amazon
v8.18.1 Overlay
  • Release: `leksimus-bot` v.8.18.1
  • Nuevo
  • + Music Bridge (`music-bridge/`): script local para Windows que lee la cancion activa desde SMTC (System Media Transport Controls) y la transmite al dashboard via WebSocket en `ws://localhost:6789`. Compatible con Amazon Music, Spotify, YouTube Music, VLC y cualquier reproductor que use SMTC en Windows 10/11
  • + Music Bridge: `smtc-poller.ps1`; script PowerShell que consulta SMTC cada 3 s y emite JSON solo cuando cambia la pista; incluye lectura de portada como base64
  • + Music Bridge: `music-bridge.js`; servidor WebSocket Node.js que lanza el poller y retransmite las actualizaciones a todos los clientes conectados (dashboard). Reconecta el poller con backoff exponencial si falla
  • + Panel Now Playing: redisenado como panel independiente, igual que OBS Relay, separado de la lista de widgets. Gestiona la conexion al bridge local, muestra la pista activa, la URL del overlay para OBS y permite personalizar CSS/HTML/JS. Se autocrea el widget en la base de datos al primer uso
  • + Endpoint `POST /now-playing/push`: recibe la pista desde el panel del dashboard y la empuja al overlay de OBS via WebSocket
v8.18.0 Overlay
  • Release: `leksimus-bot` v.8.18.0, `leksimus-dashboard` v3.23.0
  • Nuevo
  • + Widget Now Playing: nuevo tipo de widget de overlay que muestra en tiempo real la cancion que esta escuchando el streamer. Se configura con el nombre de usuario de Last.fm y se actualiza automaticamente cada 15 segundos
  • + Widget Now Playing: muestra portada del album, titulo de la cancion y artista. Fondo transparente por defecto; compatible con CSS/HTML/JS personalizado como el resto de widgets
  • + Widget Now Playing: estado idle ("Sin reproduccion") cuando el usuario no esta scrobleando ninguna cancion en Last.fm
  • + Backend: nuevo modulo `UTIL_LastFmApi.js`; cliente HTTP para la API publica de Last.fm con cache en memoria y filtro del placeholder de portada vacia
  • + Backend: nuevo `CRON_NowPlayingPoller.js`; poller que se activa cada 15 s, consulta Last.fm para cada canal con un widget `now_playing` activo, y emite `widget_update` al overlay unicamente cuando la cancion cambia
  • + Variables de entorno: `LASTFM_API_KEY` y `LASTFM_SHARED_SECRET` anadidas al `.env.example`
v8.17.1 Overlay
  • Release: `leksimus-bot` v.8.17.1
  • Fix
  • + Overlay de alertas (`alerts.html`): eliminados los manejadores de eventos `sound` y `tts` para evitar duplicacion de sonidos cuando ambos overlays estan activos como Browser Sources en OBS. El overlay de alertas responde unicamente a `twitch_alert` y eventos visuales; los comandos de sonido y TTS siguen siendo responsabilidad exclusiva del overlay principal (`index.html`)
v8.17.0 Overlay
  • Release: `leksimus-bot` v.8.17.0, `leksimus-dashboard` v3.22.0
  • Nuevo
  • + Alertas de overlay: nueva URL independiente (`/overlay/alerts.html?room=`) para usar como Browser Source exclusivo de alertas en OBS, sin incluir widgets, timers, contadores ni rueda
  • + Alertas de overlay: boton "URL" en el panel de Alertas del dashboard muestra la URL con `SpoilerUrl` y permite copiarla al portapapeles, siguiendo el mismo patron que los widgets de overlay
  • + `overlay/alerts.html`: pagina standalone para el sistema de alertas; maneja `twitch_alert`, `alert_control`, TTS, sonidos, imagenes, videos y fullscreen clips. Fondo transparente, reconecta automaticamente al WebSocket del room
v8.16.0 Overlay
  • Release: `leksimus-bot` v.8.16.0
  • Nuevo
  • + OBS Relay (overlay HTML): nuevo panel "Fuentes de video"; muestra webcams y tarjetas de captura detectadas por OBS (`dshow_input` en Windows, `v4l2` en Linux, `av_capture` en macOS). Al hacer clic en una fuente se alterna su visibilidad en la escena activa mediante `SetSceneItemEnabled`
  • + OBS Relay (overlay HTML): layout del quick-panel ampliado a tres columnas (Escenas / Fuentes de audio / Fuentes de video) con colapso responsive a dos columnas en pantallas menores de 720 px
v8.15.0 Overlay
  • Release: `leksimus-bot` v.8.15.0, `leksimus-dashboard` v3.22.0
  • Nuevo
  • + Widget Chat Box: los mensajes propios del bot ahora aparecen en el widget en tiempo real. El relay intercepta cada `PRIVMSG` saliente en `sendRaw`, cubriendo todos los caminos de envio (comandos hardcoded, automaciones, respuestas personalizadas) sin necesidad de eco IRC
  • + Widget Chat Box: soporte de emotes nativos de Twitch. Se extraen las posiciones del tag IRC `emotes=` y se reemplazan por imagenes desde el CDN oficial de Twitch (`static-cdn.jtvnw.net`)
  • + Widget Chat Box: soporte de emotes de extensiones de terceros: BetterTTV (global y por canal), 7TV (global y por canal) y FrankerFaceZ (global y por canal). Los mapas de emotes se cargan de forma perezosa al recibir el primer mensaje con `broadcasterId` y se almacenan en cache en el cliente
  • + Widget Chat Box: los mensajes del chat se renderizan como HTML seguro, con texto escapado, proteccion XSS completa y emotes como etiquetas `img` con `vertical-align: middle`
  • + Nuevos tipos de widget: Webcam Overlay, Intermision y Stand By
  • + Widget Webcam Overlay: muestra un marco PNG con transparencia sobre la fuente de camara en OBS. Solo requiere la URL de la imagen del marco
  • + Widget Intermision: pantalla de pausa para usar durante descansos del stream. Configurable con titulo, subtitulo, color de acento con efecto glow y URL de imagen de fondo opcional
  • + Widget Stand By: pantalla de espera para antes de empezar el stream. Mismas opciones que Intermision. Ambas escenas renderizan el titulo con tipografia de impacto y separador con degradado del color de acento
  • + Schema DB: nuevos campos en settings de widgets: `title`, `subtitle`, `backgroundImageUrl`, `overlayImageUrl`, `ignoredUsers`, `fadeEnabled` y `fadeTimeout`, formalizados en el modelo de Mongoose
  • + Backend: funcion `sanitizeImageUrl` valida que las URLs de imagenes sean HTTPS antes de persistirlas
  • Cambios
  • ~ Widget Chat Box: la emision manual de overlay que existia en `sendChatMessage` fue eliminada; `sendRaw` es ahora el punto unico de intercepcion para mensajes del bot
  • ~ `widget.html`: `mountWidget` anade la clase `type-{tipo}` al elemento raiz del widget para permitir estilos CSS especificos por tipo
  • ~ Widgets de escena completa (`webcam_overlay`, `intermission`, `stand_by`): no muestran el titulo header del widget para no interferir con el contenido visual. La clase CSS `type-{tipo}` anula el fondo y padding del widget contenedor
v8.14.0 Overlay
  • Release: `leksimus-bot` v.8.14.0, `leksimus-dashboard` v3.21.0
  • Nuevo
  • + Widgets de overlay: cada widget genera su propia URL independiente (`/overlay/widget.html?room=&id=`) lista para usar como Browser Source en OBS. OBS controla posicion y tamano de forma nativa
  • + Widgets de overlay: boton "Copiar URL" en la lista de widgets y dentro del formulario de edicion para acceso rapido a la URL de cada widget
  • + `overlay/widget.html`: pagina standalone por widget, con fondo transparente, ocupa el 100% del Browser Source, auto-reconecta al WebSocket del room y responde a `widget_update`, `chat_message` y `activity_log` en tiempo real
  • Cambios
  • ~ Widgets de overlay: el selector de cuadrante/subposicion fue eliminado del formulario. La posicion la gestiona OBS directamente via la URL del widget
  • ~ Limites de codigo personalizado (HTML / CSS / JS) aumentados a 30000 caracteres en todos los contextos: alertas de Twitch y widgets de overlay, tanto en los modelos de base de datos como en la validacion del servidor
v8.13.1 Dashboard
  • Release: `leksimus-bot` v.8.13.1, `leksimus-dashboard` v3.20.0
  • Bugs
  • ~ `AlertsPanel`: el interruptor "Activar esta alerta" ahora persiste correctamente al servidor y mantiene su estado tras recargar la pagina
  • ~ Dependencias: versiones parchadas y sincronizadas con `package-lock` para evitar desajustes entre `package.json` y la instalacion
v8.13.0 Overlay
  • Release: `leksimus-bot` v.8.13.0, `leksimus-dashboard` v3.20.0
  • Nuevo
  • + Chat offline: los usuarios activos en el chat se persisten en MongoDB (`DB_TwitchChatter`, TTL 24h) mediante upsert batch cada 10s; el panel de chatters funciona aunque el canal este offline
  • + Widget Chat Box: los mensajes del chat de Twitch llegan al widget en tiempo real via WebSocket (`broadcastToRoom` en `PRIVMSG` handler de `REQ_TwitchOfflineChatRelay`)
  • + Widget Lista de eventos: el overlay se inicializa con los ultimos 20 eventos historicos (`DB_TwitchActivityLog`) al cargar; sigue recibiendo actualizaciones en tiempo real con cada alerta
  • + Comando SO: selector de canal de Discord desde el dashboard cuando el canal tiene un servidor vinculado. Si no se selecciona ningun canal se mantiene el comportamiento anterior, usando el primer canal vinculado
  • + Panel de Widgets de overlay: rediseno completo con lista de estado Activo/Inactivo y botones Editar / X por widget; nuevos widgets inactivos por defecto; formulario contextual con encabezado "Nuevo widget" o "Editando"
  • + Selector de posicion de widget: cuadricula 6x6 que representa los 9 cuadrantes con sus 4 subposiciones directamente, reemplazando el selector 3x3 + campo numerico de subposicion
  • ~ `TW_AlertEmitter`: prefijo de consola renombrado de `[Alert:canal]` a `[TwEvent:canal]` para reducir ruido visual
  • Bugs
  • ~ Widgets de overlay: GET `/overlay-widgets` no mapeaba `_id` -> `widgetId`; los botones Editar y X no tenian efecto porque `widgetId` era siempre `undefined` en el frontend
  • ~ Widgets de overlay: el boton Editar en la lista siempre abria el primer widget del mismo tipo en lugar del widget especifico. Corregido pasando `widgetId` a `selectOverlayWidget`
  • ~ Widgets de overlay: los separadores visuales del cuadrante (`mr-1`/`mb-1` construidos dinamicamente) eran purgados por Tailwind y no aparecian en el CSS compilado. Corregido con inline styles
v8.12.1 Overlay
  • Release: `leksimus-bot` v.8.12.1, `leksimus-dashboard` v3.19.1
  • Bugs
  • ~ `TwitchDashRoutes`: el limite de plan para automaciones de recompensas de canal no se aplicaba porque los checks usaban `channelPointReward` en lugar de `rewardRedemption`, el nombre real en MongoDB
  • ~ Overlay: `renderCustomWidgetHtml` insertaba valores de `label`, `targetValue` e `items` directamente en `innerHTML` sin escapar, permitiendo XSS. Corregido con helper `_escWidget()`
  • ~ Overlay: `startViewerCounterPolling` no guardaba el ID del `setInterval`, imposibilitando cancelarlo. Corregido
  • ~ `REQ_TwitchChatRouter`: la llamada inicial a `runIntervalAutomations()` en `attachRuntime` no tenia `catch`, dejando rechazos sin manejar en arranque. Corregido
  • ~ `AlertsPanel`: el `catch` de carga de configuracion era silencioso, dejando el componente en spinner indefinido si la API fallaba. Corregido con estado `loadError` y mensaje visible
v8.12.0 Overlay
  • Release: `leksimus-bot` v.8.12.0, `leksimus-dashboard` v3.19.0
  • Nuevo
  • + Widgets de overlay: 6 tipos configurables desde el dashboard (Chat Box, Lista de eventos, Contador de espectadores, Objetivo de seguidores, Objetivo de suscriptores y Objetivo de bits)
  • + Widgets de overlay: soporte completo de HTML, CSS y JS personalizado por widget. Variables HTML: `{currentValue}`, `{targetValue}`, `{progress}`, `{label}`, `{type}` e `{items}`; JS recibe `root`, `widget`, `state` y `settings`
  • + Widgets de overlay: Lista de eventos se actualiza automaticamente al recibir alertas Twitch sin necesidad de recarga
  • + Widgets de overlay: Contador de espectadores se refresca cada 60 segundos via polling al servidor
  • + Panel de Widgets en `TwitchCommands`: pestanas por tipo con indicador activo, selector de cuadrante 3x3, subposicion, ancho, fuente, color, metas configurables y campos HTML/CSS/JS por widget
  • + CSS de widgets aislado por widget mediante reemplazo de selector `.overlay-widget` por `#widget-{id}`, con el mismo patron que alertas
  • Bugs
  • ~ Widgets de overlay: el cuerpo del widget perdia la clase `widget-body` tras el primer `replaceWith`, rompiendo actualizaciones posteriores. Corregido en `handleWidgetUpdate` y `pushEventToListWidgets`
  • ~ Widgets de overlay: Lista de eventos nunca recibia eventos porque `pushEventToListWidgets` no estaba conectado a `handleTwitchAlert`. Corregido
v8.11.0 Overlay
  • Release: `leksimus-bot` v.8.11.0, `leksimus-dashboard` v3.18.0
  • Nuevo
  • + Alertas de overlay: soporte de HTML personalizado por evento. Reemplaza el contenido interno de la tarjeta con una plantilla libre y mantiene el wrapper `.lk-alert-card` con sus CSS vars y animacion de entrada
  • + Alertas de overlay: soporte de JS personalizado por evento. Se ejecuta cuando la tarjeta entra al DOM y recibe el elemento `card` como argumento para animaciones, efectos con canvas o logica de presentacion
  • + Alertas de overlay: integracion con TTS para leer titulo y subtitulo al dispararse la alerta, usando la voz y config del panel TTS del canal
  • + Alertas de overlay: opcion de leer el mensaje del usuario con TTS en eventos que lo tienen, como resub, bits/cheer y recompensas con input de usuario
  • + `AlertsPanel`: boton Elegir de mi media en campos de imagen y sonido para cargar el catalogo de media del canal y filtrar por categoria sin salir del editor
  • Bugs
  • ~ `pickShoutoutClip` siempre devolvia el mismo clip, el mas reciente resolvable, por falta de aleatorizacion. Corregido con shuffle Fisher-Yates, igual que `pickRandomClip`
v8.10.1 Overlay
  • Release: `leksimus-bot` v.8.10.1, `leksimus-dashboard` v3.17.1
  • Nuevo
  • + Alertas de overlay: soporte de imagen/GIF por evento. Se muestra en la parte superior de la tarjeta, encima del icono y texto, compatible con GIFs animados y URLs publicas, incluyendo las del sistema de media de comandos
  • + Alertas de overlay: soporte de sonido por evento. Se reproduce al disparar la alerta, compatible con MP3, WAV y OGG, con volumen configurable por alerta de 0 a 100% y URLs del sistema de media de comandos
  • + Boton Probar por tipo de alerta en el `AlertsPanel`: envia una alerta de prueba con datos sinteticos, usuario `TestUser`, al overlay sin esperar un evento real
  • Bugs
  • ~ Alertas de overlay: el overlay no procesaba el tipo `twitch_alert` en el switch de eventos porque OBS tenia el HTML en cache; se confirmo el fix correcto con Refresh cache of current page en OBS
  • ~ `TW_AlertEmitter` retornaba early cuando no existia documento de config en MongoDB en primer uso, ignorando los defaults hardcodeados. Corregido para emitir con defaults si no hay config
v8.10.0 Overlay
  • Release: `leksimus-bot` v.8.10.0, `leksimus-dashboard` v3.17.0
  • Nuevo
  • + Sistema de Alertas de Overlay estilo Streamlabs: tarjetas animadas en OBS al recibir follows, subs T1/T2/T3/Prime, resubs, gift subs, bits, raids, hype train y recompensas de puntos de canal
  • + Alertas organizadas en grupos, hasta 5 por canal, con activacion de uno a la vez para cambiar entre temas o temporadas sin reconfigurar desde cero
  • + Configuracion por evento: activar/desactivar, posicion en rejilla 3x3, duracion de 1 a 30 s, titulo y subtitulo con variables, animacion, color solido o gradiente, contorno configurable y CSS personalizado por tarjeta
  • + Controles de overlay en tiempo real desde el dashboard: Omitir alerta actual, Vaciar cola y Silenciar/Activar alertas globalmente
  • + Cola de alertas client-side en el overlay, maximo 15 alertas en buffer, sin uso de RAM en servidor y con el mismo patron que TTS
  • + Boton Repetir en cada fila del panel de Actividad del dashboard para re-emitir la alerta al overlay y testear sin esperar eventos reales; aparece al hacer hover sobre cada evento
  • + Modelo MongoDB `DB_TwitchAlertConfig` por canal en la coleccion `twitch_alert_configs`
  • + Rutas nuevas en `TwitchDashRoutes`: GET/PATCH `/alerts/config`, POST `/alerts/mute`, POST `/alerts/control` y POST `/alerts/replay`
  • + Hook de alertas en `REQ_TwitchStreamerEventHub`: fire-and-forget independiente de comandos personalizados y extensibles
v8.9.1 Twitch
  • Release: `leksimus-bot` v.8.9.1, `leksimus-dashboard` v3.16.1
  • Modificado
  • ~ `TW_Helpers`: `isMod()` ahora reconoce el badge `lead_moderator/1` de Twitch (Moderador principal). Afecta a TTS, `!so`, cola de sorteos, quotes, stream control, comandos custom y builtin actions; los checks exclusivos de broadcaster no se ven afectados
  • ~ TTS: filtro anti-spam de digitos consecutivos; secuencias de mas de 20 digitos se recortan a los primeros 20
  • ~ Overlay TTS: `unlockAudio()` usa `Promise.race` con timeout de 500ms como fallback para garantizar que `speechSynthesis.speak()` se ejecute aunque `AudioContext.resume()` quede pendiente indefinidamente en OBS/CEF
  • ~ `TTSPanel`: nota informativa al pie indicando que los cambios pueden tardar hasta 1 minuto en aplicarse en directo por cache TTL de config
  • Bugs
  • ~ TTS no sonaba en el overlay porque `AudioContext.resume()` en OBS/CEF puede devolver una promesa que nunca se resuelve cuando el autoplay esta bloqueado permanentemente, dejando `speak()` sin llamarse
  • ~ Moderador principal de Twitch (`lead_moderator/1`) no tenia acceso a comandos ni permisos por no estar contemplado en `isMod()`
v8.9.0 Twitch
  • Release: `leksimus-bot` v.8.9.0, `leksimus-dashboard` v3.16.0
  • Nuevo
  • + Sistema TTS (Text-to-Speech) via Web Speech API: trigger configurable por canal, cola FIFO de mensajes y reporte automatico de voces disponibles desde el overlay al dashboard
  • + Panel TTS en el dashboard Twitch con secciones General, Voz, Filtros de contenido y Palabras bloqueadas por canal
  • + Permiso nuevo `artist` para comandos y TTS, detectable via badge `artist-badge` del IRC de Twitch
  • + Badge Activo/Inactivo en el header del widget TTS sin necesidad de expandir la tarjeta
  • + Overlay reporta voces disponibles al servidor (`voices_report`) al conectarse; el dashboard las carga dinamicamente por idioma seleccionado
  • + Modelos MongoDB `DB_TwitchTTSConfig` y `DB_TwitchTTSWordFilter` por canal
  • + Rutas nuevas en `TwitchDashRoutes`: GET/PATCH `/tts/config`, GET/POST/DELETE `/tts/wordfilter` y GET `/tts/voices`
  • + Comandos de tipo Contador con modo Incrementar/Reducir y paso configurable por ejecucion
  • Modificado
  • ~ Overlay de contadores: corregido bug donde el widget desaparecia al actualizarse por perdida de `opacity` al reemplazar la animacion `itemIn` por `counterBump`
  • ~ `TW_CustomExecutor` usa `$set` en lugar de `$inc` para contadores, respetando el piso en 0 al decrementar
  • ~ `OverlayWSServer` exporta `getVoicesForRoom` y almacena voces por room al recibir `voices_report`
  • ~ Widget TTS anadido al grid drag-and-drop del dashboard Twitch (`DEFAULT_PANEL_ORDER`)
  • ~ Etiqueta del campo de valor de contador renombrada a Valor actual
  • Bugs
  • ~ Overlay: contador se volvia invisible al recibir la primera actualizacion por perdida del fill mode de la animacion CSS
v8.8.1 Dashboard
  • Release: `leksimus-bot` v.8.8.1, `leksimus-dashboard` v3.15.0
  • Nuevo
  • + Panel de anuncios global compartido entre dashboard Twitch y Discord usando el mismo documento MongoDB (`slug: global`)
  • + Columna fija independiente para Estadisticas y Usuarios en chat en el dashboard Twitch (4 columnas)
  • Modificado
  • ~ **REQ_EnsureRoles**: roles creados directamente con position destino para garantizar que el rol Leksimus quede siempre por encima; eliminados los `setPosition` posteriores que causaban Missing Permissions
  • ~ Widget `discord-clips` separado en tres bloques arrastrables independientes: Discord Oficial, Admin Canales y Clips aleatorios
  • Bugs
  • ~ **REQ_EnsureRoles**: corregida deprecacion `color` -> `colors` en `guild.roles.create()`
v8.8.0 Twitch
  • Fixes: clips sin VersionError de Mongoose, option `campana` ASCII en DnD y logs con `op.error` real de Discord en `app.js`
  • + Overlay de contadores: `counterOverlay` en `DB_TwitchCommands.js`, emision desde `TW_CustomExecutor.js` y widget `#counter-host` con 36 posiciones
  • + **StreamStatsPanel.jsx**: panel silencioso con uptime, viewers, seguidores, subs, bits de sesion y clips recientes
  • + **TwitchDashRoutes.js**: nuevos endpoints GET `/stream-stats` y GET `/chatters`
  • + **ChatUsersPanel.jsx**: usuarios en chat ordenados por actividad reciente, busqueda y polling 15s
  • + **REQ_TwitchOfflineChatRelay.js**: tracking `channelChatters` con JOIN/PART/PRIVMSG y export `getChatters(channel)`
  • + Layout personalizable: 10 paneles reordenables con `@dnd-kit/sortable` y persistencia `localStorage` por usuario
  • + **SortableWidget**: reordenacion via CSS `order` sin cambiar el DOM
  • Versiones: `leksimus-bot` v.8.8.0, `leksimus-dashboard` 3.14.0
v8.7.0 Modular
  • Twitch IRC - Refactorizacion modular del chat router (`REQ_TwitchChatRouter.js` -> `src/twitch/`)
  • + `core/`: TW_Constants, TW_Helpers, TW_Runtime, TW_DbAccess
  • + `automation/`: TW_AutoEvent, TW_AutoInterval, TW_AutoMessageCount, TW_AutoReward
  • + `custom/`: TW_CustomTrigger, TW_CustomExecutor
  • + `features/`: TW_Actions, TW_ChatTranslation, TW_Community, TW_Queue
  • + `hardcoded/`: TW_HardcodedRouter, TW_BotAdmin, TW_Clips, TW_Giveaway, TW_Quotes, TW_Shoutout, TW_StreamControl, TW_StreamInfo
  • + **TW_BotAdmin.js**: comando `!setplan <streamer> <plan>` para admins del bot
  • + **TW_PlanCommands.js**: comandos Twitch de gestion de planes para streamers
  • + **Dashboard Discord**: pagina de Recordatorios (`Reminders.jsx`) con CRUD completo
  • + **Dashboard Twitch**: panel Admin · Canales con el bot (solo leks_gg) en columna [3·3]
  • + **TwitchDashRoutes.js**: rutas GET/PUT `/admin/channel-plans`
  • + **RandomClipPlayer configurable**: presets de tamano (fullscreen/large/medium/custom), posicion y dimensiones custom
  • ~ `xpCooldowns.js`: refactor de logica de cooldowns de XP
  • ~ SO Automatico: reemplazado texto hardcodeado `leks_gg` por texto de ejemplo generico
  • ~ Clips grid: visibilidad y contraste de botones corregidos
v8.6.0 Monetizacion
  • Monetizacion - Sistema de planes y limites de suscripcion
  • Configuracion de planes (`CONF_SubscriptionPlans.json`)
  • + **Nuevo**: sentinel `-1` para ilimitado (reemplaza `999999`); `getSystemLimit()` devuelve `Infinity` al leer `-1`, eliminando comparaciones absurdas.
  • + **Nuevas claves**: `streamAlerts`, `clips`, `voiceChannels`, `streamAlertsCount`, `translatePerDay`, `discordServers`, `twitchChannels`.
  • ~ **Correcciones de limites**: `dynamicVariables` ilimitado en todos los planes; `dndCampaigns` Free -> 0; `overlayActions`/`overlayTimers` ilimitados para quien tenga acceso; `mediaAssets` fijado en 50 para Free/VIP/Suscriptor; `remindersCount` Free -> 10; `roulette`/`overlaySystem` gratuitos.
  • Enforcement Discord
  • ~ **`CMD_SetTickets.js`**: migrado de `SUBSCRIPTION_PLANS` a `validateCommandAccess(plan, 'tickets')`.
  • ~ **`CMD_Reminders.js`**: migrado a `validateUsageLimit(plan, 'remindersCount', ...)`.
  • + **`CMD_Shop_AddItem.js`**: guard `xpShop` (acceso) + `xpShopItems` (cantidad).
  • **`CMD_StreamStatus.js`**, **`CMD_StreamRecentEvents.js`**: eliminados checks de plan - comandos de vista gratuitos para todos.
  • + **`CMD_DnD.js`**: guard `dndCampaigns` al crear campaña.
  • + **`CMD_SetTempVoiceCh.js`**: guard `voiceChannels`.
  • ~ **`CMD_StreamAlert.js`**: clave `streamevents` -> `streamAlerts`.
  • ~ **`CMD_TwitchClips.js`**: clave `streamevents` -> `clips`.
  • ~ **`REQ_HandleAutoRoles.js`**: roles asignados limitados por `autoRoles` del plan (slice en tiempo de ejecucion, configuracion DB intacta).
  • + **`REQ_StreamConfigHandler.js`**: guard `streamAlertsCount` al anadir nueva alerta (no bloquea edicion de alertas existentes).
  • Enforcement Twitch
  • ~ **`REQ_TwitchOfflineChatRelay.js`**: guilds sin acceso a `chatRelayTwitchToDiscord` excluidos del mapa de destinos en tiempo de sincronizacion.
  • + **`REQ_DiscordToTwitchRelay.js`**: guard `chatRelayDiscordToTwitch` por mensaje.
  • Cuota diaria de traducciones
  • + **`DB_GuildData.js`**: campo `translateUsage: { count, date }` (reset lazy por fecha).
  • + **`UTIL_TranslateQuota.js`** (nuevo): `checkAndConsumeTranslateQuota(guildId, plan)` - compara con `translatePerDay`, incrementa atomicamente con `$set`.
  • + **`CMD_Translate.js`**: check de cuota antes de llamar a `translateText()`, mensaje de error al usuario.
  • + **`REQ_TranslateChannelHandler.js`**: check de cuota silencioso (no spammea error en canal de traduccion automatica).
  • Modelo Discord <-> Twitch (ownership y vinculacion)
  • + **`DB_TwitchChannelConfig.js`**: campo `linkedGuildIds: [String]` con indice sparse - acumula todos los Discord vinculados al canal Twitch. Retrocompatible con `primaryGuildId`.
  • + **`DB_TwitchGuildOwnership.js`**: campo `lockedUntil: Date` - bloqueo de 30 dias al reclamar ownership, impide transferencias durante ese periodo.
  • **`UTIL_TwitchGuildAuth.js`**:
  • `canGuildManageChannel`: acepta guilds presentes en `linkedGuildIds`.
  • `canStreamerClaimGuild`: respeta `lockedUntil` - devuelve `locked: true` con fecha de desbloqueo si aplica.
  • `setPrimaryGuild`: usa `$addToSet` en `linkedGuildIds` + fija `lockedUntil = now + 30d` al crear ownership.
  • + **`CMD_SetMainServer.js`**: checks de `twitchChannels` (entradas en `liveChatConfig`) y `discordServers` (guilds en `linkedGuildIds`) antes de vincular. Re-vinculacion existente no bloqueada.
  • + **`TwitchDashRoutes.js`**: mismos checks en `POST /primary-guild` y `POST /link-guild`; `DELETE /primary-guild` limpia `linkedGuildIds` ademas de `primaryGuildId`.
  • ~ **`TW_DbAccess.js`** (`getGuildPlanForChannel`): devuelve el plan del guild solo si el canal Twitch es el `ownerTwitchUsername` de `DB_TwitchGuildOwnership`. Streamers invitados (`authorizedStreamers`) obtienen siempre `free` para funciones Twitch.
  • Dashboard - Limites en rutas API
  • + **`TwitchDashRoutes.js`**: guards en `POST /commands` (customCommands, timers, channelPointRewards), `PATCH /commands/:trigger` (al activar timers/rewards), `GET /media` (devuelve `maxFiles` del plan), `POST /media/upload` (usa limite del plan en lugar de hardcoded).
  • Dashboard - Media drag & drop
  • + **`TwitchCommands.jsx`**: zona de drag & drop para subir archivos multimedia - se activa con color al arrastrar, reutiliza la misma logica de `uploadMediaFile` que el boton clasico.
  • Versiones
  • `leksimus-bot`: v.8.6.0
  • `leksimus-dashboard`: 3.12.0
v8.5.0 Ultimos cambios
  • Dashboard Twitch - Ruleta y Extensibles integrados en el dashboard principal
  • + **Nuevo** `dashboard/src/components/WheelCanvas.jsx`: componente compartido del canvas de ruleta (extrae logica antes duplicada en `TwitchRuleta.jsx`). Exporta `WheelCanvas` (default) y `slotColor`.
  • + **Nuevo** `dashboard/src/components/TimerDisplay.jsx`: componente compartido del timer con `formatSecs` y `computeCurrentSecs` (extrae logica antes duplicada en `TwitchExtensibles.jsx`).
  • + **Nuevo**: widget `Ruleta` embebido en `TwitchCommands` - `CollapsibleCard` con lista de ruletas (scroll tras `max-h: 320px`), boton Girar por ruleta, y preview de la seleccionada ocupando 2 columnas (wheel + ultimos resultados + slots con pesos).
  • + **Nuevo**: widget `Extensibles` embebido en `TwitchCommands` - `CollapsibleCard` con lista de extensibles (scroll tras `max-h: 380px`), controles Iniciar/Pausar/Reset y ajuste rapido de tiempo inline.
  • ~ **Modificado**: grid inferior del dashboard pasa de 2 filas a 4: `[Lobby][IRC][VIP]` -> `[Ruleta lista][Ruleta preview x2col]` -> `[Extensibles][Clips][Personalizados]` -> `[Traduccion]...`
  • ~ **Modificado**: `TwitchRuleta.jsx` y `TwitchExtensibles.jsx` refactorizados para importar desde los nuevos componentes compartidos (sin duplicacion).
  • Los botones "Ver todo ->" en cada widget llevan a las paginas completas de edicion.
  • Fix - Acciones OBS en comandos personalizados
  • ~ **Fix**: `normalizeActionType` en `UTIL_TwitchCommandActions.js` no reconocia los 5 tipos OBS (`obs_stream_start`, `obs_stream_stop`, `obs_switch_scene`, `obs_mute_input`, `obs_unmute_input`) - todos caian al fallback `chat` y eran descartados por falta de `content`, impidiendo guardar el comando.
  • ~ **Fix**: `sanitizeCommandActions` ahora maneja tipos OBS antes del bloque generico: los que no requieren contenido (`obs_stream_start`, `obs_stream_stop`) se guardan directamente; los que si lo requieren (`obs_switch_scene`, `obs_mute_input`, `obs_unmute_input`) validan que el campo no este vacio.
  • ~ **Fix**: `validateCommandActionsPayload` anade early-return para tipos OBS con validacion equivalente (evita falsos errores de slash-command en el bloque de chat).
  • ~ **Fix**: `buildActionsPayload` en `TwitchCommands.jsx` incluye bloque dedicado para tipos OBS antes del check de `content` vacio.
  • + **Nuevo**: helper `isObsActionType` y constante `OBS_NEEDS_CONTENT` exportados desde `UTIL_TwitchCommandActions.js`.
  • Versiones
  • `leksimus-bot`: v.8.5.0
  • `leksimus-dashboard`: 3.12.0
v8.4.0 Ultimos cambios
  • Dashboard Twitch - OBS Relay integrado
  • + Nuevo `dashboard/src/components/OBSRelayPanel.jsx`: componente embebible con toda la logica WS del relay (OBS WebSocket v5 + Leksimus WS), montado bajo la preview de Twitch en el dashboard principal con conexion persistente.
  • + Nuevo: layout de 3 columnas compactas dentro del panel OBS (Escenas / Fuentes de audio / Actividad), cada una con scroll interno independiente.
  • ~ Fix: `createExtraAction` ahora reconoce y preserva los tipos de accion OBS (`obs_stream_start`, `obs_stream_stop`, `obs_switch_scene`, `obs_mute_input`, `obs_unmute_input`) en lugar de caer al fallback `chat`; las acciones OBS ya son seleccionables en el editor de comandos personalizados.
  • ~ Modificado: la ruta `/twitch/obs-relay` redirige a `/twitch/commands` para evitar conexiones WS duplicadas si se abre la pagina standalone mientras el relay esta activo en el dashboard.
  • Eliminado: link "OBS Relay" del sidebar (el relay queda integrado en el dashboard y ya no es pagina separada).
  • Dashboard Twitch - mejoras de layout
  • ~ Modificado: preview de Twitch reducida de `640px` a `400px` para acomodar el panel OBS debajo sin desbordamiento vertical.
  • ~ Modificado: chat iframe reducido de `640px` a `500px`.
  • ~ Modificado: columnas de actividad, comandos y chat con `max-h: calc(100vh - 2rem)` + `overflow-y-auto` para altura consistente y scroll interno por panel.
  • OBS Relay standalone - fixes de reconexion (sesion anterior)
  • ~ Fix: corregido bucle infinito de reconexion en Leksimus WS (`code=1005`) al nullear handlers antes de cerrar el socket anterior.
  • ~ Fix: mismo ajuste aplicado a `connectOBS` para evitar reconexiones dobles que interferian con el handshake de autenticacion (`code=4009`).
  • ~ Fix `REQ_AnnounceChangelog`: corregido el parseo de `changelog.json` con BOM (`\uFEFF`) en archivos generados con Notepad.
  • Versiones
  • `leksimus-bot`: v.8.4.0
  • `leksimus-dashboard`: 3.11.0
v8.3.0 Ultimos cambios
  • tensibles — mejoras y correcciones
  • ~ Bug fix: el PATCH de un extensible ahora sincroniza baseValueSecs con initialValueSecs cuando el timer esta en estado idle, evitando que arranque desde un valor incorrecto tras editar el valor inicial.
  • + Nuevo: campo opcional maxValueSecs por extensible; los eventos de Twitch no suman tiempo por encima del limite configurado por el streamer.
  • + Nuevo: evento subscribe_prime como tipo reconocido en EXTENSIBLE_EVENT_TYPES y EXTENSIBLE_PRESET_EVENTS, detectado desde IRC Twitch (sub-plan=Prime).
  • + Nuevo: campo minBits en el evento cheer para definir el umbral minimo de bits requerido cuando no se usan rangos.
  • ~ Mejora: los rangos de bits se ordenan por min descendente antes de evaluar, priorizando el umbral mas alto ante solapamientos.
  • ~ Mejora: sanitizeExtensibleEvents ahora incluye minBits al persistir eventos de tipo cheer.
  • leta — rediseño de slots y accion nativa
  • + Nuevo: 10 acciones nativas disponibles para la accion global twitch_action: timeout, ban, slow, slowoff, followers, followersoff, subscribers, subscribersoff, emoteonly y emoteonlyoff.
  • + Nuevo: campo nativeActionKey en el schema de accion de la ruleta para definir la accion a ejecutar a nivel de ruleta.
  • + Nuevo: campo nativeAfterMessage en la accion para enviar mensaje opcional al chat con variables {user}, {result}, {duration}, {secs}.
  • + Nuevo: campo nativeActionArgs en la accion para argumentos adicionales (ejemplo: razon del ban).
  • ~ Mejora: UTIL_RuletaExecutor usa ruleta.action.nativeActionKey mas winner.numericValue/nativeUnit como duracion, compatible con datos legacy (nativeDuration).
  • ~ Mejora: sanitizeRuletaAction en rutas del dashboard valida y persiste los nuevos campos.
  • ~ Mejora: exportado RULETA_NATIVE_ACTIONS_WITH_DURATION para identificar acciones que consumen la duracion del slot.
  • S WebSocket — integracion completa (v8.2.0 -> v8.3.0)
  • + Nuevo: src/utils/UTIL_OBSCommandEmitter.js para emitir comandos OBS al overlay via WS.
  • + Nuevo: src/docs/obs-relay/index.html como relay local (sin instalacion) que conecta el WS de Leksimus con OBS WebSocket v5 local, con autenticacion SHA-256 via SubtleCrypto.
  • + Nuevo: src/commands/CMD_OBS.js con comando Discord /obs scene|stream|mute y permiso ManageGuild.
  • ~ Mejora: REQ_TwitchChatCommands agrega soporte para acciones OBS (obs_stream_start, obs_stream_stop, obs_switch_scene, obs_mute_input, obs_unmute_input) en comandos personalizados de Twitch IRC.
  • ~ Mejora: UTIL_TwitchCommandActions agrega 5 tipos de accion OBS al enum ACTION_TYPES.
  • dulo traduccion (v8.1.0)
  • ~ Fix: mensajes largos ahora se envian en multiples fragmentos con prefijo "🔁 [ES->EN]" en el primero y "🔁 [+]" en los siguientes, evitando truncamiento silencioso.
  • ~ Mejora: CHAT_TRANSLATION_MAX_INPUT_LEN aumenta de 320 a 800 caracteres.
  • dulo media (v8.1.0)
  • + Nuevo: /media upload acepta hasta 5 archivos simultaneos (archivo1 a archivo5).
  • Overlay / slot queue (v8.1.0)
  • ~ Fix: los shoutouts en el overlay ya no se acoplan lateralmente durante raids multiples; ahora se procesan en cola secuencial por posicion de slot.
  • ON ExtensibleExpiry (v8.1.0)
  • + Nuevo: src/scheduler/crons/CRON_ExtensibleExpiry.js verifica cada minuto los countdowns expirados y emite evento status: idle al overlay, manteniendo el cache sincronizado.
v8.0.0 Ultimos cambios
  • + Ruleta: accion por ruleta (show_result / modify_timer / twitch_action / execute_command / change_category)
  • + Ruleta: slots con 3 tipos de valor (Numerico, Accion Nativa de Twitch timeout/ban y Texto)
  • + Ruleta: overlay ampliado con showResult, resultDisplaySecs, resultMarker, centerImageUrl, spinSoundUrl
  • + Ruleta: disparador por recompensa de canal seleccionable del listado real (rewardId + rewardTitle)
  • + Ruleta: UTIL_RuletaExecutor con logica compartida de giro reutilizable desde dashboard, IRC y EventHub
  • ~ Ruleta: corregido comando IRC !ruleta <nombre> que no disparaba el giro
  • ~ Ruleta: corregido canje de recompensa de canal que no disparaba el giro
  • ~ Ruleta: mensaje de chat como seccion independiente con toggle y plantilla {user}/{result}
  • + Extensibles: 9 eventos precargados y editables (Follow, Raid, Bits, Sub T1/T2/T3, Regalo Sub, Hype Train, Recompensa)
  • + Extensibles: multiplicador Happy Hour con toggle y valor de 1 decimal (1.0x - 5.0x) con chips sugeridos
  • + Extensibles: rangos de bits para Cheer (maximo 5) con min/max configurable y valor por rango
  • + Extensibles: Hype Train aplica valor x nivel del tren al finalizar
  • + Extensibles: selector de recompensa de canal para evento reward_redemption (por ID preferente)
  • + Extensibles: UTIL_ExtensibleEvents para aplicar eventos Twitch a timers en tiempo real con soporte de multiplicador
  • + Extensibles: fuentes Google Fonts como listado curado de 20 opciones (Montserrat y Open Sans por defecto)
  • + Extensibles: ruletas vinculadas visibles en el editor (ruletas con accion modify_timer)
  • + EventHub: nuevas suscripciones channel.subscription.gift y channel.hype_train.end
  • ~ Versionado release: leksimus-bot v8.0.0 y leksimus-dashboard 3.7.0
v7.25.0 Ultimos cambios
  • + Modulo Extensibles y Ruleta para Twitch IRC
  • + Timers configurables (countdown/countup) con reaccion a eventos del canal
  • + Posicionamiento overlay en cuadricula 36 puntos (3x3 x 2x2) con Google Fonts
  • + Ruleta con pesos internos ocultos para espectadores y acciones por slot
  • + Overlay canvas animado para la ruleta con resultado ponderado en backend
  • + Dashboard React: paginas TwitchExtensibles y TwitchRuleta
  • + Navegacion "Paginas" en sidebar Twitch (Comandos / Extensibles / Ruleta)
  • + Rutas /twitch/extensibles y /twitch/ruleta registradas en App.jsx
v7.24.0 Últimos cambios
  • + Dashboard Discord: nuevo módulo Self Roles para crear/editar/eliminar paneles desde web y publicarlos en Discord
  • + Dashboard Discord: nuevo módulo Bienvenida/Despedida con selección de canal y toggle de tarjeta visual por servidor
  • + Sistema de bienvenida: tarjeta SVG con base NewOnServer.dashboard.jpg y avatar del usuario centrado en el círculo principal
  • + Dashboard Twitch IRC: !comandos y !so quedan unificados bajo Comandos IRC nativos editables en un solo bloque
  • ~ Twitch chat commands: respuestas largas ahora se fragmentan en varios PRIVMSG (custom commands y !comandos) para evitar recortes
  • ~ Sistema de bienvenida: tarjeta reemplazada por composición real de imagen con sharp (avatar circular sobre banner) eliminando fallos de render SVG en Discord
  • ~ Twitch relay (sendChatMessage): mensajes salientes se dividen automáticamente en chunks de máx 450 chars en vez de truncarse
  • ~ Dashboard Discord: overview con mejor uso de columnas y accesos directos a configuración avanzada
  • ~ Sincronización de módulos: al desactivar Torneos/D&D desde dashboard se aplican limpiezas y se evita recreación automática de estructura
  • ~ UX Twitch IRC: iconos visuales corregidos en vista moderador y flujo de importación de comandos