Discord机器人Presence Update触发重复通知spam问题如何修复
Discord机器人PresenceUpdate重复发送开播通知的解决方法
问题原因
presenceUpdate 事件会在用户的状态发生任何变更时触发,包含但不限于切换在线状态、修改自定义状态、增减活动状态、Discord客户端后台自动刷新状态。你当前的逻辑没有做去重判断,只要事件触发时检测到用户处于直播状态,就会执行日志打印和通知发送逻辑,自然会出现重复触发的问题。
解决方法
你只需要新增一个已通知直播的状态缓存,用来记录已经发过通知的正在直播的用户信息,每次触发事件时先做判断再执行操作即可,具体实现步骤如下:
- 第一步:在事件监听代码的外层作用域,声明一个缓存结构用来存储当前活跃的直播信息,这里推荐用
Map,键存用户ID,值存对应正在直播的链接,方便快速判断是否为已经通知过的同一场直播 - 第二步:修改原有的事件处理逻辑,增加缓存判断:
- 检测到直播活动时,先判断当前用户的直播是否已经在缓存中存在
- 不存在则执行打印、发通知逻辑,同时将该场直播存入缓存
- 存在则跳过执行,避免重复发送
- 第三步:增加下播状态检测逻辑,用户停止直播时将对应的记录从缓存中移除,保证下次开播可以正常触发通知
修改后的参考代码:
// 外层作用域声明缓存,不要写在presenceUpdate事件回调内部 const activeStreams = new Map(); // 你的presenceUpdate事件监听 client.on('presenceUpdate', (oldPresence, newPresence) => { const userId = newPresence.userId; // 查找当前是否存在直播活动 const streamingActivity = newPresence.activities?.find(act => act.type === 'STREAMING'); if (streamingActivity) { const streamUrl = streamingActivity.url; // 判断是否已经通知过当前这场直播 if (activeStreams.get(userId) !== streamUrl) { // 新开播/更换了直播链接,执行通知逻辑 console.log(`${newPresence.user.tag} is streaming at ${streamUrl}.`); // 此处保留你原有的发送频道通知的代码 // 将直播信息写入缓存 activeStreams.set(userId, streamUrl); } } else { // 没有检测到直播活动,如果该用户之前在缓存中则删除记录 if (activeStreams.has(userId)) { activeStreams.delete(userId); // 可选:此处可添加下播通知逻辑 } } });
补充说明
如果你的机器人需要长期运行且重启后不想丢失缓存状态,可以将activeStreams的数据定期写入本地JSON文件或者轻量数据库,重启时读取恢复即可,个人自用场景下用内存缓存已经足够满足需求。
内容的提问来源于stack exchange,提问作者Murus
相关产品推荐
相关产品推荐

