Widget de chat de Twitch moderno y extensible para OBS Studio, construido con Astro y Web Components.
🌐 Demo en vivo: https://chrisvdev.github.io/CVTalk/
CVTalk es parte de un ecosistema de proyectos para Twitch:
- MTMI - Librería base para conexión IRC de Twitch (by ManzDev)
- mtmi-async-badges - Paquete para carga asíncrona de badges con persistencia localStorage
- CVTalk (este proyecto) - Widget para OBS que consume ambos paquetes
MTMI (IRC Client) + mtmi-async-badges (Badges CDN)
↓
CVTalk Widget
↓
OBS Studio Browser Source
- 🔌 Conexión en tiempo real a Twitch IRC usando mtmi
- 🎨 Personalización visual con ornamentos según roles (broadcaster, mod, VIP, suscriptor)
- 🦆 Sistema de efectos extensible para procesar mensajes (incluye PatoBotTribute)
- 🖼️ Avatares y badges de usuarios cargados dinámicamente
- ⏱️ Auto-expiración configurable de mensajes
- 🎯 Configuración por URL - fácil integración con OBS
- 🌈 Curación de colores para mejor legibilidad
- 🏗️ Componentes Web nativos - sin frameworks pesados en el frontend
- 📦 Build optimizado con Astro para máximo rendimiento
- Node.js >= 22.12.0
- pnpm (recomendado) o npm
# Clonar el repositorio
git clone https://github.com/chrisvdev/CVTalk.git
cd CVTalk
# Instalar dependencias
pnpm install
# Iniciar servidor de desarrollo
pnpm devEl servidor estará disponible en http://localhost:4321
Agrega una Browser Source en OBS con la URL de producción:
https://chrisvdev.github.io/CVTalk/?channel=tu_canal_twitch
-
Construye el proyecto para producción:
pnpm build
-
Previsualiza el build localmente:
pnpm preview
-
Agrega una Browser Source en OBS con la URL local:
http://localhost:4321/?channel=tu_canal_twitch
- Dimensiones recomendadas: 1920x1080
- FPS personalizado: 60
- Shutdown source when not visible: Desactivado (recomendado)
Configura el widget mediante parámetros URL:
| Parámetro | Tipo | Default | Descripción |
|---|---|---|---|
channel |
string | - | Requerido. Nombre del canal de Twitch |
messageTTL |
number | 10000 |
Tiempo de vida de mensajes (ms) |
pato_bot |
boolean | false |
Habilitar efecto PatoBot (quack) 🦆 |
mute_bots |
boolean | false |
Silenciar mensajes de bots 🤖 |
mute_replays |
boolean | false |
Silenciar mensajes que son respuestas 💬 |
mute_prefixes |
string | "" |
Prefijos para silenciar comandos (separados por comas) 🔇 |
tts |
string | "" |
Habilitar funcionalidad TTS (Text-to-Speech) 🔊 |
tts_accent |
string | "es-AR" |
Acento predeterminado para TTS (ej: es-AR, en-US) 🌍 |
tts_variant |
number | 1 |
Variante de voz predeterminada (1-n) 🎙️ |
experimental_features |
boolean | false |
⚡ Activar funcionalidades experimentales (notificaciones) |
insecureHTML |
string | "" |
"onCommand" (con $html) o "onHighlight" ⚡ |
remoteAdmin |
string | "" |
🎛️ Control remoto: "streamer" (solo streamer) o "moderators" (streamer + mods) 🔐 |
# Configuración básica
?channel=micanal
# Con mensaje TTL personalizado (20 segundos)
?channel=micanal&messageTTL=20000
# Con efecto PatoBot habilitado
?channel=micanal&pato_bot=true
# Silenciar bots, respuestas y comandos
?channel=micanal&mute_bots=true&mute_replays=true&mute_prefixes=!,.,/
# Con TTS habilitado (español de Argentina, variante 1)
?channel=micanal&tts=true&tts_accent=es-AR&tts_variant=1
# ⚠️ Con HTML habilitado en comandos (USAR CON PRECAUCIÓN)
?channel=micanal&insecureHTML=onCommand
# 🎛️ Con control remoto para streamer (puede cambiar propiedades desde el chat)
?channel=micanal&remoteAdmin=streamer
# 🔐 Con control remoto para streamer y moderadores
?channel=micanal&remoteAdmin=moderatorsCVTalk incluye varios efectos que procesan los mensajes antes de mostrarlos:
- 😺 cuteMichi: Convierte
:3en "AliMoyi" - ❤️ afordiLove: Reemplaza
<3y❤️con el emote "afordiLove" - 🚫🔗 antiLinks: Censura URLs (excepto para mods y broadcaster)
- 🦆 antiGoose: Reemplaza "goose"/"ganso" por "duck"/"pato"
- 🚫📏 antiLongWords: Censura palabras excesivamente largas (spam)
- 🦆 PatoBotTribute: Reproduce sonido de pato al detectar
*quack*(configurable) - 🤖 muteBots: Oculta mensajes de bots (configurable)
- 💬 muteReplays: Oculta mensajes que son respuestas (configurable)
- 🔇 muteCommandsByPrefix: Oculta comandos por prefijo (configurable)
- ⚡ insecureHTML:
⚠️ Permite HTML controlado en mensajes (configurable, usar con precaución) - 🎙️ commandsProcessor: Procesador de comandos TTS y control remoto (habilitado con
tts=trueoremoteAdmin)
Ver documentación completa de efectos para más detalles.
⚡ FUNCIONALIDAD EXPERIMENTAL
CVTalk incluye un sistema de notificaciones para eventos de Twitch (subs, raids, bits, etc.) que se encuentra en fase experimental. Esta funcionalidad está deshabilitada por defecto.
Para habilitar las notificaciones, añade el parámetro experimental_features=true:
?channel=micanal&experimental_features=trueEl sistema de notificaciones escucha y procesa más de 28 eventos diferentes de Twitch:
- Suscripciones: Nuevas suscripciones, resubs, gift subs, mystery gifts
- Bits: Donaciones con bits (Cheers)
- Raids: Notificaciones de raids entrantes
- Moderación: Bans, timeouts, mensajes eliminados
- Modos de sala: Emote-only, subs-only, followers-only, slow mode, R9K
Las notificaciones se configuran mediante un archivo JSON que define:
- Plantillas de mensaje: Texto con variables reemplazables (ej:
{user},{bits},{months}) - Efectos de sonido: Array de sonidos a reproducir
- Repositorio de sonidos: URL del repositorio de audio a utilizar
El sistema carga automáticamente la configuración desde:
/default_config_files/notifications.json
{
"soundsRepositoryUrl": "notifications",
"onSub": {
"messageTemplate": "{user} se ha suscrito! 🎉",
"soundEffect": ["ba_yell"]
},
"onBits": {
"messageTemplate": "{user} ha donado {bits} bits! 🎉",
"soundEffect": ["ba_yell"]
}
}Nota: Actualmente la sustitución de variables está implementada principalmente para eventos de suscripciones y bits. Otros eventos usan la plantilla como texto plano hasta completar lógica adicional.
Cada tipo de evento tiene variables específicas que puedes usar en las plantillas:
- onSub, onResub:
{user},{months} - onSubGift:
{gifter},{recipient},{months},{plan} - onBits:
{user},{bits} - onRaid:
{raider},{viewers}
✅ Implementado:
- Sistema de configuración JSON
- Carga de repositorios de sonidos
- Renderizado de notificaciones con auto-expiración
- Plantillas de mensaje con variables
- Eventos completamente funcionales:
onSub,onResub,onSubGift,onSubMysteryGift,onPrimePaidUpgrade,onBits - Stubs base para todos los eventos de Twitch (28+ eventos)
- Sistema de placeholders para eventos no implementados
🚧 Pendiente:
- Completar lógica para eventos:
onRaid,onBan,onTimeout,onClearChat,onClearMsg,onViewerMilestone - Completar lógica para modos de sala:
onEmoteOnlyOn/Off,onFollowersOn/Off,onSlowOn/Off,onSubsOn/Off,onR9kOn/Off - Completar eventos de pago:
onCommunityPayforward,onStandardPayforward,onGiftPaidUpgrade - Sistema de animaciones y transiciones CSS
- Editor visual de configuración
- Soporte para GIFs y stickers
- Esta es una funcionalidad en desarrollo activo
- La API puede cambiar sin previo aviso
- Algunos eventos pueden no funcionar completamente
- Se recomienda usar solo en entornos de prueba
🔐 CARACTERÍSTICA DE ADMINISTRACIÓN REMOTA
CVTalk permite controlar las propiedades del widget en tiempo real desde el chat de Twitch, sin necesidad de recargar la página. Esta funcionalidad está deshabilitada por defecto.
remoteAdmin=""(default): Deshabilitado - nadie puede ejecutar comandos remotosremoteAdmin=streamer: Solo el streamer/broadcaster puede ejecutar comandosremoteAdmin=moderators: El streamer y los moderadores pueden ejecutar comandos
| Comando | Descripción |
|---|---|
!remoteAdmin <propiedad> <valor> |
Comando completo para cambiar propiedades |
!cvsudo <propiedad> <valor> |
Alias corto del comando |
| Propiedad | Tipo | Ejemplo |
|---|---|---|
messageTTL |
number | !cvsudo messageTTL 15000 |
pato_bot |
boolean | !remoteAdmin pato_bot true |
mute_bots |
boolean | !cvsudo mute_bots false |
mute_replays |
boolean | !remoteAdmin mute_replays true |
mute_prefixes |
string | !cvsudo mute_prefixes !,.,/ |
tts |
string | !remoteAdmin tts true |
tts_accent |
string | !cvsudo tts_accent es-MX |
tts_variant |
number | !remoteAdmin tts_variant 2 |
insecureHTML |
string | !cvsudo insecureHTML onCommand |
- ❌
remoteAdmin- No se puede cambiar su propio nivel de seguridad - ❌
baseUrl- URL base del sistema - ❌
channel- Canal de Twitch conectado
# Habilitar en modo streamer
?channel=micanal&remoteAdmin=streamer
# En el chat, el streamer puede escribir:
!cvsudo pato_bot true # Activa PatoBot
!remoteAdmin messageTTL 20000 # Cambia TTL a 20 segundos
!cvsudo tts_accent es-MX # Cambia acento TTS a mexicano# Habilitar para moderadores también
?channel=micanal&remoteAdmin=moderators
# Ahora tanto el streamer como los mods pueden usar:
!cvsudo mute_bots true
!remoteAdmin insecureHTML onCommand- Control total: Los comandos remotos pueden cambiar cualquier configuración del widget
- Moderadores de confianza: Solo usar modo
moderatorscon mods de alta confianza - Logs en consola: Todos los comandos se registran en la consola del navegador
- Cambios en vivo: Los cambios se aplican inmediatamente sin recargar
- 🎮 Streams interactivos: Ajustar configuración en respuesta a eventos
- 🎪 Testing en vivo: Probar diferentes configuraciones durante el stream
- 🔧 Debugging: Cambiar parámetros para diagnosticar problemas
- 🎨 Personalización dinámica: Adaptar el widget según el contenido
CVTalk permite la inyección controlada de HTML en mensajes del chat. Esta funcionalidad está deshabilitada por defecto y debe usarse solo en entornos controlados donde confías en los usuarios.
-
insecureHTML=onCommand: Permite HTML solo en mensajes que empiezan con$htmlUsuario: $html <b>Texto en negrita</b> y <i>cursiva</i> -
insecureHTML=onHighlight: Permite HTML solo en mensajes destacados (highlighted messages)[Usuario con mensaje destacado]: <span style="color: red;">Mensaje importante</span>
Se bloquean automáticamente las siguientes etiquetas y atributos peligrosos:
<script>- Ejecución de JavaScript<iframe>- Carga de contenido externo<object>- Objetos embebidos<details>- Elementos interactivosonload,onerror- Eventos JavaScript inline
- NO garantiza protección total contra XSS (Cross-Site Scripting)
- Usar SOLO en streams privados o con comunidad de confianza
- Los usuarios pueden usar CSS para modificar la apariencia del chat
- Posibles riesgos: robo de cookies, phishing, defacement
# Solo permitir HTML en comandos específicos
?channel=micanal&insecureHTML=onCommand
# Ahora los usuarios pueden usar:
# $html <marquee>¡Texto en movimiento!</marquee>
# $html <span style="font-size: 2em;">Grande</span>CVTalk incluye un sistema completo de síntesis de voz que permite a los usuarios del chat sintetizar mensajes con diferentes acentos y voces.
| Comando | Descripción | Ejemplo |
|---|---|---|
!speak <texto> |
Sintetiza el texto con configuración predeterminada | !speak Hola mundo |
!s <texto> |
Alias corto de !speak | !s Hola |
!speak <acento> <texto> |
Sintetiza con acento específico | !speak es-MX Hola desde México |
!speak <acento> <variante> <texto> |
Sintetiza con acento y variante específicos | !speak es-AR 2 Hola Argentina |
!speak -config <acento> [variante] |
Configura acento personalizado del usuario | !speak -config es-AR 2 |
!speak -reset |
Resetea la configuración personalizada | !speak -reset |
Los acentos disponibles dependen del navegador/sistema. Ejemplos comunes:
- Español:
es-ES(España),es-MX(México),es-AR(Argentina),es-US(Estados Unidos) - Inglés:
en-US(Estados Unidos),en-GB(Reino Unido),en-AU(Australia) - Otros:
pt-BR(Portugués Brasil),fr-FR(Francés),de-DE(Alemán), etc.
Cada usuario puede configurar su propio acento y variante que se aplicará automáticamente a sus mensajes:
Usuario: !speak -config es-AR 2
[Se configura la voz española argentina, variante 2]
Usuario: !speak Hola chat
[Sintetiza "Hola chat" con la configuración guardada: es-AR, variante 2]
La configuración se guarda en localStorage del navegador y persiste entre sesiones.
CVTalk incluye un sistema robusto de gestión de audio que permite reproducir sonidos de forma centralizada y eficiente, con soporte para colas de reproducción secuencial y manejo automático de políticas de autoplay.
El componente AudioProcessor es el núcleo del sistema de audio y proporciona:
- Carga dinámica de audios: Carga archivos de audio bajo demanda desde URLs
- Sistema de colas: Reproducción secuencial automática de múltiples audios
- Desbloqueo automático: Manejo inteligente de políticas de autoplay de navegadores
- Aviso de desbloqueo: Overlay interactivo que solicita la primera interacción del usuario para habilitar audio
- Estado de desbloqueo: Consultar si el audio ya está disponible con
isAudioUnlocked - Control de volumen: Ajuste de volumen global para todos los audios
- Gestión de cola: Limpiar la cola con
clearQueue()o detener todos los audios constopAll() - Gestión de memoria: Los audios se crean y eliminan dinámicamente
const processor = window.OBSChat.audioProcessor;
// Cargar un audio
processor.loadAudio("notification", "/assets/notification.mp3");
// Reproducir un audio inmediatamente
processor.playAudio("notification");
// Reproducir múltiples audios en secuencia
processor.enqueueAudios("audio1 audio2 audio3");
// Control de volumen
processor.volume = 0.5; // 50% de volumenCVTalk incluye un sistema modular y extensible para cargar y gestionar repositorios de sonidos desde configuraciones JSON remotas. Este sistema permite añadir fácilmente conjuntos temáticos de audio sin necesidad de recompilar la aplicación.
SoundsBank (Singleton)
↓
├─→ SoundsRepository (hl1_vox)
├─→ SoundsRepository (hl1_suit)
└─→ SoundsRepository (custom_sounds)
↓
AudioProcessor
Gestor centralizado que maneja múltiples repositorios de sonidos:
import SoundsBank from "@/lib/sounds_bank";
const soundsBank = SoundsBank.getInstance();
// Cargar repositorio por nombre corto (desde GitHub)
soundsBank.loadRepository("hl1_vox", (vox) => {
vox.warn("system online");
});
// Cargar desde URL completa
soundsBank.loadRepository(
"https://example.com/custom_sounds.json",
(custom) => {
custom.playSound("beep");
}
);Cada repositorio gestiona un conjunto temático de sonidos con métodos de conveniencia:
// Reproducir sonido individual
repository.playSound("beep");
// Métodos con prefijos automáticos
repository.log("system initialized"); // Añade logPrefix
repository.warn("temperature high"); // Añade warnPrefix
repository.error("critical failure"); // Añade errorPrefixLos repositorios se definen mediante archivos JSON con el siguiente esquema:
{
"name": "hl1_vox",
"baseURL": "https://github.com/sourcesounds/hl1/raw/refs/heads/master/sound/vox/",
"sounds": {
"beep": "beep.wav",
"online": "online.wav",
"warning": "warning.wav"
},
"logPrefix": "bloop",
"warnPrefix": "buzwarn buzwarn",
"errorPrefix": "woop woop"
}Sistema de voz sintética de Black Mesa (Half-Life 1):
- 500+ palabras del vocabulario VOX
- Números, direcciones, estados, alertas
- Términos científicos y del complejo
Sistema de voz del traje HEV (Half-Life 1):
- 150+ clips de audio del traje
- Alertas de salud, armadura, sistemas
- Notificaciones de equipamiento
CVTalk carga automáticamente los repositorios de Half-Life 1 al iniciar:
// En src/components/audio_processor/index.ts
this.soundBank.loadRepository("hl1_vox", (hl1_vox) => {
hl1_vox.warn("vox_login");
});
this.soundBank.loadRepository("hl1_suit", (hl1_suit) => {
hl1_suit.warn("hev_logon communications_on voice_on safe_day");
});- Crear archivo JSON de configuración:
{
"name": "my_sounds",
"baseURL": "https://cdn.example.com/sounds/",
"sounds": {
"welcome": "welcome.mp3",
"goodbye": "goodbye.mp3"
},
"logPrefix": "",
"warnPrefix": "alert",
"errorPrefix": "error"
}- Cargar en la aplicación:
soundsBank.loadRepository("https://cdn.example.com/my_sounds.json", (repo) => {
repo.log("welcome"); // Reproduce: welcome.mp3
repo.warn("system"); // Reproduce: alert.mp3 → system.mp3
});- ✅ Lazy Loading: Los sonidos se cargan bajo demanda
- ✅ Validación: Validación automática de configuraciones
- ✅ CDN-Ready: Carga desde GitHub o cualquier CDN
- ✅ Type-Safe: Totalmente tipado con TypeScript
- ✅ Extensible: Añade repositorios sin modificar código
- ✅ Prefijos automáticos: Construye secuencias complejas fácilmente
Los repositorios de configuración están en /default_config_files/:
sounds_repository/- Directorio de repositorios de sonidosexample.json- Plantilla para crear repositorioshl1_vox.json- Configuración del sistema VOX (movido desde raíz)hl1_suit.json- Configuración del traje HEV (movido desde raíz)
notifications.json- Configuración de notificaciones de eventos de Twitchnotifications_example.json- Plantilla de configuración de notificaciones
Los audios de Half-Life 1 provienen del repositorio sourcesounds/hl1 y son propiedad de Valve Corporation.
CVTalk incluye un sistema completo para capturar y procesar todos los eventos de Twitch de forma centralizada. El componente NotificationsView escucha eventos como suscripciones, raids, bits, y más, permitiendo personalizarlos mediante configuración JSON.
NotificationsView (Custom Element)
↓
├─→ Escucha eventos MTMI (sub, raid, bits, etc.)
├─→ Carga configuración desde JSON
├─→ Procesa eventos según configuración
└─→ Reproduce efectos de sonido y muestra mensajes
El sistema captura todos los eventos de Twitch IRC:
Suscripciones y Regalos:
sub- Nueva suscripciónresub- Resuscripciónsubgift- Regalo de suscripciónsubmysterygift- Regalos misteriosos masivosprimepaidupgrade- Upgrade de Prime a pagogiftpaidupgrade- Upgrade de regalo a pagocommunitypayforward- Pago adelantado de comunidadstandardpayforward- Pago adelantado estándar
Moderación:
ban- Usuario baneadotimeout- Usuario en timeoutclearchat- Chat limpiadoclearmsg- Mensaje eliminado
Eventos Especiales:
raid- Raid entrantebits- Cheers con bitsannouncement- Anuncio oficialviewermilestone- Hito de espectador
Modos de Chat:
emote_only_on/off- Modo solo emotesfollowers_on/off- Modo solo seguidoresslow_on/off- Modo lentosubs_on/off- Modo solo suscriptoresr9k_on/off- Modo R9K (mensajes únicos)
Otros:
action- Mensaje con /meroomstate- Cambio de estado de salaraw- Eventos IRC sin procesar
Las notificaciones se configuran mediante archivos JSON con el siguiente esquema:
{
"soundsRepositoryUrl": "notifications",
"onSub": {
"messageTemplate": "¡{user} se ha suscrito!",
"soundEffect": ["celebration", "tada"]
},
"onBits": {
"messageTemplate": "{user} ha donado {bits} bits",
"soundEffect": ["coins"]
}
}soundsRepositoryUrl(opcional): Repositorio de sonidos a cargar automáticamenteon[EventName]: Configuración para cada eventomessageTemplate: Plantilla del mensaje a mostrar (acepta variables)soundEffect: Array de nombres de sonidos a reproducir en secuencia
Por defecto, el sistema carga notifications.json desde GitHub:
// URL por defecto
https://raw.githubusercontent.com/chrisvdev/CVTalk/refs/heads/main/default_config_files/notifications.jsonPuedes personalizar la URL de configuración:
// En el componente NotificationsView
const notificationsView = document.querySelector('notifications-view');
notificationsView.loadNotificationsConfig('https://mi-cdn.com/config.json');El sistema se integra automáticamente con el sistema de sonidos:
{
"soundsRepositoryUrl": "mi_repositorio",
"onSub": {
"messageTemplate": "",
"soundEffect": ["fanfare", "applause", "celebration"]
}
}Esto cargará el repositorio mi_repositorio.json y reproducirá la secuencia de sonidos cuando ocurra una suscripción.
El sistema de notificaciones está parcialmente implementado. Actualmente:
✅ Implementado:
- Estructura base del componente
- Escucha de todos los eventos de Twitch
- Carga y validación de configuración JSON
- Integración con SoundsBank
- Sistema de handlers para cada evento
⏳ Pendiente:
- Implementación de lógica de cada handler (actualmente solo hacen
console.debug) - Sistema de renderizado de notificaciones visuales
- Sistema de plantillas para mensajes personalizados
- Animaciones y transiciones de notificaciones
El componente se inicializa automáticamente al cargar la página:
<!-- En src/pages/index.astro -->
<notifications-view></notifications-view>Todos los eventos se capturan automáticamente y se loguean en la consola del navegador:
console.debug("Not Implemented SUB: ", data);
console.debug("Not Implemented RAID: ", data);
// etc...- Crear archivo de configuración personalizado:
{
"soundsRepositoryUrl": "custom_notifications",
"onSub": {
"messageTemplate": "¡Gracias {user} por suscribirte!",
"soundEffect": ["ba_yell", "tada"]
},
"onBits": {
"messageTemplate": "¡{user} ha donado {bits} bits!",
"soundEffect": ["raid_horn"]
}
}-
Subirlo a tu servidor/CDN
-
Modificar el código para usar tu configuración:
// En src/components/notifications-view/index.ts
this.loadNotificationsConfig('https://mi-server.com/mi-config.json');default_config_files/notifications.json: Configuración activadefault_config_files/notifications_example.json: Plantilla de ejemplo
/
├── public/
│ ├── assets/
│ │ ├── audio/ # Archivos de audio (quack.mp3)
│ │ ├── fonts/ # Fuentes personalizadas
│ │ └── styles/ # Estilos CSS globales
│ └── favicon.ico
├── default_config_files/ # Configuraciones por defecto
│ ├── notifications.json # Config de notificaciones activa
│ ├── notifications_example.json # Plantilla de notificaciones
│ └── sounds_repository/ # Repositorios de sonidos
│ ├── example.json # Plantilla de ejemplo
│ ├── hl1_vox.json # Config sistema VOX Half-Life 1
│ └── hl1_suit.json # Config traje HEV Half-Life 1
├── src/
│ ├── components/ # Web Components
│ │ ├── audio_processor/ # Gestor centralizado de audio
│ │ ├── chat-view/ # Contenedor principal del chat
│ │ ├── notifications-view/ # Sistema de notificaciones de Twitch
│ │ └── user-message/ # Mensaje individual de usuario
│ ├── lib/ # Utilidades y lógica de negocio
│ │ ├── efects_loop/ # Sistema de efectos
│ │ │ ├── index.ts # EfectsLoop core
│ │ │ └── efects/ # Efectos disponibles
│ │ │ └── pato_bot_tribute.ts
│ │ ├── sounds_bank.ts # Gestor de repositorios de sonidos (Singleton)
│ │ ├── sounds_repository.ts # Repositorio individual de sonidos
│ │ ├── get_curated_color.ts
│ │ ├── get_ornament.ts
│ │ └── mock_messages.ts
│ ├── pages/
│ │ └── index.astro # Página principal
│ └── scripts/
│ ├── global.ts # Configuración global
│ └── start.ts # Inicialización del cliente IRC
└── package.json
CVTalk incluye un sistema extensible de efectos que permite procesar mensajes antes de renderizarlos.
Los efectos son funciones middleware que se ejecutan secuencialmente en una cadena de procesamiento:
Message → Effect 1 → Effect 2 → Effect N → Renderimport type { Effect } from "@/lib/efects_loop";
import { type UserMessageInfoType } from "mtmi";
export default class MiEfecto {
constructor() {
// Inicialización
}
public getEfect(): Effect {
return (message, next) => {
// Procesar el mensaje
if (message.message.includes("palabra_clave")) {
// Modificar el mensaje o ejecutar lógica
message.userInfo.color = "#FF0000";
}
// Llamar al siguiente efecto
next();
}
}
}🦆 Tributo a PatoBot - Homenaje al legendario bot creado por Nivek el pato (PatitoDev), un querido amigo y gran creador de contenido que se retiró del streaming. Este efecto mantiene vivo su legado en la comunidad.
Características:
- 🦆 Reproduce sonido de pato cuando detecta
*quack*en mensajes - 🖼️ Cambia el avatar del usuario por uno aleatorio de pato
- 🔊 Maneja políticas de autoplay del navegador con desbloqueo inteligente
Uso:
?channel=micanal&pato_bot=true
💙 Nota: Este efecto es un tributo cariñoso a PatoBot, que aunque ya no está en funcionamiento, dejó una marca especial en la comunidad de streaming.
| Comando | Acción |
|---|---|
pnpm dev |
Inicia servidor de desarrollo en localhost:4321 |
pnpm build |
Construye para producción en ./dist/ |
pnpm preview |
Previsualiza el build de producción |
pnpm astro |
Ejecuta comandos CLI de Astro |
Los mensajes se decoran automáticamente según el rol del usuario:
- 👑 Broadcaster - Propietario del canal
- 🔧 Moderator - Moderador
- 💎 VIP - VIP del canal
- ⭐ Subscriber - Suscriptor
Los colores de usuario se procesan para mejorar la legibilidad, oscureciéndolos automáticamente para un mejor contraste sobre fondos oscuros.
Personaliza la apariencia editando:
public/assets/styles/user-message.css- Estilos de mensajespublic/assets/styles/chat-view.css- Estilos del contenedorpublic/assets/styles/fonts.css- Fuentes personalizadas
- Astro
^6.1.3- Framework SSG de alto rendimiento - mtmi
^0.0.19- Cliente Twitch IRC read-only by ManzDev - mtmi-async-badges
^1.0.6- Badges de Twitch con carga asíncrona y persistencia localStorage (desarrollo propio)
- Verifica que el parámetro
channelesté en la URL - Comprueba la consola del navegador para errores de conexión IRC
- Asegúrate de que el canal exista y esté activo
- Verifica que
ChatViewesté correctamente inicializado - Comprueba los listeners de eventos en la consola
- Revisa que el
messageTTLno sea demasiado corto
- Los navegadores requieren interacción del usuario antes de reproducir audio
- En OBS, el audio debería funcionar automáticamente
- Verifica que el archivo
quack.mp3exista enpublic/assets/audio/
Las contribuciones son bienvenidas! Por favor:
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature) - Commit tus cambios usando conventional commits (
git commit -m '✨ feat: add amazing feature') - Push a la rama (
git push origin feature/AmazingFeature) - Abre un Pull Request
Este proyecto está bajo la Licencia MIT. Ver el archivo LICENSE para más detalles.
Christian Villegas (ChrisVDev)
- Email: christian@chrisvdev.com
- GitHub: @chrisvdev
- mtmi por el excelente cliente de Twitch IRC - Gracias ManzDev!
- Astro por el excelente framework
- Nivek el pato / PatitoDev por el legado de PatoBot 🦆💙 - Un amigo y creador de contenido que dejó huella en la comunidad
- La comunidad de Twitch por el apoyo continuo
Hecho con ❤️ para la comunidad de streamers
