Discord bot look for reactions - javascript

So its hard to explain my situation because i am new to discord.js and i have been trying to figure this out for hours
What i need is my bot to look at a certain channel and see that a staff member (or anyone because normal users cannot add reactions) reacted with "👍" and logs it.
Later my end goal is it sees this and replys and sends a command to a minecraft server. but ill figure all that out later. i just need the bot to see that there is that certain reaction on a message
Like i said i am new, and the docs to discord.js are not helping, all i could find/do is this:
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
const filter = (reaction, user) => {
return reaction.emoji.name === '👍' && user.id === Discord.Message.author.id;
};
const collector = Discord.Message.createReactionCollector(filter, { time: 15000 });
collector.on('collect', (reaction, user) => {
console.log(`Collected ${reaction.emoji.name} from ${user.tag}`);
});
And it throws errors about the Message.createReactionCollector

To use the ReactionCollector you will need an instance of Message to create the collector on.
If you don't have a specific message and want to collect the reactions globally, you could listen for an event messageReactionAdd.
client.on("messageReactionAdd", (reaction, user) => {
// Ignore the bot's reactions
if (client.user.id == user.id) return;
// Look only for thumbs up reaction
if (reaction.emoji.name != "👍") return;
// Accept reactions only from specific channel
if (reaction.message.channel.id != "870115890367176724") return;
console.log(`${user.tag} reacted with 👍.`);
});
Note that this won't work for reactions cast on messages sent before the bot was started. The solution is to enable Partial Structures. (If you are dealing with partial data, don't forget to fetch)

Related

How would I kick a user after a certain amount of time of joining the server in Discord.JS

So I am trying to make a bot that kicks a member after a certain amount of time of them joining the server if they dont have a role. this is my code so far. Keep in mind i am using sleep npm plugin https://www.npmjs.com/package/sleep
const fs = require('fs');
const Discord = require('discord.js');
const { prefix, token } = require('./config.json');
const db = require('quick.db')
const sleep = require('sleep');
const client = new Discord.Client();
client.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for (const file of commandFiles) {
const command = require(`./commands/${file}`);
client.commands.set(command.name, command);
}
client.once('ready', () => {
console.log('Ready!');
});
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const command = args.shift().toLowerCase();
if (!client.commands.has(command)) return;
try {
client.commands.get(command).execute(message, args);
} catch (error) {
console.log(error);
}
});
client.on("guildMemberAdd", (member) => {
member.send("Welcome to the faith garden server! Please verify in the <#685597195789008993> to verify, you can see the questions at <#765603302774669372>")
sleep.sleep("5")
if(member.guild.roles.find(role => role.name === "Member")) {
}
else if(member.guild.roles.find(role => role.name === "Pre-Member")) {
}
else if(member.guild.roles.find(role => role.name === "Alpha-Member")) {
}
else if(member.guild.roles.find(role => role.name === "Observer")) {
}
else {
member.kick
member.send("Sorry we had to kick you because you didnt respond soon enough, you can always join back since this is just a temporary kick.")
}
});
client.login(token);
How i know the code isnt working is because is did node . in the console already, then i joined on an alt, and nothing happened, no dm, no kick after 5 seconds. Nothing. if you know how to fix the bot not doing anything, please let me know. :)
From your code, it is clear that you are using discord.js v11. You can't use djs v11 if you want to listen to the guildMemberAdd event. Discord added an intents feature to its API relatively recently that prevents you from reliably listening to guild events without specifically subscribing to them. Discord.js v11 does not support intents, so you must update to discord.js v12.
You need to subscribe to specific intents in order to reliably receive the affiliated events. guildMemberAdd is on the list of events that will require subscription to an intent.
Here's one possible fix wherever you are defining your client:
const intents = ["GUILDS", "GUILD_MEMBERS"];
const client = new Discord.Client({intents: intents, ws:{intents: intents}});
You will also need to enable the below setting for your bot on its discord developers page, since the guild member join event is a privileged intent:
There are possibly portions of your code that need to be changed due to the update to v12.x.x; please look into what's changed between the versions.
Furthermore, your code is very problematic and unnecessarily over-complicated. Why did you use the node package sleep when you could just use a setTimeout? Why do you have a ton of empty if statements? Furthermore you're not checking if the member has a role, you're doing member.guild.roles.find() which is checking whether or not the guild has a role. Here are some corrections in your event handler:
client.on("guildMemberAdd", (member) => {
member.send("Welcome to the faith garden server! Please verify in the <#685597195789008993> to verify, you can see the questions at <#765603302774669372>");
var verifiedRoles = ["Member","Pre-Member","Alpha-Member","Observer"];
setTimeout(() => {
if(!member.roles.cache.find(role => verifiedRoles.includes(role.name))) {
member.send("Sorry we had to kick you because you didnt respond soon enough, you can always join back since this is just a temporary kick.")
.then(() => {
member.kick();
});
}
}, 5 * 1000); //The timeout is in ms, convert by multiplying seconds by 1000
});
Relevant resources:
List of intents and associated events
General info about intents

