discord.js开发时即便在语音频道中message.member.voice返回undefined问题
Discord音乐机器人join接口返回undefined问题修复方案
核心问题原因
问题由Discord.js版本迭代带来的API变动导致:
- Discord.js v12及以上版本中,
message.member.voice下的频道属性已从voiceChannel重命名为channel,你代码中提取的voiceChannel本身就是undefined,后续调用join方法自然返回异常 - Discord.js v13及以上版本已完全移除内置的语音连接功能,原先的
voiceChannel.join()方法被废弃,相关能力拆分到独立的@discordjs/voice包中 - 你当前代码中的
videoFinder方法判断逻辑有误,当搜索结果仅返回1条视频时会返回null,也会导致后续播放逻辑失效
分步修复方案
适配Discord.js v12版本
如果你使用的是v12版本,仅需修改属性提取代码即可:
// 把原先的const { voiceChannel } = message.member.voice; 替换为以下代码 const voiceChannel = message.member.voice.channel;
同时修正videoFinder的判断逻辑:
const videoFinder = async (query) => { const videoResult = await ytSearch(query); // 把原先的>1改为>0 return (videoResult.videos.length > 0) ? videoResult.videos[0] : null; }
修改后即可正常调用join()方法获取连接实例。
适配Discord.js v13及以上版本(推荐使用最新稳定版)
v13及更高版本需要按照新的语音API规则调整全量逻辑:
- 首先安装语音相关依赖:
npm install @discordjs/voice opusscript sodium-native
- 替换全量play指令代码:
const { joinVoiceChannel, createAudioPlayer, createAudioResource, StreamType } = require('@discordjs/voice'); const ytdl = require('ytdl-core'); const ytSearch = require('yt-search'); module.exports = { name: 'play', description: '加入语音频道并播放YouTube音频', async execute(message, args) { const voiceChannel = message.member.voice.channel; if (!voiceChannel) return message.channel.send('请先加入语音频道再使用该指令'); const permissions = voiceChannel.permissionsFor(message.client.user); if (!permissions.has('CONNECT')) return message.channel.send('机器人缺少连接语音频道的权限'); if (!permissions.has('SPEAK')) return message.channel.send('机器人缺少在语音频道说话的权限'); if (!args.length) return message.channel.send('请指定要播放的内容关键词或链接'); // 新API加入语音频道 const connection = joinVoiceChannel({ channelId: voiceChannel.id, guildId: voiceChannel.guild.id, adapterCreator: voiceChannel.guild.voiceAdapterCreator, }); const videoFinder = async (query) => { const videoResult = await ytSearch(query); return (videoResult.videos.length > 0) ? videoResult.videos[0] : null; } const video = await videoFinder(args.join(' ')); if (video) { const stream = ytdl(video.url, { filter: 'audioonly' }) const player = createAudioPlayer(); const resource = createAudioResource(stream, { inputType: StreamType.Arbitrary, }); player.play(resource); connection.subscribe(player); } } }
额外配置检查
- 请确认你在Discord开发者后台给机器人开启了
Privileged Gateway Intents下的Voice State Intent权限 - 邀请机器人进入服务器时请确认勾选了
连接、说话两个语音相关权限
内容的提问来源于stack exchange,提问作者Finn
相关产品推荐
相关产品推荐

