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

Discord频道点击按钮未触发on_button_click代码执行问题排查

问题原因与解决方案

问题根源

你用@bot.event装饰了on_button_click函数,但discord.py中不存在on_button_click这个内置事件,所以按钮点击后该函数永远不会被触发,终端自然没有输出。

正确实现方式

discord.py处理按钮交互的标准方式是给按钮绑定回调函数,或通过on_interaction事件统一处理,推荐前者,更清晰易维护:

方式一:给按钮绑定回调(推荐)

修改open_ticket命令的代码,给按钮添加回调逻辑:

@bot.command()
async def open_ticket(ctx):
    print("hello function executed")
    
    # 定义按钮点击后的回调逻辑
    async def button_callback(interaction: discord.Interaction):
        print(f"Button clicked by {interaction.user}")
        if interaction.component.custom_id == "openTicket":
            print("Button clicked")
            user = interaction.user
            guild = interaction.guild
            channel_name = f"{user.name}'s Ticket"
            overwrites = {
                guild.default_role: discord.PermissionOverwrite(read_messages=False),
                user: discord.PermissionOverwrite(read_messages=True)
            }
            new_channel = await guild.create_text_channel(channel_name, overwrites=overwrites)
            await interaction.respond(content=f"Hello {user.mention}! Your ticket has been created in {new_channel.mention}.")
    
    view = discord.ui.View(timeout=None)
    button = discord.ui.Button(label="Open Ticket", custom_id="openTicket")
    # 给按钮绑定回调函数
    button.callback = button_callback
    view.add_item(button)
    bot.add_view(view)
    await ctx.send("Click the button to open a new support ticket.", view=view)

之后删除原来的on_button_click函数即可。

方式二:使用on_interaction事件统一处理

如果需要统一处理所有交互组件,可以替换原on_button_click为on_interaction事件:

@bot.event
async def on_interaction(interaction: discord.Interaction):
    # 仅处理按钮类型的交互
    if isinstance(interaction.data, dict) and interaction.data.get("component_type") == 2:
        print(f"Button clicked by {interaction.user}")
        custom_id = interaction.data.get("custom_id")
        if custom_id == "openTicket":
            print("Button clicked")
            user = interaction.user
            guild = interaction.guild
            channel_name = f"{user.name}'s Ticket"
            overwrites = {
                guild.default_role: discord.PermissionOverwrite(read_messages=False),
                user: discord.PermissionOverwrite(read_messages=True)
            }
            new_channel = await guild.create_text_channel(channel_name, overwrites=overwrites)
            await interaction.respond(content=f"Hello {user.mention}! Your ticket has been created in {new_channel.mention}.")

这种方式适合多组件统一管理的场景,但单按钮场景下不如第一种直观。

额外注意点

  • 确保你的discord.py版本为v2.x及以上,组件交互是该版本引入的特性。
  • 你已设置view.timeout = None并调用bot.add_view(view),这部分逻辑正确,能保证机器人重启后仍能响应旧按钮的点击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:01:12