如何使用 discord.js V12 检测用户何时离开 Discord 中的语音频道

How to detect when a user leaves a voice channel in Discord with discord.js V12

我正在 v12 上制作一个 Discord.js 机器人,它包含一个静音命令,可以使您所在的整个语音频道静音。问题是当有人离开频道时他们会保持静音。我正在尝试通过一个简单的事件来解决此问题以取消静音,但我不理解 VoiceStateUpdateOldStateNewState。我已经广泛搜索,但我只能找到一个加入 vc,而不是离开。这是我到目前为止得到的:

静音命令:

    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();
        }
    }

取消静音事件:

client.on('voiceStateUpdate', (oldState, newState) => {
    if (oldState.member.user.bot) return;

    if (oldState.member.user !== newState.member.user) member.voice.setMute(false);
});

感谢您花时间帮助我! :)

根据 this link(我还没有测试过)你需要这样的东西:

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

  }
})

好吧,你已经在正确的轨道上了。你应该做的是检查某人在离开语音频道时是否被静音,然​​后取消静音。

让我们开始吧。

首先我们检查这个人是否正在离开语音频道。这很重要,因为 voiceStateUpdate event is triggered every time some does anything to their voice, i.e. mute or joining. We do that by checking if oldState.channelIDnullundefined,因为这表示加入。

if (oldState.channelID === null || typeof oldState.channelID == 'undefined') return;

接下来我们需要检查离开的人是否静音,如果没有return。

if (!oldState.member.voice.mute) return;

最后我们去掉静音。

oldState.member.voice.setMute(false);

所以你的整个 voiceStateUpdate 看起来应该有点像这样。

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);
});
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);
  }
});

您可以在 json 文件中写入静音频道的 ID 并从那里获取它,我想不出其他方法,抱歉:(

你不能操纵不在语音通道上的人的语音状态,这会导致 DiscordAPIError: Target user is not connected to voice.,即使你可以,你可能仍然不想这样做,因为即使你没有得到另一个未处理的承诺错误,你可能仍然会通过检查新状态的频道是否为空来获得无限循环,因为一旦你取消静音,它就会触发另一个带有空频道的事件并且等等。

所以,我现在的看法是,当用户加入频道时,取消静音是您问题的一个可能解决方案。如果除了使用 newState.channel === null 之外,有人可以找到一种更好的方法来检查它是否正在离开正在发生的频道,则可能没有必要采用这种方式。不管怎样,如果您可以在加入时取消静音,您可以这样做:

client.on('voiceStateUpdate', (oldState, newState) => {
  if (oldState.channel === null && newState.channel !== null) {
    newState.setMute(false);
  }
});

请注意,如果有人刚好在离开后加入频道,这可能会出现错误,否则,您应该没有问题。