Discord.py中如何检测用户是否屏蔽机器人并删除对应消息
Discord.py 检测用户屏蔽机器人的实现方案
首先明确核心前提:Discord 官方出于用户隐私规则,没有开放任何可以直接查询用户是否屏蔽机器人的API接口,不存在无副作用的前置检测手段,只能通过API异常捕获的方式间接判定,实现你需要的删消息逻辑。
可行实现逻辑
如果用户屏蔽了机器人,或是关闭了所在服务器的陌生人私信权限,机器人尝试向该用户发送私信时会直接抛出discord.Forbidden(403权限错误),这个特征可以作为判定依据。
为了避免检测操作骚扰正常用户,可以采用「发空测试私信→立刻撤回」的逻辑,未被屏蔽的用户完全感知不到检测操作。
前置要求:机器人必须拥有目标频道的
管理消息权限,才能执行删除用户消息的操作;同时需要在开发者后台开启消息内容意图、服务器成员意图。
参考代码
import discord from discord.ext import commands # 配置必要权限 intents = discord.Intents.default() intents.message_content = True intents.members = True bot = commands.Bot(command_prefix="!", intents=intents) # 简单缓存检测结果,避免重复调用API触发限流,缓存有效期2小时 block_cache = {} @bot.event async def on_message(message): # 跳过机器人自身发送的消息 if message.author.bot: return user_id = message.author.id # 优先读缓存 if user_id in block_cache: is_blocked = block_cache[user_id] else: is_blocked = False try: # 发送空内容测试私信 test_msg = await message.author.send("") # 发送成功立刻撤回,用户无感知 await test_msg.delete() except discord.Forbidden: # 403错误即判定为无法向用户发私信(含被屏蔽、关闭私信两种情况) is_blocked = True # 写入缓存 block_cache[user_id] = is_blocked # 判定为被屏蔽时删除对应消息 if is_blocked: await message.delete() # 保持原有命令逻辑正常运行 await bot.process_commands(message) bot.run("你的机器人Token")
注意事项
- 该方案无法区分「用户主动屏蔽机器人」和「用户关闭了服务器成员私信权限」两种情况,Discord返回的错误完全一致,没有进一步区分的手段。
- 缓存机制是必须的,高频调用私信接口会触发Discord的API速率限制,严重时可能导致机器人被临时限制接口权限。
- 不要在测试私信里携带任何实际内容,否则会对正常用户造成骚扰。
内容的提问来源于stack exchange,提问作者Astraeus
相关产品推荐
相关产品推荐

