How do I add multiple reactions? - javascript

I've looked everywhere for answers and I can't figure this out.
Here's what I want to do:
I want to run some command initially for my bot to send an embed to a specific channel only admins have access to. Done.
Then the bot will immediately react to its own message with the number emojis 1, 2, and 3. Problem.
I don't want the bot to await a reaction to the message from an admin. This embed is meant to stay there UNTIL an admin reacts to it. That could be within 1 minute, or 3 days, but if I have to reboot the bot for any reason then it will stop awaiting the reaction. So I have an event that triggers when someone reacts with a given emoji, this works. It can be improved, but it functions:
bot.on("messageReactionAdd", (messageReaction, user) => {
console.log(messageReaction);
if(reaction.emoji.name === "\u0031\u20E3") {
message.channel.send('one'); //This is temporary to test it out. There will be other code here eventually.
}
else if(reaction.emoji.name === "\u0032\u20E3") {
message.channel.send('two');
}
else if(reaction.emoji.name === "\u0033\u20E3") {
message.channel.send('three');
}
});
My problem is that when I run this code:
let cmdEmbed = new discord.RichEmbed()
.setTitle('**Command Menu Test**')
.setDescription("Type commands")
.setAuthor('InfernoBot', 'https://cdn.discordapp.com/avatars/533089334224617474/17ddec7cb178601d17964040ed8dc32d.png?size=2048')
.setColor(0xD41519);
message.channel.sendEmbed(cmdEmbed).then(function (message) {
message.react('\u0031\u20E3')
message.react('\u0032\u20E3') //This doesn't run
message.react('\u0033\u20E3') //This doesn't run
});
It only ever reacts with the '1' emoji.
How do I make it react with emoji numbers 1, 2, and 3, without awaiting for a reaction?
PS: I'm going to implement some code that will resend the exact same embed with the same reactions once the existing embed has been reacted to, to reset it.
EDIT: The bot doesn't always react with 1. However, it only ever adds one reaction. It's not consistent.
.

Found the answer about 30 mins after posting this. I'll share for anyone who was having the same issue.
My first chunk of code in the original post was causing the bot to break and reboot.
I replaced the first chunk of code with:
bot.on("messageReactionAdd", (reaction, user) => {
if(user.toString() !== '<#533089334224617474>' /*InfernoBot ID*/) {
console.log('User is not InfernoBot')
if(reaction.emoji.name === "\u0031\u20E3") {
//code here
}
}
});
And I replaced the second chunk of code with:
let cmdEmbed = new discord.RichEmbed()
.setTitle('**Command Menu Test**')
.setDescription("Type commands")
.setAuthor('InfernoBot', 'https://cdn.discordapp.com/avatars/533089334224617474/17ddec7cb178601d17964040ed8dc32d.png?size=2048')
.setColor(0xD41519);
message.channel.sendEmbed(cmdEmbed).then(function (message) {
message.react('\u0031\u20E3').then(() => message.react('\u0032\u20E3')).then(() => message.react('\u0033\u20E3'));
});

Related

How make a bot delete Discord channel messages that start with or are from a bot

I have a bot in my Discord server for playing music. As it works with commands, and it answers if there is something like a playlist the channel is spammed with songs or messages that later on are meaningless. So I want the bot that each time it leaves a voice channel, it clears the command messages that were sent to it and the answer messages that it sent.
So I have looked around a bit and came to this code but it doesnt work. I added some console logs to see up where it goes in, and it reaches FLAG 1 but not FLAG 2. So what is wrong in that condition? PREFIX is the "!" that commands start with, and 0123456789 is the bot ID
else if (msg.content.trim().toLowerCase() == _CMD_LEAVE) {
const channel = msg.channel;
const messageManager = channel.messages;
messageManager.fetch({ limit: 100 }).then((messages) => {
messages.forEach((message) => {
console.log("FLAG 1: "+ util.inspect(message))
if ( (message.content.startWith(PREFIX)) || (message.author.id == 0123456789)) {
console.log("FLAG 2: "+ util.inspect(message))
message.delete();
}
});
});
}
Thanks in advance
Two things here: startWith should actually be startsWith since you didn't mention any errors I'll assume this is just a typo from the example code.
Second, message.author.id == 0123456789 won't work since IDs should be strings, not numbers.

How do I fix DiscordAPIError: Unknown Message?

