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

如何在discord.py的bot.tree中模拟内置help命令功能

解决方案

你的核心问题在于原代码混用了前缀命令的HelpCommand体系和斜杠命令(app_commands)的对象结构,且/help斜杠命令的调用逻辑错误。以下是完整的修复实现:

修复后代码

import discord
from discord import app_commands
import random
from discord.ext import commands

# 替换为你实际的配置
prefix = "!"
master_guild = 1234567890  # 你的主服务器ID

# 禁用前缀命令的help功能,完全用斜杠命令实现
bot = commands.Bot(command_prefix=prefix, intents=discord.Intents.all(), help_command=None)

@bot.event
async def on_ready():
    try:
        synced = await bot.tree.sync()
        print(f"Synced {len(synced)} command{'s' if len(synced) > 1 else ''}.")
    except Exception as e:
        print(f"Error syncing commands: {e}")

@bot.tree.command(description="查看所有斜杠命令或指定命令的详细信息")
@app_commands.describe(command="要查看详情的命令名称")
async def help(ctx: discord.Interaction, command: str = None):
    # 仅允许在指定服务器使用
    if ctx.guild.id != master_guild:
        await ctx.response.send_message("此命令仅在指定服务器可用", ephemeral=True)
        return
    
    if command is None:
        # 展示所有已注册的斜杠命令
        all_commands = bot.tree.get_commands()
        if not all_commands:
            await ctx.response.send_message("暂无已注册的斜杠命令", ephemeral=True)
            return
        
        cmd_list = [f"- `/ {cmd.name}`: {cmd.description or '无描述'}" for cmd in all_commands]
        embed = discord.Embed(
            title=f"所有斜杠命令 ({len(all_commands)})",
            description="\n".join(cmd_list),
            color=discord.Color.blue()
        )
        embed.set_footer(text=f"使用 `/help <命令名>` 查看详情,例:/help {random.choice(all_commands).name}")
        await ctx.response.send_message(embed=embed)
    else:
        # 查找指定命令并展示详情
        target_cmd = None
        for cmd in bot.tree.get_commands():
            if cmd.name.lower() == command.lower():
                target_cmd = cmd
                break
        
        if not target_cmd:
            await ctx.response.send_message(f"未找到命令 `/{command}`", ephemeral=True)
            return
        
        # 构建命令详情嵌入
        embed = discord.Embed(
            title=f"/{target_cmd.name}",
            description=target_cmd.description or "无描述",
            color=discord.Color.green()
        )
        
        # 生成使用方法(区分必填/可选参数)
        usage_parts = [f"/{target_cmd.name}"]
        for param in target_cmd.parameters:
            if param.required:
                usage_parts.append(f"<{param.name}>")
            else:
                usage_parts.append(f"[{param.name}]")
        embed.add_field(name="使用方法", value=f"`{' '.join(usage_parts)}`", inline=False)
        
        # 添加参数详情
        if target_cmd.parameters:
            param_details = []
            for param in target_cmd.parameters:
                req_status = "必填" if param.required else "可选"
                param_details.append(f"- **{param.name}** ({req_status}): {param.description or '无描述'}")
            embed.add_field(name="参数说明", value="\n".join(param_details), inline=False)
        
        await ctx.response.send_message(embed=embed)

关键修改说明

  1. 禁用前缀命令的help:直接在commands.Bot初始化时设置help_command=None,避免混淆两种命令体系。
  2. 直接在斜杠命令中处理逻辑:不再依赖前缀命令的HelpCommand类,直接在/help斜杠命令中实现两种场景:
    • 无参数时遍历所有已同步的斜杠命令,生成命令列表嵌入。
    • 有参数时根据名称匹配命令,生成包含使用方法、参数详情的嵌入。
  3. 适配斜杠命令对象结构:使用bot.tree.get_commands()获取斜杠命令集合,通过cmd.parameters访问命令参数,区分必填/可选状态。
  4. 正确响应交互:使用ctx.response.send_message()处理斜杠命令的响应,替代原代码中错误的send_help调用。
  5. 添加错误处理:包含命令不存在、无已注册命令的提示,以及服务器权限检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 12:05:36