How to give a role to all members, with a interval - discord.js

I want to make a command so i can give all the users in my discord server a role.
Problem is now with the code i have, that he gives not all the members the specified role because it are to much members and it will spam the discord api.
How can i make it so that after i do the command, the bot will give all the members the specified role, but not directly to prevent spamming the API, but for example every 10 min he gives 5 members the role until all the members got the role.
Hope some one could helpe me
this is what i have now :
module.exports = {
name: "give-roles",
aliases: ["gr"],
category: "roles",
description: "Give's all members the Verified-Member role",
usage: `${prefix}give-roles`,
run: async (Client, message) => {
message.guild.members.fetch()
.then(console.log)
.catch(console.error);
let role = message.guild.roles.cache.find(r => r.name === 'Verified-Member')
if (!role) return message.channel.send(`**${message.author.username}**, role not found`)
message.guild.members.cache.filter(m => !m.user.bot).forEach(member => member.roles.add(role))
message.channel.send(`**${message.author.username}**, role **${role.name}** was added to all members`)
},
}```

A way to get round this is to add a role when a member joins instead of all at once (which will never work since not all members will be cached)
<client>.on('guildMemberAdd', member => {
var memberRole = member.guild.roles.cache.find(role => role.name === "<role name here>");
member.roles.add(memberRole); //auto assign role on join
});
change the code in <> to fit your needs
The reason you cannot add a role to all members is due to the v12 addition of cache.
Managers/Cache
v12 introduces the concept of managers, you will no longer be able to directly use collection methods such as Collection#get on data structures like Client#users. You will now have to directly ask for cache on a manager before trying to use collection methods. Any method that is called directly on a manager will call the API, such as GuildMemberManager#fetch and MessageManager#delete.
I would recommend that you read the docs to further understanding of how bots work here

Related

Role.members only contains a single value when there are multiple

I have a slash command with this option definition:
.addRoleOption(option =>
option.setName('role')
.setRequired(true)
.setDescription("The role associated with the game.")
)
In execute() of the same file/command, I have this part where I want to collect and store all members who have the role.
const existingParticipants = [];
interaction.options.getRole('role').members
.each(member => existingParticipants.push(member.id));
console.log(`Import compiled a list of all role-having members: ${existingParticipants}`);
And this is printed:
Import compiled a list of all role-having members: [userid redacted]
When I have other people do the command, their IDs are added to the list until I restart the bot, at which point the list goes back to just my ID. I have also tried to bypass the cache to see if that was the issue but it still persists:
await interaction.guild.roles.fetch(interaction.options.getRole('role').id, { force: true })
.then(role => role.members
.forEach(member => existingParticipants.push(member.id)))
Is it possible to get all of the guild members that have the role?
I have the GUILD_MEMBERS gateway intent enabled. Running Discord.js v14.7.1.

Set Role Color for Discord.js bot

I am trying to make my bot's role a pink color for the current server using the Client.on("ready") However whenever I run the bot with what I currently have the console returns:
(node:6504) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'cache' of undefined
Here is my code I am currently using. I know I need to for loop on every guild but I'm not sure how I would do that, I could use a for or just a .forEach however I can't find the correct way to do such.
const role = client.guild.roles.cache.get('Aiz Basic+');
role.edit({ name: 'Aiz Basic+', color: '#FFC0CB' });
In advance thank you to anybody who replies and helps with my message.
Client#Guild Isn‘t existing. Only Client#Guilds. You can fix this problem by looping through the cache of all your guilds with:
client.guilds.cache.forEach((g) => { })
And inside the loop you can use your code after fixing the .get function, because the get function needs a role id not a role name. You could find the role via the name by writing:
const role = <Guild>.roles.cache.find((r) => r.name === /* The role name */);
Make sure you replaced <Guild> with your guild variable.
Try this code if client.guild is not defined, it could also be because you are using bot instead of client
let role = message.guild.roles.cache.find(role => role.name === "Aiz Basic+");

Set autorole on specific guilds only

I'd like to auto set roles for new users when they join server X, problem is that this bot is on server Y as well, and server Y doesn't have the role.
client.on('guildMemberAdd', member => {
console.log('User ' + member.user.tag + ' has joined Steampunk.');
var role = member.guild.roles.find(x => x.name === "name");
member.addRole('247442955651121154');
})
I was hoping that I could do a simple check before applying the role, if user have joined server X, add the role, if else, do nothing. So far my attempts have failed.
Any input would be appreciated!
The original code is trying add a specific role you put in, and not the role you just looked up a line before that. There shouldn't be any issues with other servers the bot is in, because member.guild gives the guild of the member object, and since this member object is coming from a guildMemberAdd it means that member.guild will only return the guild that was just joined. The code in the edit has a lot of strange things going on, though.
The first issue I see is that in order to look through the channels in a guild, you have to use guild.channels.cache.find(), guild.channels.find() is old now and doesn't work in v12. Same goes for client.guild, guild.roles, etc. The part at the bottom of your edited code doesn't seem to make much sense at all. The code should get the roles of the newly joined guild (member.guild.roles.cache), look through them to find the role you want (you did this correctly with the .find()) and then apply the role to the member. Neither server nor role ever get used in your code, and guild.id is a property, not a method.
Let me know if you need help following these instructions, although it looks like you should be able to do it now. Always look at the discord.js docs first to check properties, methods, etc.
I ended up defining the guild in question by name, saved it as a const, and made a check for the specific guild.
If your bot is on several servers but you only want the greet/addRole on a specific one, all integrated into the message displayed on joining;
//Welcome message and autorole for specific server and channel.
client.on('guildMemberAdd', member => {
const = client.guilds.find(guild => guild.name === "Steampunk");
if (!guild) return;
const channel = member.guild.channels.find(ch => ch.name === "greetings");
if (!channel) return;
let botembed = new Discord.RichEmbed()
.setColor("#ff9900")
.setThumbnail(member.user.avatarURL)
.setDescription(`${member} Welcome to the Ark Steampunk Sponsored Mod Discord!\nPlease report all <#244843742568120321> and if u need any help view or ask your question in <#334492216292540417>. Have any ideas we got a section for that too <#244843792132341761>. Enjoy!:stuck_out_tongue: Appreciate all the support! <http://paypal.me/ispezz>`)
.setTimestamp()
.setFooter("Steampunk Bot", client.user.avatarURL);
channel.send(botembed);
console.log('User ' + member.user.tag + ' has joined ' + member.guild.name + '.');
var role = member.guild.roles.find(x => x.name === "name");
member.addRole('247442955651121154');
});

