For a command of my discord bot I need to get the ID of the voicechannel the user is currently connected to. I've got something similar working currently:
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);
}
};
The problem is that this only returns the voicechannel id of the channel that the user was in when the bot was started. If the user switches the channel or leaves every channel the voicechannel id that is returned here still stays the same. I also tried this, which had the exact same problem:
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);
}
I think it is because discord.js caches these information when starting up. But I have no idea how to update said cache...
Edit: not sure if this helps but here is the main.js which calls every command:
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);
bump
Ok, I'm making some points:
ready
event is fired, so a good practice would be to move all your listeners(message, join or whatever) inside the ready event callback.split(' ')
but what if the user enters !ping user
(with two spaces)? That will results in ['ping', '', 'user']
, instead you can call the split function with a regex: .split(/ +/)
in this way you will split the message with at least one spaceconst commandName = args.shift().toLowerCase()
, you can do: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')
Said that, the solution for your problem is simple, you just forgot to add the GUILD_VOICE_STATES
intent on your client, that's it, that should fix this issue