0

I'm developing a bot where at a set interval, like every hour the bot will pick a random user and remove a role from them, it will be using the positioning on the side to do this. The problem was I couldn't really find a function in Discord.JS that had a property for a guild member's position on the side.

I've tried finding other bots that do this and try to mimic them, but I didn't find anything. I double checked the documentation but didn't find anything.

      var thatguild = message.guild.id.find(`576463944298790929`);
      thatguild.fetchMembers();

    setInterval(function() {
      let sizes = thatguild[Math.floor(Math.random() * thatguild.members.size())];
      if(thatguild.member.id == `userid1` || `userid2`)
      return(thatguild.member.removeRole('roleid'))
    }, 1000) 

I expect a bot where it randomly picks a user by the position, and remove a role from the member. What I actually get is code and no way of knowing if it works or not.

SomePerson
  • 1,171
  • 4
  • 16
  • 45

3 Answers3

0

Explanation:

Let's go through what we need to do if we want to accomplish what you want.

  1. Acquire the desired guild.
    • A collection of guilds (GuildStore in master) a client is handling is available with Client.guilds.
    • To find a value by its key, use Map.get().
    • To find a value by another property or testing of an expression, use Collection.find().
    • To simply use the guild the message was sent in within a message event, use message.guild.
  2. Acquire the desired role.
    • A collection of roles within a guild (GuildMemberRoleStore in master) a client is handling is available with Guild.roles.
    • Refer to the options previously listed to obtain a value from the collection.
  3. Select a random member.
    • A collection of a guild's members (GuildMemberStore in master) is available with Guild.members.
    • Before selecting a member, the possible choices need to be limited to those with the role, so use Collection.filter().
    • To select a random value from a collection, use Collection.random().
  4. Remove the role from the member.
  5. Set an interval.
    • To set an interval, use setInterval().
    • In case something goes wrong, assign it to a variable so it can be cleared later.

Code:

function roleRoulette(guild, role) {
  const possible = guild.members.filter(m => m.roles.has(role.id));
  if (possible.size === 0) return clearInterval(interval);

  const member = possible.random();

  member.removeRole(role)
  // MASTER: member.roles.remove(role)
    .then(() => console.log(`Removed ${role.name} from ${member.tag}.`))
    .catch(err => {
      console.error(err);
      clearInterval(interval);
    });
}

const guild = client.guilds.get('576463944298790929');
if (!guild) return;

const role = guild.roles.get('576464298088333323');
if (!role) return;

const interval = setInterval(roleRoulette(), 60 * 1000, guild, role);

Discord.js Docs:

stable
master

slothiful
  • 5,548
  • 3
  • 12
  • 36
  • When I was modifying the code to the correct IDs, and ran the code, it said the setInterval has an error, so I added a function and I got spammed in console with `Removed role from undefined.` and I slowed down the timer to about 10 seconds. The console message, however, went faster. Everyone's member role got removed faster than 10 seconds. – SomePerson May 18 '19 at 10:01
  • `function roleRoulette(guild, role) { const member = guild.members.random(); member.removeRole(role) // ...or use the following for master: // member.roles.remove(role) .then(() => console.log(`Removed role from ${member.tag}.`)) .catch(err => console.error(err)); } const guild = bot.guilds.get('576939601500045312'); // ...or use one of the following: // const guild = client.guilds.find(g => g.name === 'test'); // const guild = message.guild; if (!guild) return; setInterval(roleRoulette(guild, '576946568591048726'), 10000); // min * sec * ms` – SomePerson May 18 '19 at 17:59
  • Edited answer with updated code. As for the speed of it, the timing is in milliseconds. Make sure multiple intervals aren't being set, i.e. if the code is in a `message` event. – slothiful May 18 '19 at 18:08
  • using this edited code, it still proceeds to remove roles from everyone within 3 seconds. – SomePerson May 18 '19 at 22:39
  • Edited code again. My apologies, it should work now. – slothiful May 19 '19 at 10:39
  • now it's saying it can't read property 'members' of undefined (the `guild.members.filter`) Do I defined guild as in const guild = require(discord.js)? – SomePerson May 21 '19 at 04:25
  • Where you're calling the function, you need to define `guild` using one of the ways mentioned in the explanation. – slothiful May 21 '19 at 09:56
0

It's honestly a bit hard to understand what you exactly want. I understand you want the bot to remove a random role from a random member at a set interval. Also, you want to do that based on the role hirarchy somehow, I'm guessing the highest role first? If that is the case, what you could try is this:

let randomMember = message.guild.members.cache.random()
if(randomMember.roles.cache.length === 0) return
let roleToRemove = randomMember.roles.cache.first()
for (let r in randomMember.roles.cache){
    if(r.position < roleToRemove.position) roleToRemove = r;
}
await randomMember.roles.remove(roleToRemove)

Well, no matter what, if you are looking to remove roles based on their position then role.position will be required for your code in some way.

https://discord.js.org/#/docs/discord.js/main/class/Role?scrollTo=position

Good luck :)

Edit: Don't forget to exclude bots and bot roles from the removal when you implement something like this!

0

This is probably what I wanted:

  • Every hour, the bot picks a random user from the entire guild, removes a specific role from them, and repeats.

It's still hard to understand what past-me actually wanted, but here's another answer.

I don't know what version of D.JS was hot at the time, but I'm gonna use v9 in my answer.

  • You want an interval removing members every hour, so 1000 * 60 * 60 means 1000 milliseconds, 60 times -> 60 seconds(1 minute) * 60 times -> 1 hour.
  • This function inside the interval needs* to be async, so we can request a guild with ALL the members.
  • Then, we get the members collection and filter it in a way to remove users that don't have the role we're looking for OR if they are in an ignore list.
  • If no members have a role, don't do anything.
  • Else, pick a random member and remove the role. Repeat.
var ignore = ['...'];
var guildSel = client.guilds.get('...');
var role2Remove = '...';
setInterval(async () => {
   var guild = await guildSel.fetchMembers();
   var members = guild.members.filter(m=>m.roles.has(role2Remove) && !ignore.includes(m.id));
   if(members.size > 0) {
      var randUsr = members.random();
      randUsr.removeRole(role2Remove);
   } else return;
}, 1000 * 60 * 60);
SomePerson
  • 1,171
  • 4
  • 16
  • 45