Trying to implement Patreon-only commands/functions on my discord bot, how would I accomplish this?

My discord bot gives the role of 'Patreon' to my patreon supporters. This role is given on my main discord bot server. So right now I'm trying to write some commands that would be only available to users who have the role 'Patreon' in the BOTS discord server, how can I accomplish this?
Like is there a way I can be like -
message.member.has('Patreon Role').in('My Discord Server)?
Let's go over the tasks you need to accomplish this.
Get the "home guild" with your users and corresponding Patreon role.
See Client.guilds and Map.get().
Find the user in the guild.
See Guild.member().
Check whether or not the user has the Patreon role.
See GuildMember.roles and Collection.find().
You can define a function to help you out with this, export it and require it where you need it (or define it within relevant scope), and then call it to check if a user is one of your Patreon supporters.
Here's what this function would look like...
// Assuming 'client' is the instance of your Discord Client.
function isSupporter(user) {
const homeGuild = client.guilds.get('idHere');
if (!homeGuild) return console.error('Couldn\'t find the bots guild!');
const member = homeGuild.member(user);
if (!member) return false;
const role = member.roles.find(role => role.name === 'Patreon');
if (!role) return false;
return true;
}
Then, as an example, using this function in a command...
// Assuming 'message' is a Message.
if (!isSupporter(message.author)) {
return message.channel.send(':x: This command is restricted to Patreon supporters.')
.catch(console.error);
}
message.member.roles.find('name', 'Patreon Role');//this returns either undefined or a role
What that does is it searches the users collection to see if the have "Patreon Role"
If the message is on the same server, otherwise you could do
client.guild.find('name','My Discord Server').member(message.author).roles.find('name', 'Patreon Role'); //this also returns undefined or a role
Clearly that second option is long, but what is basically does is searches the servers the bot is in for a server called 'My Discord Server' then it finds the GuildMember form of the message.author user resolvable, then it searches their roles for the role 'Patreon Role'
There is a chance it will crash though if they aren't on the server(the documentation doesn't say if it returns and error or undefined for some reason) so if it does crash you could instead do
client.guild.find('name','My Discord Server').members.find('id', message.author.id).roles.find('name', 'Patreon Role'); //this also returns undefined or a role
You can read more here: https://discord.js.org/#/docs/main/stable/class/User
and here
https://discord.js.org/#/docs/main/stable/class/Client
and here
https://discord.js.org/#/docs/main/stable/class/Guild
To try and give a full example, assuming this is in your message event
if (message.member.roles.find(r => r.name === 'Patreon') == undefined &&
commandIsExclusive || message.guild.id !== 'this-id-for-BOTS-server') {
// Don't allow them in here
}
Essentially, to run a command they must be a supporter, in a specific server and if it is exclusive and the other criteria aren't met, they are denied

