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

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。

修复步骤

  1. 在guild.members.fetch()前添加await,确保获取到实际的GuildMember对象
  2. 用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:30:54