使用discord.py为Discord机器人斜杠命令加按钮失败求助
问题分析与解决
你的代码报错核心原因有两个:
- 组件类引用错误:discord.py v2.x中,按钮、行组件都放在
discord.ui模块下,而非直接调用discord.Button/discord.ActionRow - 组件交互响应写法存在问题,同时可能使用了不支持该特性的旧版本discord.py
第一步:确认并更新discord.py版本
确保安装的是v2.0及以上版本,执行命令更新:
pip install -U discord.py
修正后的代码方案(适配你的原有写法)
import discord from discord import app_commands intents = discord.Intents.all() client = discord.Client(intents=intents) tree = app_commands.CommandTree(client) # 替换为你的服务器ID(整数类型) croc = discord.Object(id=你的服务器ID) @tree.command(name="hello", description="发送带按钮的问候消息", guild=croc) async def hello(ctx: app_commands.Context): # 使用discord.ui下的组件类 button1 = discord.ui.Button(label="Hello", custom_id="hello") button2 = discord.ui.Button(label="World", custom_id="world") # ActionRow需传入组件列表 action_row = discord.ui.ActionRow(button1, button2) await ctx.response.send_message("点击一个按钮!", components=[action_row]) @client.event async def on_interaction(interaction: discord.Interaction): if interaction.type == discord.InteractionType.component: custom_id = interaction.data.get("custom_id") if not custom_id: return if custom_id == "hello": await interaction.response.send_message("你点击了Hello按钮!", ephemeral=True) elif custom_id == "world": await interaction.response.send_message("你点击了World按钮!", ephemeral=True) @client.event async def on_ready(): await tree.sync(guild=croc) print(f"已登录为 {client.user}") client.run("你的机器人令牌")
更规范的写法(使用View绑定回调)
discord.py推荐用discord.ui.View管理组件和回调,代码更清晰易维护:
import discord from discord import app_commands intents = discord.Intents.all() client = discord.Client(intents=intents) tree = app_commands.CommandTree(client) croc = discord.Object(id=你的服务器ID) class HelloView(discord.ui.View): def __init__(self): super().__init__(timeout=None) # 设置timeout=None让按钮永久有效 @discord.ui.button(label="Hello", custom_id="hello") async def hello_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message("你点击了Hello按钮!", ephemeral=True) @discord.ui.button(label="World", custom_id="world") async def world_button(self, interaction: discord.Interaction, button: discord.ui.Button): await interaction.response.send_message("你点击了World按钮!", ephemeral=True) @tree.command(name="hello", description="发送带按钮的问候消息", guild=croc) async def hello(ctx: app_commands.Context): await ctx.response.send_message("点击一个按钮!", view=HelloView()) @client.event async def on_ready(): await tree.sync(guild=croc) # 若设置timeout=None,需将View注册到客户端 client.add_view(HelloView()) print(f"已登录为 {client.user}") client.run("你的机器人令牌")
注意:
- 替换代码中的
你的服务器ID和你的机器人令牌为实际值 - 若需全局命令,去掉
guild=croc参数,同步时也移除该参数
内容的提问来源于stack exchange,提问作者ICHi
相关产品推荐
相关产品推荐

