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原生用户选择器无法直接选中,但可以通过以下逻辑处理@提及输入:
- 识别提及格式:解析用户输入的
<@123456789>或<@!123456789>格式,提取其中的数字ID - 验证ID合法性:用
SnowflakeUtil.deconstruct确认ID是有效的Discord雪花ID - 执行解封操作:通过提取出的ID调用
unban方法完成解封
上述修复后的代码已内置该逻辑,用户只需在命令中输入@提及格式(即使对方已封禁,可手动输入或复制提及文本),命令会自动解析ID并执行解封。
内容的提问来源于stack exchange,提问作者FireEmblem
相关产品推荐
相关产品推荐

