
本文详解如何在 discord.py 的 `@app_commands`(slash 命令)中,通过类型提示自动解析并验证用户是否提及了有效成员,并给出清晰的响应逻辑与健壮的错误处理。
在使用 discord.py 构建 Slash 命令时,无需手动解析消息文本中的 @ 提及——Discord 客户端会在用户选择成员时,自动将该成员作为结构化参数传递给后端。关键在于:正确声明参数类型,并利用可选参数 + 类型安全机制实现“有无提及”的逻辑判断。
以你的 /ping 命令为例,原始代码中将 kimi: str 作为纯字符串接收,这会导致 Discord 无法识别提及意图,也无法自动补全/校验成员,更无法保证输入是合法用户。正确做法是将参数类型设为 discord.Member(或 discord.User),并设为可选(=None)。Discord.py 会自动完成以下工作:
- 若用户在命令中选择了某位成员(如 /ping kimi:@Arda),kimi 将被实例化为 Member 对象;
- 若用户未提供该参数,kimi 值为 None,此时可触发提示逻辑;
- 所有无效提及(如已退出服务器的用户、不存在的 ID)会被 Discord 前端拦截,不会传入命令;即使极端情况发生,也可额外加 try/except 防御。
✅ 正确实现如下:
@bot.tree.command(name="ping")
@app_commands.describe(kimi="要提及的服务器成员(必填)")
async def ping(interaction: discord.Interaction, kimi: discord.Member = None):
if kimi is None:
await interaction.response.send_message("❌ You should mention someone!", ephemeral=True)
return
await interaction.response.send_message(
f"✅ {interaction.user.mention} mentioned {kimi.mention}!",
allowed_mentions=discord.AllowedMentions(users=True) # 确保提及能被正常展示(非默认禁用)
)? 重要注意事项:
- ephemeral=True 可让提示仅对执行者可见,提升用户体验(如错误提示);
- allowed_mentions 参数必须显式设置,否则 kimi.mention 在响应中可能显示为纯文本(如 而不触发高亮),尤其在私信或受限频道中更易失效;
- 若需支持跨服务器用户(如 Bot 公共命令),应改用 discord.User 类型(但无法获取昵称、角色等服务器专属信息);
- 不推荐使用 str 类型 + 手动正则匹配 @(如 re.search(r'', message)),因为该方式绕过 Discord 安全校验,易受伪造 ID、格式错误、权限越界等风险影响,且不兼容前端自动补全与类型提示。
? 进阶建议:
若希望命令更友好,可添加 @app_commands.choices() 或自定义 Autocomplete 实现成员搜索补全;如需检测「消息内容中是否包含提及」(非参数形式,例如监听普通消息),则需监听 on_message 并结合 message.mentions 属性——但该场景与 Slash 命令设计初衷相悖,应优先采用参数化交互。
综上,Discord.py 的 Slash 命令本质是结构化 API 调用,“提及”不是文本特征,而是语义参数——善用类型系统,既简洁又安全。










