如何让Discord机器人加入所在全部服务器的语音频道?代码报错如何解决
问题根因与修复方案
报错核心原因
Cannot read property 'join' of undefined 说明你调用join()方法的主体是无效值,也就是代码里.filter(...).random()这一步没有返回有效的语音频道对象,才会在调用方法时报错。
具体排查点
- 首先匹配discord.js版本判断频道类型:v13及以上版本的语音频道类型枚举已经更新,旧的
ch.type === 'voice'判断方式失效,v13+版本需要判断ch.type === ChannelType.GuildVoice,也可以直接用枚举对应数值ch.type === 2 - 部分服务器可能不存在任何语音频道,或是所有语音频道机器人都没有进入权限,筛选后的频道集合为空,调用
random()自然返回undefined - 原有代码中冗余获取了一遍
targetGuild,forEach遍历拿到的guild本身就是有效服务器对象,不需要再从缓存重复查询 - 缺少异常捕获逻辑,部分频道即使筛选出来也可能因为权限、服务器异常等原因加入失败,没有catch捕获会直接抛出报错
修复后代码(兼容discord.js v13/v14)
+eval const { ChannelType, PermissionsBitField } = require('discord.js'); client.guilds.cache.forEach(async guild => { // 筛选符合条件的语音频道:类型匹配、机器人有连接权限 const availableChannels = guild.channels.cache.filter(ch => ch.type === ChannelType.GuildVoice && ch.permissionsFor(guild.members.me).has(PermissionsBitField.Flags.Connect) ); // 确认有可用频道再执行加入操作 if (availableChannels.size >= 1) { const targetChannel = availableChannels.random(); await targetChannel.join().catch(err => console.log(`加入频道失败:${err.message}`)); } });
额外注意事项
- 如果你使用的是discord.js v12及更低版本,频道类型判断改为
ch.type === 'voice',权限判断改为ch.permissionsFor(guild.me).has('CONNECT')即可正常运行 - discord.js v14版本已经废弃了频道对象原生的
join()方法,需要额外安装@discordjs/voice依赖,使用该库提供的joinVoiceChannel方法实现连接逻辑 - 短时间内批量加入大量服务器的语音频道可能触发Discord平台风控,建议控制操作频率
内容的提问来源于stack exchange,提问作者AKSHAT
相关产品推荐
相关产品推荐

