El camino completo que recorrimos — la arquitectura, cada fase del montaje y, sobre todo, el porqué de cada pieza. Hecho para que repitas los pasos y tengas tu propio DJ en tu sala.
Aquí hay dos caminos — y conviene elegir antes de meter las manos. El capítulo 03 (Las fases del montaje) monta la versión con navegador: un Chromium invisible que lee la página de la sala. Es la forma más didáctica de entender cada pieza, y fue como empezamos.
Pero hoy ya no usamos navegador. La versión que de verdad funciona es un cliente WebSocket ~10x más liviano, y reaprovecha casi todo de aquí — solo cambia la forma de hablar con el chat. Si sigues las fases en orden, vas a montar el Chromium primero y solo después descubrir que dejó de hacer falta.
¿Quieres ir directo al método actual? Salta a El giro — el camino dorado: te lleva de cero al aire por sí solo, reutilizando las fases que no cambiaron.
Antes de los pasos, entiende el diseño. Sabiendo qué resuelve cada pieza, adaptas en vez de copiar a ciegas.
Una cuenta de IMVU aparte se convierte en el "bot". Funciona 24/7 en una máquina virtual gratis que hace dos cosas a la vez: transmite una radio de música (un stream de audio) y mantiene un navegador invisible con la sesión iniciada en tu sala, leyendo el chat y obedeciendo comandos. IMVU apunta a la dirección de la radio; la gente en la sala escucha la música y conversa con el bot.
Cada pieza resuelve un problema real que solo descubrimos a golpes. Las secciones de abajo explican cada decisión — lee los "porqués", valen más que el código. Nota: empezamos con un navegador invisible (Chromium); después evolucionó a un cliente sin navegador, mucho más liviano — el capítulo El giro cuenta cómo y por qué (y por qué el "bot = Chromium" del diagrama es la versión original).
Qué tener a mano. Nada de esto cuesta dinero.
Instala las herramientas del PC de una vez. Elige tu sistema, haz clic en copiar y pégalo en tu terminal (la página no ejecuta nada por ti — ves el comando antes de ejecutarlo).
# Windows 10/11 - winget ya viene incluido (Terminal o PowerShell)
winget install OpenJS.NodeJS.LTS
winget install yt-dlp.yt-dlp
winget install Gyan.FFmpeg
winget install Git.Git# macOS - con Homebrew (instala brew antes, en brew.sh)
brew install node yt-dlp ffmpeg git# Debian/Ubuntu - el Node de apt puede ser viejo; para v18+ mira nodejs.org
sudo apt update
sudo apt install -y nodejs npm ffmpeg git python3-pip
python3 -m pip install -U yt-dlpGuarda los secretos (la sesión del bot, la clave de Gemini, el token de DuckDNS) fuera del control de versiones. Un .gitignore con auth.json, *.key, *.token y cache/ evita filtrar todo en el primer git push.
El orden importa — cada fase se apoya en la anterior. Monta y prueba en tu PC primero; solo después súbelo a la nube.
En el fondo, el bot es un navegador automatizado. Usa Playwright para abrir un Chromium, iniciar sesión con la cuenta del bot una vez y guardar la sesión (un login.js que graba un auth.json). Después solo reabres la sala reutilizando esa sesión.
Dentro de la sala, IMVU se comunica por un WebSocket (el "IMQ"). El bot escucha los mensajes que llegan por ahí, y así es como "lee" el chat y detecta comandos. Empieza simple: iniciar sesión, entrar a la sala, imprimir en la terminal cada mensaje que aparece.
IMVU no tiene API pública de chat. La forma confiable de participar en la sala es ser un cliente de verdad — un navegador con la sesión iniciada. Headless (invisible) para funcionar en un servidor sin pantalla.
Un servidor HTTP simple que transmite un MP3 continuo en un puerto (ej.: :8000). Tiene una carpeta de canciones de "relleno" (filler, las que suenan solas), mezcla el orden y expone rutas internas para encolar y saltar pistas (/add, /skip, /status). El bot habla con esas rutas por localhost.
Más adelante vas a querer reiniciar el bot (acumula memoria) sin cortar la música. Mantener la radio como un servicio propio hace que el sonido siga aunque el bot se reinicie.
Ahora conecta lo que el bot lee del chat con la rocola. Un mensaje como !play nombre de la canción hace que el bot llame al stream por localhost y la encole. !skip, !queue etc. siguen la misma idea.
Para poner "cualquier canción", el bot necesita descargar de YouTube — y ahí está la mayor trampa: YouTube bloquea las IP de datacenter, así que la VM no puede descargar sola. La solución es un pequeño agente HTTP en el PC de tu casa (IP residencial, que YouTube acepta) ejecutando yt-dlp. La VM llega a ese agente por un túnel SSH inverso.
Eso significa que !play/!add solo funcionan con tu PC encendido y el bridge corriendo. Todo lo demás (radio, chat, IA) funciona sin él. Si no quieres esa dependencia, puedes poner solo la carpeta local de canciones y olvidarte de YouTube.
Crea una instancia Always Free (la E2.1.Micro, 1 GB de RAM, es la más fácil de conseguir; la A1 ARM da más margen si hay cupo). Ubuntu. Instala Node, el Chromium de Playwright y ffmpeg, manda los archivos por scp y registra los dos servicios en systemd para que arranquen con el sistema y se reinicien solos.
# esqueleto de un servicio systemd (/etc/systemd/system/bot.service)
[Service]
ExecStart=/usr/bin/node /home/ubuntu/bot/bot.js
Restart=always
WorkingDirectory=/home/ubuntu/bot
Solo el Chromium se come ~500 MB. Activa swap (ej.: 2 GB en /swapfile) o la VM se cuelga. Y olvídate de 3D/WebGL en esa máquina — lo intentamos y se quedó sin memoria. Ejecuta el navegador sin 3D.
IMVU Next es una página HTTPS y rechaza direcciones de stream en HTTP simple — TLS es obligatorio. Pero Let's Encrypt no emite certificados para una IP "pelada", y por eso existe DuckDNS: te da un dominio gratis que apunta a la IP de la VM. Delante de todo va Caddy, que consigue el certificado HTTPS automáticamente y lo reenvía al stream.
# Caddyfile — reenvía el 443 al stream local
tu-nombre.duckdns.org {
reverse_proxy localhost:8000 {
flush_interval -1 # ESENCIAL: sin esto Caddy retiene el búfer y el sonido se traba
}
}
En Oracle, un puerto solo se abre si las dos lo permiten: el firewall del sistema (iptables) y la "Security List" de OCI. Abre 22, 80 y 443; deja el 8000 cerrado al público (solo Caddy habla con él por dentro). Y recuerda: la IP de Oracle es efímera — un cron que actualice DuckDNS cada 5 min mantiene el dominio correcto si la IP cambia.
En el panel de edición de tu sala en IMVU, pega la URL del stream (https://tu-nombre.duckdns.org/stream) en el campo de música. Listo: quien entre a la sala ya escucha la radio. El bot, con la sesión de la cuenta dueña de la sala, aparece en el chat.
Un bot que se cae de madrugada no sirve. Estas defensas nacieron, una por una, de problemas reales:
Casi toda esta lista salió de "¿por qué desapareció otra vez?". Anota tus propios síntomas — lo que parece un bug casi siempre es IMVU o Chromium reaccionando a algo específico.
Con la base en pie, lo demás es sabor. Conecta un modelo (usamos Gemini, tiene nivel gratis) para dar respuestas con una persona; deja que el bot decida solo cuándo el mensaje es para él (respondiendo "saltar" cuando no lo es, para no entrometerse). Puedes agregar saludos, memoria de quién ya visitó, conocimiento de la propia sala/sus muebles y una ventana de conversación continua.
Si usas un modelo con un nombre tipo -latest, ten en cuenta que "avanza" solo y un día puede romperse en silencio (ya nos pasó). Fija una versión específica y prueba después de cualquier cambio.
Las fases de arriba son como empezamos — y enseñaron todo. Este capítulo es lo que usamos hoy, y se sostiene solo: más abajo hay un paso a paso desde cero que reutiliza las fases que no cambiaron y enseña, con calma, la única parte que de verdad cambió.
El bot de la Fase 0 era un Chromium invisible manejado por Playwright. Funcionaba, pero era un mensajero carísimo — un navegador entero solo para llevar unos recados. Entonces caímos en la cuenta: la "presencia" de IMVU en la sala es solo un protocolo — un WebSocket (el IMQ) más algunas llamadas REST. Se puede hablar ese protocolo directo, sin ningún navegador.
Eso hicimos: ingeniería inversa del protocolo — observando los mensajes que un navegador real intercambia con IMVU, partiendo de un build viejo encontrado en GitHub y puliéndolo para nuestro uso — y escribimos un cliente sin navegador ("browserless") que inicia sesión, entra a la sala, lee el chat, se sienta, habla y revisa los participantes hablando IMQ a pelo. Misma cuenta, misma sala, mismos comandos — cero Chromium.
Solo el Chromium se comía ~500 MB (y tenía fugas hasta quedarse sin memoria a las ~19 h de funcionamiento). El cliente en Node puro se queda en ~50 MB. Y de paso desaparecen TODOS los parches que solo existían por culpa del navegador: el swap obligatorio, el "olvídate de 3D/WebGL", las flags anti-throttle "estructurales", el watchdog de página congelada y el "breather" que reiniciaba solo para limpiar memoria. Sin navegador, nada de eso necesita existir.
Con el bot tan liviano, esa angustia de "1 GB es poco" se evapora — y vale decirlo fuerte: quizás ni siquiera necesites una VM. Un PC de casa decente (un Windows 11 con 16 GB de RAM, digamos) ejecuta el bot, el stream y todo lo demás localmente, de sobra. La nube gratis servía en realidad para tener una máquina siempre encendida y una dirección pública; si tu casa ya resuelve eso, todo el esqueleto de arriba — Oracle, swap, systemd — pasa a ser opcional. Usa la nube si te resuelve un problema, no por obligación. Las fases de arriba son el camino más barato, no el único.
Y lo mejor: el cliente sin navegador reaprovechó casi todo. La radio/rocola (server.js), el puente de YouTube, la capa de IA y las defensas de la sala nunca dependieron de Chromium — solo la mitad "navegador" del bot se volvió "protocolo directo". Las demás fases siguen valiendo palabra por palabra. Y fue esa ligereza la que abrió espacio para crecer después (poner música en varias salas al mismo tiempo, por ejemplo, sin que la máquina sude).
No necesitas montar el Chromium para llegar aquí. Si estás empezando ahora y solo quieres lo que funciona hoy, sigue este recorrido: los pasos que no cambiaron te remiten a las fases de arriba (es literalmente lo mismo), y el paso del medio — el corazón nuevo — viene explicado con calma.
El IMQ no está documentado. Descubres el formato de los eventos observando un login real (las herramientas de red del navegador, pestaña WebSocket) o partiendo de un build de referencia — eso hicimos, encontrando uno viejo en GitHub y puliéndolo. Reserva tiempo para esta parte; es el único tramo "detectivesco" del proyecto.
Hablar el protocolo directo es liviano y rápido, pero es un protocolo no oficial: si IMVU cambia los mensajes del IMQ, tu cliente se rompe y lo arreglas a mano (un navegador de verdad se adaptaría solo). Es un intercambio consciente — mucho más liviano, un poquito más frágil. Aquí valió muchísimo la pena.
Si lees una sola sección, que sea esta. Cada línea costó horas de depuración.
A grandes rasgos, quién hace qué. Los nombres son los que usamos — los tuyos pueden variar.