0
votes

I have a line of code for a discord bot to remove a specific named role and add a role named "muted" for a specific amount of time. Basically, the server can only have 3 roles, one that can issue the command, a "normal" rank with normal permissions, and then a "muted" role. and my code specifically removed the normal role and adds the muted role so they don't have any permissions.

Well I added my bot onto another server with more than 3 roles, I decided to give everyone the normal role and also make the muted role. when I run the command, it works, but since the people have other roles, it allows then to continue speaking even though the muted role is at the top priority.

My questions is that is there some code where I can just remove all their roles and add the muted role. and when the muted period is over, the muted role is removed and their previous roles are restored? here is my code below:

 case 'mute':

    if(!message.member.roles.cache.find(r => r.name === "Admin")) return message.channel.send('You dont have permissions to do that you clown')

    let person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]))
    if(!person) return message.reply("User Doesn't Exist");

    let mainrole = message.guild.roles.cache.find(role => role.name == "normal");
    let muterole = message.guild.roles.cache.find(role => role.name == "muted");

    if(!muterole) return message.reply("Role Doesn't Exist");

    let time = args[2];

    if(!time){
        return message.reply("How Long?");
    }

    person.roles.remove(mainrole.id);
    person.roles.add(muterole.id);

    message.channel.send(`@${person.user.tag} has now been muted for ${ms(ms(time))}`);

    setTimeout(function(){
        person.roles.add(mainrole.id);
        person.roles.remove(muterole.id);
        message.channel.send(`@${person.user.tag} has now been unmuted`)
    }, ms(time));
        break;
    case 'help':
        const embed2 = new MessageEmbed()
        .setTitle("How To Get Commands")
        .setColor(0x00fff7)
        .setDescription("Do /commands to get the list of commands");

        message.author.send(embed2);
        break;
2

2 Answers

2
votes

The simplest way to do this would be to get the list of roles from the user, clear their roles, and then apply for the Muted role. You'd then want to cache their previous roles or even store the data in a database in case the bot goes down, that way once restarted you could fetch the data and continue where you left off.

Here's a quick example I wrote on the fly. You probably want to cache the roles a bit differently than the way I did since my method was just for a quick demo, and i highly recommend saving the data to a database or even something like a .json file.

let cachedUserRoles = {};

function addMutedRole(guildId, userId, roleId) {
    //Get the guild the user is apart of
    let guild = client.guilds.get(guildId);
    //Specify the user from the guild
    let guildMember = guild.members.get(userId);

    //Cache the users existing roles so we can restore them later
    cachedUserRoles[userId] = guildMember.roles.cache
    //Remove all roles from user
    guildMember.roles.set([])
        //Add the muted role after all roles have been removed with an array of the single role ID
        .then(member => member.roles.add([roleId]))
        //Catch and report any errors that might happen
        .catch(console.error)
}

function restoreRoles(guildId, userId) {
    //Get the guild the user is apart of
    let guild = client.guilds.get(guildId);
    //Specify the user from the guild
    let guildMember = guild.members.get(userId);
    //Get and set the user's previouse roles from cachedUserRoles and error log if anything goes wrong
    guildMember.roles.set(cachedUserRoles[userId]).catch(console.error)
}

In your case, it would look something like this:

case 'mute':
        if(!message.member.roles.cache.find(r => r.name === "Admin")) return message.channel.send('You dont have permissions to do that you clown')

        let person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]))
        if(!person) return message.reply("User Doesn't Exist");

        let muterole = message.guild.roles.cache.find(role => role.name == "muted");

        if(!muterole) return message.reply("Role Doesn't Exist");

        let time = args[2];

        if(!time){
            return message.reply("How Long?");
        }

        //Cache their already existing roles
        cachedUserRoles[person.id] = person.roles.cache;
        //Set their roles to an empty array to clear them, then add the muted role once all roles were removed successfully
        person.roles.set([]).then(member => member.roles.add(muterole)).catch(console.error);

        message.channel.send(`@${person.user.tag} has now been muted for ${ms(ms(time))}`);

        setTimeout(function(){
            //Grab their existing roles and set them back to the user, we wont need to remove the muted role since setting the roles would override all existing ones already
            person.roles.set(cachedUserRoles[person.id]).catch(console.error)
            message.channel.send(`@${person.user.tag} has now been unmuted`)
        }, ms(time));
        break;
    case 'help':
        const embed2 = new MessageEmbed()
            .setTitle("How To Get Commands")
            .setColor(0x00fff7)
            .setDescription("Do /commands to get the list of commands");

        message.author.send(embed2);
        break;
0
votes

I am not sure if there is a more efficient way to do this but you can try the following:

Loop through all their roles and save them to a file or even a database and once the time runs out, remove the muted role and loop through the list of saved roles to add them back.