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
相关产品推荐
相关产品推荐

