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,就是这样,应该可以解决这个问题