I made a bot that deletes text messages in an image channel, but when I use it it's logs this error.
client.on("message", async message => {
if (message.author.bot) return;
const users = ['853248522563485717'];
if (message.channel.id === '841260660960395287') {
if (users.includes(message.author.id)) return;
if (message.attachments.size !== 0) return;
message.member.send("You can't send text in 'images' channel")
await message.delete();
} else return;
});
(this is different from the other questions with the same topic)
how do I fix it?
The most likely problem is that you are running multiple instances of the Discord bot. Check if you have multiple command lines open, if so, check if they are running the bot. Apart from that, if users spam, Discord API tends to get confused about which messages to delete, making it try to delete the same message more than 1 time. You can try adding an if statement checking if the message is undefined.
client.on("message", async (message) => {
if (!message) return; // ADDED THIS LINE OF CODE
if (message.author.bot) return;
const users = ["853248522563485717"];
if (message.channel.id === "841260660960395287") {
if (users.includes(message.author.id)) return;
if (message.attachments.size !== 0) return;
message.member.send("You can't send text in 'images' channel");
await message.delete();
} else {
return;
}
});
From your error above, you are seemingly using a message event listener for every command or function you want your bot to perform. The maximum for this is 11 (of the same type). This is not the correct way to do this.
What is an event listener?
//the 'client.on' function is called every time a 'message' is sent
client.on("message", async (message) => {
//do code
});
How to fix this:
Instead of using 1 event listener per command, use 1 for the whole client. You could solve this a multitude of ways, with command handlers or such, however I will keep it simple.
This is the basic setup you should see in your index.js or main.js file:
// require the discord.js module
const Discord = require('discord.js');
// create a new Discord client
const client = new Discord.Client();
// on message, run this
client.on('message', (message) => {
if (!message) return;
console.log(`message sent in ${message.channel.name}. message content: ${message.content}`);
//this event will fire every time a message is sent, for example.
});
// login to Discord with your app's token
client.login('your-token-goes-here');
So what do you do if you want to do multiple functions with your bot? (for example deleting text in an images only channel and logging messages to console)
Command handling. It is the only way. I linked an official Discord.js guide above, read through it and see what you can do. I would highly recommend trying this with an entirely different bot and clean index file, as it would be easier than trying to fit in code you dont understand between your already problematic code.

Message collecter spams messages, and wont start in the correct channel

So, I have been making a message collector that gets activated when "grimm!record" is sent, I have been working on this piece of code for hours, but yet the code seems to keep getting more broken.
This was the code before I started working on it
client.on('message', message => {
if (message.content === 'grimm!record') {
const filter = m => true;
const collector = message.channel.createMessageCollector(filter);
message.channel.send(Start)
const log = message.guild.channels.cache.find(ch => ch.name === 'recording-log');
collector.on('collect', collectedMessage=>{
log.send(`${message.author.username} - ${collectedMessage.content}`)
if(collectedMessage.content === "grimm!record-stop"){
collector.stop();
}
});
}})
and this is the code after I made edits, If grimm!record was sent in the channel called recording-log, the bot would send a message saying "I can't record the recording log!" and it would exit out of the collector
client.on('message', message => {
if (message.content === 'grimm!record') {
const channelID = message.guild.channels.cache.find(channel => channel.name === "recording-log").id;
if (message.channel.id === channelID)
message.channel.send('I cant record in the Recording Log!')
return;
} else {
message.channel.send(Start)
const filter = m => true;
const collector = message.channel.createMessageCollector(filter);
const log = message.guild.channels.cache.find(ch => ch.name === 'recording-log');
collector.on('collect', collectedMessage=>{
log.send(`${message.author.username} - ${collectedMessage.content}`)
if(collectedMessage.content === "grimm!record-stop"){
collector.stop();
}
});
}})
Once I made these edits, I would send grimm!record in a different channel, it does not start the collector, or even send the "Start" embed, and the collector does start as well, when I sent grimm!record in the recording-log, I got a message saying that the bot cant record the recording log, but it still starts the collector, while spamming the "Start" embed in the channel. I have been working on this for hours, I've been looking all over the internet for help, but yet I still have no clue on what I've been doing wrong, could someone tell me what's wrong with the 2nd piece of code I sent? Thanks!
EDIT - so it turns out, that anytime I use a command with my bot, or if someone says a word that is in my bots swear list, it starts the collector, and starts the message spam, so I have no clue on why that happens, so if someone could help explain that, I would appreciate that too, thanks!
Changing this line should theoretically solve your issue:
const filter = m => true;
As I stated in my comment, there is a purpose to the filter, it should not simply return true. The filter is responsible for "filtering" out the messages you do not want collected. Only messages that match the conditions of the filter will be collected. In your example, there is no filter, so any message sent by anyone will be collected by the collector, including messages sent by the bot itself. Since your bot sends a new message whenever a message is collected, this results in an infinite loop of spam.
Try changing it to this:
const filter = m => m.author.id == message.author.id;
This will ensure that the collector only collects messages sent by the user that used the command.
Alternatively, if you want to record the messages of everyone that sends a message (except your bot), try changing it to this:
const filter = m => m.author.id != message.client.user.id;
This will solve at least the spam portion of your problem.
The other problem simply appears to be an incorrect placement of your else statement. If you look at your second example, the else should come after if (message.channel.id === channelID), but instead comes after the initial if statement if (message.content === 'grimm!record').

