How to detect when user receives a role? - discord.js

I just began trying to learn how to write my first Discord bot this morning so I am very inexperienced with discord.js, but I am familiar with JavaScript. However I have been searching for a couple of hours trying to find a way to call a function whenever a user in my server receives or loses a role.
In my server I have added the Patreon bot which assigns a role to users who become patrons. And I would like to create a custom bot that posts "hooray username" in my general channel when a user receive the patron role.
I can not find any example that shows how to detect when a user gains or loses a role. Is it possible to do this simply using an event? Or would I possibly need to periodically iterate over all users and maintain a list of their current roles while checking for changes?
I apologize that my question doesn't include any code or examples but I haven't made any progress and am reaching out to the SO community for guidance.

You want to use the event guildMemberUpdate.
You can compare the oldMember state to the newMember state and see what roles have changed.
This is not the most elegent solution but will get the job done.
client.on('guildMemberUpdate', (oldMember, newMember) => {
// Roles
const oldRoles = oldMember.roles.cache,
newRoles = newMember.roles.cache;
// Has Role?
const oldHas = oldRoles.has('role-id'),
newHas = newRoles.has('role-id');
// Check if removed or added
if (oldHas && !newHas) {
// Role has been removed
} else if (!oldHas && newHas) {
// Role has been added
}
});
https://discord.js.org/#/docs/main/stable/class/Client?scrollTo=e-guildMemberUpdate

This is simple with Client#guildMemberUpdate. Here’s some simple code that may help you
(This is the shortest code I could come up with)
client.on('guildMemberUpdate', async (oldMember, newMember) => {
if(oldMember.roles.cache.has('patreonRoleId')) return;
if(newMember.roles.cache.has('patreonRoleId')) {
//code here to run if member received role
//Warning: I didn’t test it as I had no time.
}
})
To see the removed role, just put the logical NOT operator (!) in front of both of the if statements like this:
if(!oldMember.roles.cache.has('patreonRoleId'))
if(!newMember.roles.cache.has('patreonRoleId'))
Note: make sure you have guildMembers intent enabled from the developers portal

Related

Discord Autocode reaction reply bot (not reaction role bot)

I have been using autocode.com to create some Discord bots. I have very little programming experience and found autocode to be quite easy. However, I've tried asking a question on autocode's discord that no one seems to understand or is asking.
I am trying to create a bot that replies to reactions--but does not assign roles, but instead, provides a reply--either in thread or a DM to that user who uses that specific emoji reaction.
For example, this is what I am looking to do: if there is a bot message in #channelx, userX will react to that message with a pepperoni emoji and then a pizza bot will reply back with a message either in thread or DM such as, "Hi #userx, your pizza topping has been recorded and will be ready for pickup in 15 minutes, please visit this link.com to track your order".
Autocode has a bot that can react to reactions and assign roles but I can't seem to reverse engineer it give a reply, rather than assign roles.
I appreciate any assistance. Thanks!
What does autocode use? Python or node.js? If python, you can do something like this:
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('message'):
await message.channel.send('hi')
If node.js, you can do something like this:
client.on('messageCreate', msg => {
if (msg.content === 'specific message') {
msg.reply(`response text`);
}
});
I was previously a Community Hero at the Autocode Discord server. Try finding another app through this, and if none are available, the thing to do would be looking through the API's. Here's one for messaging in general, here's one for responding, and here's one for dm-ing.
Let's say, for example, I'd be making it reply to a reaction through DM:
The first thing you do is make sure the event trigger is set to message.reaction.add. This is so that the code you will write is triggered whenever a reaction is added.
Make either a switch or if statement to change what happens depending on what reaction triggers the code. In this example, I'll just use an if statement for easy explanation.
const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});
if (context.params.event.emoji.id == '1234567890') {
await lib.discord.users['#0.2.1'].dms.create({
recipient_id: `${context.params.event.member.user.id}`,
content: `Hi <#${context.params.event.member.user.id}>, your pizza topping has been recorded and will be ready for pickup in 15 minutes, please visit this link.com to track your order`
});
}
What this does is check if the thing that triggered this event has the emoji id equaling '1234567890': If it does, then it follows into that if statement, and if it does not, it skips over it.
In the future, please stay patient in the Autocode Discord server; The ones who are helping are also community members, similar to here. You may always ask the same question every now and then.

Discord.js check for member getting a role

I am currently trying to find a way to execute some code whenever a user is granted a specific role
However sadly I havent found any good resources on it
I imagine there could be a way of using the AUDIT log ,however Id like to avoid using the audit log due to security concerns
client.on('guildMemberUpdate', async(before, after) => {
const role = before.guild.roles.cache.get('ROLE_ID');
if(!before.roles.has(role) && after.roles.has(role)){
//code
}
})
Pretty simple, guildMemberUpdate event is fired on a guild member update, ie a role update.
#guildMemberUpdate

Checking if message author has specific permissions in Discord.js v16?

I’m making a command that should only be ran by people that can kick or ban, assuming that the role they have is some sort of mod or admin. I’ve only seen answers for previous versions, like .hasPermissions.
what do i do?
As said in this question (self-answered by me), .hasPermission() has been removed. Use .permissions.has() instead
if (message.member.permissions.has("KICK_MEMBERS")) {
// member HAS kick members permissions
}
You can also check multiple permissions at the same time. This is just an example that would probably not be used
if (message.member.permissions.has(["MANAGE_GUILD", "SEND_MESSAGES"])) {
// member HAS *BOTH* permissions to send messages and manage server
}
You can check all the permission flags at the discord.js docs for Permissions.FLAGS
It's really simple
if (message.member.permissions.has('KICK_MEMBERS') || message.member.permissions.has('BAN_MEMBERS')) {
//your code here
}

Retrieve all members from specific channel in Discord

I have been trying different ways to retrieve the current list of members in a specific channel (e.g. 'networking'). But I am only get one, the actual bot user inside the channel, but nothing else.
This is the latest version of the code I am trying.
client.channels.cache.filter((c) => c.name === 'networking').forEach(channel => {
channel.fetch().then((channel) => {
console.log(channel.name);
for (let [snowflake, guildMember] of channel.members) {
console.log(`${guildMember.displayName} (${guildMember.id})`);
}
});
});
It's probably something to do with caching but I'm just not able to find the right sequence. Any help would be appreciated.
Thank you Tyler2P for the answer. You were absolutely right. Membership intents were disabled by default. I have lost so much time on this :) Thanks a million.
For everyone who gets to this question. Solution is so simple as enabling the "Server Members Intent".
Bot configuration in Discord Application page

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

Resources