David Lee
David Lee

Reputation: 601

Discord.js v14 how to return members of a Guild that have one role and not another role?

I have a server where members of that server can have the role of "Member" and another role of the state they live in (id "Ohio", "Colorado", etc)

I am now in a situation where I need to make the role of "Member" dependent on also having the role of the state they live in. For example, someone can have the roles of "Member" and "California", but they cannot have only the role of "Member" and no state role. Also it is ok for a member to only have a role of the state they live in.

The bot that I coded is having trouble returning all the members that have the "Member" role and not a state role. It is returning members that have the role of "Member" and another state, as well as members who only have the role of "Member". In other words, it's not working properly.

I am not sure if it's because Discord is not returning the most up to date cache, or if my code is wrong.

Here is my code for the command.


    const { SlashCommandBuilder } = require('discord.js');
    
    module.exports = {
      data: new SlashCommandBuilder()
        .setName('remove-tag')
        .setDescription('This will remove the role of Member if a member does not have a State role'),
      async execute(interaction) {
        // gets all members in the server
        const allMembers = await interaction.guild.members.fetch()
        // gets the Role called Member
        const memberRole = interaction.guild.roles.cache.find(r => r.name === "Member");
        // array of the state roles listed by id
        const stateRole = [1, 2, 3, 4, 5, ... 50] //(these ID's are dummy ids since I want to keep that information confidential)
    
        arrayOfPeopleWithTheMemberRoleRemoved = []
    
        allMembers.forEach(member => {
          if (member.roles.cache.has(memberRole.id) && !member.roles.cache.hasAny(stateRole)) {
            member.roles.remove(memberRole.id);
            arrayOfPeopleWithTheMemberRoleRemoved.push(member);
    
            // console.log(member.roles.remove(arrayOfPeopleWithTheMemberRoleRemoved))
          }
        })
    
        await interaction.reply(`You removed the Member role from these people:${arrayOfPeopleWithTheMemberRoleRemoved}`);
      },
    };
  

Upvotes: 2

Views: 964

Answers (1)

Elitezen
Elitezen

Reputation: 6710

I copied your code and adapted it to TypeScript, intellisense immediately showed an error on .hasAny():

enter image description here

Looking at the documentation, .hasAny() takes an infinite amount of string parameters and not a single array. Try using the spread operator on stateRole:

if (member.roles.cache.has(memberRole.id) && !member.roles.cache.hasAny(...stateRole)) {
   
}

An alternative to .hasAny() or for those not using Collections:

!GivenArray.some(value => DataArray.includes(value))
if (member.roles.cache.has(memberRole.id) && !member.roles.cache.some(r => stateRole.includes(r.id)) {
   
}

Upvotes: 1

Related Questions