Assigned Roles by Reactions - javascript

I have recently been trying to make a Reaction-to-Role bot and have been struggling with some criteria for making it.
I have researched and looked at other peoples' versions of a similar bot on it, yet I have not been able to use it purposefully in my own code.
The goal of the bot is to have multiple options on a message. Here's an example of what it would look like as a message.
**What do you drive?**
šŸš™ - A car
šŸš² - A bicycle
āŒ - Nothing
There would be reactions under the message of each emoji that was specified. Once a user clicked on one of these emojis, it would add a role to them such as "Drives a Bike" or "Rides a Bicycle."
I have managed to go as far as making an addrole command (which receives the message the bot will react to, the emoji, and the role it assigns) and stores some info to a JSON file.
The area in which I have been having issues is actually capturing each user that reacts to the specific message, finding out which reaction they sent, and assigning the role assigned to that emoji.
Here is my current code, I'm thank you for any help you may provide :)
addrole.js
if(!args[0] || !args[1] || !args[2] || !args[3]) return message.reply("please use the following format: `autorole #channel messageID icon #role`.");
let channel = message.mentions.channels.first();
let messageID = args[1];
let icon = args[2];
let role = message.mentions.roles.first();
if(!channel.fetchMessage(messageID)) return message.reply("could not find the specified message. Please check the channel and message ID again.");
channel.fetchMessage(messageID).then(msg => {
msg.react(icon);
info[role.name] = {
roleID: role.id,
channelID: channel.id,
icon: icon,
};
fs.writeFile("./configs/info.json", JSON.stringify(info), (err)=>{
if(err) console.log(err);
});
});
I know that creating an event named messageReactionAdd and messageReactionRemove are needed, but I'm not sure how to find their variables and match them accordingly.
Additionally, I am not sure how to make it constantly watch one message even after a restart. From some testing, I noticed that messageReactionAdd would not continue watching the specified messages reactions after a restart.
I am looking for any guidance/help that anyone may provide, thank you!

I've seen on: https://github.com/Sam-DevZ/Discord-RoleReact/blob/master/roleReact.js that there is an event. I've tried this out and it's working.

Related

How to work with member role update part of audit log in discord.js

