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

Discord.js机器人开发:如何获取被提及用户的Presence/Activity活动信息

问题原因
  • 你直接访问activities[0]没有做空判断,当用户没有任何公开活动时,activities是空数组,activities[0]为undefined,调用.name自然会抛出未定义错误
  • 机器人未开启Presence相关权限,即使是公开状态也无法读取到用户活动数据
  • 未区分活动类型,自定义状态、听歌等非游戏活动也会被读取,不符合你的需求
修复步骤

1. 前置权限配置

  • 打开Discord开发者平台你的Bot应用页面,进入「Bot」标签页,开启PRESENCE INTENT和SERVER MEMBERS INTENT两个权限开关
  • 初始化Client时确保包含所需Intent,v14版本示例:
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.GuildPresences
  ]
});

如果你使用的是v13版本,将GatewayIntentBits.xxx替换为对应的intent字符串即可。

2. 命令代码修改

// v14版本用EmbedBuilder,v13版本替换为MessageEmbed
const { EmbedBuilder } = require('discord.js');

module.exports = {
    name: 'game',
    aliases: ['gm', 'status'],
    category: 'Commands',
    utilisation: '{prefix}game',

    execute(client, message) {
        // 获取被提及用户,默认取指令发送者本人
        const targetMember = message.mentions.members.first() || message.member;
        // 在线状态映射
        const statusMap = {
            online: '在线',
            idle: '闲置',
            dnd: '请勿打扰',
            offline: '离线'
        };
        const userStatus = statusMap[targetMember.presence?.status] || '未知状态';

        // 过滤出类型为「正在游玩」的游戏活动
        const playingActivity = targetMember.presence?.activities?.find(act => act.type === 'PLAYING');
        
        // 无正在游玩的游戏时返回状态提示
        if (!playingActivity) {
            return message.channel.send(`**${targetMember.user.tag}** 当前状态为:**${userStatus}**,没有正在游玩的游戏。`);
        }

        // 计算游戏时长
        const startTime = playingActivity.timestamps?.start;
        let playTimeStr = '未知时长';
        if (startTime) {
            const playTimeMs = Date.now() - startTime;
            const hours = Math.floor(playTimeMs / 3600000);
            const minutes = Math.floor((playTimeMs % 3600000) / 60000);
            playTimeStr = hours > 0 ? `${hours}小时${minutes}分钟` : `${minutes}分钟`;
        }

        const replyText = `**${targetMember.user.tag}** 已游玩 **${playingActivity.name}** 共 **${playTimeStr}**`;
        // 存在游戏封面资产时用Embed附带图片发送
        if (playingActivity.assets?.largeImage) {
            const gameEmbed = new EmbedBuilder()
                .setDescription(replyText)
                .setImage(`https://cdn.discordapp.com/app-assets/${playingActivity.applicationId}/${playingActivity.assets.largeImage}.png`);
            return message.channel.send({ embeds: [gameEmbed] });
        }

        // 无封面时直接发送文本
        return message.channel.send(replyText);
    },
};
代码说明
  • 全程加入空值安全判断,避免用户没有活动时抛出语法错误
  • 只过滤类型为PLAYING的活动,确保拿到的是游戏数据
  • 自动计算游戏时长,格式化为小时+分钟的可读形式
  • 存在游戏封面资产时,自动拼接Discord官方资源链接通过Embed发送封面图
  • 无游戏时自动返回用户当前的在线状态,符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:54:04