Discord.js v14中/crociera命令移动成员报错TypeError求助
问题解决:Discord.js 移动用户时出现 "Cannot read properties of undefined (reading 'setChannel')" 错误
错误核心原因
你遇到的问题本质是:操作对象类型错误。interaction.options.getUser('utente')获取的是全局User对象,该对象不包含服务器内的语音状态信息;只有服务器成员对象(GuildMember)才具备voice属性及对应的语音操作方法。
修复后的完整代码
const { SlashCommandBuilder } = require('@discordjs/builders'); const { PermissionsBitField } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('crociera') .setDescription('Sposta un utente nei canali vocali specificati') .addUserOption(option => option.setName('utente') .setDescription('L\'utente da spostare') .setRequired(true) ), async execute(interaction) { // 关键修改:获取服务器成员对象而非全局用户对象 const userToMove = interaction.options.getMember('utente'); await interaction.reply(`Ciao, ${userToMove}!`); // 检查命令使用者权限 if (!interaction.member.permissions.has(PermissionsBitField.Flags.MoveMembers)) { return interaction.editReply('Non hai il permesso di spostare membri.'); } if (!userToMove) { await interaction.editReply('Errore: Nessun utente specificato.'); return; } // 恢复检查:确保目标用户处于语音频道中 if (!userToMove.voice.channel) { await interaction.editReply('Errore: L\'utente menzionato non è in un canale vocale.'); return; } // 获取目标语音频道列表 const channelIds = ['729013398368419891', '729016216894832641', '892746358061146152', '729016744605384784']; const channels = channelIds.map(id => interaction.guild.channels.cache.get(id)).filter(Boolean); if (channels.length === 0) { return interaction.editReply('Non sono stati trovati i canali vocali di destinazione.'); } // 依次移动用户到目标频道 for (const channel of channels) { try { console.log(`CANALE: ${channel}`) await userToMove.voice.setChannel(channel); await new Promise(resolve => setTimeout(resolve, 2000)); // 等待2秒再执行下一次移动 } catch (error) { console.error(`Errore durante lo spostamento dell'UTENTE:${userToMove} nel CANALE: ${channel} con errore: ${error}`); } } await interaction.editReply(`L'utente ${userToMove} è stato spostato nei canali vocali specificati.`); }, };
核心修改说明
- 替换对象获取方式:将
getUser改为getMember,确保拿到的是包含语音状态的服务器成员对象 - 恢复语音状态检查:如果用户不在任何语音频道,
userToMove.voice仍会是undefined,必须提前拦截这种情况 - 清理冗余依赖:移除了不需要的
Permissions导入,仅保留PermissionsBitField即可
额外注意事项
- 确认机器人账号拥有移动成员的服务器权限,否则即使命令使用者有权限,机器人也无法执行操作
- 核对目标频道ID的准确性,确保这些频道存在于当前服务器且为语音频道
内容的提问来源于stack exchange,提问作者Darla
相关产品推荐
相关产品推荐

