You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Discord.js机器人在presenceUpdate触发时自动发送状态更新消息

解决Discord机器人自动发送用户状态变更消息的问题

我来帮你搞定这个自动触发状态更新通知的需求!你的现有代码已经监听了presenceUpdate事件,但问题出在状态变更后没有直接推送消息,反而存在数组里等待手动指令触发,另外还有几个小bug需要修正。

先说说现有代码的核心问题

  1. userStatus数组的使用逻辑混乱:每次状态变更你会push两个元素(用户名+状态),但手动触发时只解构前两个值,多次状态变更后数据会完全错乱。
  2. message事件里的无效判断:if (console.log())这个条件永远不成立(console.log()返回undefined),导致后面的用户名和状态根本取不到。
  3. 没有利用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('你的机器人令牌');

关键优化点说明

  1. 状态变更过滤:通过oldPresence?.status === newPresence.status判断,只处理真实的状态变更事件,避免冗余通知。
  2. 固定通知频道:指定STATUS_NOTIFY_CHANNEL_ID让消息发送到固定频道,不会乱发到用户聊天频道。
  3. 友好状态文字:把机器人返回的online/idle/dnd/offline转换成更易懂的中文(需要英文的话直接去掉转换逻辑即可)。
  4. 错误处理:增加了频道不存在的判断,避免机器人崩溃。
  5. 版本适配:针对Discord.js v13+的API调整了Embed发送方式,如果你用的是旧版本,把{ embeds: [statusEmbed] }改成直接传statusEmbed即可。

注意事项

  • 确保机器人在目标服务器拥有发送消息和嵌入链接的权限。
  • 替换代码中的STATUS_NOTIFY_CHANNEL_ID和你的机器人令牌为实际值。

内容的提问来源于stack exchange,提问作者ANUBIS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:13:22