discord.py中on_presence_update事件无法触发的问题求助
Discord.py on_presence_update事件无法触发的解决方案
问题背景
使用commands.AutoShardedBot开发Discord机器人,已配置如下Intents:
intents = discord.Intents.all() intents.message_content = True intents.guilds = True intents.members = True intents.presences = True
且已在开发者门户启用presence gateway,但on_presence_update监听器完全不触发,即使简化代码也无响应;同时自定义的whatstatus命令可正常查询用户状态。
排查与解决步骤
1. 确认Intents已正确传递给Bot实例
配置Intents后,必须在创建Bot对象时传入该配置,否则所有Intent设置无效:
bot = commands.AutoShardedBot(command_prefix="你的前缀", intents=intents)
2. 二次验证特权网关Intent的启用状态
前往Discord开发者门户,进入对应应用的「Bot」标签页:
- 确保「Privileged Gateway Intents」下的Presence Intent和Server Members Intent均已开启
- 保存设置后重启机器人
3. 检查Cog是否成功加载
监听器所在的Cog必须被正确加载,否则事件不会被注册:
# 在Bot启动代码中加载Cog async def setup(bot): try: await bot.load_extension("你的Cog文件名") print("Cog加载成功") except Exception as e: print(f"Cog加载失败: {str(e)}")
4. 修正监听器代码的缩进与Bot引用
Cog内的监听器需使用self.bot引用Bot实例,且缩进需符合Python规范:
from discord import Status @commands.Cog.listener() async def on_presence_update(self, before: discord.Member, after: discord.Member): # 替换为目标用户ID和通知频道ID if after.id == 123456789 and before.status != Status.offline and after.status == Status.offline: print(f"{before.name} 状态从 {before.status} 变为 {after.status}") channel = await self.bot.fetch_channel(949000882853400699) await channel.send("目标用户已下线")
5. 测试基础事件触发
先编写无过滤的基础监听器,验证事件是否能正常触发:
@commands.Cog.listener() async def on_presence_update(self, before: discord.Member, after: discord.Member): print(f"状态更新: {before.name} | {before.status} → {after.status}")
启动机器人后切换自身在线状态,查看控制台是否有输出。若有输出,说明之前的过滤逻辑存在问题;若无输出,回到前几步重新排查Intent和Cog加载。
6. 确认目标用户在机器人所在服务器
on_presence_update仅触发机器人已加入服务器内的用户状态变化,若目标用户不在任何机器人所在的服务器,事件不会触发。
内容的提问来源于stack exchange,提问作者hecker5556
相关产品推荐
相关产品推荐

