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

如何在discord.py斜杠命令响应中添加按钮(Python3.8)

问题解决与实现方案

错误原因分析

你遇到的TypeError核心原因有两个:

  1. 参数名误用:discord.py v2.x中,发送带组件的消息需要用view参数,而非你写的components;
  2. 组件格式错误:按钮必须包裹在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:24:52