You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py按钮点击事件无响应问题求助

Discord按钮点击事件无法捕获,触发超时且显示“交互失败”

我写了一个测试按钮命令,但机器人始终无法捕获按钮点击事件,即使移除检查条件、自定义ID等设置,仍会触发超时,点击按钮后显示“交互失败”。我希望在命令内保留按钮及事件监听逻辑,点击按钮后机器人能发送“You pressed the button!”,但实际总是触发超时。

测试代码如下:

@tree.command(name="button", description="testing")
async def button(interaction):
    view = discord.ui.View()  # make a view
    style = discord.ButtonStyle.primary  # makes the button blue
    item = discord.ui.Button(style=style, label="Click to continue!", custom_id="continue_button")  # make the button
    view.add_item(item=item)  # add button to view
    await interaction.response.send_message("Waiting until you press the button!", view=view)  # send message with button

    def check(i):
        return i.user.id == interaction.user.id and i.custom_id == "continue_button"

    try:
        interaction, button = await client.wait_for("button_click", check=check, timeout=10)
        # when button is pressed
        await interaction.channel.send("You pressed the button!")
    except asyncio.TimeoutError:
        # button wasn't pressed before timeout
        await interaction.channel.send("You didn't press the button within the specified time.")

问题原因

discord.py v2.0及以上版本已移除button_click事件,改用View类绑定回调函数的方式处理按钮交互。你使用client.wait_for监听已废弃的事件,自然无法捕获点击,导致超时;同时未对按钮交互做出响应,Discord会判定为“交互失败”。

修复方案(两种方式)

方式1:使用View回调函数(推荐,符合v2.x规范)

将按钮逻辑封装在View类中,绑定回调函数处理点击:

import discord
from discord import app_commands

class ContinueView(discord.ui.View):
    def __init__(self, user_id):
        super().__init__(timeout=10)
        self.user_id = user_id

    async def interaction_check(self, interaction: discord.Interaction) -> bool:
        # 仅允许命令发起者点击按钮
        return interaction.user.id == self.user_id

    @discord.ui.button(label="Click to continue!", style=discord.ButtonStyle.primary, custom_id="continue_button")
    async def continue_button(self, interaction: discord.Interaction, button: discord.ui.Button):
        # 响应按钮交互,避免“交互失败”提示
        await interaction.response.send_message("You pressed the button!", ephemeral=False)
        self.stop()  # 终止View超时计时

@tree.command(name="button", description="testing")
async def button(interaction: discord.Interaction):
    view = ContinueView(user_id=interaction.user.id)
    await interaction.response.send_message("Waiting until you press the button!", view=view)
    
    # 等待View结束(按钮点击或超时)
    await view.wait()
    if not view.children[0].disabled:
        # 超时处理:禁用按钮并更新原消息
        view.children[0].disabled = True
        await interaction.edit_original_response(view=view)
        await interaction.followup.send("You didn't press the button within the specified time.")

方式2:保留命令内监听逻辑(使用view.wait())

如果想在命令函数内处理后续逻辑,可通过标记变量记录按钮状态:

import discord
from discord import app_commands
import asyncio

@tree.command(name="button", description="testing")
async def button(interaction: discord.Interaction):
    view = discord.ui.View(timeout=10)
    button_clicked = False
    clicked_interaction = None

    async def button_callback(i: discord.Interaction):
        nonlocal button_clicked, clicked_interaction
        button_clicked = True
        clicked_interaction = i
        await i.response.send_message("You pressed the button!", ephemeral=False)
        view.stop()

    item = discord.ui.Button(style=discord.ButtonStyle.primary, label="Click to continue!", custom_id="continue_button")
    item.callback = button_callback
    view.add_item(item)

    await interaction.response.send_message("Waiting until you press the button!", view=view)
    
    # 等待View超时或按钮点击
    await view.wait()
    
    if not button_clicked:
        # 超时处理:禁用按钮并提示
        view.children[0].disabled = True
        await interaction.edit_original_response(view=view)
        await interaction.followup.send("You didn't press the button within the specified time.")

关键改动说明

  1. 替换废弃事件:弃用client.wait_for("button_click"),改用View回调或view.wait()实现等待逻辑
  2. 强制交互响应:按钮点击后必须调用interaction.response相关方法,否则Discord会显示“交互失败”
  3. 用户验证:通过interaction_check或回调内判断,确保只有命令发起者能操作按钮
  4. 超时优化:利用View自带的timeout参数,超时后禁用按钮并更新原消息,避免无效按钮残留

内容的提问来源于stack exchange,提问作者IceFire03

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 20:13:16