Discord.js结合MongoDB实现AFK功能:@AFK用户时无法触发提示消息的问题求助
解决Discord机器人AFK提及提示失效的问题
看起来你遇到的核心问题是:你把「检测提及AFK成员」的逻辑放在了afk命令的执行函数里——这意味着只有当用户主动输入afk命令的时候,这段检测才会运行,而不是在日常聊天消息里自动触发。我们需要把这个检测逻辑移到全局的消息监听事件里,才能实现@AFK成员时自动提示的效果。
1. 移除AFK命令中的无效逻辑
先把原代码里那段位置错误的检测代码删掉,它根本无法实现你想要的全局监听效果:
// 删除这段无效代码 if (message.mentions.member) { message.reply(`This user is currently AFK! **${afkReason}**`); }
2. 添加全局消息监听事件
在你的机器人主文件(比如index.js)里,添加messageCreate事件监听,用来处理所有消息中的AFK成员检测:
const Afk = require('./models/afk.js'); // 确保路径与你的项目结构匹配 client.on('messageCreate', async (message) => { // 跳过机器人自己的消息,避免无限循环 if (message.author.bot) return; // 场景1:如果发消息的用户本身处于AFK状态,自动解除AFK const userAfkRecord = await Afk.findOne({ userID: message.author.id, guildID: message.guild.id }); if (userAfkRecord) { // 从数据库删除AFK记录 await Afk.deleteOne({ userID: message.author.id, guildID: message.guild.id }); // 恢复用户原昵称(移除[AFK]前缀) const originalNick = message.member.nickname?.replace('[AFK] ', '') || message.author.username; await message.member.setNickname(originalNick); // 发送临时提示后自动删除 message.reply(`Welcome back! Your AFK status has been removed.`).then(msg => setTimeout(() => msg.delete(), 5000)); } // 场景2:检测消息中@的成员是否处于AFK状态 if (message.mentions.members.size > 0) { for (const mentionedMember of message.mentions.members.values()) { const afkData = await Afk.findOne({ userID: mentionedMember.id, guildID: message.guild.id }); if (afkData) { message.reply(`This user is currently AFK!\n**${afkData.afkReason}**`); } } } });
3. 优化AFK命令的体验
可以给原AFK命令添加重复检测,避免用户重复设置AFK:
module.exports.run = async (client, message, args) => { await message.delete(); // 先检查用户是否已经处于AFK状态 const existingAfk = await Afk.findOne({ userID: message.author.id, guildID: message.guild.id }); if (existingAfk) { return message.reply(`You're already AFK: **${existingAfk.afkReason}**`).then(msg => setTimeout(() => msg.delete(), 3000)); } let afkReason = args.slice(0).join(" ") || "No reason provided"; const nAfk = new Afk({ username: message.author.tag, userID: message.author.id, afkReason: afkReason, guildID: message.guild.id, time: message.createdAt.toUTCString() }); await nAfk.save().catch(err => console.log(err)); await message.member.setNickname(`[AFK] ${message.author.username}`); message.reply(`You are now AFK: **${afkReason}.**`).then(msg => setTimeout(() => msg.delete(), 5000)); }
关键细节说明
- 全局监听必要性:只有通过
messageCreate事件监听所有消息,才能实时捕获用户提及AFK成员的行为。 - 精准数据库查询:查询AFK记录时同时匹配
userID和guildID,确保只对当前服务器的AFK状态生效。 - 自动解除AFK:当AFK用户主动发消息时自动移除状态,提升交互体验。
- 临时消息清理:用
setTimeout自动删除提示消息,避免聊天区冗余信息堆积。
这样修改后,当用户@AFK成员时机器人会自动发送提示,AFK用户自己发消息也会自动解除状态,完美实现你想要的功能。
内容的提问来源于stack exchange,提问作者user15215695
相关产品推荐
相关产品推荐

