如何使用discord.py实现带选择菜单的帮助命令
discord.py 帮助命令下拉选择菜单实现方案
方案基于discord.py 2.0+ 原生UI组件实现,不需要额外依赖。
实现逻辑
- 命令触发后返回携带下拉选择器的初始帮助消息,选择器选项对应不同帮助分类
- 选择器回调内校验操作人权限,仅允许命令触发用户操作菜单
- 根据用户选中的分类动态更新原消息的嵌入内容,菜单超时后自动禁用避免无效交互
完整代码
import discord from discord.ext import commands from discord import app_commands # 初始化bot,注意开启对应意图 intents = discord.Intents.default() intents.message_content = True bot = commands.Bot(command_prefix="!", intents=intents) class HelpSelect(discord.ui.Select): def __init__(self, bot: commands.Bot): self.bot = bot # 配置下拉菜单选项,可根据自身需求增删 options = [ discord.SelectOption(label="通用命令", description="基础功能命令说明", emoji="📖"), discord.SelectOption(label="管理命令", description="服务器管理类命令说明", emoji="🛡️"), discord.SelectOption(label="娱乐命令", description="娱乐互动类命令说明", emoji="🎮"), discord.SelectOption(label="音乐命令", description="音乐播放类命令说明", emoji="🎵") ] super().__init__( placeholder="选择要查看的帮助分类", min_values=1, max_values=1, options=options ) async def callback(self, interaction: discord.Interaction): # 非命令触发用户操作直接拦截 if interaction.user != self.view.author: return await interaction.response.send_message("你无权操作该帮助菜单", ephemeral=True) # 根据选中值生成对应帮助嵌入 selected = self.values[0] embed = discord.Embed(color=discord.Color.blue()) if selected == "通用命令": embed.title = "📖 通用命令列表" embed.add_field(name="/help", value="呼出帮助菜单", inline=False) embed.add_field(name="/ping", value="查询机器人延迟", inline=False) embed.add_field(name="/userinfo [用户]", value="查询指定用户信息", inline=False) elif selected == "管理命令": embed.title = "🛡️ 管理命令列表" embed.add_field(name="/ban [用户] [原因]", value="封禁指定服务器成员", inline=False) embed.add_field(name="/kick [用户] [原因]", value="踢出指定服务器成员", inline=False) embed.add_field(name="/clear [数量]", value="批量删除当前频道消息", inline=False) elif selected == "娱乐命令": embed.title = "🎮 娱乐命令列表" embed.add_field(name="/roll [上限]", value="掷骰子生成随机数", inline=False) embed.add_field(name="/meme", value="随机获取趣味梗图", inline=False) embed.add_field(name="/8ball [问题]", value="魔法8球随机答疑", inline=False) elif selected == "音乐命令": embed.title = "🎵 音乐命令列表" embed.add_field(name="/join", value="加入你当前所在语音频道", inline=False) embed.add_field(name="/play [关键词/链接]", value="播放指定音频内容", inline=False) embed.add_field(name="/skip", value="跳过当前播放曲目", inline=False) embed.add_field(name="/leave", value="断开语音频道连接", inline=False) # 更新消息内容 await interaction.response.edit_message(embed=embed) class HelpView(discord.ui.View): def __init__(self, bot: commands.Bot, author: discord.User | discord.Member, timeout=180): super().__init__(timeout=timeout) self.author = author self.add_item(HelpSelect(bot)) self.message = None async def on_timeout(self): # 超时后禁用所有组件 for child in self.children: child.disabled = True await self.message.edit(view=self) # 斜杠命令形式的帮助指令 @bot.tree.command(name="help", description="查看机器人功能帮助") async def help(interaction: discord.Interaction): # 初始默认展示通用分类帮助 default_embed = discord.Embed(title="📖 通用命令列表", color=discord.Color.blue()) default_embed.add_field(name="/help", value="呼出帮助菜单", inline=False) default_embed.add_field(name="/ping", value="查询机器人延迟", inline=False) default_embed.add_field(name="/userinfo [用户]", value="查询指定用户信息", inline=False) view = HelpView(bot=bot, author=interaction.user) await interaction.response.send_message(embed=default_embed, view=view) view.message = await interaction.original_response() @bot.event async def on_ready(): # 同步斜杠命令到discord await bot.tree.sync() print(f"登录成功:{bot.user}") # 替换为你的bot token bot.run("YOUR_BOT_TOKEN")
注意事项
- 该方案仅适用于discord.py 2.0及以上版本,1.x版本无原生组件支持,需先升级依赖
- 必须在discord开发者后台开启bot的
Message Content Intent、Server Members Intent开关,同时代码中对应intents配置要匹配,否则组件交互、消息读取会报错 - 组件回调必须在3秒内返回响应,若有耗时逻辑需先调用
await interaction.response.defer()延迟响应,否则discord会判定交互失败 - 不需要全局监听
on_interaction事件处理菜单逻辑,通过View绑定组件回调的方式天然支持多菜单实例隔离,不会出现自定义ID冲突问题 - 若需要实现多级菜单、分页效果,只需在回调中动态替换View内的组件或嵌入内容即可,核心逻辑和上述示例一致
内容的提问来源于stack exchange,提问作者Tryxx
相关产品推荐
相关产品推荐