Creating channel permission overwrites

I am creating a bot command so that when you type !setup it sets up the whole server (creating channels and roles, etc). I have already set it to create the roles and channels but there are some channels that only specific roles can type in, whereas, other roles can only read the channel. I don't know how to set up permission overwrites for certain roles.
I have already looked on the Discord.js documentation and it doesn't help much. I receive an error that supplied parameter was neither a user nor a role, but I don't know how to gain the role ID.
message.guild.createRole({
name: 'Admin',
color: '#2494ad',
permissions: ['ADMINISTRATOR', 'VIEW_AUDIT_LOG', 'MANAGE_GUILD', 'MANAGE_CHANNELS', 'SEND_TTS_MESSAGES', 'CREATE_INSTANT_INVITE', 'KICK_MEMBERS', 'BAN_MEMBERS', 'ADD_REACTIONS', 'PRIORITY_SPEAKER', 'READ_MESSAGES', 'SEND_MESSAGES', 'MANAGE_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY', 'MENTION_EVERYONE', 'USE_EXTERNAL_EMOJIS', 'CONNECT', 'SPEAK', 'MUTE_MEMBERS', 'DEAFEN_MEMBERS', 'MOVE_MEMBERS', 'USE_VAD', 'CHANGE_NICKNAME', 'MANAGE_NICKNAMES', 'MANAGE_ROLES', 'MANAGE_WEBHOOKS', 'MANAGE_EMOJIS']
});
message.guild.createRole({
name: 'Requesting Role',
color: '#1bb738',
permissions: ['READ_MESSAGES', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY',]
});
//Categories and Channels
message.guild.createChannel('clan-communications', {
type: 'category',
permissionOverwrites: [{
id:'25311096',
deny: ['SEND_MESSAGES']
}]
});
//Permissions
message.channel.overwritePermissions('25311096', {
SEND_MESSAGES: false
});
break;
I would like roles to have base permissions for the whole server. But certain roles have overwrites for different channels. Instead it says the supplied parameter was neither a user nor a role.
First and foremost, welcome to Stack Overflow. Hopefully we can be of help to you.
Let's walk through a solution step by step to achieve your desired result.
When you create your roles, you should declare a variable to store them. That way, you can use what the client just created later on. Since Guild.createRole() returns a promise, we can save the fulfilled result into a variable.
Note that the keyword await must be placed in async context (within an async function).
const vip = await message.guild.createRole('VIP', { ... });
Then, when you need to use that role, you can refer to the variable.
await message.guild.createChannel('VIPs Only', {
type: 'category',
permissionOverwrites: [
{
id: vip.id,
allow: ['READ_MESSAGES']
}, {
id: message.guild.defaultRole.id, // #everyone role
deny: ['READ_MESSAGES']
}
]
});
If the role already exists, you can retrieve it from the Collection of roles returned by Guild.roles.
const testRole = message.guild.roles.get('IDhere');
const adminRole = message.guild.roles.find(r => r.name === 'Admin');
Other simple improvements.
In your code snippet, I don't see any error handling. The methods you're using return promises. If an error occurs in any, the promise state will become rejected. Any rejected promises that aren't caught will throw errors. To fix this, attach catch() methods to each promise (better for individual handling) or wrap async code in a try...catch statement.
When creating your Admin role, know that the ADMINISTRATOR permission automatically grants all other permissions (and allows users to bypass channel-specific permissions). Therefore, there's no need to list any other permission, or change the role's permission overwrites in any channels.
Your IDs in your code don't appear to be valid. Discord IDs are snowflakes, represented by strings of 18 digits. You can access them through Developer Mode in Discord. However, you shouldn't have to hard-code them with this solution, unless they already exist.
In the permissions array for your Requesting Role role, you have an extra comma.

Resources