I am currently making a bot to notify people by sending a message when a member role is being updated on the server. I donā€™t know how to set up the initial part which should be formally client.on part.
Here I have shown a bit of my code that I think should be working but unfortunately it is not working.
const Discord = require(ā€˜discord.jsā€™);
const client = Discord.Client();
client.on('guildMemberUpdate', (oldMember, newmember) => {
This is what Iā€™m expecting to do:
Before I give you the code, I'll give you the steps that I took to achieve it.
Tip: ALWAYS use the documentation. The discord.js documentation helped me a lot of times.
Process:
Set up a designated text channel. In my case, I manually grabbed the channel's ID and set it as the variable txtChannel. You will have to replace my string of numbers with your own channel ID.
I cached every single role ID from the "new" member as well as from the "old" member.
Checked whether or not the length of the new member roles array was longer than the old member roles array. This signifies that the member has gained a role.
Created a filter function that "cancels" out every single role ID that both new and old role arrays have in common.
Grabbed the icon URL - I found out that if you try to get the URL of a user who has the default discord icon, it'll return NULL. To bypass this, you could just grab some sort of invisible PNG online and set it as a placeholder. Else you'll get an error saying that it wasn't able to retrieve the proper URL link.
Set up the embed, and sent it into the text channel!
Note:
At first, I couldn't figure out why the bot wasn't registering for other users who have their roles changed. Then I found this question on Stack Overflow. The link states that you have to make sure to enable Guild Members Intent. Just follow the instructions from the link and you should be all set! It's a little bit outdated (in terminology), so when it references "Guild Members Intent" it actually is "Server Members Intent" now.
Code:
It's awfully elaborate, but it gets the job done.
client.on('guildMemberUpdate', (oldMember, newMember) => {
let txtChannel = client.channels.cache.get('803359668054786118'); //my own text channel, you may want to specify your own
let oldRoleIDs = [];
oldMember.roles.cache.each(role => {
console.log(role.name, role.id);
oldRoleIDs.push(role.id);
});
let newRoleIDs = [];
newMember.roles.cache.each(role => {
console.log(role.name, role.id);
newRoleIDs.push(role.id);
});
//check if the newRoleIDs had one more role, which means it added a new role
if (newRoleIDs.length > oldRoleIDs.length) {
function filterOutOld(id) {
for (var i = 0; i < oldRoleIDs.length; i++) {
if (id === oldRoleIDs[i]) {
return false;
}
}
return true;
}
let onlyRole = newRoleIDs.filter(filterOutOld);
let IDNum = onlyRole[0];
//fetch the link of the icon name
//NOTE: only works if the user has their own icon, else it'll return null if user has standard discord icon
let icon = newMember.user.avatarURL();
const newRoleAdded = new Discord.MessageEmbed()
.setTitle('Role added')
.setAuthor(`${newMember.user.tag}`, `${icon}`)
.setDescription(`<#&${IDNum}>`)
.setFooter(`ID: ${IDNum}`)
.setTimestamp()
txtChannel.send(newRoleAdded);
}
})

I have a problem with the discord bot that gives an automatic roll to every new user

I am trying to create a discord bot that will give an automatic roll to any new user who enters the site and it does not work (I am actually interested in this way that the code should work according to the roll ID because my rollers' names are in a foreign language) I would be happy if someone could help me understand
The code is attached.
client.on('guildMemberAdd', (member) => {
let welcomeRole = member.guild.roles.cache.get("814461419298750475");
if (!welcomeRole) return console.log('Couldn\'t find the member role.');
member.roles.add(welcomeRole);
})
According to the error message that you show in : https://prnt.sc/10dbibn
It clearly stated that your bot doesn't have the permission to do that.
Try giving your bot the "Manage Role" permission and retry to see if that fixes your issue !

Problems with messageDelete in Discord js

I try to make my bot on Discord server. Want to make a function, which will copy all deleted message in text channel, but, messageDelete hear only deleted message which was writing after bot start. When I delete message which make earlier bot start, its not work.
{
client.on ("messageDelete", messageDelete =>{
let channel = client.channels.find(channel => channel.name === 'log-deleted-message')
console.log(`Deleted :${messageDelete.content}`)
channel.send(`${messageDelete.author.username} write : ${messageDelete.content}`
})
}
The above answer is now outdated.
With Discord.js V12 you can now Cache messages on the messageDelete event, You would need to enable Partials. Once this is enabled, you can fetch the message beforehand like this:
if(message.partial){
let msg = await message.fetch()
console.log(msg.content)
}
That will then log the content of the previously uncached message.
messageDelete is an event that is called when a message is deleted while the bot is on. If a message is deleted before the bot is turned on there is no way to recover it, which is why it's known as deleted. The only way to accomplish the goal that you want is to leave the bot on permanently. Read more in the docs if you want more information.

How to make a bot find a channel owner / compare to the author's ID

I'm making a bot where if you do d!move, the bot will move the channel where the message was sent in under a category via ID. I also want to make it so that whoever does the command has permissions such as MANAGE_CHANNELS, which I've already added. The problem is that when I want to confirm whoever created that channel is the person that activated the command, the bot says yes. I did this on an alt account, where I made the channel and my alt was the one initializing it, and the bot said "success!" I also wanted to make it so if someone else made the channel, and when I did it, it would work because I made the bot know my ID.
I've researched Google and found nothing.
I've tried using a function with fetchAuditlog but get anywhere.
if(!message.channel.client.user.id == message.author || !message.author.id == `329023088517971969`) return message.channel.send("You don't own this channel!")
else message.channel.send("success!");
message.channel.setParent(`576976244575305759`);
I expect the bot to be able to check if the author created the channel, and lead to You don't own this channel if they don't own it. But if they do then the bot moves the channel.
The actual result is the bot moving the channel anyway regardless if they own the channel or not.
As #AndrƩ has pointed out, channel.client represents the client itself, not the user who created the channel. Also, the last line in your code is not part of the else statement, so that's why it's run regardless of the conditions you defined.
To reach a solution, you can make use of the guild's audit logs. You can search for entries where the user is the message author and a channel was created. Then, all you have left is to check if one of those entries is for the current channel, and run the rest of your code if so.
Sample:
message.guild.fetchAuditLogs({
user: message.author,
type: 'CHANNEL_CREATE'
}).then(logs => {
if (!logs.entries.find(e => e.target && e.target.id === message.channel.id)) return message.channel.send('You don\'t own this channel.');
else {
// rest of code
}
}).catch(err => console.error(err));
When you go <anything>.client.user it will return the bot client.
If you want to see who created the channel you would have to check the Audit Logs or save it internally.
I've checked the documents. Here's what it says for .client about the
channel. It says the person that initialized the channel, or the
person that created it.
On documentation I see this:
The client that instantiated the Channel
instantiated is different of initialized

Sending private messages to user

I'm using the discord.js library and node.js to create a Discord bot that facilitates poker. It is functional except the hands are shown to everyone, and I need to loop through the players and send them a DM with their hand.
bot.on("message", message => {
message.channel.sendMessage("string");
});
This is the code that sends a message to the channel when any user sends a message. I need the bot to reply in a private channel; I've seen dmChannel, but I do not understand how to use it. I have the username of the member that I want to send a message to.
An example would be appreciated.
Edit:
After looking around for a user object, I found that I can get all of the users using the .users property of the client (bot). I will try using the user.sendMessage("string") method soon.
In order for a bot to send a message, you need <client>.send() , the client is where the bot will send a message to(A channel, everywhere in the server, or a PM). Since you want the bot to PM a certain user, you can use message.author as your client. (you can replace author as mentioned user in a message or something, etc)
Hence, the answer is: message.author.send("Your message here.")
I recommend looking up the Discord.js documentation about a certain object's properties whenever you get stuck, you might find a particular function that may serve as your solution.
To send a message to a user you first need to obtain a User instance.
Obtaining a User instance
use the message.author property of a message the user sent .
call client.users.fetch with the user's id
Once you got a user instance you can send the message with .send
Examples
client.on('message', (msg) => {
if (!msg.author.bot) msg.author.send('ok ' + msg.author.id);
});
client.users.fetch('487904509670337509', false).then((user) => {
user.send('hello world');
});
The above answers work fine too, but I've found you can usually just use message.author.send("blah blah") instead of message.author.sendMessage("blah blah").
-EDIT- : This is because the sendMessage command is outdated as of v12 in Discord Js
.send tends to work better for me in general than .sendMessage, which sometimes runs into problems.
Hope that helps a teeny bit!
If your looking to type up the message and then your bot will send it to the user, here is the code. It also has a role restriction on it :)
case 'dm':
mentiondm = message.mentions.users.first();
message.channel.bulkDelete(1);
if (!message.member.roles.cache.some(role => role.name === "Owner")) return message.channel.send('Beep Boing: This command is way too powerful for you to use!');
if (mentiondm == null) return message.reply('Beep Boing: No user to send message to!');
mentionMessage = message.content.slice(3);
mentiondm.send(mentionMessage);
console.log('Message Sent!')
break;
Just an FYI for v12 it's now
client.users.fetch('487904509670337509', false).then((user) => {
user.send('heloo');
});
where '487904509670337509' is an id number.
If you want to send the message to a predetermined person, such as yourself, you can set it so that the channel it would be messaging to would be their (your) own userID. So for instance, if you're using the discord bot tutorials from Digital Trends, where it says "to: ", you would continue with their (or your) userID. For instance, with how that specific code is set up, you could do "to: userID", and it would message that person. Or, if you want the bot to message you any time someone uses a specific command, you could do "to: '12345678890'", the numbers being a filler for the actual userID. Hope this helps!
This is pretty simple here is an example
Add your command code here like:
if (cmd === `!dm`) {
let dUser =
message.guild.member(message.mentions.users.first()) ||
message.guild.members.get(args[0]);
if (!dUser) return message.channel.send("Can't find user!");
if (!message.member.hasPermission('ADMINISTRATOR'))
return message.reply("You can't you that command!");
let dMessage = args.join(' ').slice(22);
if (dMessage.length < 1) return message.reply('You must supply a message!');
dUser.send(`${dUser} A moderator from WP Coding Club sent you: ${dMessage}`);
message.author.send(
`${message.author} You have sent your message to ${dUser}`
);
}
Make the code say if (msg.content === ('trigger') msg.author.send('text')}

Categories