如何实现Discord Bot命令的指定用户排除拦截逻辑
原实现失效的核心原因
- 代码中
user = discord.Member仅为discord.py的Member类本身做了变量绑定,没有获取到实际触发命令的用户实例,更没有提取用户的唯一标识做比对 - 用类对象和存储用户ID的列表做成员判断,逻辑路径完全不连通,判断结果永远和预期不符
- 拦截逻辑写在单个命令内部,后续新增命令需要重复编写判断代码,维护成本高
可落地的拦截实现方案
方案特性
基于discord.py内置的全局命令检查逻辑实现拦截,不需要在每个命令内部重复写判断代码,拦截规则对Bot的所有命令统一生效。这套逻辑和临时asyncio事件的运行流完全解耦,不会因为Bot重启丢失拦截规则。
具体实现步骤
- 定义固定的屏蔽用户ID列表,所有列表元素必须是整数类型的Discord用户ID,不要存储字符串形式的ID、也不要存可随时修改的用户名:
# 替换为你需要屏蔽的真实用户ID BLOCKED_USER_IDS = [123456789012345678, 234567890123456789] - 编写全局检查函数,该函数会在每一个命令实际执行前自动运行,提前完成拦截判断:
async def block_blocked_users(ctx): # 从命令上下文直接提取触发用户的ID,无需手动获取Member对象 if ctx.author.id in BLOCKED_USER_IDS: await ctx.send("You are on the blocklist.") # 返回False会直接阻断当前命令的后续逻辑 return False # 不在屏蔽列表则放行命令 return True - 将检查规则注册到Bot实例上,全量命令自动应用拦截逻辑:
# 以commands.Bot初始化的bot实例为例 bot.add_check(block_blocked_users)
单命令场景的修正写法
如果你只需要给单个特定命令加拦截,不需要全局生效,可以直接修正原代码的取值逻辑,不要绑定Member类:
修正后的单命令示例:
@commands.command() async def test(self, ctx): # 直接获取触发命令的用户ID,为整数类型 trigger_user_id = ctx.author.id BLOCKED_USER_IDS = [123456789012345678] if trigger_user_id in BLOCKED_USER_IDS: await ctx.send("You are on the blocklist.") return # 后续原有命令逻辑
注意事项
- 拦截比对必须使用整数形式的用户ID,不要将ID转成字符串存储,否则会出现类型不匹配、判断永远不生效的问题
- 不要使用用户名做拦截依据,用户名支持用户随意修改,没有长期唯一性,稳定性远低于固定的用户ID
- 屏蔽列表直接放在代码或本地持久化配置文件中,Bot重启后会自动加载规则,不会出现临时asyncio事件丢失的问题
内容的提问来源于stack exchange,提问作者Dominik
相关产品推荐
相关产品推荐

