Discord.js:返回用户的当前 voice.channelId 已过时
Discord.js: Returning the current voice.channelId of a user is outdated
对于我的 discord 机器人的命令,我需要获取用户当前连接到的语音通道的 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);
}
};
问题是这只是 returns 机器人启动时用户所在频道的语音频道 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);
颠簸
好的,我说几点:
- 我看到你没有使用数据库,而是为每个公会创建了几个 json 文件,这不是野兽方法(如果你计划为多个公会服务),你可以解决这个问题考虑使用 MongoDB,它实际上以相同的方式工作(BSON 不是 JSON,但您不会看到差异)。
- 除非
ready
事件被触发,否则您正在收听的事件不会被触发,因此一个好的做法是将所有监听器(消息、加入或其他)移动到就绪事件中回调
- (提示):您正在使用
.split(' ')
拆分消息,但是如果用户输入 !ping user
(有两个 space)怎么办?这将导致 ['ping', '', 'user']
,相反,您可以使用正则表达式调用拆分函数:.split(/ +/)
这样,您将使用 至少 拆分消息 space
- 一旦你有了带有
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,就是这样,应该可以解决这个问题
对于我的 discord 机器人的命令,我需要获取用户当前连接到的语音通道的 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);
}
};
问题是这只是 returns 机器人启动时用户所在频道的语音频道 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);
颠簸
好的,我说几点:
- 我看到你没有使用数据库,而是为每个公会创建了几个 json 文件,这不是野兽方法(如果你计划为多个公会服务),你可以解决这个问题考虑使用 MongoDB,它实际上以相同的方式工作(BSON 不是 JSON,但您不会看到差异)。
- 除非
ready
事件被触发,否则您正在收听的事件不会被触发,因此一个好的做法是将所有监听器(消息、加入或其他)移动到就绪事件中回调 - (提示):您正在使用
.split(' ')
拆分消息,但是如果用户输入!ping user
(有两个 space)怎么办?这将导致['ping', '', 'user']
,相反,您可以使用正则表达式调用拆分函数:.split(/ +/)
这样,您将使用 至少 拆分消息 space - 一旦你有了带有
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,就是这样,应该可以解决这个问题