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

Discord.js TypeError问题:无法读取undefined的'options'属性

Discord 解封命令错误修复与提及解封实现

一、修复 TypeError: Cannot read properties of undefined (reading 'options') 错误

你的代码核心问题是错误处理了交互选项的返回值:interaction.options.get('target') 返回的是 CommandInteractionOption 对象,而非直接的字符串ID,直接将其传入 SnowflakeUtil.deconstruct 或 client.users.fetch 会触发类型错误,进而导致你看到的 options 属性读取失败。

修复后的完整代码

const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
const { SnowflakeUtil } = require('discord.js');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('unban')
        .setDescription('解封指定Discord用户')
        .addStringOption(option =>
            option
                .setName('target')
                .setDescription('用户ID、提及或用户标签(如User#1234)')
                .setRequired(true))
        .addStringOption(option =>
            option
                .setName('reason')
                .setDescription('解封理由'))
        .setDefaultMemberPermissions(PermissionFlagsBits.BanMembers)
        .setDMPermission(false),

    async execute(client, interaction) {
        const targetOption = interaction.options.get('target');
        if (!targetOption) return interaction.reply({ content: "缺少目标用户参数", ephemeral: true });
        
        let targetId = targetOption.value;

        // 处理用户提及格式(<@123456789> 或 <@!123456789>)
        if (targetId.match(/^<@!?(\d+)>$/)) {
            targetId = targetId.match(/^<@!?(\d+)>$/)[1];
        }
        // 处理用户标签格式(如User#1234)
        else if (targetId.includes('#')) {
            const bans = await interaction.guild.bans.fetch();
            const bannedUser = bans.find(ban => ban.user.tag === targetId);
            if (!bannedUser) {
                return interaction.reply({ content: "未找到匹配的封禁用户", ephemeral: true });
            }
            targetId = bannedUser.user.id;
        }

        // 验证雪花ID有效性
        if (!SnowflakeUtil.deconstruct(targetId).valid) {
            return interaction.reply({ content: "无效的用户ID", ephemeral: true });
        }

        const reason = interaction.options.get('reason')?.value || '无理由';
        let user;
        try {
            user = await client.users.fetch(targetId);
        } catch (err) {
            return interaction.reply({ content: "无法获取该用户信息", ephemeral: true });
        }

        try {
            await interaction.guild.members.unban(user.id, { reason });
            await interaction.reply(`已解封用户 **${user.tag}**,理由:${reason}`);
        } catch (err) {
            await interaction.reply({ content: "解封失败:可能用户未被封禁或机器人权限不足", ephemeral: true });
        }
    },
};

关键修改点

  • 提取选项实际值:用 targetOption.value 获取用户输入的字符串,而非直接使用 get 返回的对象
  • 增加错误捕获:对 users.fetch 和 unban 操作添加 try/catch,处理网络或权限异常
  • 多格式兼容:支持用户提及、标签、纯ID三种输入方式

二、通过@提及解封已封禁用户的实现逻辑

由于已封禁用户不在服务器成员列表中,Discord原生用户选择器无法直接选中,但可以通过以下逻辑处理@提及输入:

  1. 识别提及格式:解析用户输入的 <@123456789> 或 <@!123456789> 格式,提取其中的数字ID
  2. 验证ID合法性:用 SnowflakeUtil.deconstruct 确认ID是有效的Discord雪花ID
  3. 执行解封操作:通过提取出的ID调用 unban 方法完成解封

上述修复后的代码已内置该逻辑,用户只需在命令中输入@提及格式(即使对方已封禁,可手动输入或复制提及文本),命令会自动解析ID并执行解封。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:35:16