Quando um bot do Discord envia um modal para um usuário e o usuário demora mais de três segundos para enviá-lo, a interação falha e o bot não consegue processar o envio. Isso acontece porque o Discord invalida automaticamente qualquer interação de bot que não seja reconhecida em uma janela de 3 segundos. Este artigo explica o motivo técnico por trás desse timeout, fornece as etapas corretas para lidar com envios de modal e aborda padrões de falha relacionados que desenvolvedores de bots encontram com frequência.
Principais conclusões: Como lidar com timeouts de modal do Discord
- Adie a interação dentro de 3 segundos: Use
interaction.deferReply()ouinteraction.deferUpdate()para reconhecer o envio do modal e ganhar tempo para processamento. - Use follow-ups efêmeros: Após adiar, envie a resposta real com
interaction.followUp()para evitar um segundo timeout. - Verifique os custom IDs do modal: Certifique-se de que o bot escuta exatamente o string de custom ID definido no modal para evitar interações não tratadas.
Por que o Discord impõe um timeout de 3 segundos para interações
O sistema de interação do Discord foi projetado para capacidade de resposta em tempo real. Quando um usuário clica em um botão, seleciona uma opção de menu ou envia um modal, o Discord espera que o bot reconheça essa interação em até três segundos. Se o bot não responder a tempo, o Discord considera a interação expirada e o bot recebe um erro HTTP 400 com a mensagem “interaction failed”. Esse timeout não é um bug — é uma escolha de design deliberada para evitar que bots mantenham interfaces de usuário abertas indefinidamente.
O limite de 3 segundos se aplica apenas ao reconhecimento inicial. Após o bot reconhecer a interação, ele tem até 15 minutos para enviar mensagens de acompanhamento usando o token da interação. O ponto chave é que o reconhecimento deve acontecer dentro dos primeiros três segundos. Envios de modal são particularmente propensos a esse timeout porque o bot muitas vezes precisa validar dados, consultar um banco de dados ou chamar uma API externa antes de responder. Se qualquer uma dessas operações levar mais de três segundos, a interação falha silenciosamente da perspectiva do usuário — o modal fecha, mas nenhum feedback aparece.
Outra causa comum é usar interaction.reply() diretamente com uma operação de longa duração. O método reply() do Discord reconhece e envia uma resposta em uma única chamada. Se o conteúdo da resposta não estiver pronto em três segundos, toda a interação falha. A abordagem correta é separar o reconhecimento da resposta usando métodos de adiamento.
Etapas para corrigir timeouts de envio de modal em bots do Discord
A solução envolve duas partes: reconhecer a interação dentro de três segundos e depois enviar a resposta real como um follow-up. As etapas a seguir assumem que você está usando discord.js versão 14 ou posterior e tem um bot básico que pode receber modais.
Passo 1: Adie o envio do modal imediatamente
- Use
interaction.deferReply()para novas mensagens
Dentro do seu manipulador de envio de modal, chameawait interaction.deferReply({ ephemeral: true })como a primeira linha. Isso informa ao Discord que o bot recebeu a interação e responderá em breve. A opçãoephemeral: trueoculta a resposta de outros usuários no canal. - Use
interaction.deferUpdate()para mensagens existentes
Se o modal foi acionado a partir de um botão ou menu de seleção em uma mensagem existente, useawait interaction.deferUpdate()em vez disso. Isso reconhece a interação sem enviar uma nova mensagem. Você pode editar a mensagem original com os resultados posteriormente. - Adicione tratamento de erros para adiamentos com falha
Envolva o adiamento em um bloco try-catch. Se o adiamento lançar um erro (por exemplo, porque a interação já expirou), registre-o e saia do manipulador graciosamente. Exemplo:try { await interaction.deferReply(); } catch (e) { console.error('Adiamento falhou:', e); return; }
Passo 2: Execute sua lógica de processamento
- Realize validação de dados e chamadas externas
Após adiar, você tem até 15 minutos para concluir sua lógica. Valide campos do modal, consulte um banco de dados ou chame uma API REST. O usuário vê um estado de carregamento no cliente do Discord enquanto espera. - Use
interaction.followUp()para enviar a resposta
Assim que o processamento for concluído, envie o resultado comawait interaction.followUp({ content: 'Seu envio foi salvo.', ephemeral: true }). Isso envia uma nova mensagem como follow-up da interação adiada. Não useinteraction.reply()após adiar — isso lançará um erro.
Passo 3: Corresponda o Custom ID corretamente
- Defina um custom ID único ao criar o modal
Ao criar o objeto modal, atribua um string à propriedadecustomId, por exemplonew ModalBuilder().setCustomId('feedback_modal'). Esse ID deve ser único no escopo do seu bot. - Escute exatamente esse custom ID no manipulador
No seu evento de criação de interação, filtre porinteraction.customId === 'feedback_modal'. Se o ID não corresponder, o bot ignora o envio e a interação expira. Use uma convenção de nomenclatura consistente para evitar erros de digitação.
Se os modais do Discord ainda expirarem após a correção principal
Bot fica offline durante o processamento do modal
Se o seu bot travar ou desconectar entre o adiamento e o follow-up, a interação expirará após 15 minutos. O usuário não vê nenhuma mensagem de erro. Para evitar isso, adicione um fallback que edite a resposta adiada para uma mensagem de erro genérica se a lógica principal lançar uma exceção não tratada. Use um try-catch em todo o bloco de processamento e chame interaction.editReply() dentro do catch.
Modal fecha, mas nenhuma resposta aparece
Isso geralmente significa que o bot nunca chamou deferReply() ou deferUpdate(), ou a própria chamada de adiamento levou mais de três segundos. Verifique se o seu manipulador não contém operações síncronas bloqueantes — por exemplo, fs.readFileSync() ou um loop for longo — antes do adiamento. Mova todo o trabalho pesado para depois do adiamento.
Múltiplos modais abertos ao mesmo tempo
O Discord permite apenas um modal aberto por usuário por cliente. Se um usuário abrir um segundo modal enquanto o primeiro ainda está ativo, o primeiro modal é descartado e sua interação é invalidada. O bot pode receber um envio para o segundo modal, mas o primeiro é perdido. Eduque os usuários a enviar um modal de cada vez, ou implemente um cooldown que impeça a abertura de um novo modal até que o anterior seja resolvido.
Métodos de reconhecimento de interação do Discord: Defer vs Reply vs Follow-Up
| Método | DeferReply | Reply |
|---|---|---|
| Propósito | Reconhecer interação sem enviar resposta imediatamente | Reconhecer interação e enviar resposta em uma chamada |
| Limite de tempo | 3 segundos para chamar; 15 minutos para follow-up | 3 segundos para concluir toda a chamada |
| Tipo de resposta | Deve usar followUp() ou editReply() após adiar |
Resposta enviada imediatamente; nenhum follow-up necessário |
| Caso de uso | Consultas longas ao banco de dados, uploads de arquivos, chamadas de API externas | Respostas instantâneas como confirmações simples ou erros |
Os envios de modal do Discord falham com um timeout de interação de 3 segundos porque o bot não reconhece a interação dentro da janela exigida. Ao chamar interaction.deferReply() ou interaction.deferUpdate() como a primeira ação no seu manipulador de modal, você estende a janela de resposta para 15 minutos. Após o processamento, use interaction.followUp() para enviar o resultado. Para maior confiabilidade, envolva seu manipulador em um try-catch e forneça uma mensagem de fallback se a lógica principal falhar. Teste seu bot com uma simulação de rede lenta para confirmar que o adiamento funciona antes de qualquer operação bloqueante.