Discord.js 18:如何获取用户在指定guild的加入日期?
获取用户加入Discord服务器的时间方法
我已经掌握获取用户账号创建时间的方法,但不知道如何获取用户加入某一服务器(guild)的时间?以下是我当前的命令代码,我使用强制拉取(force fetch)来获取用户信息:
const { SlashCommandBuilder, EmbedBuilder, Client, GatewayIntentBits, PermissionFlagsBits } = require('discord.js'); const {createFooter, userAvatar, creationDateTimestamp} = require('../../utility'); const {token} = require('../../config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds], }); module.exports = { data: new SlashCommandBuilder() .setName('user') .setDescription('Provides information about the user.') .addUserOption(option => option .setName('user') .setDescription('Select a user to view')), async execute(interaction) { // Currently only works with a single user at a time... client.login(token); // Must log in let targetUser = interaction.options.getUser('user') ?? interaction.user; const user = await client.users.fetch(targetUser.id); // Force fetch let accentColor = user.hexAccentColor; if (user.hexAccentColor != null && user.hexAccentColor != undefined) user.hexAccentColor = 0xffffff; const userEmbed = new EmbedBuilder() .setColor(user.hexAccentColor) .setTitle(user.displayName) .setDescription(user.username) //.setThumbnail(userAvatar(interaction.user)) .addFields( { name: 'Creation date', value: `${creationDateTimestamp(user)}` }, ) .setThumbnail(userAvatar(user)) .setTimestamp() .setFooter(createFooter(interaction.user)); await interaction.reply({ embeds: [userEmbed] }); }, };
解决方案
要获取用户加入服务器的时间,需要拉取用户在当前服务器的GuildMember对象——用户的服务器关联信息(包括加入时间)都存储在这个对象中,而非单纯的User对象。
关键修改点:
- 移除重复登录逻辑:
client.login(token)不应该写在命令的execute方法里,客户端应在项目入口文件(如index.js)中初始化登录,避免每次执行命令都重复登录。 - 获取GuildMember对象:通过
interaction.guild.members.fetch(targetUser.id)强制拉取用户在当前服务器的成员信息,该对象包含joinedAt属性(用户加入服务器的时间)。 - 添加加入时间字段:在Embed中新增显示加入时间的字段,复用你现有的时间格式化工具函数。
修改后的完整代码:
const { SlashCommandBuilder, EmbedBuilder, Client, GatewayIntentBits } = require('discord.js'); const { createFooter, userAvatar, creationDateTimestamp } = require('../../utility'); const { token } = require('../../config.json'); const client = new Client({ intents: [GatewayIntentBits.Guilds], }); // 建议将client.login移至项目入口文件,比如index.js // client.login(token); module.exports = { data: new SlashCommandBuilder() .setName('user') .setDescription('提供用户相关信息') .addUserOption(option => option .setName('user') .setDescription('选择要查看的用户')), async execute(interaction) { let targetUser = interaction.options.getUser('user') ?? interaction.user; // 获取用户基础信息 const user = await client.users.fetch(targetUser.id); // 获取用户在当前服务器的成员信息 const member = await interaction.guild.members.fetch(targetUser.id); // 修正颜色处理逻辑(原逻辑存在矛盾:有accentColor时反而设为白色,这里调整为保留原颜色,无则用白色) let accentColor = user.hexAccentColor ?? 0xffffff; const userEmbed = new EmbedBuilder() .setColor(accentColor) .setTitle(user.displayName) .setDescription(user.username) .addFields( { name: '账号创建时间', value: `${creationDateTimestamp(user)}` }, { name: '加入服务器时间', value: `${member.joinedAt ? creationDateTimestamp({ createdAt: member.joinedAt }) : '无法获取加入时间'}` } ) .setThumbnail(userAvatar(user)) .setTimestamp() .setFooter(createFooter(interaction.user)); await interaction.reply({ embeds: [userEmbed] }); }, };
补充说明:
- 如果你现有的
creationDateTimestamp函数是基于user.createdAt编写的,需要确保它能处理member.joinedAt(两者都是Date对象)。如果原函数只接收User对象,可以修改函数接收Date参数,或者像示例中那样包装一个包含createdAt属性的对象临时适配。 - 如果用户不在当前服务器,
member.joinedAt会返回null,所以需要添加判断避免报错。
内容的提问来源于stack exchange,提问作者Alistair Manicardi
相关产品推荐
相关产品推荐

