2
votes

I wanted to create a script that when a person connects to specific voice-channel it creates a room which only that person can join and others can't.

The script's logic is simple; it creates permissions for the person who connected to the channel (speak, voice activity, etc.) and denies CONNECT permission from the @everyone role.

The problem is that my bot gives permissions to the person who connected to the voice channel but does not change any permission of the @everyone role. How can I solve that?

const { VoiceState } = require('discord.js');
const SettingsJSON = require('../../Configuration/Settings.json');
const Settings = SettingsJSON.PrivHub;

module.exports = async (oldState, newState) => {
  let mainChannel = oldState.guild.channels.cache.get(Settings.Room);
  if (!mainChannel) return;

  if (
    !oldState.channelID &&
    newState.channelID &&
    newState.channel.parentID == mainChannel.parentID &&
    newState.channelID == mainChannel.id
  ) {
    newState.guild.channels
      .create(
        `${Settings.Symbol} ${newState.member.displayName} kişisinin odası`,
        {
          type: 'voice',
          parent: mainChannel.parentID,
          permissionOverwrites: [
            mainChannel.permissionOverwrites.clone().set(
              newState.member.id,
              {
                id: newState.member.id,
                allow: [
                  'MANAGE_CHANNELS',
                  'STREAM',
                  'VIEW_CHANNEL',
                  'CONNECT',
                  'SPEAK',
                  'USE_VAD',
                ],
              },
              {
                id: oldState.guild.roles.everyone.id,
                deny: ["CONNECT"],
              },
            ),
          ],
        },
      )
      .then((channel) => {
        if (newState.member && newState.member.voice.channelID)
          newState.member.voice.setChannel(channel);
      });
    return;
  } else if (oldState.channelID && newState.channelID) {
    let oldChannel = oldState.channel;
    if (
      oldChannel.position > mainChannel.position &&
      oldChannel.parentID == mainChannel.parentID &&
      oldChannel.members.size <= 0 &&
      !oldChannel.deleted
    )
      oldChannel.delete().catch(undefined);
    if (
      newState.channelID == mainChannel.id &&
      newState.channel.parentID == mainChannel.parentID
    ) {
      newState.guild.channels
        .create(
          `${Settings.Symbol} ${newState.member.displayName} kişisinin odası`,
          {
            type: 'voice',
            parent: mainChannel.parentID,
            permissionOverwrites: [
              mainChannel.permissionOverwrites.clone().set(
                newState.member.id,
                {
                  id: newState.member.id,
                  allow: [
                    'MANAGE_CHANNELS',
                    'STREAM',
                    'VIEW_CHANNEL',
                    'CONNECT',
                    'SPEAK',
                    'USE_VAD',
                  ],
                },
                {
                id: oldState.guild.roles.everyone.id,
                deny: ["CONNECT"],
                },
              ),
            ],
          },
        )
        .then((channel) => {
          if (newState.member && newState.member.voice.channelID)
            newState.member.voice.setChannel(channel);
        });
    }
    return;
  } else if (
    oldState.channelID &&
    oldState.channel.parentID == mainChannel.parentID &&
    !newState.channelID
  ) {
    let oldChannel = oldState.channel;
    if (
      oldChannel.position > mainChannel.position &&
      oldChannel.members.size <= 0 &&
      !oldChannel.deleted
    )
      oldChannel.delete().catch(undefined);
  }
};

module.exports.config = {
  Event: 'voiceStateUpdate',
};
1

1 Answers

1
votes

After you clone the collection mainChannel.permissionOverwrites, you only use the set() method with the key newState.member.id.

The set() method only accepts two arguments, the key and the value of the element to add. In your code above you use three arguments, first the key, second an object with the allow property, and lastly another object with the deny property (which should be used for the @everyone role).

In JavaScript, if you pass some extra arguments when a function only needs two, nothing happens, it just ignores it. That's what happens here. You only set the first overwrite with the allow prop.

To fix this, you could use two set() methods; one for the member, and one for the @everyone role:

{
  type: 'voice',
  parent: mainChannel.parentID,
  permissionOverwrites: [
    mainChannel.permissionOverwrites
      .clone()
      .set(newState.member.id, {
        id: newState.member.id,
        allow: [
          'MANAGE_CHANNELS',
          'STREAM',
          'VIEW_CHANNEL',
          'CONNECT',
          'SPEAK',
          'USE_VAD',
        ],
      })
      .set(oldState.guild.roles.everyone.id, {
        id: oldState.guild.roles.everyone.id,
        deny: ['CONNECT'],
      }),
  ],
}