Se o seu bot do Discord perde a conexão de voz após aproximadamente dois minutos de silêncio, você está enfrentando um tempo limite de inatividade integrado imposto pelo Discord. Esse tempo limite foi projetado para liberar recursos do servidor quando nenhum dado de áudio está sendo transmitido. A desconexão não é um bug ou um problema de hardware — é um comportamento deliberado do gateway de voz do Discord. Este artigo explica o mecanismo técnico por trás da desconexão por inatividade de 2 minutos e fornece estratégias concretas de codificação para manter seu bot conectado.
Principais conclusões: Mantendo o canal de voz do seu bot do Discord ativo
- discord.py voice_client.idle_timeout: O temporizador interno que aciona a desconexão após 120 segundos de silêncio.
- discord.py VoiceClient.play() com áudio silencioso: Enviar um quadro de áudio silencioso redefine o temporizador de inatividade sem ruído audível.
- discord.js VoiceConnection.receiver.speaking.started event: Um listener que pode redefinir o tempo limite de inatividade quando os usuários falam.
Por que o Discord desconecta bots de voz inativos após 2 minutos
A infraestrutura de voz do Discord usa um gateway baseado em WebSocket para transmitir áudio em tempo real. Cada conexão de voz mantém uma máquina de estados que rastreia se o áudio está sendo ativamente enviado ou recebido. Quando nenhum pacote de áudio é transmitido por 120 segundos, o servidor do Discord fecha a conexão WebSocket com um código de fechamento específico (4015 para tempo limite de inatividade). Esse comportamento economiza largura de banda e poder de processamento no lado do Discord, especialmente em servidores grandes onde muitos bots poderiam manter conexões abertas indefinidamente.
O tempo limite se aplica tanto a clientes de usuário quanto a contas de bot, mas os usuários raramente notam porque geralmente estão em conversas ativas. Bots, no entanto, frequentemente ficam em silêncio em um canal aguardando um comando. O temporizador de inatividade é redefinido cada vez que o bot envia um pacote de áudio (mesmo um silencioso) ou recebe áudio de outro usuário. Simplesmente estar no canal não redefine o temporizador — o bot deve participar ativamente do fluxo de áudio.
Detalhes técnicos do tempo limite de inatividade
O tempo limite é aplicado no nível do gateway de voz do Discord, não na biblioteca do bot. O opcode de gateway relevante é Voice Speaking (opcode 5) e o Voice Heartbeat (opcode 3). Heartbeats mantêm o WebSocket ativo, mas não redefinem o temporizador de inatividade. Apenas dados de áudio (quadros PCM) o redefinem. No discord.py, o objeto VoiceClient tem um atributo interno idle_timeout (padrão 120 segundos) e um _idle_timer que aciona disconnect() quando o tempo limite expira. No discord.js, o VoiceConnection emite um evento disconnect com o motivo idle.
Passos para evitar desconexão por inatividade no discord.py
O método mais confiável é enviar um quadro de áudio silencioso em intervalos menores que 120 segundos. Abaixo está uma implementação completa usando discord.py 2.x.
- Importe os módulos necessários
Adicione estas importações no início do seu script do bot:import discord, asyncio, struct, io. Você precisa destructpara construir o quadro PCM silencioso eiopara a fonteFFmpegPCMAudio. - Crie uma fonte de áudio silenciosa
Defina uma função que retorna um objetodiscord.FFmpegPCMAudioreproduzindo um arquivo WAV silencioso. A abordagem mais simples é gerar um quadro PCM silencioso de 20 milissegundos na memória. Usediscord.FFmpegPCMAudio(io.BytesIO(silent_wav_bytes))ondesilent_wav_bytesé um cabeçalho WAV válido mais 1764 bytes de zeros (44,1 kHz, 16 bits, mono). - Inicie uma tarefa em segundo plano para reproduzir silêncio
Após conectar a um canal de voz, inicie umasyncio.create_taskque faz um loop a cada 60 segundos. Dentro do loop, chamevoice_client.play(silent_source). Isso redefine o temporizador de inatividade. A tarefa deve capturarasyncio.CancelledErrorquando o bot desconectar. - Cancele a tarefa na desconexão
Sobrescreva o eventoon_voice_state_updatepara detectar quando o bot sai do canal. Cancele a tarefa em segundo plano usandotask.cancel()para evitar vazamento de recursos. - Teste a conexão
Entre em um canal de voz com seu bot e aguarde 3 minutos. O bot deve permanecer conectado. Verifique usando o statusvoice_client.is_connected().
Passos para evitar desconexão por inatividade no discord.js
No discord.js, você pode usar o receptor VoiceConnection para detectar quando os usuários falam e redefinir o tempo limite, ou enviar quadros silenciosos usando createAudioResource com um arquivo silencioso.
- Instale as dependências
Certifique-se de ter@discordjs/voiceeffmpeg-staticinstalados. Executenpm install @discordjs/voice ffmpeg-static. - Crie um recurso de áudio silencioso
Crie um arquivo WAV silencioso de 20 milissegundos usando Node.jsfsechild_process. Alternativamente, use um arquivo silencioso pré-gerado na pasta do seu projeto. Carregue-o comcreateAudioResource('silence.wav'). - Reproduza silêncio em um loop
Após entrar em um canal comjoinVoiceChannel, useplayer.play(resource)dentro de umsetIntervalque executa a cada 60 segundos. Useplayer.stop()antes de reproduzir para evitar sobreposição de áudio. - Limpe o intervalo na desconexão
Escute o eventostateChangenoVoiceConnection. Quando o status se tornarVoiceConnectionStatus.Disconnected, limpe o intervalo comclearInterval.
Se o bot ainda desconectar após aplicar a correção principal
Bot desconecta devido a picos de latência de rede
Mesmo que você envie quadros silenciosos, um problema repentino de rede pode fechar o WebSocket. Verifique o ping do seu bot para o Discord usando voice_client.ping no discord.py ou voiceConnection.ping no discord.js. Se o ping exceder 500 ms, o gateway pode desconectar. Use um servidor mais próximo das regiões de voz do Discord ou implemente um loop de reconexão que chame voice_client.connect() novamente.
Bot desconecta após uma atualização do Discord
O Discord ocasionalmente altera a duração do tempo limite de inatividade ou o código de fechamento. Em 2023, o tempo limite foi reduzido de 3 minutos para 2 minutos em algumas regiões. Sempre verifique a documentação de Conexões de Voz do Discord Developer para os valores mais recentes de tempo limite. Atualize sua biblioteca do bot para a versão mais recente para lidar com novos códigos de fechamento.
Bot desconecta quando não há usuários no canal
O tempo limite de inatividade se aplica independentemente de quantos usuários estão presentes. Se o seu bot estiver sozinho em um canal, a mesma regra de 2 minutos se aplica. O método de quadro silencioso funciona aqui também. Para bots que só precisam ouvir comandos, considere usar um gatilho de canal de texto e entrar no canal de voz apenas quando necessário, depois sair após o comando terminar. Isso evita completamente o tempo limite de inatividade.
Comparação: Soluções alternativas para tempo limite de inatividade no discord.py vs discord.js
| Item | discord.py | discord.js |
|---|---|---|
| Método de quadro silencioso | Use FFmpegPCMAudio com um WAV silencioso na memória |
Use createAudioResource com um arquivo silencioso |
| Mecanismo de loop | asyncio.create_task com while True e asyncio.sleep(60) |
setInterval com 60000 ms |
| Limpeza na desconexão | Capture on_voice_state_update e cancele a tarefa |
Escute o evento stateChange e limpe o intervalo |
| Redefinição baseada em receptor | Não suportado nativamente; requer rastreamento manual com on_voice_state_update |
Use o evento VoiceConnection.receiver.speaking.started |
| Versão da biblioteca testada | discord.py 2.3.2 | discord.js 14.14.1 com @discordjs/voice 0.17.0 |
Bots do Discord desconectam de canais de voz após 2 minutos de inatividade devido a um tempo limite deliberado no lado do servidor que conserva recursos. Você pode evitar isso enviando quadros de áudio silenciosos em intervalos regulares usando os métodos descritos acima. Para discord.py, use FFmpegPCMAudio com um WAV silencioso em uma tarefa em segundo plano. Para discord.js, use createAudioResource com um arquivo silencioso em um setInterval. Se o bot ainda desconectar, verifique a latência da rede e atualize sua biblioteca. Uma abordagem mais avançada é usar o método VoiceClient.reconnect() para reconectar automaticamente ao canal após uma desconexão por inatividade, embora isso possa causar uma breve interrupção no áudio.