如何在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)
关键修改说明
- 禁用前缀命令的help:直接在
commands.Bot初始化时设置help_command=None,避免混淆两种命令体系。 - 直接在斜杠命令中处理逻辑:不再依赖前缀命令的
HelpCommand类,直接在/help斜杠命令中实现两种场景:- 无参数时遍历所有已同步的斜杠命令,生成命令列表嵌入。
- 有参数时根据名称匹配命令,生成包含使用方法、参数详情的嵌入。
- 适配斜杠命令对象结构:使用
bot.tree.get_commands()获取斜杠命令集合,通过cmd.parameters访问命令参数,区分必填/可选状态。 - 正确响应交互:使用
ctx.response.send_message()处理斜杠命令的响应,替代原代码中错误的send_help调用。 - 添加错误处理:包含命令不存在、无已注册命令的提示,以及服务器权限检查。
内容的提问来源于stack exchange,提问作者benz
相关产品推荐
相关产品推荐

