Discord.js:返回用户当前的 voice.channelId 已过时
Posted
技术标签:
【中文标题】Discord.js:返回用户当前的 voice.channelId 已过时【英文标题】:Discord.js: Returning the current voice.channelId of a user is outdated 【发布时间】:2021-12-04 12:32:49 【问题描述】:对于我的不和谐机器人的命令,我需要获取用户当前连接的语音通道的 ID。我目前有类似的工作:
module.exports =
name: 'hit',
description: "Return your voiceChannel ID",
execute(message)
console.log('User ' + message.author.username + ' // ' + message.author.id + ' used the hit command.');
console.log(message.member.voice.channelId);
;
问题在于,这仅返回启动机器人时用户所在频道的语音频道 ID。如果用户切换频道或离开每个频道,此处返回的语音频道 ID 仍然保持不变。 我也试过这个,有完全相同的问题:
module.exports =
name: 'hit',
description: "Return your voiceChannel ID",
execute(message, config, commands)
console.log('User ' + message.author.username + ' // ' + message.author.id + ' used the hit command.');
awaitFetch(message);
;
async function awaitFetch(message)
let newInfo = await message.member.fetch(true);
console.log(newInfo.voice.channelId);
我认为是因为 discord.js 在启动时缓存了这些信息。但我不知道如何更新所说的缓存......
编辑:不确定这是否有帮助,但这是调用每个命令的 main.js:
const Discord = require('discord.js');
let config = require('./config.json');
const client = new Discord.Client(
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES,
Discord.Intents.FLAGS.GUILD_MEMBERS,
Discord.Intents.FLAGS.GUILD_PRESENCES,
]
);
const fs = require('fs');
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles)
const command = require(`./commands/$file`);
client.commands.set(command.name, command);
client.once('ready', () =>
console.log('Online!');
);
client.on('messageCreate', message =>
console.log (message.member.voice.channelId);
if(message.author.bot || message.mentions.everyone === true) return;
if(fs.existsSync(`guildConfigs/$message.guild.id.json`))
delete require.cache[require.resolve(`./guildConfigs/$message.guild.id.json`)];
config = Object.assign(, require(`./guildConfigs/$message.guild.id.json`));
else
config = require('./config.json');
let prefix = config.prefix;
if(message.mentions.has(client.user) && !message.author.bot)
client.commands.get('pinged').execute(message, config);
else if(!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).split(' ');
const command = args.shift().toLowerCase();
if(command === 'help')
client.commands.get('help').execute(message, config, client.commands);
else if(command === 'ping')
client.commands.get('ping').execute(message);
else if(command === 'hit')
client.commands.get('hit').execute(message, args, config);
else if(command === 'topic')
client.commands.get('topic').execute(message);
else if(command === 'fact')
client.commands.get('fact').execute(message);
else if(command === 'settings')
if(message.member.permissions.has('ADMINISTRATOR'))
client.commands.get('settings').execute(message, args, config);
else
message.channel.send('Sorry bro, but this command is only available for server admins ????');
);
client.login(config.token);
撞
【问题讨论】:
我不知道为什么会这样;我从来没有遇到过message.member.voice.channelId
过时的问题。但是,您可以尝试的一件事是在.fetch()
上使用force
布尔值,如docs 所示。像这样:message.member.fetch(true)
。这会跳过缓存检查并强制 djs 直接请求 Discord API。
我试过了,但遗憾的是它仍然过时了......
您是否尝试过使用message.member.voice.channel.id
?根据官方docs,语音状态的只读属性channel
为:The channel that the member is connected to
。我猜他们的意思是当前已连接
另外,如果用户在没有进入频道的情况下调用该命令,您的代码将抛出异常,请改用 message.member.voice?.channel?.id
。会更安全
@Nick 仍然过时,只显示机器人启动时用户所在的频道...:/
【参考方案1】:
好的,我要说明几点:
我看到您没有使用数据库,而是为每个公会创建了几个 json 文件,这不是野兽方法(如果您计划为多个公会服务),以解决您可以考虑使用 MongoDB,它字面上的工作方式相同(BSON 不是 JSON,但您不会看到区别)。 除非触发ready
事件,否则不会触发您正在侦听的事件,因此一个好的做法是将所有侦听器(消息、加入或其他)移动到就绪事件回调中
(只是提示):您将消息与.split(' ')
分开,但如果用户输入!ping user
(有两个空格)怎么办?这将导致['ping', '', 'user']
,您可以使用正则表达式调用拆分函数:.split(/ +/)
,这样您将用至少一个空格拆分消息
一旦您拥有带有const commandName = args.shift().toLowerCase()
的命令名称,您可以执行以下操作:
const command = client.commands.get(commandName);
if(!command) return;
// The permissions check you do for the settings command should be moved on the
// command logic itself, what you should do in the main file is just take a message,
// get a command and execute it
command.execute(message, args) // from the message instance you can get the client and the config can be required(using a db would resolve this 'issue')
说了这么多,解决你的问题很简单,你只是忘了在客户端添加GUILD_VOICE_STATES
intent,就是这样,应该可以解决这个问题
【讨论】:
这就是解决方案,不敢相信这么简单的东西被我和其他许多人偷走了......对于其他事情:1)这将更麻烦,因为机器人正在运行在一台可能是 2 或 3 台服务器上。 2)所有事件都按预期触发,该消息就在那里,以便我知道机器人何时完全启动 3)谢谢,很高兴知道! ^^ 4) 有趣...以上是关于Discord.js:返回用户当前的 voice.channelId 已过时的主要内容,如果未能解决你的问题,请参考以下文章
Discord.js 错误:错误:找不到 FFmpeg/avconv!即使安装
Discord.js 13 channel.join 不是函数