Discord.js中member.timeout不是函数的问题求助
问题描述
我在开发Discord的/timeout斜杠命令时遇到问题:该功能需要使用GuildMember对象而非User对象,但Discord斜杠命令选项仅支持选择User。于是我先获取User,再通过guild.members.fetch({target, force: true})获取对应服务器成员,随后检查member != null确认成员在服务器内。但调用member.timeout(durationInMs, ${reason} | Von ${interaction.user.username});时,出现错误TypeError: member.timeout is not a function。
错误原因
guild.members.fetch()是异步方法,会返回一个Promise对象,你没有用await处理,导致member变量实际是Promise而不是GuildMember实例,自然没有timeout方法。同时原来的member == null检查逻辑也会失效,因为Promise永远不会等于null。
修复步骤
- 在
guild.members.fetch()前添加await,确保获取到实际的GuildMember对象 - 用
try/catch捕获fetch过程中的异常(比如用户不在服务器时,fetch会抛出错误)
修正后的完整代码
const { SlashCommandBuilder, EmbedBuilder, Colors, PermissionFlagsBits } = require('discord.js'); const ms = require('ms'); module.exports = { data: new SlashCommandBuilder() .setName('timeout') .setDescription('Versetze einen Nutzer für eine bestimmte Zeit in den Timeout') .addUserOption(option => option.setName('target') .setDescription('Der Nutzer, den du timeouten möchtest') .setRequired(true)) .addStringOption(option => option.setName('duration') .setDescription('Die Dauer (bspw. 30m für 30 Minuten oder 2h für 2 Stunden), nach der der Timeout aufgehoben wird') .setRequired(true)) .addStringOption(option => option.setName('reason') .setDescription('Der Grund, aus dem du den Nutzer timeouten möchtest')) .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers), async execute(interaction) { const { guild } = interaction; const target = interaction.options.getUser('target'); const reason = interaction.options.getString('reason') ?? 'Kein Grund angegeben'; const duration = interaction.options.getString('duration'); const durationInMs = ms(duration); // 处理时间格式错误 if (durationInMs == null) { const embed = new EmbedBuilder() .setColor(Colors.Red) .setTitle('Aktion') .addFields( { name: '<:scroll:1133359100252651591> Ergebnis', value: 'Fehlschlag', inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:info:1133359642664251492> Aktion', value: 'Timeout', inline: true }, { name: '<:clipboard:1133357741394645084> Nachricht', value: `Die angegebene Dauer ist falsch.`, inline: true }, ) .setTimestamp(); await interaction.reply({ embeds: [embed] }); return; } // 检查时间上限 if (durationInMs > 2419200000) { const embed = new EmbedBuilder() .setColor(Colors.Red) .setTitle('Aktion') .addFields( { name: '<:scroll:1133359100252651591> Ergebnis', value: 'Fehlschlag', inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:info:1133359642664251492> Aktion', value: 'Timeout', inline: true }, { name: '<:clipboard:1133357741394645084> Nachricht', value: `Die Dauer darf 28 Tage nicht überschreiten.`, inline: true }, ) .setTimestamp(); await interaction.reply({ embeds: [embed] }); return; } // 检查时间下限 if (durationInMs < 1000) { const embed = new EmbedBuilder() .setColor(Colors.Red) .setTitle('Aktion') .addFields( { name: '<:scroll:1133359100252651591> Ergebnis', value: 'Fehlschlag', inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:info:1133359642664251492> Aktion', value: 'Timeout', inline: true }, { name: '<:clipboard:1133357741394645084> Nachricht', value: `Die Dauer darf eine Sekunde nicht unterschreiten.`, inline: true }, ) .setTimestamp(); await interaction.reply({ embeds: [embed] }); return; } // 获取GuildMember并处理异常 let member; try { member = await guild.members.fetch({ user: target, force: true }); } catch (err) { const embed = new EmbedBuilder() .setColor(Colors.Red) .setTitle('Aktion') .addFields( { name: '<:scroll:1133359100252651591> Ergebnis', value: 'Fehlschlag', inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:info:1133359642664251492> Aktion', value: 'Timeout', inline: true }, { name: '<:clipboard:1133357741394645084> Nachricht', value: `Der Nutzer ist nicht Teil dieses Servers.`, inline: true }, ) .setTimestamp(); await interaction.reply({ embeds: [embed] }); return; } const formattedDuration = ms(durationInMs); const embed = new EmbedBuilder() .setColor(Colors.DarkRed) .setTitle('Aktion') .addFields( { name: '<:scroll:1133359100252651591> Ergebnis', value: 'Erfolg', inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:info:1133359642664251492> Aktion', value: 'Timeout', inline: true }, { name: '<:clipboard:1133357741394645084> Grund', value: `${reason}`, inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: '<:moderator:1133359611852886047> Moderator', value: `${interaction.user}`, inline: true }, { name: '\u200B', value: '\u200B', inline: true }, { name: ':alarm_clock: Dauer', value: `${formattedDuration}`, inline: true }, { name: '<:check:1133357168993783910> Ausgeführt gegen', value: `ㅤㅤ<:arrow:1133359137091227648> ${target}`, inline: false }, ) .setTimestamp(); await interaction.reply({ embeds: [embed] }); await member.timeout(durationInMs, `${reason} | Von ${interaction.user.username}`); }, };
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

