Reputation: 33
I am making a Discord.js Bot on v12 that includes a mute command, that mutes the whole voice channel you are in. The problem is when somebody leaves the channel they stay muted. I am trying to fix that with a simple event to unmute the person, but I don't understand the VoiceStateUpdate
and the OldState
and NewState
. I've searched widely, but I can only find one for joining a vc, not leaving. Here is what I got so far:
Mute command:
else if (command === 'mute') {
message.delete()
if (!message.member.roles.cache.has('') && !message.member.roles.cache.has('')) {
message.reply('You don\'t have permission to use this commmand!')
.then(message => {
message.delete({ timeout: 5000 })
}).catch();
return;
}
if (message.member.voice.channel) {
let channel = message.guild.channels.cache.get(message.member.voice.channel.id);
for (const [memberID, member] of channel.members) {
member.voice.setMute(true);
}
} else {
message.reply('You need to join a voice channel first!')
.then(message => {
message.delete({ timeout: 5000 })
}).catch();
}
}
Unmute event:
client.on('voiceStateUpdate', (oldState, newState) => {
if (oldState.member.user.bot) return;
if (oldState.member.user !== newState.member.user) member.voice.setMute(false);
});
Thanks for taking your time to help me! :)
Upvotes: 0
Views: 7599
Reputation: 728
You can't manipulate the voice state of a person that isn't on a voice channel, it would cause a DiscordAPIError: Target user is not connected to voice.
, and even if you could, you probably would still not want to, because even if you don't get another unhandled promise error of some sort, you would probably still get an infinite loop by checking if the New State's channel is null, because it would fire another event with null channel as soon as you unmute the person and so on.
So, the way I see it right now, a possible solution to your problem, is to unmute whenever the user joins a channel. It might not be necessary to be this way if someone can figure out a better way to check if it is a channel leaving that is happening other than just using newState.channel === null
. Whatever, if it's okay for you to unmute on join, you could do it this way:
client.on('voiceStateUpdate', (oldState, newState) => {
if (oldState.channel === null && newState.channel !== null) {
newState.setMute(false);
}
});
Notice though that this could bug if someone joins the channel exactly after leaving, otherwise, you should have no problems.
Upvotes: 0
Reputation: 26
client.on('voiceStateUpdate', (oldMember, newMember) => {
const oldUserChannel = oldMember.voice.channelID
const newUserChannel = newMember.voice.channelID
if (oldUserChannel === 'MUTED CHANNEL ID' && newUserChannel !== 'MUTED CHANNEL ID') {
newMember.voice.setMute(false);
}
});
You can write in a json file the id of the muted channel and take it from there, I can't think of another way, sorry :(
Upvotes: 0
Reputation: 1245
Well, you are already on the right track. What you should do is check if someone is muted when they leave a voice channel and then remove that mute.
So lets get to that.
First we check if the person is leaving the voice channel. Thats important because the voiceStateUpdate
event is triggered every time some does anything to their voice, i.e. mute or joining. We do that by checking if oldState.channelID
is either null
or undefined
as that indicates a joining.
if (oldState.channelID === null || typeof oldState.channelID == 'undefined') return;
Next we need to check if the person leaving is muted and return if not.
if (!oldState.member.voice.mute) return;
And lastly we remove the mute.
oldState.member.voice.setMute(false);
So your entire voiceStateUpdate
should look a little something like this.
client.on('voiceStateUpdate', (oldState, newState) => {
if (oldState.channelID === null || typeof oldState.channelID == 'undefined') return;
if (!oldState.member.voice.mute) return;
oldState.member.voice.setMute(false);
});
Upvotes: 1
Reputation: 10019
according to this link (and I havent tested this) you need something like this:
const Discord = require("discord.js")
const bot = new Discord.Client()
bot.login('*token*')
bot.on('voiceStateUpdate', (oldState, newState) => {
let newUserChannel = newState.voiceChannel
let oldUserChannel = oldState.voiceChannel
if(oldUserChannel === undefined && newUserChannel !== undefined) {
// User Joins a voice channel
} else if(newUserChannel === undefined){
// User leaves a voice channel
}
})
Upvotes: 0