Discord.JS - Moving users in Discord to your VC using roles

I'm trying to move all users from a VC with a specific role, for example: !summon #role
With that, all users with that specific role should come to the VC where the user typed that command
At the moment my code looks like this:
else if (command === 'summon') {
const channel = message.member.voice.channel;
message.guild.members.cache.forEach(member => {
member.voice.setChannel(channel);
});
message.channel.send(`${message.author} users moved to your channel!`);
}
At the moment i'm moving all users, however I only want users with the informed role
I tried to use:
message.mentions.roles.forEach(member => {
member.setChannel(channel);
});
But without success... can someone help me with this problem?
You can try replacing
message.guild.members.cache.forEach(member => {
member.voice.setChannel(channel);
});
with
message.guild.members.cache.forEach(member => {
if(member.roles.cache.has(message.mentions.roles.first()) {
member.voice.setChannel(channel);
}
}
Since member.roles.cache is a Collection it has a function .has. We take the first role mention from the message using message.mentions.roles.first() and check if it exists in the user's current roles using member.roles.cache.has(). If the user does have the first role mentioned in the message, the function returns true and we can move the to the specified channel. Hope this helps, don't forget about https://discord.js.org/#/docs for some documentation, can be quite useful 😅.

Making a verification system with reactions

I have spotted some posts regarding the same topic, but not the exact problem.
I have also referred to javascript discords, where they were unable to assist me with my problem.
So to inform you,
The purpose of this verification system is to make sure the user understood the rules and can proceed to have the rest of the discord unlocked after he adds a checkmark reaction.
I have made a bot that has the command |message and it works fine and all, but I then want the bot to react to its own message once sent, and then wait for a user to also add a reaction, which will trigger a function, in this case. Triggering the bot to send a PM to the user and giving him a rank.
The bot adds his reaction fine, and upon reacting from me as an example it sends me a PM, but in the PM between me and the bot, the bot reacts once again to his message. And this might be because of the code checking if the message author is the bot.
I was told in the JS Discord that the messageReactionAdd function has a Message Property, however upon searching I couldn't find a way to implement this into my code. How would I do so? Also trying to give the user a rank also spits out an error, and I am simply stuck between understanding and making stuff work. I am getting confused with my own code, and I have minimal understanding of what I am doing, so with that said, Can anyone assist me doing this change, so I can get it in my head? Giving me links to the discord.js documentation is just making me more confused, and the only way for me to learn is by creating, and successfully making it work. Any help is appreciated of course.
So, here is the code for the messageReactionAdd:
bot.on('messageReactionAdd', (reaction, user) => {
if(reaction.emoji.name === "✅") {
if(user === bot.user) return;
// if(bot.channel === "dm") return;
// let role = bot.guild.roles.find("name", "C - Verified");
// let role1 = bot.guild.roles.find("name", "C - Unverified");
//if(user.roles.has(role.id));
//await(user.addRole(role.id) && user.removeRole(role1.id));
user.send("Thank you for being apart of the community! As a thanks for accepting the rules, you have been awarded the verified role!");
return;
}
});
And here is the code for the react function itself:
513769507907567628 is the bots' ID.
bot.on("message", async message => {
if(message.author.id != "513769507907567628") return;
message.react("✅");
});
So, if you have any input that'd be great! If you can join a Discord Call please message me, That'd be the easiest and quickest.
Regards, Marius.
If your problem occured here:
await(user.addRole(role.id) && user.removeRole(role1.id));
then it is because:
1) await only exists inside async functions.
2) you cannot just chain promises with &&, a && b will result in b and that gets then awaited, so in your case you only wait for the removal.
bot.on('messageReactionAdd', async (reaction, user) => {
if(reaction.emoji.name === "✅") return;
if(user === bot.user) return;
let role = bot.guild.roles.find("name", "C - Verified");
let role1 = bot.guild.roles.find("name", "C - Unverified");
await user.addRole(role.id);
await user.removeRole(role1.id);
});

Categories