如何在discord.py斜杠命令响应中添加按钮(Python3.8)
问题解决与实现方案
错误原因分析
你遇到的TypeError核心原因有两个:
- 参数名误用:discord.py v2.x中,发送带组件的消息需要用
view参数,而非你写的components; - 组件格式错误:按钮必须包裹在
discord.ui.View实例中才能被正确识别,不能直接传入按钮列表;
额外问题:ctx.response.send_message是异步方法,必须添加await关键字。
完整修改代码
以下是修正后的代码,同时实现条款同意检查、带按钮的提示消息以及同意状态保存功能,全程避免使用自定义类:
import discord, json, os from discord.ext import commands from discord import app_commands, ButtonStyle from discord.ui import Button, View from typing import Optional TOKEN='your_token_here' intents=discord.Intents.default() intents.message_content=True client=commands.Bot(command_prefix='!', case_insensitive=True, intents=intents) tree=client.tree # 获取用户同意状态文件路径 USER_AGREE_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'botconfig', 'imageusers.json') # 确保文件及父目录存在 os.makedirs(os.path.dirname(USER_AGREE_FILE), exist_ok=True) if not os.path.exists(USER_AGREE_FILE): with open(USER_AGREE_FILE, 'w') as f: json.dump([], f) @tree.command(name="image", description="Generates an image using stable diffusion", guild=discord.Object(id=1140580736412434472)) async def image(ctx, prompt: str, replyprivately: Optional[bool] = False): print(f'{ctx.user.name} added {prompt} to the queue.') # 读取已同意用户列表 with open(USER_AGREE_FILE, 'r') as f: agreed_users = json.load(f) if ctx.user.id not in agreed_users: # 定义按钮回调函数 async def agree_button_callback(interaction): # 仅允许发起命令的用户点击按钮 if interaction.user.id != ctx.user.id: await interaction.response.send_message("这不是你的同意请求,请自行发起/image命令", ephemeral=True) return # 更新同意列表 agreed_users.append(ctx.user.id) with open(USER_AGREE_FILE, 'w') as f: json.dump(agreed_users, f) # 回复用户并删除原提示消息 await interaction.response.send_message("你已同意条款,现在可以使用/image命令生成图片了", ephemeral=True) await ctx.delete_original_response() # 创建按钮并绑定回调 agree_button = Button(style=ButtonStyle.primary, label='我同意条款', custom_id="Confirm image") agree_button.callback = agree_button_callback # 创建View容器并添加按钮 view = View() view.add_item(agree_button) # 发送带按钮的隐私提示消息 await ctx.response.send_message( "我们使用的部分模型可能生成NSFW内容,请确认你已了解相关风险并同意条款", view=view, ephemeral=True ) return # 用户已同意,执行图片生成逻辑 await ctx.response.send_message(f"开始生成图片:{prompt}", ephemeral=replyprivately) # 此处添加你的图片生成代码 client.run(TOKEN)
关键修改点说明
- 按钮与View的正确使用:将按钮添加到
View实例中,通过view参数传入消息发送方法; - 异步方法调用:给
ctx.response.send_message添加await关键字; - 按钮回调绑定:直接给按钮的
callback属性赋值异步函数,避免自定义类; - 用户权限校验:确保只有发起命令的用户能点击按钮;
- 状态持久化:自动创建并维护用户同意状态的JSON文件,避免重复提示。
内容的提问来源于stack exchange,提问作者DaCosySheeep
相关产品推荐
相关产品推荐

