'Discord bot to kick users based on role

Good Afternoon,

first off I apologize for my lack of knowledge when it comes to Java Script. I am trying to fill a need for one of our servers without exactly knowing how :D The end goal is to kick a user once they received a specific role called "Inactive".

Figure i'd start with creating a bot that kicks a user if you 'kick @username'. These are the files I have:

Config.json:

{
"token": "(mytoken, which i'm obviously not posting :D)"
}

Index.js:

// Require the necessary discord.js classes
const { Client, Intents } = require('discord.js');
const { token } = require('./config.json');

// Create a new client instance
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });

client.once('ready', () => {
    console.log('Ready!');
});

client.on('message', message => {

    if(!message.content.startsWith(prefix) || message.author.bot) return;

    const args = message.content.slice(prefix.length).split(/ +/);
    const command = args.shift().toLowerCase();

    if(command === 'kick'){
        client.commands.get('kick').execute(message, args);
        }

});

client.login(token);

package.json:

{
  "name": "kickbyrole",
  "version": "1.0.0",
  "description": "Bot to kick based on discord role",
  "main": "index.js",
  "author": "Tri",
  "dependencies": {
    "@discordjs/builders": "^0.12.0",
    "@discordjs/rest": "^0.3.0",
    "discord-api-types": "^0.28.0",
    "discord-prefix": "^3.0.0",
    "discord.io": "^2.5.3",
    "discord.js": "^13.6.0",
    "winston": "^3.6.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "ISC"
}

kick.js:

module.exports = {
    name: 'kick',
    description: "This command kicks a member!",
    execute(message, args){
        const target = message.mentions.users.first();
        if(target){
            const memberTarget = message.guild.members.cache.get(target.id);
            memberTarget.kick();
            message.channel.send("User has been kicked");
        }else{
            message.channel.send("You couldn't kick that member");
        }
    }
}

I can "node ." to initiate it without error. My bot shows online.. but nothing happens when I try to !kick @username.

Two asks.. a) what am I missing for my bot to work and b) what do I need to change for it to kick based off user role? So like 'kick @role'

Appreciate all your time and help!

Cheers

Tri



Solution 1:[1]

If you want to remove a user from a voice channel I think it's not memberTarget.kick() but perhaps memberTarget.setVoiceChannel(null).

to kick all users I think what you could do is get all the users that contains this role and run a forEach function

message.member?.guild.roles.cache.
find((role) => role.name === "Inactive")?.
members.
forEach(m => m.voice.setChannel(null))

If you want to make it into a fully working bot I would do like this:

const { Client, Intents } = require("discord.js");
const { token } = require("./config.json");

const prefix = "!" // mention the prefix

// Create a new client instance
const client = new Client({ intents: [Intents.FLAGS.GUILDS] });

client.once("ready", () => {
  console.log("Ready!");
});

client.on("message", async (message) => {
    if (message.author.bot) return;
    if (!message.guild) return;
    if (!message.content.startsWith(prefix)) return;


    const args = message.content.replace(prefix, "").split(" ");
    const cmd = args[0].toLowerCase();
    args.shift();


  if (cmd === "kick") {
   const role =  message.member?.guild.roles.cache.find(
    (role) => role.name === "Inactive"
  );
  role?.members.forEach((m) => {
    m.voice.setChannel(null);
    m.roles.remove(role);
  });
  }
});

client.login(token);

now when you run !kick it should kick every user that has Inactive role and remove the Inactive role from the user.

Solution 2:[2]

To kick all the users who have the Inactive role, is pretty simple. All you have to do is go through all the users with the role by first fetching the mentioned role and using role.members and then kicking them. The code might look something like this:

client.on('message', (message) => {
    if (message.author.bot) return
    if (message.content.startsWith('kick')) {
        const mentionedRole = message.mentions.roles.first() // Gets the mentioned role
        const usersWithRole = mentionedRole.members // Gets all the members with the role
        usersWithRole((user) => { // Go through the collection of members
            user.kick() // Kick them
        })
    }
})

In this case, the bot will first get the mentioned role, then get all the members who have the role, go through each member and then kick them one by one. If instead of getting the mentioned role, you just want to always kick the users with the Inactive role, you can replace the mentionedRole variable with this:

const mentionedRole = message.guild.roles.cache.find(r => r.name === 'Inactive')

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Caladan