Move all users to your Channel (Discord JS)

I'd like to create a command, that moves all users in my Discord voice channel.
Here is what i tried.
...
client.on('message', async message =>{
//Check message is not Bot
if(message.author.bot) return;
if(message.content=="!movetome"){
if(message.member.voice.channel) {//Is user in voicechannel
message.guild.members.cache.forEach(member => { //Loop every user
if(member.id!=message.member.id&&member.voice.channel){//Is user in voicechannel and is user the command executer
member.setVoiceChannel(message.member.voice.channel)//Sets user to channel
}
});
}
}
});
...
After I tried to run the command "!movetome" in discord chat I got the following error message:
(node:12268) UnhandledPromiseRejectionWarning: TypeError: member.setVoiceChannel is not a function
Thanks for your help :)
Firstly this seems like a bad idea if any user can do it but regardless, .setVoiceChannel is v11, they moved it to <GuildMember>.voice.setChannel()
Change the contents inside of if(message.content=="!movetome") to this
const channel = message.member.voice.channel;
message.guild.members.cache.forEach(member => {
//guard clause, early return
if(member.id === message.member.id || !member.voice.channel) return;
member.voice.setChannel(channel);
});

How can I make my Discord bot give a user a role?

How can I make my Discord bot give a user a role? It has the "Administrator" permission, and I'm using the nodejs library. Here's my code so far (this initializes the bot):
var auth = require("./auth.json");
var fs = require("fs");
var bot = new discord.Client();
bot.login("TOKENTOKENTOKENTOKENTOKENTOKENTOKENTOKENTOKEN")
bot.on("ready", function(event) {
console.log("Initialized");
});
You must use the GuildMember.addRole() function. (to get a guild member, use Guild#members.get()). Read the Discord.js.org documentation for more informations.
You can use:
bot.on("message", (message) => {
if(!message.member) return
// Find the role by name
var role = message.guild.roles.find((r) => r.name === "Name of your role");
// Assign the role to the message author
message.member.roles.add(role);
});
You can try this
client.on('guildMemberAdd', member => {
//Search and add the role to the new user
member.addRole(member.guild.roles.find(nm => nm.name === "Your role name"));
// Send the message to a designated channel on a server:
const channel = member.guild.channels.find(ch => ch.name === 'general');
// Do nothing if the channel wasn't found on this server
if (!channel) return;
// Send the message, mentioning the member
channel.send(`Welcome to the server, ${member}`);
});

How to make an emoji-hopping command that sends invite links of participating servers

I'm trying to make an emoji-hopping system for my bot.
But I can't seem to get anything to work, except creating the channel.
What's meant to happen:
The server owner/mod is meant to do a command emojihop and it creates the channel then a few seconds later post in that channel saying this server has hopped in on the Emoji-Hopping Quest with server invite etc. but the issue is it just creates the channel and if the command is mentioned over and over it creates more channels.
My Code:
if (command === "emojihop") {
const logChannel = client.channels.find('name', 'emoji-hop');
console.log(command)
if (!logChannel) {
const invite = message.guild.channels.find(c => c.type !== "category" && c.position === 0).createInvite({
maxAge: 0
});
message.guild.createChannel('emoji-hop', 'text')
.then(console.log)
.catch(console.error);
const logChannel = client.channels.find('name', 'emoji-hop');
let embed = new Discord.RichEmbed()
.setTimestamp()
.setTitle(`This Server Has Hopped In On The Emoji-Hopping.`)
.addField(`Server Name: `, `${message.guild.name}`)
.addField(`Server ID:`, `${message.guild.id}`)
.addField(`Server Owner:`, `${message.guild.owner}`)
.addField(`Server Invite:`, `https://discord.gg/${invite.code}`)
.setColor("RANDOM")
.setFooter("Emoji-Hopping Quest")
logChannel.send(embed)
} else {
message.channel.send("Channel Exists")
return;
}
}
When you create the channel you have to change a few things. Here is what you should have:
message.guild.createChannel('emoji-hop', 'text')
.then(c=>{
c.send(richEmbedGoesHere)
})
.catch(err=>{
console.error(err)
});
With this, it will send as soon as the channel is created.
For your other problem, I think I know what you did wrong. Either node or discord changed this to where you can't do .find('name','emoji-hop') anymore. You have to do it like this
message.guild.channels.find(c=>c.name==="emoji-hop")
Tell me if any of this helps!
Wishing you luck,
Zaedus

Send a message with Discord.js

I am trying to make a discord bot, but I can't quite understand Discord.js.
My code looks like this:
client.on('message', function(message) {
if (message.content === 'ping') {
client.message.send(author, 'pong');
}
});
And the problem is that I can't quite understand how to send a message.
Can anybody help me ?
The send code has been changed again. Both the items in the question as well as in the answers are all outdated. For version 12, below will be the right code. The details about this code are available in this link.
To send a message to specific channel
const channel = <client>.channels.cache.get('<id>');
channel.send('<content>');
To send a message to a specific user in DM
const user = <client>.users.cache.get('<id>');
user.send('<content>');
If you want to DM a user, please note that the bot and the user should have at least one server in common.
Hope this answer helps people who come here after version 12.
You have an error in your .send() line. The current code that you have was used in an earlier version of the discord.js library, and the method to achieve this has been changed.
If you have a message object, such as in a message event handler, you can send a message to the channel of the message object like so:
message.channel.send("My Message");
An example of that from a message event handler:
client.on("message", function(message) {
message.channel.send("My Message");
});
You can also send a message to a specific channel, which you can do by first getting the channel using its ID, then sending a message to it:
(using async/await)
const channel = await client.channels.fetch(channelID);
channel.send("My Message");
(using Promise callbacks)
client.channels.fetch(channelID).then(channel => {
channel.send("My Message");
});
Works as of Discord.js version 12
The top answer is outdated
New way is:
const channel = await client.channels.fetch(<id>);
await channel.send('hi')
To add a little context on getting the channel Id;
The list of all the channels is stored in the client.channels property.
A simple console.log(client.channels) will reveal an array of all the channels on that server.
There are four ways you could approach what you are trying to achieve, you can use message.reply("Pong") which mentions the user or use message.channel.send("Pong") which will not mention the user, additionally in discord.js you have the option to send embeds which you do through:
client.on("message", () => {
var message = new Discord.MessageEmbed()
.setDescription("Pong") // sets the body of it
.setColor("somecolor")
.setThumbnail("./image");
.setAuthor("Random Person")
.setTitle("This is an embed")
msg.channel.send(message) // without mention
msg.reply(message) // with mention
})
There is also the option to dm the user which can be achieved by:
client.on("message", (msg) => {
msg.author.send("This is a dm")
})
See the official documentation.
Below is the code to dm the user:
(In this case our message is not a response but a new message sent directly to the selected user.)
require('dotenv').config({ path: __dirname + '/.env.local' });
const Discord = require("discord.js");
const client = new Discord.Client();
client.on("ready", () => {
console.log(client.users.get('ID_OF_USER').send("hello"));
});
client.login(process.env.DISCORD_BOT_TOKEN);
Further documentation:
https://github.com/AnIdiotsGuide/discordjs-bot-guide/blob/master/frequently-asked-questions.md#users-and-members
You can only send a message to a channel
client.on('message', function(message) {
if (message.content === 'ping') {
message.channel.send('pong');
}
});
If you want to DM the user, then you can use the User.send() function
client.on('message', function(message) {
if (message.content === 'ping') {
message.author.send('pong');
}
});
Types of ways to send a message:
DM'ing whoever ran the command:
client.on('message', function(message) {
if (message.content === 'ping') {
message.author.send('pong');
}
});
Sends the message in the channel that the command was used in:
client.on('message', function(message) {
if (message.content === 'ping') {
message.channel.send('pong');
}
});
Sends the message in a specific channel:
client.on('message', function(message) {
const channel = client.channels.get("<channel id>")
if (message.content === 'ping') {
channel.send("pong")
}
});
It's message.channel.send("content"); since you're sending a message to the current channel.

Categories