Por que o bot do Discord desconecta do canal de voz após 2 minutos de inatividade
🔍 WiseChecker

Por que o bot do Discord desconecta do canal de voz após 2 minutos de inatividade

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.

ADVERTISEMENT

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.

  1. 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 de struct para construir o quadro PCM silencioso e io para a fonte FFmpegPCMAudio.
  2. Crie uma fonte de áudio silenciosa
    Defina uma função que retorna um objeto discord.FFmpegPCMAudio reproduzindo um arquivo WAV silencioso. A abordagem mais simples é gerar um quadro PCM silencioso de 20 milissegundos na memória. Use discord.FFmpegPCMAudio(io.BytesIO(silent_wav_bytes)) onde silent_wav_bytes é um cabeçalho WAV válido mais 1764 bytes de zeros (44,1 kHz, 16 bits, mono).
  3. Inicie uma tarefa em segundo plano para reproduzir silêncio
    Após conectar a um canal de voz, inicie um asyncio.create_task que faz um loop a cada 60 segundos. Dentro do loop, chame voice_client.play(silent_source). Isso redefine o temporizador de inatividade. A tarefa deve capturar asyncio.CancelledError quando o bot desconectar.
  4. Cancele a tarefa na desconexão
    Sobrescreva o evento on_voice_state_update para detectar quando o bot sai do canal. Cancele a tarefa em segundo plano usando task.cancel() para evitar vazamento de recursos.
  5. 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 status voice_client.is_connected().

ADVERTISEMENT

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.

  1. Instale as dependências
    Certifique-se de ter @discordjs/voice e ffmpeg-static instalados. Execute npm install @discordjs/voice ffmpeg-static.
  2. Crie um recurso de áudio silencioso
    Crie um arquivo WAV silencioso de 20 milissegundos usando Node.js fs e child_process. Alternativamente, use um arquivo silencioso pré-gerado na pasta do seu projeto. Carregue-o com createAudioResource('silence.wav').
  3. Reproduza silêncio em um loop
    Após entrar em um canal com joinVoiceChannel, use player.play(resource) dentro de um setInterval que executa a cada 60 segundos. Use player.stop() antes de reproduzir para evitar sobreposição de áudio.
  4. Limpe o intervalo na desconexão
    Escute o evento stateChange no VoiceConnection. Quando o status se tornar VoiceConnectionStatus.Disconnected, limpe o intervalo com clearInterval.

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.

ADVERTISEMENT

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.

ADVERTISEMENT