I have simple code, that checks if a user has an specific role:
message.member.roles.cache.some(role => role.id === 'role_id')
The problem is now, that when I change the roles, so remove the specific role while the bot is running, the user still has the rights. So in the Bot Cache, the user still has the specific role.
Is there any way to renew the bot cache when user roles change?
Thanks in advance
GuildMemberManager.fetch updates the cache. Simply do this above that statement:
await message.guild.members.fetch();
//rest of code with cached members
Related
So atm I'm working on a Discord.js bot and have a command to ban people. The issue is if I turn the bot off and on again all the setTimeouts reset. So say, if I were to ban someone for a week, turn the bot off and on in between there, they will never automatically be unbanned.
setTimeout(function () {
memberTarget.roles.remove(bannedRole);
}, ms(args[1]));
What other way could I use for it to remember to unban everyone after the bot has been turned on again?
You need to use database or data persist
Store bans data to database/data persist then set worker to check for unban (expiry).
Database https://www.tutorialsteacher.com/nodejs/data-access-in-nodejs
Data Persist https://www.npmjs.com/package/node-persist
I've currently got reaction roles set up in my code and they work, however I have to rerun the command every time I restart the bot, which isn't optimal.
Is it possible at all to cache the data so that there is only one reaction role message and the roles are given out regardless of how many times the bot has rebooted?
Any help with this is greatly appreciated!
in order to do this you need to have a database setup and store the message's id.
Then when your bot starts you can fetch that message inside messageReactionAdd/messageReactionRemove client event(s) and track for reactions on the message id you have previously stored.
I'm currently having an issue with editing channel permissions for each member who reacts to an embed.
The current code I have is:
channel.createOverwrite([{ id: user.id, allow: ['VIEW_CHANNEL'] }])
This does allow the user to view the channel but it only changes the channel permissions once.
So for example:
User 1 clicks the embed reaction which allows them for the channel.
User 2 then reacts to the embed which removes User 1 from being able to view the channel and adds user 2.
I want both users to be allowed to view the channel once the reaction has been clicked but just can't figure out how to do this.
When I was creating a bug-reporting system (using a ticketing-type system) for my own discord bot, I faced the exact same issue and realized that I couldn't use channel.createOverwrite() because it overrides any and all permissions that were previously setup for the channel (including the overwrites created for other users, as well as the overwrites that prevented everyone from sending messages in my bug-reports channel).
My solution was to first fetch all of the current overwrites for the channel, and then simply append the overwrites for the user that reacted onto them. It's possible that there might be a simpler method of doing this; but my solution is tested and worked for me, so that's what I'm including in this answer. Here's an example, based on the code from my bot and modified to suit your purpose.
Giving the user(s) perms to view the channel
//Fetch current channel permission overwrites
var overwrites = channel.permissionOverwrites.array();
//If overwrite already exists for reacting user, address it (to prevent dupe overwrites)
if (overwrites.find(o => o.id == user.id)) return;
//Add the overwrite for the user that reacted
overwrites.push({
id: user.id,
allow: ['VIEW_CHANNEL'],
})
//Give permissions to view channel
channel.overwritePermissions(overwrites, 'Add reason for allowing user to view channel here');
Removing the user(s) perms to view the channel
//Fetch current channel permission overwrites
var overwrites = channel.permissionOverwrites.array();
//Remove the user's perms to send messages in channel
overwrites.splice(overwrites.findIndex(o => o.id == user.id), 1);
message.channel.overwritePermissions(overwrites, 'Reason');
Explanation
So in both examples, we first get all of the current permission overwrites in the channel (including the permissions set for both roles and users in that channel).
When giving the user perms, we then check to see if the user already has an overwrite in the channel and if so, return (assuming the only overwrites they will be getting in this channel are the VIEW_CHANNEL perms they receive from this bot; otherwise, change the return to something else that suits your purposes). Then, we add in a new overwrite created for our reacting user, and replace all of the channel's permission overwrites with our newly modified version; this allows us to include both the overwrite for the user that just reacted as well as the overwrites for all of the users that have already reacted.
When removing the user's perms to view the channel, we simply use .splice() to remove the overwrite's index from the array of overwrites, and then we update the channel's overwrites with our newly modified version.
If you find a simpler way of achieving this at any point in time, feel free to comment it below and I will append it to this answer.
Relevant Resources
Discord.js docs for channel.overwritePermissions()
A working example in my discord bot
So, I wanted to create a command like .getuser #role and the bot then tags every user with that role and after it says x people have this role..
The problem is that I couldn't find anywhere something that resembles this, I hope someone will help me cause I'm out of luck on this one!
You can use roles.get()
members = message.guild.roles.cache.find(role => role.name === 'role name').members.map(m=>m.user.tag);
Edit:
I've been received lots of messages claiming that the bot is inaccurately showing what members have what roles. This is because discord uses the cache to grab info about roles. To fix this do the following...
Navigate to your application at https://discord.com/developers/applications
Go to the bot section
Turn ON "Server Members Intent"
This will make it so that your discord bot doesn't grab from the cache for member data from the api.
let membersWithRole = guild.roles.resolve('role_ID').members.size
Basically we get a specific role from a guild trough its ID and then we see the size of the members collection of the role.
I have a discord bot that uses a leveling system. It listens to message.author.id, logs the latest message, gives the user XP and at certain levels, users are awarded a new role. Have been working fine for months.
Recently I added a few(10 to be exact) webhooks to the server to enable users to send in bug reports.
Problem is that my bot is reading those webhooks messages as well, and webhooks don't have an author ID, hence, bot crash every time a webhook is posting something.
I know we can except certain webhooks like this if (message.webhookID != 'X') return;
but its kinda inconvenient since I might add or delete webhooks in the future. Is there a way to make my bot ignore all webhooks similar to how it can ignore other bots?
EDIT
This is what I did,
client.on('message', (message) => {
//Check if its a webhook.
if (message.webhookID) {
// block of code to be executed if the condition is true
} else {
// block of code to be executed if the condition is false
if (message.guild.id != '335008833267040256')return;{
....
Yes, you can do if (message.webhookID) return;, that should return if the message is sent from any webhook.