
Discord.py 中按钮(Button)在发送后约3分钟自动失效,导致“Interaction failed”错误;根本原因是 View 默认 180 秒超时,需显式设置 timeout=None 或启用持久化视图以支持重启后继续响应。
discord.py 中按钮(button)在发送后约3分钟自动失效,导致“interaction failed”错误;根本原因是 view 默认 180 秒超时,需显式设置 `timeout=none` 或启用持久化视图以支持重启后继续响应。
你遇到的 Interaction failed 错误并非代码逻辑错误,而是 Discord.py 的设计机制所致:所有 discord.ui.View 实例默认具有 180 秒(3 分钟)的自动超时。一旦超过该时限,View 中的按钮将不再响应点击事件,Discord 会返回 “Interaction failed” —— 这正是 /add_button 发送的按钮在 5 分钟后失效的根本原因。
✅ 正确修复:禁用超时或启用持久化
1. 禁用超时(适用于短期有效场景)
只需在 SuggestionButtonView 类定义中传入 timeout=None:
class SuggestionButtonView(discord.ui.View):
def __init__(self):
# 显式禁用超时:按钮永久有效(直到 bot 进程结束)
super().__init__(timeout=None)
@discord.ui.button(label="Enviar Sugestão", style=discord.ButtonStyle.primary, custom_id="send_suggestion")
async def button_click(self, interaction: discord.Interaction, button: discord.ui.Button):
modal = SuggestionModal()
await interaction.response.send_modal(modal)
⚠️ 注意:timeout=None 仅保证 View 在 bot 运行期间持续有效;bot 重启后,所有已发送的 View 将丢失状态,按钮仍会失效(因为内存中 View 实例已被销毁)。
2. 启用持久化视图(推荐用于生产环境)
若需按钮在 bot 重启后依然可用,必须使用 Persistent View —— 即通过 custom_id 唯一标识 View,并在 bot 启动时通过 bot.add_view() 注册:
✅ 修改 View 类(添加 @discord.ui.view 装饰器不必要,关键在 custom_id + timeout=None + 启动时注册):
class SuggestionButtonView(discord.ui.View):
def __init__(self):
# timeout=None 是持久化前提之一
super().__init__(timeout=None)
@discord.ui.button(label="Enviar Sugestão", style=discord.ButtonStyle.primary, custom_id="persistent_send_suggestion")
async def button_click(self, interaction: discord.Interaction, button: discord.ui.Button):
modal = SuggestionModal()
await interaction.response.send_modal(modal)
✅ 在 bot 启动完成事件中注册该 View(确保它能恢复已发送消息的交互能力):
@bot.event
async def on_ready():
print(f'Bot {bot.user} está online.')
# 必须在 on_ready 中注册 View,且 custom_id 需与按钮完全一致
bot.add_view(SuggestionButtonView())
✅ 同时,修改 /add_button 命令,确保每次发送都使用同一类实例(无需新建 View,但可新建):
@bot.tree.command(name='add_button', description='Adicione um botão para enviar sugestões。')
@app_commands.checks.check(check_roles)
async def add_button(interaction: discord.Interaction):
try:
embed = discord.Embed(
title="Envie sua Sugestão",
description="Clique no botão abaixo para enviar sua sugestão!\n\n Com seu feedback conseguimos melhorar em vários aspectos!",
color=discord.Color.gold()
)
embed.set_author(name="Sistema de Sugestões")
embed.set_image(url="https://cdn.discordapp.com/attachments/...") # 保持原图链接
embed.set_footer(text="BOT Powered by Rodopoulos")
view = SuggestionButtonView() # 每次创建新实例(不影响持久化)
await interaction.response.send_message(embed=embed, view=view)
except Exception as e:
print(f"Erro ao adicionar botão de sugestões: {e}")
await interaction.response.send_message("Erro ao adicionar botão de sugestões。 Por favor, tente novamente mais tarde。", ephemeral=True)
? 补充注意事项
- custom_id 必须全局唯一且不可变更:一旦用于持久化 View,后续任何修改(如拼写错误、大小写变化)都会导致恢复失败。
- 不要重复调用 bot.add_view():仅在 on_ready 中注册一次即可;重复注册会引发警告或冲突。
- Modal 和 Button 无超时限制:Modal 提交本身不受 View 超时影响,只要用户在 Modal 弹出后及时填写即可。
- 日志排查建议:启用 discord 日志级别为 INFO 或 DEBUG,可捕获 View 恢复失败、interaction 超时等底层信息。
通过以上配置,你的“Enviar Sugestão”按钮将稳定运行,既解决短期超时问题,也具备生产级的重启容灾能力。











