如何让Discord.js机器人在presenceUpdate触发时自动发送状态更新消息
解决Discord机器人自动发送用户状态变更消息的问题
我来帮你搞定这个自动触发状态更新通知的需求!你的现有代码已经监听了presenceUpdate事件,但问题出在状态变更后没有直接推送消息,反而存在数组里等待手动指令触发,另外还有几个小bug需要修正。
先说说现有代码的核心问题
userStatus数组的使用逻辑混乱:每次状态变更你会push两个元素(用户名+状态),但手动触发时只解构前两个值,多次状态变更后数据会完全错乱。message事件里的无效判断:if (console.log())这个条件永远不成立(console.log()返回undefined),导致后面的用户名和状态根本取不到。- 没有利用
presenceUpdate事件直接发送消息:这才是实现自动通知的关键环节。
修正后的完整代码
我帮你重构了代码,直接在状态变更时发送通知,同时保留了可选的手动查询功能,还适配了Discord.js新版本的API:
// 注意:Discord.js v12+ 使用MessageEmbed,v11及以下用RichEmbed const { Client, MessageEmbed } = require('discord.js'); const bot = new Client(); const prefix = '!'; // 替换成你想要发送通知的服务器频道ID(比如公告频道) const STATUS_NOTIFY_CHANNEL_ID = '你的频道ID'; bot.on("presenceUpdate", (oldPresence, newPresence) => { // 过滤掉状态未变化的事件(避免游戏更新等无意义触发) if (oldPresence?.status === newPresence.status) return; const username = newPresence.user.username; const status = newPresence.status; // 把机器状态转换成更友好的文字 const friendlyStatus = { online: '在线', idle: '离开', dnd: '请勿打扰', offline: '离线/隐身' }[status] || status; console.log(`${username} 的状态更新为:${friendlyStatus}`); // 获取目标频道 const notifyChannel = bot.channels.cache.get(STATUS_NOTIFY_CHANNEL_ID); if (!notifyChannel) { console.error('找不到指定的状态通知频道,请检查频道ID是否正确!'); return; } // 构建通知Embed const statusEmbed = new MessageEmbed() .setDescription("🔔 成员状态更新") .setColor("#4287f5") .addField('成员', username, true) .addField('当前状态', friendlyStatus, true) .setTimestamp(); // 发送消息(v13+用embeds数组,v12及以下直接传statusEmbed) notifyChannel.send({ embeds: [statusEmbed] }); }); // 保留手动查询状态的指令(可选) bot.on('message', (message) => { // 忽略机器人消息和非指令消息 if (!message.content.startsWith(prefix) || message.author.bot) return; const args = message.content.slice(prefix.length).trim().split(/ +/); const command = args.shift().toLowerCase(); if (command === "status") { const userStatus = message.author.presence?.status || '未知'; const friendlyStatus = { online: '在线', idle: '离开', dnd: '请勿打扰', offline: '离线/隐身' }[userStatus] || userStatus; const queryEmbed = new MessageEmbed() .setDescription("📊 状态查询结果") .setColor("#ffffff") .addField('你的当前状态', friendlyStatus); message.channel.send({ embeds: [queryEmbed] }); } }); // 登录机器人 bot.login('你的机器人令牌');
关键优化点说明
- 状态变更过滤:通过
oldPresence?.status === newPresence.status判断,只处理真实的状态变更事件,避免冗余通知。 - 固定通知频道:指定
STATUS_NOTIFY_CHANNEL_ID让消息发送到固定频道,不会乱发到用户聊天频道。 - 友好状态文字:把机器人返回的
online/idle/dnd/offline转换成更易懂的中文(需要英文的话直接去掉转换逻辑即可)。 - 错误处理:增加了频道不存在的判断,避免机器人崩溃。
- 版本适配:针对Discord.js v13+的API调整了Embed发送方式,如果你用的是旧版本,把
{ embeds: [statusEmbed] }改成直接传statusEmbed即可。
注意事项
- 确保机器人在目标服务器拥有发送消息和嵌入链接的权限。
- 替换代码中的
STATUS_NOTIFY_CHANNEL_ID和你的机器人令牌为实际值。
内容的提问来源于stack exchange,提问作者ANUBIS
相关产品推荐
相关产品推荐

