本文详解如何在 discord.py 的 `@app_commands`(slash 命令)中,通过类型提示自动解析并验证用户是否提及了有效成员,并给出清晰的响应逻辑与健壮的错误处理。
在使用 discord.py 构建 Slash 命令时,无需手动解析消息文本中的 @ 提及——Discord 客户端会在用户选择成员时,自动将该成员作为结构化参数传递给后端。关键在于:正确声明参数类型,并利用可选参数 + 类型安全机制实现“有无提及”的逻辑判断。
以你的
/ping 命令为例,原始代码中将 kimi: str 作为纯字符串接收,这会导致 Discord 无法识别提及意图,也无法自动补全/校验成员,更无法保证输入是合法用户。正确做法是将参数类型设为 discord.Member(或 discord.User),并设为可选(=None)。Discord.py 会自动完成以下工作:
✅ 正确实现如下:
@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) # 确保提及能被正常展示(非默认禁用)
)? 重要注意事项:
? 进阶建议:
若希望命令更友好,可添加 @app_commands.choices() 或自定义 Autocomplete 实现成员搜索补全;如需检测「消息内容中是否包含提及」(非参数形式,例如监听普通消息),则需监听 on_message 并结合 message.mentions 属性——但该场景与 Slash 命令设计初衷相悖,应优先采用参数化交互。
综上,Discord.py 的 Slash 命令本质是结构化 API 调用,“提及”不是文本特征,而是语义参数——善用类型系统,既简洁又安全。