← Leksimus
Changelog
Registro de cambios, mejoras y correcciones de Leksimus.
- Release: v.10.24.0
- Tus cuentas de Discord, Twitch, Kick y YouTube por fin se pueden unir en una sola desde Conexiones. Ademas, invitar al bot a tu servidor ya tiene enlace propio y Leksimus estrena casa: servicio encendido de forma continua y una pagina publica donde ver como esta el bot ahora mismo.
- Nuevo
- +Conexiones / Une tus cuentas en una sola - Si alguna vez entraste con Discord y otra con Twitch, tenias dos cuentas distintas sin saberlo. Ahora entras en Conexiones, pulsas Vincular, autorizas la otra plataforma y pasan a ser la misma. Solo se unen asi, demostrando que las dos son tuyas: nunca por correo ni por nombre parecido.
- +Conexiones / Al unir no pierdes nada - La cuenta resultante conserva tu plan, tus canales vinculados y tus enlaces de overlay antiguos, que siguen funcionando en OBS sin que tengas que tocar nada.
- +Twitch / Vincular sin cerrar sesion - Si entraste al Studio con otra plataforma, el boton de Twitch ya abre su propia autorizacion, igual que Discord, Kick y YouTube. El Studio tambien recuerda con que cuenta entraste, en lugar de suponerlo.
- +Discord / Enlace propio para invitar al bot - app.digitalbite.net/invite abre la instalacion oficial con los permisos justos que Leksimus necesita para funcionar. No pide Administrator.
- +Web / El boton de invitar, a la vista - El menu de Leksimus y su pagina principal enlazan ese acceso, asi que sumar el bot a tu servidor deja de depender de encontrar el enlace correcto.
- +Monitor / Pagina de estado tecnico - Nueva pagina publica con la version en marcha, cuanto lleva encendido, comunidades conectadas, directos en curso y como va de recursos, refrescando cada 15 segundos.
- +Monitor / Como responde cada plataforma - Muestra tambien si Twitch, Kick, YouTube y Discord estan contestando bien: cuantas peticiones fallan, si alguna esta frenando al bot y cuanto tardan. Sirve para distinguir "esta caido Leksimus" de "esta caido Twitch".
- +Monitor / Que no guarda - Las muestras caducan a las 24 horas y no incluyen usuarios, canales, servidores ni nada del contenido de los mensajes.
- Corregido
- +Discord / Los selfroles decian que el bot no respondio - Al pulsar el selector de roles, Discord podia mostrar "La aplicacion no ha respondido" aunque el rol si se hubiera dado o quitado. Ahora el bot confirma primero y hace el trabajo despues, asi que el aviso desaparece.
- +Discord / Comandos lentos que se quedaban colgados - /notifyall, /listservers, /setsubscription, /translate, /compareplans, /serverinfo y /upgrade podian agotar el tiempo de espera de Discord mientras trabajaban, aunque acabaran bien. Ahora responden primero y completan la respuesta al terminar.
- +Web / Entrar con Discord y editar lo de Twitch - Si entrabas al Studio con Discord, el editor podia decir "No autenticado" aunque tu canal de Twitch estuviera vinculado a la misma cuenta. Ya lo reconoce.
- +Web / La sesion vale en todo el panel - Una sesion iniciada con Discord no llegaba a todas las secciones, y al cerrar sesion podia quedar rastro de la anterior. Las dos cosas quedan corregidas.
- +Web / Errores de acceso que culpaban a Kick - Cuando fallaba una autorizacion de Discord, Twitch o YouTube, el aviso hablaba de Kick. Ahora nombra la plataforma correcta.
- +Web / Entrar con Discord, Kick y YouTube - Durante el cambio de infraestructura esos tres accesos dejaron de completarse. Vuelven a funcionar con normalidad.
- Cambiado
- +Servicio / Casa nueva y encendido continuo - Leksimus termina su mudanza de infraestructura y pasa a un servicio unico que no se apaga por inactividad, con una comprobacion automatica cada minuto que lo levanta si algo va mal. La instalacion anterior queda apagada: no hay dos bots publicos a la vez.
- +Monitor / Solo el servicio real - La pagina deja de mezclar el entorno de pruebas y calcula el estado unicamente con datos frescos del servicio que atiende a los canales.
- Release: v.10.23.0
- Vincular Discord desde el Studio ya no depende de tener abierto el panel clasico de Discord.
- Corregido
- +Web / Vincular Discord desde cualquier sesion - Si habias entrado con Twitch, Kick o YouTube, el boton "Vincular Discord" no hacia nada util: daba por hecho que tenias una sesion de Discord abierta en el mismo navegador. Ahora abre su propia autorizacion y vuelve a tu misma cuenta, igual que las demas plataformas.
- Release: v.10.22.0
- Un fallo de configuracion tras el cambio de infraestructura dejo el panel inalcanzable y rompio el inicio de sesion con Twitch. Corregido, y protegido para que un reinicio no lo repita.
- Corregido
- +Web / El panel estuvo caido - El servicio que sirve el dashboard quedo respondiendo en un sitio distinto al que se consultaba, asi que la web del panel no cargaba pese a estar el bot vivo. Ademas de corregirlo, el arranque pasa a ser automatico para que un reinicio no vuelva a dejarlo abajo.
- +Web / Iniciar sesion con Twitch daba error de redireccion - Las direcciones de retorno de Twitch, Discord, Kick y YouTube seguian apuntando a una direccion de desarrollo en vez de a app.digitalbite.net. El mismo fallo dejaba sin datos a los overlays de OBS.
- Release: v.10.21.0
- Leksimus empieza a mudarse de infraestructura. El cambio destapo dos fallos que se corrigieron el mismo dia, con el servicio anterior en pausa como red de seguridad.
- Corregido
- +Overlay / Widgets de OBS sin datos - Tras el cambio, los eventos seguian enviandose al servicio antiguo y los widgets se quedaban en blanco. Ya llegan al servicio activo.
- +Cuentas / Una misma persona con dos cuentas - Entrar por Discord y entrar por Twitch podia crear dos cuentas separadas para la misma persona, una con tu plan y otra sin el. El caso detectado se unifico a mano; la solucion general para todo el mundo llega en la v.10.24.0.
- Release: v.10.20.0
- Version de preparacion, sin cambios visibles en el bot: los cambios pasan a probarse en un entorno aparte y nace la pagina de estado tecnico.
- Nuevo
- +Monitor / Primera pagina de estado - Una pagina publica empieza a mostrar como va el servicio por dentro (memoria, procesador y capacidad de respuesta). Solo datos tecnicos agregados: ningun dato de canales ni de usuarios.
- Cambiado
- +Pruebas / Entorno separado - Los cambios pasan primero por una copia aislada del bot, con su propia base de datos, donde se pueden simular directos sin usar tu canal ni tus datos reales.
- Release: v.10.19.0
- Primeros arreglos de la cuenta multiplataforma: YouTube vuelve a detectar directos y a leer el chat completo, la descarga de tus datos se entiende y los comandos se pueden activar plataforma por plataforma.
- Corregido
- +YouTube / Directos sin detectar - Una consulta mal formada impedia reconocer que estabas en vivo. Ademas, las dos vias de deteccion se separan, asi que si una falla la otra sigue funcionando.
- +YouTube / Mensajes de chat que se perdian - El lector se quedaba con parte del chat cuando habia movimiento. Ahora recoge todos los mensajes, y al engancharse a un directo ya empezado solo trae los ocho ultimos para no inundar el relay.
- +YouTube / Se acababa el cupo diario - El sistema anterior gastaba tanto que agotaba el limite que YouTube da al bot cada dia con solo dos canales conectados, y a partir de ahi se quedaba ciego hasta el dia siguiente. El nuevo lo mantiene muy por debajo.
- +Privacidad / Descargar mis datos, en cristiano - La exportacion mostraba nombres internos del sistema. Ahora entrega secciones con nombres normales, limita cada bloque a 200 filas y describe los permisos que has concedido sin incluir ninguna clave.
- +Web / Cerrar sesion - El boton vuelve al menu lateral y cierra la sesion sea de Twitch, Kick, YouTube o Discord.
- Nuevo
- +Twitch y Kick / Comandos por plataforma - Los comandos del bot y los tuyos se pueden activar en general y tambien uno a uno para cada plataforma. Kick hereda lo que tuvieras en Twitch hasta que elijas otra cosa.
- +Web / Planes y canales en la misma vista - Se unifican en una sola pantalla; asignar plan a un canal que solo tenia la cuenta autorizada ya no da error.
- Cambiado
- +YouTube / !streamevents gasta mucho menos - Reutiliza datos que el bot ya tiene en vez de volver a preguntarlo todo. Es el cambio que libero el cupo diario.
- +Web / Interaccion a ancho completo - Se elimina la media columna vacia del diseno anterior.
- Release: v.10.18.0
- Tu cuenta de Leksimus deja de depender de Discord: puedes entrar al Studio con Discord, Twitch, Kick o YouTube, la que prefieras.
- Nuevo
- +Cuenta / Entra con la plataforma que quieras - Discord deja de ser obligatorio para identificarte y cualquiera de las cuatro cuentas puede ser la principal, sin tener que pasar antes por Discord.
- +Web / Pantalla de acceso unica - Las cuatro plataformas se ofrecen desde un mismo sitio al entrar al Studio.
- +Web / Pagina Conexiones - Tus cuentas vinculadas se administran en una seccion propia.
- +Web / Modulos con selector de plataforma - Los siete modulos de Interaccion pasan a tarjetas unificadas donde eliges la plataforma.
- +Privacidad / Descargar mis datos - Puedes exportar un resumen legible de tu cuenta desde Conexiones.
- +Seguridad / Avisos de pago verificados - Las notificaciones de suscripcion de PayPal se comprueban antes de aplicarse, para que solo cuenten las que vienen de PayPal de verdad.
- Cambiado
- +Suscripciones / El plan es tuyo, no del servidor - El plan de pago pasa a pertenecer a tu cuenta de Leksimus, conservando las suscripciones anteriores que estaban asociadas a un servidor de Discord.
- Release: v.10.17.0
- El chat de YouTube deja de ser solo lectura: ya puedes responder desde el multichat del Studio.
- Nuevo
- +YouTube / Responder en el chat del directo - Los mensajes que escribes desde el Studio se publican con la identidad de tu propio canal, igual que en Kick. Si uno falla no se reintenta solo, para no gastar el cupo diario que YouTube da al bot.
- Cambiado
- +Web / Botones unificados del multichat - Twitch, Kick y YouTube comparten una sola fila de botones: encendido, ves su chat y le escribes; apagado, se oculta. Aviso: Kick venia apagado de fabrica solo para enviar, asi que ahora tambien empieza con su chat oculto hasta que lo enciendas.
- Release: v.10.16.0
- Lote de mantenimiento del dashboard: se corrige una pantalla negra al editar !so y se cierran los avisos de seguridad de las librerias del panel.
- Corregido
- +Twitch / Pantalla negra al editar !so - El editor podia dejar el panel entero en negro si tu canal tenia configurado un servidor de Discord principal. Corregido, y el panel gana comprobaciones para cazar este tipo de fallo antes de publicarse.
- +Seguridad / Librerias del panel actualizadas - Se actualizan nanoid, postcss, react-router y react-router-dom con sus correcciones de seguridad. Ninguno de los avisos era aprovechable por la forma en que Leksimus las usa, y la auditoria queda sin vulnerabilidades.
- Nuevo
- +Web / Ocultar el chat de YouTube - Se puede ocultar o mostrar el chat de YouTube sin dejar de recibir mensajes ni perder el historial. Sustituido por los botones unificados de la v.10.17.0.
- Cambiado
- +Web / Textos con las cuatro plataformas - El Studio deja de nombrar solo a Discord, Twitch y Kick e incluye tambien YouTube.
- Release: v.10.15.0
- La pagina de estado publico estrena horas de directo acompanadas y directos en curso, y se corrige que la actividad de YouTube no se contaba y ademas inflaba la de Twitch.
- Nuevo
- +Web / Horas de directo acompanadas - el total de horas de directo que el bot ha acompanado, sumando todos los streams ya terminados. Un directo que empieza a las 23:00 y acaba a las 02:00 cuenta sus 3 horas de una pieza: no se parte por dias, asi que no hay descuadres.
- +Web / Directos en curso - cuantas emisiones hay en marcha ahora mismo. Cuenta emisiones, no personas: si alguien emite a la vez en tres plataformas, son tres.
- +Web / Mensajes relay por plataforma - cada tarjeta muestra los suyos, asi se ve como se usa realmente cada plataforma. Un servidor puede tener pocos comandos y mucho relay.
- Corregido
- +Web / La actividad de YouTube no aparecia y sumaba a Twitch - su tarjeta salia vacia mientras su chat engordaba el contador de Twitch. Eran cuatro fallos encadenados y ninguno daba error, asi que arreglar solo uno no cambiaba nada. Aviso: al desplegar, el numero de mensajes relay de Twitch baja de golpe, porque incluia los de YouTube y no se pueden separar hacia atras.
- Cambiado
- +Web / Fila principal de la pagina de estado - fuera "Acciones realizadas" y "Mensajes relay". La primera era una suma nuestra que nadie de fuera puede interpretar; los segundos bajan a las tarjetas, donde cada cifra tiene su plataforma. Quedan cuatro: horas de directo, comandos, alertas y comunidades.
- +Web / Perfil de uso - el hueco que dejaba el feed de actividad pasa a mostrar la hora punta, el dia mas fuerte y como va hoy frente a lo normal. Son datos que la pagina ya recibia y solo dibujaba como barras sin numeros.
- Release: v.10.14.0
- Los comandos del cronometro ya salen en la lista de !comandos y puedes elegir quien los usa.
- Nuevo
- +Cronometro / Elige quien puede usarlo - !timerstart, !timerpause, !timerlap y !timerstop dejan de ser solo para moderadores: ahora eliges entre todos, VIP, suscriptores, moderadores o solo tu, desde el panel de comandos. El permiso es el mismo para los cuatro, porque controlan el mismo cronometro y con permisos distintos alguien podria arrancarlo sin poder pararlo. Por defecto se queda como estaba, en moderadores.
- Cambiado
- +Cronometro / Aparece en !comandos - Los cuatro comandos salen en la lista si tienes creado un widget de cronometro y quien pide la lista tiene permiso. Si no has creado ninguno no se anuncian, para no ofrecer algo que responderia que no hay cronometro configurado.
- Release: v.10.13.0
- Se corrige un fallo por el que el bot podia escribir en el chat con el nombre de otro streamer. Ademas, tus comandos ya pueden ejecutar otros comandos de tu canal.
- Fix
- +Twitch / El bot podia escribir con el nombre de otro streamer - El bot usa una unica conexion al chat, y si su propia sesion caducaba, tomaba prestada la de otro canal para no quedarse sin chat. A partir de ese momento sus mensajes salian en todos los canales firmados por ese streamer. Ya no puede: el bot solo escribe si esta identificado como el mismo, y si no puede, se queda leyendo sin publicar nada.
- +Twitch / La sesion del bot se recupera sola - Su acceso se renueva antes de caducar y se guarda de forma permanente, asi que ya no se pierde al reiniciar el servicio. Antes era la causa de que acabara tomando prestada otra identidad.
- Nuevo
- +Comandos / Ejecutar comando - Un comando tuyo puede lanzar otro comando de tu canal, sea nativo o creado por ti: lo eliges de una lista con los tuyos y los del bot. Se ejecuta como si lo hubiera escrito quien uso el comando, asi que se respetan el permiso y el tiempo de espera del comando llamado. Un comando encadenado no puede encadenar otro, y no se admiten bucles.
- Release: v.10.12.0
- La seccion Actividad y participantes deja de apilar todas las plataformas: ahora eliges Twitch, Kick o YouTube igual que en el preview del canal, y los paneles se reparten mejor el espacio. YouTube se suma al preview del canal y estrena listado de ultimos videos. Se arreglan tres fallos del resumen del directo.
- Nuevo
- +Dashboard / Actividad y participantes, una plataforma cada vez - Pulsa Twitch, Kick o YouTube para ver solo esa, en vez de bajar por los seis paneles seguidos. Si solo tienes una cuenta vinculada, se ve como hasta ahora.
- +Dashboard / YouTube en el preview del canal - Faltaba la tercera pestana: ya puedes ver tu directo de YouTube desde el mismo cuadro que Twitch y Kick.
- +YouTube / Tus ultimos videos - Los tres ultimos que subiste, con miniatura y fecha, dentro del panel de estadisticas de YouTube. Aparecen tanto videos largos como shorts.
- Fix
- +Twitch / El resumen del directo no se enviaba solo - Con el envio automatico activado, el mensaje no salia al terminar el directo, pero el boton Reenviar ahora si funcionaba. Los dos usaban vias distintas para llegar al chat y la automatica no esperaba a que la conexion estuviera lista.
- +Kick / El resumen del directo no se enviaba nunca - El interruptor se guardaba bien, pero el bot lo buscaba con el nombre equivocado y no lo encontraba jamas, salvo que tu canal de Kick se llamase exactamente igual que el de Twitch. Tambien hacia que el mensaje saliera siempre en espanol.
- +YouTube / Directos sin detectar en algunas instalaciones - Un canal autorizado podia quedarse sin deteccion de directo, y por tanto sin metricas ni resumen, por una comprobacion de configuracion que sobraba.
- Cambiado
- +Dashboard / Mejor reparto del espacio - Estadisticas ocupa la columna izquierda entera y Participantes queda arriba a la derecha, con Entradas y salidas justo debajo.
- +Dashboard / YouTube aparece en el resumen aunque no haya sesion - Si tienes el canal vinculado y no se registro sesion, la seccion aparece explicando por que en vez de desaparecer sin mas.
- Release: v.10.11.0
- YouTube se suma al dashboard al mismo nivel que Twitch y Kick: vinculas tu canal, ves su chat junto al del resto, consultas sus metricas y editas el titulo del directo sin salir de Leksimus. Llegan tambien el panel de colaboraciones de Twitch y un chat privado entre streamers.
- Nuevo
- +YouTube / Vincula tu canal - Nueva tarjeta en Cuentas vinculadas para autorizar YouTube, igual que ya hacias con Kick. Al desvincular se borran tambien los permisos concedidos.
- +YouTube / Su chat, en el chat unificado - Los mensajes de tu directo de YouTube aparecen junto a los de Twitch y Kick, con su color e icono. De momento es solo lectura: se leen, pero todavia no se puede responder desde el dashboard.
- +YouTube / Metricas y resumen del directo - Espectadores en vivo, tiempo emitiendo, suscriptores y numero de videos. Al terminar, YouTube tiene su propia seccion en el resumen del directo.
- +YouTube / Cambia el titulo sin salir del panel - Editable desde Informacion del stream, con el directo en marcha. Se anade tambien el corte publicitario para canales monetizados.
- +Twitch / Panel de colaboraciones (Guest Star) - Invita, da sitio en la llamada, silencia camara o microfono de un invitado y expulsa, todo desde el dashboard. El video de la llamada sigue estando en Twitch: solo se administra desde aqui.
- +Chat entre streamers - Habla en privado con otros canales que tengan Leksimus, pensado para cuando emitis juntos. Hace falta que ambos acepten, y cualquiera puede bloquear.
- +Dashboard / Pliega cada panel por separado - Actividad, informacion del stream y resumen del directo se pliegan uno a uno ademas de la seccion entera, y recuerdan como los dejaste.
- Fix
- +Kick / Interruptores descolocados - Los botones de activar y desactivar del panel de Kick se salian de su sitio.
- +Streamers nuevos / Entraban sin plan asignado - Al invitar al bot, el canal aparecia sin plan en vez de entrar directamente en el plan gratuito. No afectaba a las funciones disponibles.
- Release: v.10.10.2
- El cobro del plan Suscriber ahora se procesa desde la cuenta empresarial de Digital Bite Chile en vez de la cuenta personal.
- Cambiado
- +Suscripciones / Cuenta de cobro actualizada - El plan Suscriber (9,50 EUR/mes) pasa a facturarse a traves de la cuenta empresarial de Digital Bite Chile en PayPal. Sin cambios en el precio, el flujo de suscripcion ni las funciones incluidas en el plan.
- Release: v.10.10.1
- Mantenimiento interno de la base de datos: se resuelve un aviso de compatibilidad que aparecia en los registros de arranque del bot. Sin cambios de funcionamiento.
- Fix
- +Backend / Aviso de compatibilidad en la base de datos - El motor de base de datos usaba una forma de pedir "el documento ya actualizado" que la version mas reciente del motor marca como obsoleta. Se actualiza a la forma recomendada en las 56 consultas que la usaban, sin cambios de comportamiento para el streamer ni para el bot.
- Release: v.10.10.0
- Nuevo panel de Chat con IA en el dashboard Multicanal para gestionar permisos y consultar limites de uso.
- Nuevo
- +Dashboard / Panel Chat con IA - Nueva seccion en Multicanal > Twitch con un selector visual para decidir quien puede usar @LeksimusBot: todos, suscriptores, VIP, moderadores o solo el streamer. Es la alternativa visual al comando !aichatpermiso.
- +Dashboard / Limites reales del Chat con IA - El panel muestra el cooldown por usuario, el cupo diario del canal con el consumo actual y el cupo global compartido del bot. Los datos se leen desde el mismo sistema que aplica los limites, y los canales sin plan Suscriber o Unlimited ven el aviso de upgrade.
- Release: v.10.9.1
- Actualizacion de seguridad de axios en el Bot y el Dashboard.
- Fix
- +Seguridad / axios actualizado - La dependencia pasa de la rama 1.16.x a la version 1.18.1 para corregir vulnerabilidades de severidad alta relacionadas con recursion excesiva, contaminacion de prototipo y limites del cuerpo de las peticiones. La auditoria queda en 0 vulnerabilidades, sin cambios funcionales para los usuarios.
- Release: v.10.9.0
- Chat con IA por mencion en Twitch: menciona al bot en el chat y te responde.
- Nuevo
- +Twitch / Chat con IA por mencion - En canales con plan Suscriber o Unlimited, escribir @LeksimusBot seguido de una pregunta hace que el bot responda usando inteligencia artificial directamente en el chat. El streamer decide quien puede usarlo con el nuevo comando !aichatpermiso (todos, suscriptores, VIP, moderadores o solo el streamer).
- Release: v.10.8.1
- El Cronometro ya es inmune a relojes desajustados.
- Fix
- +Overlay / Cronometro con la hora del PC desviada - Si el reloj del ordenador donde corre OBS iba adelantado, el cronometro pintaba ese desfase como tiempo ya transcurrido nada mas pulsar Iniciar (por ejemplo, arrancaba "desde 59 minutos" con el reloj una hora adelantado). Ahora el widget mide la diferencia con el reloj del servidor y la descuenta automaticamente; con relojes bien sincronizados no cambia nada.
- Release: v.10.8.0
- Vueltas en el Cronometro con !timerlap y arreglo del reinicio que "recordaba" el tiempo anterior.
- Nuevo
- +Overlay / Vueltas en el Cronometro - Nuevo comando !timerlap (y boton "Vuelta" en el panel de Widgets): marca una vuelta sin detener el tiempo total y el bot canta en el chat la duracion de la vuelta y el total acumulado. Se recuerdan las ultimas 5 vueltas y !timerstop canta el resumen (Lap 1, Lap 2... y Total) antes de reiniciar. Pensado para desafios de varias rondas; disponible en modo countup.
- Fix
- +Overlay / El Cronometro ya no "recuerda" el tiempo viejo - Tras pulsar Reiniciar, el siguiente Iniciar podia retomar el ultimo valor pausado o el tiempo total historico en vez de arrancar de cero. Lo causaba un estado atrasado que llegaba al overlay tras las reconexiones; ahora cada estado lleva un sello de orden, los estados viejos se descartan y la fuente de OBS recibe siempre el estado fresco.
- Release: v.10.7.0
- Cronometro de overlay tipo speedrun y dos arreglos del dashboard: el editor de Ruletas vuelve y el recap de Kick aparece para los canales vinculados por LeksID.
- Nuevo
- +Overlay / Cronometro tipo speedrun - Nuevo widget "Cronometro" para OBS con centesimas reales y dos modos: countup (cuanto tardas en hacer algo) y countdown (hacerlo en menos de un tiempo). Se controla desde el panel de Widgets del dashboard o desde el chat con !timerstart, !timerpause y !timerstop (mods y streamer). Aguanta recargas de la fuente de OBS sin perder el tiempo. No sustituye a los timers de subaton, que siguen igual.
- Fix
- +Dashboard / Editor de Ruletas recuperado - Desde la consolidacion en Studio no se podia crear una segunda Ruleta ni editar las existentes: los botones devolvian a la misma pantalla. El editor vive ahora dentro del propio panel de Ruletas, con "+ Nueva Ruleta" siempre visible y el borrado incluido.
- +Dashboard / Recap de Kick con cuenta vinculada - El "Recap del directo" solo mostraba Kick si el canal tenia la alerta configurada en un servidor de Discord; con Kick vinculado solo a la cuenta (LeksID) no salia nunca. Ahora la sesion se registra igualmente y el recap aparece con pico y media de viewers y la hora real de inicio.
- Release: v.10.6.0
- Telemetria completa en todas las plataformas y comandos de Kick con variables completas.
- Nuevo
- +Kick / Variables completas en comandos personalizados - Los comandos disparados desde el chat de Kick resuelven ahora todas las variables con el mismo motor que Twitch (webrequest, datos del stream...). Antes las variables avanzadas se vaciaban y comandos como una ruleta externa respondian incompletos en Kick.
- Fix
- +Live / Kick y relay ya cuentan - Los comandos nativos y personalizados de Kick y los mensajes relay de Twitch hacia Discord no sumaban en la pagina de estado; ahora todas las rutas cuentan.
- +Live / Enlace de Discord corregido en la pagina de estado.
- Release: v.10.5.1
- Fix de lectura de la telemetria: los contadores se registraban bien pero la pagina de estado los mostraba a 0.
- Fix
- +Live / Contadores a cero - El endpoint publico leia los contadores con un formato distinto al que se guarda en la base de datos y los descartaba todos. Los datos ya registrados eran validos y aparecieron completos con el despliegue.
- Release: v.10.5.0
- Leksimus Live fase 2: la pagina de estado deja de mostrar guiones. Contadores reales de comandos, alertas, relay y automatizaciones, con actividad reciente anonimizada.
- Nuevo
- +Live / Contadores reales - digitalbite.net/live muestra ya las acciones realizadas, comandos ejecutados (Discord, Twitch y Kick), alertas de directo, mensajes relay y acciones de hoy, todo contado por el propio bot y actualizado cada pocos segundos.
- +Live / Actividad reciente - Feed con los ultimos eventos del bot en formato generico ("Comando ejecutado", "Alerta de directo enviada") con plataforma y hora. Sin nombres de usuarios, sin servidores y sin contenido de mensajes: solo el pulso del bot.
- +Telemetria / Conteo eficiente - Los contadores se acumulan en memoria y se guardan por lotes una vez por minuto: la telemetria no anade trabajo por mensaje ni toca la base de datos en caliente.
- Release: v.10.4.0
- Primer paso de Leksimus Live: la nueva pagina publica de estado en digitalbite.net/live muestra en tiempo real que Leksimus esta operativo y cuantas comunidades atiende, y sera la base del canal de emision continua del bot en Twitch.
- Nuevo
- +Web / Pagina de estado en vivo - Nueva pagina digitalbite.net/live con el estado del servicio (online/degradado), version, uptime y comunidades conectadas en Discord, Twitch y Kick. Disenada para verse bien en navegador, como fuente de OBS y en el reproductor de Twitch.
- +API / Estado publico del bot - Nuevo endpoint publico de solo lectura que alimenta la pagina: entrega solo datos agregados y anonimos (nada de nombres de usuarios, servidores ni mensajes). Los contadores de actividad detallados llegaran con el servicio de metricas de la fase 2.
- Release: v.10.3.0
- Release del relay unificado: un solo canal #relay por servidor donde desemboca el chat de todas las plataformas, eventos como embeds de color que hacen de alertas, comando /relay para configurarlo en segundos y candado de permisos para que nadie modere tu Twitch desde Discord sin galones.
- Nuevo
- +Discord / Comando /relay y canal relay unico - /relay twitch usuario:<user> (o kick) configura el relay en un canal #relay que el bot crea y recuerda: uno solo por servidor, reutilizado por todas las plataformas; si se borra a mano, se recrea solo. Subcomandos list y remove para gestion. El editor del dashboard usa el mismo canal.
- +Relay / Chat multiplataforma en vivo hacia Discord - Cada mensaje de Twitch, Kick o YouTube llega a Discord como linea de texto con el cuadrado de su plataforma. Solo publica en servidores con relay configurado y plan que lo incluya.
- +Relay / Eventos como embeds de color - Entradas y salidas del chat, subs y resubs, subs regaladas, raids y anuncios llegan como embeds que destacan sobre el chat y hacen de alertas dentro de Discord.
- +Studio / Card de anuncio con foto de perfil - La card de "Anunciar stream" incorpora la foto de perfil de Twitch del canal.
- Seguridad
- +Relay / Permiso minimo para comandos nativos - ban, timeout, mod, vip y demas comandos nativos de Twitch escritos en el canal relay solo se ejecutan si el autor tiene el permiso de Discord correspondiente. Sin permiso, el bot lo deniega en publico con cooldown anti-flood.
- +Relay / Anti-bucle Discord-Twitch - Los ecos que el propio bot publica en Twitch al relayear Discord ya no vuelven a Discord duplicados.
- Fix
- +Dashboard / Acciones de relay sin cliente gateway - "Reparar" el canal relay y "crear canal nuevo" funcionan ahora tambien cuando el backend corre separado del bot, usando la REST API de Discord como fallback.
- +Panel Kick / Boton "Probar" reparado en el proceso web, y botones primario/secundario alineados.
- Release: v.10.2.0
- Release de idiomas y visibilidad: el selector "Idioma del bot" de Discord por fin manda de verdad, el traductor de Twitch aprende el modo "todo a un idioma" con palabras excluidas, el chat unificado gana URL propia para OBS y los unfollows entre streams se detectan cada hora.
- Nuevo
- +Discord / El idioma del bot por fin manda - El selector "Idioma del bot" del dashboard ahora gobierna las respuestas de todos los comandos del bot. Antes cada usuario recibia las respuestas en el idioma de su cliente de Discord y el selector no hacia nada; ahora el servidor decide: eliges English y Leksimus responde en ingles a todo el mundo, con la misma personalidad. El cambio se aplica en menos de un minuto, sin reiniciar nada.
- +Twitch / Traductor "todo a un idioma" - Nuevo modo del traductor de chat: en vez de traducir solo entre un par de idiomas fijo, traduce cualquier mensaje que llegue en un idioma distinto al tuyo. Ideal para raids internacionales: te escriban en el idioma que te escriban, lo ves en el tuyo. Se activa desde el panel de traduccion del dashboard.
- +Twitch / Palabras excluidas del traductor - Lista configurable de palabras que el traductor ignora como contenido (emotes tipo "KEKW", jerga del canal): si el mensaje solo trae eso, no se traduce; si trae algo mas, se traduce completo. Menos traducciones absurdas de emotes.
- +Overlay / Chat unificado para OBS - El chat combinado de Twitch + Kick + Discord ya tiene URL propia para usar como fuente de navegador en OBS: fondo transparente, insignia de plataforma en cada mensaje y desvanecido opcional de mensajes viejos. Boton "Copiar URL chat" en la seccion Multicanal.
- +Unfollows / Barrido horario entre streams - Los unfollows que ocurren cuando llevas dias sin emitir ya no esperan a tu proximo directo: un barrido cada hora los detecta y los registra en el panel de Unfollows del Studio con su fecha real.
- Release: v.10.1.0
- Dos funciones nuevas del Studio: vigilancia completa de unfollows con historico permanente y panel propio, y la franja "Anunciar stream" para publicar tu directo en redes sin APIs de pago.
- Nuevo
- +Unfollows / Deteccion entre streams - Hasta ahora los unfollows solo se detectaban durante el directo; los que ocurrian entre streams se perdian. Ahora, al iniciar cada directo, el bot compara la lista de seguidores contra la ultima conocida antes de actualizarla: ningun unfollow se escapa, y los detectados fuera de sesion quedan marcados "Entre streams".
- +Unfollows / Historico permanente - Los unfollows quedan registrados para siempre (usuario, fecha y cuantos dias duro el follow), independientes del feed de actividad que expira a los 30 dias.
- +Unfollows / Panel dedicado en el Studio - Nuevo panel en Resumen, junto a Actividad reciente, con la lista completa. El badge "Follow fugaz" marca a quien te siguio menos de 3 dias: el clasico follow tras raid que se esfuma si no devuelves el gesto queda expuesto con nombre y fecha.
- +Studio / Franja "Anunciar stream" - Cuando estas en vivo, una franja sobre la cabina del Resumen prepara el anuncio del directo: texto por plantilla configurable (titulo, categoria y link del canal). "Publicar en X" abre el compose con el texto listo y copia una card del stream al portapapeles para pegarla con Ctrl+V como imagen nativa; por defecto el texto va sin link (el algoritmo de X penaliza los links externos) con boton para copiarlo y dejarlo en el primer comentario. Para Instagram y TikTok: copiar texto y descargar la card. Tras publicar o descartar se colapsa a un chip y no vuelve a molestar hasta el siguiente directo.
- Release: v.10.0.0
- Release de optimizacion transversal: 37 mejoras que reducen carga de CPU, MongoDB, APIs externas, disco y dashboard manteniendo el mismo comportamiento visible. Punto de rollback: v.9.1.0.
- Nota de despliegue
- Requiere `NODE_ENV=production` en Web Service y Worker, y la misma `MONGO_URI` en ambos procesos para que el puente de alertas de Kick y la invalidacion de configuracion crucen correctamente.
- Cambios
- +Motor de eventos / Mapa estatico evento-requisitos - El motor precalcula que modulos escuchan cada evento y deja de recorrer todos los requisitos en cada evento de Discord. Mismos modulos, mismo orden, menos trabajo por mensaje.
- +Arranque / Hot reload solo en desarrollo - El watcher de comandos queda desactivado en produccion; cada deploy sigue re-registrando comandos al arrancar.
- +Base de datos / Cache de configuracion e indice de usuarios - Nueva cache compartida para configuracion de guild y ajustes globales, con invalidacion inmediata desde dashboard, PayPal y SignalBus. `DB_UserData` gana indice `{guildId, userId}`.
- +Cumpleanos y XP / Menos consultas por mensaje - El XP de cumpleanos consulta solo al autor y un cron horario cubre usuarios que no escriben. La concesion de XP ya no colisiona con la felicitacion publica.
- +Watchtime / Muestreo configurable cada 5 minutos - El contador reduce frecuencia de escritura y vuelca mensajes pendientes antes de cerrar la sesion para no perder los ultimos minutos del directo.
- +Alertas / YouTube, TikTok y Kick mas eficientes - YouTube usa RSS como via primaria, TikTok cachea por cuenta y Kick pasa a webhook con polling de respaldo cada 15 minutos.
- +Clips / EventSub con respaldo legacy - El sistema nuevo toma prioridad cuando esta sano y el cron legacy queda como fallback si se degrada, sin duplicar clips ya publicados.
- +Overlay / Init mas barato y datos vivos frescos - `/api/overlay/init` cachea solo estructura y recalcula viewers, followers, subs, bits y actividad en cada reconnect para evitar estados atrasados en OBS.
- +Dashboard / Polling consciente de visibilidad - Los paneles dejan de pedir datos mientras la pestana esta oculta y refrescan al volver. Tambien se reducen proyecciones y se cachean listas de Discord.
- +Web/API / Compresion y cache de assets - El servidor sirve gzip/brotli y cachea assets con hash por un ano; `index.html` queda no-cacheable.
- +Senales / SignalBus menos ruidoso - El sondeo pasa de 500 ms a 1500 ms porque las senales son sincronizaciones, no acciones de tiempo real.
- +Logs y memoria / Menos ruido sostenido - Niveles de log configurables y barridos periodicos de caches internas para procesos largos.
- +Deploy / Dashboard precompilado - Render deja de recompilar el dashboard en cada deploy; `dashboard-dist/` versionado es la fuente desplegable.
- Fix
- +Watchtime / Resumen post-stream sin ultimos mensajes - El cierre de sesion fuerza el volcado del contador antes de generar el resumen.
- +Clips / Migracion y salud en caliente - La migracion ya no marca como publicados clips recientes pendientes y el fallback reacciona a fallos ocurridos despues del arranque.
- +Overlay / Estado inicial atrasado tras reconnect - La cache ya no conserva viewers, subs ni bits viejos al recargar OBS dentro de la ventana de cache.
- +TikTok / Fallos temporales no silencian alertas - Los errores puntuales usan TTL corto y se reintentan pronto sin volver al scraping excesivo.
- +Cumpleanos / Felicitacion y XP separados - Se evita que una felicitacion ya procesada bloquee el XP del dia, con fallback para no dar XP doble el dia del deploy.
- Release: v.9.1.0
- Paridad de comandos en Kick y control total para streamers que usan varios bots, más los fixes de despacho del Jukebox.
- Nuevo
- +Studio / Interruptor maestro de comandos nativos - Nuevo toggle "Comandos nativos ON/OFF" en la pestaña Comandos. En OFF el bot deja de responder a todos los comandos integrados en Twitch y Kick, para que no se dupliquen respuestas si usas otro bot; tus comandos personalizados siguen funcionando con normalidad.
- +Kick / `!comandos` con la lista real - Hasta ahora `!comandos` en Kick devolvía una lista fija de 6 comandos. Ahora genera la lista real del canal, igual que en Twitch: comandos integrados disponibles en Kick (quotes, `!so`, sorteo, cola, jukebox, notas, traducción) y tus comandos personalizados marcados para Kick, mostrando a cada usuario solo lo que puede usar según su rol.
- +Kick / Comandos personalizados completos - Los comandos marcados para Kick ejecutan ahora acciones de overlay (sonidos, imágenes, video en tu OBS) y acciones de OBS, además de texto. Antes solo respondían texto público: un comando de solo-sonido marcado para Kick no hacía nada. Los permisos (mod, streamer…) se respetan usando los badges de Kick.
- +Kick / Respuestas largas en varios mensajes - Las respuestas largas (como la lista de `!comandos`) se dividen en varios mensajes en vez de cortarse a la mitad.
- Cambios
- +Twitch / Triggers reservados - Los triggers del jukebox (`!music` y compañía) y `!relay` ya no se pueden usar en comandos personalizados: la capa integrada los ocupaba y el comando personalizado quedaba eclipsado sin aviso.
- Fix
- +Jukebox / Solicitudes auto-aprobadas - En canales donde la opción "Requiere aprobación" nunca se había guardado explícitamente, las peticiones de canción llegaban aprobadas solas aunque el toggle apareciera activo. Corregido: la aprobación manual vuelve a ser la puerta real.
- +Jukebox / Peticiones aprobadas que no sonaban - El botón "Reintentar" no reenviaba la petición al bridge, y si el bridge estaba desconectado al aprobar, la petición quedaba varada para siempre. Ahora el retry despacha de verdad y la reconexión del bridge retoma la cola pendiente.
- Release: v.9.0.0
- Overhaul mayor de estabilidad, latencia y arquitectura: se eliminan los errores silenciosos detectados en una auditoria completa del bot, se añade observabilidad de proceso y los tres archivos mas grandes del proyecto se modularizan sin cambio funcional.
- Nuevo
- +Extensibles / Raid por espectador - El evento Raid admite dos modos: suma fija por raid (comportamiento clasico) o valor multiplicado por cada espectador que llega (por ejemplo, 1 minuto por persona). Selector nuevo en la fila Raid del editor; el resultado respeta el valor maximo del timer.
- +Bot + API / Observabilidad de proceso - Muestreo del lag del event loop (p50/p99/max) y memoria cada 60 s con aviso automatico si el p99 supera 200 ms. Los crons por-minuto y el Random Clip Player ganan guard de re-entrancia (una pasada lenta ya no se monta sobre la siguiente) y catch-all (un cron roto ya no tumba el proceso).
- +Bot / Red de seguridad global de errores - Toda promesa rechazada sin catch queda logueada con stack en vez de matar el proceso sin causa registrada.
- +Overlay / Buffer de reenvio de alertas - Los eventos que no llegan a ningun cliente (overlay de OBS recargandose o desconectado) se retienen 15 s y se reenvian al reconectar, en vez de perderse para siempre. La emision ademas reintenta fallos de transporte y loguea cada entrega a 0 clientes.
- +Overlay / Cola de sonidos - Los efectos de sonido ganan cola FIFO: dos sonidos cercanos ya no se reproducen encimados.
- Cambios
- +Arquitectura / Modularizacion - Los tres archivos mas grandes del proyecto (diccionario de personalidad, rutas del dashboard Twitch y pagina de comandos del dashboard) se dividen en modulos por dominio sin cambio funcional, verificados identicos contra el original.
- +Overlay / Posicion por defecto de tarjetas de alerta - Las tarjetas pasan del centro al superior-centro cuando no hay posicion configurada, para no hacer cola detras de los clips de `!so` y del Random Clip Player. Quien tenga posicion explicita configurada no se ve afectado.
- +Startup / Comandos perdidos tras reinicio - El bus de señales purga señales obsoletas al arrancar y los handlers de chat esperan a que el relay IRC complete su conexion antes de procesar: los comandos ya no se pierden en la ventana inmediata tras cada reinicio.
- Fix
- +Twitch / `!so` bloqueante - El mensaje de chat del shoutout esperaba la resolucion del clip (hasta minutos en el peor caso). Ahora el chat sale de inmediato salvo que el mensaje use `{target.clip_random}`, y la resolucion tiene presupuesto global de 8 s. Latencia tipica del `!so`: menos de 1 s.
- +Discord / `/clear todo` en bucle infinito - Con mensajes de mas de 14 dias (que Discord no permite borrar en bloque) el comando reintentaba para siempre. Ahora termina cuando un lote no borra nada y responde cuantos mensajes quedaron fuera.
- +Discord / Cumpleaños marcados sin enviarse - Si el envio de la felicitacion fallaba (canal borrado, permisos), el usuario quedaba marcado como felicitado igualmente. Ahora solo se marca tras envio exitoso y el fallo se reintenta en la siguiente pasada.
- +Twitch / Chatters perdidos en fallos de base de datos - Un hipo de BD perdia el lote completo de chatters pendientes de persistir. Ahora el fallo se loguea y el lote se re-encola para el siguiente ciclo.
- +Sistema / Suite de tests reparada - La suite completa vuelve a correr en verde (116 checks) y sirve de gate real para los cambios.
- Release: v.8.37.1
- Nuevo
- +Studio / Notas de directo - Pizarra privada y lista de apuntes sueltos (privados o publicos) para el streamer, disponible en chat (`!nota <texto>`, `!nota +pub <texto>` solo mods/streamer, `!pendientes`/`!notas` para listar las publicas abiertas) y en el dashboard (`StreamNotesPanel` en Multicanal, con checkbox para marcar resuelto y papelera). Backend: `DB_TwitchStreamNote`, `UTIL_TwitchStreamNotes`, endpoints `GET/POST /twitch-dashboard/api/notes` y `PUT /notes/board`.
- +Jukebox / Busqueda 1-clic Amazon Music - En `JukeboxPanel`, cada peticion en cola incluye un enlace para buscarla directo en Amazon Music (la cola es asistida: el provider SMTC no auto-reproduce, asi que el streamer busca y reproduce con un clic). `UnifiedActivityPanel` ahora muestra spin y deshabilita el boton de refrescar mientras consulta, para que el refresco manual sea perceptible.
- Fix
- +Bot / Stream / Reconciliacion de sesiones ante eventos EventSub perdidos - Twitch EventSub no reenvia eventos perdidos: si el bot se reiniciaba mientras un streamer estaba en vivo, se perdia `stream.online` (sin sesion -> sin recap/pico/media ni snapshot de seguidores) o `stream.offline` (sesion colgada en `live`, sin resumen post-stream). Nuevo `CRON_StreamSessionReconcile` (cada 2 min) compara el estado real (Helix `/streams`) contra la sesion en BD por cada streamer autorizado y reconcilia: abre la sesion perdida + snapshot de seguidores, o cierra la huerfana (tras 3 detecciones offline consecutivas) publicando el resumen + diff de unfollows. Ademas, `TwitchLiveSessionCatchupService` cubre el mismo hueco al conectar/reconectar EventSub y al autorizar por OAuth, sin esperar el ciclo del cron.
- +Bot / Twitch / Comandos de notas de directo no llegaban en el chat de Twitch - El router de Twitch (`REQ_TwitchChatRouter`) solo despachaba `!so`, `!comandos` y `!commands` directo al motor de comandos hardcoded; el resto de comandos integrados necesitaba estar en `RESERVED_TRIGGERS` para no quedar atrapado en la resolucion de comandos personalizados. `nota`, `note`, `pendientes`, `pend` y `notas` faltaban en esa lista: `!nota` y `!pendientes` funcionaban en Kick (sin ese filtro) pero se ignoraban en silencio en Twitch. Agregados a `RESERVED_TRIGGERS`.
- +Jukebox / Canjes de recompensa rechazados por triggerMode obsoleto - `submitRequest` rechazaba toda solicitud `source='reward'` con `trigger_mismatch` cuando el canal tenia `triggerMode='bits'` heredado en BD (default antiguo). Los Bits estan retirados por politica de Twitch, asi que la recompensa es la unica via de activacion y ese gate solo bloqueaba silenciosamente los canjes. Eliminada la validacion de `triggerMode`; el unico filtro real para reward sigue siendo `rewardId`.
- +Jukebox / Canjes rechazados sin aviso al viewer - Cuando `submitRequest` rechazaba un canje (formato invalido, cola llena, duplicado o input vacio) el unico rastro era un log interno; el viewer no se enteraba de por que su canje no hizo nada. `REQ_TwitchStreamerEventHub` ahora responde en el chat del canal via el relay del bot (no como el propio streamer, para no atribuirle la personalidad sarcastica del bot) usando las claves de personalidad ya existentes. Solo avisa en los errores que ocurren tras confirmar que la recompensa canjeada es la de Jukebox, para no generar spam en canjes de recompensas ajenas.
- Release: v.8.37.0
- Nuevo
- +Studio / Chat unificado / Persistencia de mensajes - El Chat Unificado en el dashboard multicanal persiste los mensajes en `localStorage` (clave `uc_<room>`). Botón de base de datos en la cabecera para activar/desactivar la persistencia (encendido por defecto); botón de papelera para limpiar el historial. La preferencia se guarda en `unified_chat_persist` y se mantiene entre recargas.
- Fix
- +Overlay / Chat unificado / Mensajes de Kick duplicados - `/overlay/emit` emitía el mensaje al room de plataforma (`broadcastToRoom`) y `mirrorToUnifiedRoom` lo emitía de nuevo al room unificado, que en muchas configuraciones apuntan al mismo room `lks_xxx`. El endpoint ahora llama a `resolveUnifiedToken` y omite el `broadcastToRoom` cuando el token de plataforma coincide con el room unificado del LeksID, eliminando la duplicación en el dashboard multicanal.
- +Overlay / Widget de chat / Init fallaba para rooms `lks_...` - `/overlay/init` resolvía el token de room exclusivamente contra `DB_TwitchChannelConfig.overlayRoomToken`; los rooms unificados (`lks_<hex>`) viven en `DB_LeksId`. Añadida detección de prefijo `lks_` con lookup en `DB_LeksId → DB_TwitchChannelConfig`. El widget OBS recibe ahora mensajes de Kick por el room unificado sin necesidad de cambiar la URL del Browser Source.
- +Overlay / Widget de chat / Sin mensajes cuando no hay widget configurado - `handleChatMessage` en `widget.html` descartaba todos los mensajes cuando `widgetState` era null (no se había configurado ningún widget para ese ID). El guard se cambió a saltar solo si el tipo no es `chat_box`; se añade `ensureChatBoxMounted()` para crear la estructura DOM mínima y mostrar mensajes con el estilo por defecto cuando no hay widget asignado.
- Release: v.8.36.0
- Nuevo
- +Studio / Actividad / Métricas de sesión Twitch - `StreamStatsPanel` muestra durante el directo el pico de viewers, la media, los chatters únicos y los mensajes de sesión. `GET /twitch-dashboard/api/stream-stats` obtiene esos valores de `DB_StreamSession` y los añade a la respuesta existente. También se muestra una tarjeta con el título y el juego en curso al inicio del panel.
- +Dashboard / Conexiones / Migrar desde otro bot - Nuevo `BotMigratorPanel` en la pestaña Conexiones de Studio. Permite importar comandos personalizados desde Nightbot, StreamElements, Streamlabs y StreamBot/MixItUp: se pega o sube el JSON exportado del bot, se previsualizan los comandos con checkboxes para elegir cuáles importar y se respetan el límite del plan y los duplicados (se omiten). También exporta todos los comandos de Leksimus como JSON de respaldo. Backend: `POST /bot-migrator/parse` (normaliza el formato de cada bot), `POST /bot-migrator/import` (guarda en `DB_TwitchCommands`), `GET /bot-migrator/export` (descarga completa del canal).
- +Dashboard / Conexiones / Revocar accesos - Nueva sección en la pestaña Conexiones con enlaces directos a las páginas de aplicaciones autorizadas de Twitch, Kick y Discord, para que el streamer pueda revocar permisos de cualquier bot sin salir del dashboard.
- 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 / Vista de moderador / Botón de retorno - Cuando `managedChannel` está activo (modo moderación), aparece un enlace "← Volver a mi Studio" en el encabezado del Studio para regresar a la vista propia sin navegar manualmente.
- +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. Ver LKS-V6QQRUJFEN.
- +Studio / Anuncios globales / Posición - `AnnouncementBanner` se desplazó fuera de la zona global anterior al contenido de pestañas y se colocó dentro de una sección en la pestaña Resumen, donde tiene contexto visual correcto.
- +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.
- +Dashboard / Emojis como iconos - `AlertsPanel` (tipos de evento, controles de overlay, selector de media, nota de cobertura Kick), `UnifiedSidebar`, `KickStatsPanel`, `StreamStatsPanel` y `ObsWebSocketPanel` usaban emojis como iconos, contra la convención del proyecto. Todos migrados a SVG inline estilo Feather.
- +Overlay / General / Alertas duplicadas en OBS - `handleTwitchAlert` en `index.html` encolaba y pintaba tarjetas de alerta además de actualizar los widgets de eventos, causando alertas duplicadas cuando el overlay general y `alerts.html` se añadían a la vez como Browser Sources en OBS. El overlay general ahora solo alimenta los widgets de eventos; las tarjetas de alerta las renderiza exclusivamente `alerts.html`.
- +Overlay / Sonidos / No se reproducían con capa activa - El switch de dispatch en `alerts.html` carecía del `case 'sound'`. Los eventos de sonido (`playSound`) se descartaban silenciosamente cuando había una capa activa (`?layer=general`). Añadido el case faltante.
- +Bot / Permisos / `isSub()` contaba VIP en vez de mod - `TW_Helpers.isSub()` hacía `isVip(badgesStr) || hasBadge('subscriber')`, dejando a los moderadores fuera del nivel de suscriptor. Corregido a `isMod(badgesStr) || hasBadge('subscriber')` para que mod y broadcaster siempre pasen el check de nivel sub.
- 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.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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`.
- 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.
- 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.
- 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.
- 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`.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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).
- 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.
- 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.
- 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.
- 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`).
- 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.
- 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.
- 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").
- 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
- 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"
- 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.)
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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`
- 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`)
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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`
- 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
- 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
- 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()`
- 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
- 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()`
- 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
- 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
- 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
- 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
- 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
- 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.
- +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
- +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
- +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