O caminho completo que a gente percorreu — a arquitetura, cada fase da montagem e, principalmente, o porquê de cada peça. Feito pra você refazer os passos e ter o seu próprio DJ na sua sala.
Existem dois caminhos aqui — e vale escolher antes de pôr a mão na massa. O capítulo 03 (As fases da montagem) monta a versão com navegador: um Chromium invisível que lê a página da sala. É a forma mais didática de entender cada peça, e foi como a gente começou.
Mas hoje a gente não usa mais navegador. A versão que roda de verdade é um cliente WebSocket ~10x mais leve, e ela reaproveita quase tudo daqui — só a forma de conversar com o chat muda. Se você seguir as fases em ordem, vai montar o Chromium primeiro e só depois descobrir que ele virou dispensável.
Já quer ir direto ao método atual? Pule pra A virada — o caminho dourado: ela te leva do zero ao ar sozinha, reusando as fases que não mudaram.
Antes dos passos, entenda o desenho. Sabendo o que cada peça resolve, você adapta em vez de copiar cego.
Uma conta IMVU separada vira o "bot". Ela roda 24/7 numa máquina virtual grátis que faz duas coisas ao mesmo tempo: transmite um rádio de música (um stream de áudio) e mantém um navegador invisível logado na sua sala, lendo o chat e obedecendo comandos. O IMVU aponta pro endereço do rádio; as pessoas na sala ouvem a música e conversam com o bot.
Cada peça resolve um problema real que a gente só descobriu apanhando. As seções abaixo explicam cada escolha — leia os "porquês", eles valem mais que o código. Nota: a gente começou com um navegador invisível (Chromium); depois evoluiu pra um cliente sem navegador, bem mais leve — o capítulo A virada conta como e por quê (e por que o "bot = Chromium" no diagrama é a versão original).
O que ter em mãos. Nada aqui custa dinheiro.
Instalar as ferramentas do PC de uma vez. Escolha seu sistema, clique em copiar e cole no seu terminal (a página não roda nada por você — você vê o comando antes de rodar).
# Windows 10/11 - o winget ja vem incluso (Terminal ou PowerShell)
winget install OpenJS.NodeJS.LTS
winget install yt-dlp.yt-dlp
winget install Gyan.FFmpeg
winget install Git.Git# macOS - via Homebrew (instale o brew antes, em brew.sh)
brew install node yt-dlp ffmpeg git# Debian/Ubuntu - o Node do apt pode ser antigo; p/ v18+ veja nodejs.org
sudo apt update
sudo apt install -y nodejs npm ffmpeg git python3-pip
python3 -m pip install -U yt-dlpGuarde segredos (sessão de login do bot, chave do Gemini, token do DuckDNS) fora do controle de versão. Um .gitignore com auth.json, *.key, *.token e cache/ evita vazar tudo no primeiro git push.
A ordem importa — cada fase se apoia na anterior. Monte e teste no seu PC primeiro; só depois suba pra nuvem.
O bot é, no fundo, um navegador automatizado. Use o Playwright pra abrir um Chromium, logar na conta do bot uma vez e salvar a sessão (um login.js que grava um auth.json). Depois é só reabrir a sala reaproveitando essa sessão.
Dentro da sala, o IMVU conversa por um WebSocket (o "IMQ"). O bot escuta as mensagens que chegam por ele e é assim que ele "lê" o chat e detecta comandos. Comece simples: logar, entrar na sala, imprimir no terminal cada mensagem que aparece.
O IMVU não tem API pública de chat. A forma confiável de participar da sala é ser um cliente de verdade — um navegador logado. Headless (invisível) pra rodar num servidor sem tela.
Um servidor HTTP simples que transmite um MP3 contínuo numa porta (ex.: :8000). Ele tem uma pasta de músicas "filler" (as que tocam sozinhas), embaralha a ordem, e expõe rotas internas pra enfileirar e pular faixas (/add, /skip, /status). O bot fala com essas rotas por localhost.
Mais tarde você vai querer reiniciar o bot (ele acumula memória) sem cortar a música. Manter o rádio como um serviço próprio faz o som continuar mesmo quando o bot reinicia.
Agora conecte o que o bot lê do chat à jukebox. Uma mensagem tipo !play nome da música faz o bot chamar o stream por localhost e enfileirar. !skip, !queue etc. seguem a mesma ideia.
Pra tocar "qualquer música", o bot precisa baixar do YouTube — e aí mora a maior armadilha: o YouTube bloqueia IPs de datacenter, então a VM não consegue baixar sozinha. A solução é um pequeno agente HTTP no seu PC de casa (IP residential, que o YouTube aceita) rodando o yt-dlp. A VM alcança esse agente por um túnel SSH reverso.
Isso significa que !play/!add só funcionam com o seu PC ligado e o bridge rodando. Todo o resto (rádio, chat, IA) funciona sem ele. Se não quiser essa dependência, dá pra tocar só a pasta local de músicas e dispensar o YouTube.
Crie uma instância Always Free (a E2.1.Micro, 1 GB de RAM, é a mais fácil de conseguir; a A1 ARM dá mais folga se aparecer vaga). Ubuntu. Instale Node, o Chromium do Playwright e o ffmpeg, mande os arquivos por scp, e registre os dois serviços no systemd pra subirem no boot e reiniciarem sozinhos.
# esqueleto de um serviço systemd (/etc/systemd/system/bot.service)
[Service]
ExecStart=/usr/bin/node /home/ubuntu/bot/bot.js
Restart=always
WorkingDirectory=/home/ubuntu/bot
O Chromium sozinho come ~500 MB. Ative swap (ex.: 2 GB em /swapfile) ou a VM trava. E esqueça 3D/WebGL nessa máquina — a gente tentou, deu out-of-memory. Rode o navegador sem 3D.
O IMVU Next é uma página HTTPS e recusa endereços de stream em HTTP puro — TLS é obrigatório. Mas o Let's Encrypt não emite certificado pra um IP "pelado", e é por isso que o DuckDNS existe: ele te dá um domínio grátis apontando pro IP da VM. Na frente de tudo vai o Caddy, que pega o certificado HTTPS automaticamente e repassa pro stream.
# Caddyfile — repassa 443 pro stream local
seu-nome.duckdns.org {
reverse_proxy localhost:8000 {
flush_interval -1 # ESSENCIAL: sem isso o Caddy segura o buffer e o som trava
}
}
Na Oracle, uma porta só abre se as duas deixarem: o firewall do sistema (iptables) e a "Security List" da OCI. Abra 22, 80 e 443; deixe a 8000 fechada pro público (só o Caddy fala com ela por dentro). E lembre: o IP da Oracle é efêmero — um cron atualizando o DuckDNS a cada 5 min mantém o domínio certo se o IP mudar.
No painel de edição da sua sala no IMVU, cole a URL do stream (https://seu-nome.duckdns.org/stream) no campo de música. Pronto: quem entrar na sala já ouve o rádio. O bot, logado na conta dona da sala, aparece no chat.
Um bot que cai de madrugada não serve. Estas defesas nasceram, uma a uma, de problemas reais:
Quase toda essa lista é fruto de "por que ela sumiu de novo?". Anote seus próprios sintomas — o que parece um bug é quase sempre o IMVU ou o Chromium reagindo a algo específico.
Com a base de pé, o resto é sabor. Ligue um modelo (a gente usa o Gemini, tem tier grátis) pra dar respostas com uma persona; deixe o bot decidir sozinho quando a mensagem é pra ele (respondendo "pular" quando não for, pra não se intrometer). Dá pra adicionar saudações, memória de quem já visitou, conhecimento da própria sala/móveis e uma janela de conversa contínua.
Se usar um modelo com nome tipo -latest, saiba que ele "rola pra frente" sozinho e um dia pode quebrar em silêncio (já aconteceu aqui). Fixe uma versão específica e teste depois de qualquer troca.
As fases acima são como a gente começou — e ensinaram tudo. Este capítulo é o que a gente roda hoje, e ele se banca sozinho: lá embaixo tem um passo a passo do zero que reaproveita as fases que não mudaram e ensina, com calma, a única parte que de fato mudou.
O bot da Fase 0 era um Chromium invisível pilotado pelo Playwright. Funcionava, mas era um mensageiro caríssimo — o navegador inteiro só pra carregar uns recados. Aí a ficha caiu: a "presença" do IMVU na sala é só um protocolo — um WebSocket (o tal IMQ) mais algumas chamadas REST. Dá pra falar esse protocolo direto, sem navegador nenhum.
Foi o que fizemos: engenharia reversa do protocolo — observando os quadros que um navegador real troca com o IMVU, partindo de um build antigo achado no GitHub e lapidando pro nosso uso — e escrevemos um cliente sem navegador ("browserless") que loga, entra na sala, lê o chat, senta, fala e confere os participantes falando IMQ na lata. Mesma conta, mesma sala, mesmos comandos — zero Chromium.
O Chromium sozinho comia ~500 MB (e vazava até dar out-of-memory lá pelas ~19 h de uptime). O cliente em Node puro fica em ~50 MB. De quebra, somem TODAS as gambiarras que só existiam por causa do navegador: o swap obrigatório, o "esqueça 3D/WebGL", as flags anti-throttle "load-bearing", o watchdog de página travada e o "breather" que reiniciava só pra limpar memória. Sem navegador, nada disso precisa existir.
Com o bot tão leve, aquela agonia de "1 GB é pouco" evapora — e vale dizer alto: talvez você nem precise de uma VM. Um PC de casa decente (um Windows 11 com 16 GB de RAM, digamos) roda o bot, o stream e o resto tudo localmente, de sobra. A nuvem grátis servia mesmo era pra ter uma máquina sempre ligada e um endereço público; se a sua casa já resolve isso, todo o esqueleto de cima — Oracle, swap, systemd — vira opcional. Use a nuvem se ela te resolver um problema, não por obrigação. As fases acima são o caminho mais barato, não o único.
E o melhor: o cliente sem navegador reaproveitou quase tudo. O rádio/jukebox (server.js), a ponte do YouTube, a camada de IA e as defesas de sala nunca dependeram do Chromium — só a metade "navegador" do bot virou "protocolo direto". As outras fases seguem valendo palavra por palavra. E foi essa leveza que abriu espaço pra crescer depois (tocar em várias salas ao mesmo tempo, por exemplo, sem a máquina suar).
Você não precisa montar o Chromium pra chegar aqui. Se está começando agora e quer só o que roda hoje, siga esta trilha: os passos que não mudaram apontam de volta pras fases lá em cima (é literalmente o mesmo), e o passo do meio — o coração novo — vem explicado com calma.
O IMQ não é documentado. Você descobre o formato dos eventos observando um login real (as ferramentas de rede do navegador, aba WebSocket) ou partindo de um build de referência — foi o que a gente fez, achando um antigo no GitHub e lapidando. Reserve um tempo pra essa parte; é o único trecho "de detetive" do projeto.
Falar o protocolo direto é leve e rápido, mas é um protocolo não-oficial: se o IMVU mudar os quadros do IMQ, seu cliente quebra e você conserta na mão (um navegador de verdade se adaptaria sozinho). É uma troca consciente — muito mais leve, um tico mais frágil. Aqui valeu demais a pena.
Se ler só uma seção, leia esta. Cada linha custou horas de debug.
A grosso modo, quem faz o quê. Os nomes são os que usamos — o seu pode variar.