I am making a discord bot, and I have a problem with a waifu command.
With this command the bot sends an embed, and I want to detect when someone reacts to this embed. I tried this code but nothing happens.
const Discord = require("discord.js");
const axios = require("axios")
const Client = new Discord.Client;
module.exports = {
name : 'waifu',
description : "waifu command",
execute(message, args) {
Client.on('messageReactionAdd', (reaction, user) => {
message.channel.send("Reacted")
})
axios.get("https://api.waifu.pics/sfw/waifu")
.then((res) => {
let wembed = new Discord.MessageEmbed()
.setTitle(`Voici votre waifu ${message.author.username}`)
.setImage(res.data.url)
message.channel.send(wembed)
.then(function (message) {
message.react("❤")
Client.on('messageReactionAdd', (reaction, user) => {
console.log("reacted")
})
})
})
.catch((err) => {
console.error("ERR: ", err)
})
}
}
You can't add a messageReactionAdd listener inside your message listener. You can however set up a reaction collector using createReactionCollector for example, like in my example below:
const { MessageEmbed } = require('discord.js');
const axios = require('axios')
module.exports = {
name: 'waifu',
description: 'waifu command',
execute(message, args) {
axios
.get('https://api.waifu.pics/sfw/waifu')
.then((res) => {
let wembed = new MessageEmbed()
.setTitle(`Voici votre waifu ${message.author.username}`)
.setImage(res.data.url);
// make sure you use a different var name here
// like msg instead of message
message.channel.send(wembed).then((msg) => {
msg.react('❤');
// set up a filter to only collect reactions with the ❤ emoji
let filter = (reaction, user) => reaction.emoji.name === '❤';
let collector = msg.createReactionCollector(filter);
collector.on('collect', (reaction, user) => {
// in case you want to do something when someone reacts with ❤
console.log('reaction added');
});
collector.on('remove', (reaction, user) => {
// in case you want to do something when someone removes their reaction
console.log('reaction removed');
});
});
})
.catch((err) => {
console.error('ERR: ', err);
});
},
};
A couple things here.
First, you defined message twice; once as the message initiating the command that originated from your command handler, and once as the message the bot sent. You need to rename one of these or else various unexpected issues may arise.
Second, you should never define your client twice. Instead, you should reuse the client. To do this, you can either export it to your command handler the same way you export message and args, or you can access it via <message>.client and use it the same way you did here.
Related
I am making a command to kick all members from a discord server. Here is my code:
client.on("message", message =>{
if (message.content.startsWith(prefix + "amstronglikeabullinapool")) {
message.channel.send("ok i dont care")
const user = message.member;
var allMembers = message.guild.members
allMembers.kick()
message.channel.send("oki")
}
})
I am getting the error:
allMembers.kick is not a function
You could try fetching all members first, loop through them and kick every member separately.
Example:
const allMembers = await message.guild.members.fetch();
allmembers.forEach(member => {
member.kick()
.catch(error => console.log(error))
});
I'm attempting to filter out bot accounts that advertise on my server by banning usernames that join with the "discord.gg" username.
However it keeps returning error "member is undefined"
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = '-';
client.once('ready', () => {
console.log('online');
})
client.on("message", async message => {
if (member.user.username.includes("discord.gg")) {
member.ban({days:7,reason:"Advertising."})
.then(() => console.log(`Banned ${member.displayName}, ${m}`))
.catch(console.error);
}
});
client.login(process.env.token);
You will need to use this
if (member.user.username.includes("discord.gg")) {
member.ban({days:7,reason:"Advertising."})
.then(() => console.log(`Banned ${member.displayName}`))
.catch(console.error);
}
in a scope where member is defined.
One way to do this would be to listen to the guildMemberAdd event instead of the message
For example:
client.on("guildMemberAdd", async (member) => {
if (member.user.username.includes("discord.gg")) {
member.ban({days:7,reason:"Advertising."})
.then(() => console.log(`Banned ${member.displayName}`))
.catch(console.error);
}
});
This would ban any member whose username includes discord.gg as soon as they join the server.
Otherwise you could just modify your current code like:
client.on("message", async message => {
if (message.member.user.username.includes("discord.gg")) {
message.member.ban({days:7,reason:"Advertising."})
.then(() => console.log(`Banned ${member.displayName}`))
.catch(console.error);
}
});
But this would error if a user sends the bot a direct message (message.member is undefined if there is no guild)
To counteract that you could also check if the message was sent in a guild with
if (message.guild) {
/* rest of the code */
}
I am developing my ticketing system in the last time. I saw an update of 'Ticketsbot' and turned curious "how is that possible???, i have never seen that!"
So, can you please help me how can I replace reactions with such buttons.
The part of my code (part which is responsible for reactions):
let embed = new discord.MessageEmbed()
.setAuthor(`Welcome to your ticket!`)
.addField('Here you can:', ':one: Report an issue or bug of the server.\n:two: Suggest any idea for the server.\n:three: Report a staff member of the server.')
.addField('Make sure to be patient, support will be with you shortly.', `<#&837064899322052628>`)
.setColor('#468DFF')
.setFooter(`AftNetwork`)
let embed2 = new discord.MessageEmbed()
.setAuthor(`React with ⛔ if your issue has been resolved.`)
.setColor('#468DFF')
.setFooter(`AftNetwork`)
let reactionMessage = null;
try {
reactionMessage = await channel.send(`${message.author}`, {
embed: embed,
}).then(message => message.channel.send(embed2));
} catch (error) {
console.log(error);
return message.channel.send(
'⚠️ Error sending message in ticket channel!',
);
}
try {
await reactionMessage.react('🔒');
await reactionMessage.react('⛔');
} catch (err) {
console.log(err);
return channel.send('⚠️ Error sending emojis!');
}
const collector = reactionMessage.createReactionCollector(
(reaction, user) => {
// collect only reactions from the original
// author and users w/ admin permissions
const isOriginalAuthor = message.author.id === user.id;
const isAdmin = message.guild.members.cache
.find((member) => member.id === user.id)
.hasPermission('MANAGE_MESSAGES');
return isOriginalAuthor || isAdmin;
},
{ dispose: true },
);
collector.on('collect', (reaction, user) => {
switch (reaction.emoji.name) {
// lock: admins only
case '🔒':
const isAdmin = message.guild.members.cache
.find((member) => member.id === user.id)
.hasPermission('MANAGE_MESSAGES');
if (isAdmin) {
channel.updateOverwrite(message.author, {
SEND_MESSAGES: false,
});
} else {
// if not an admin, just remove the reaction
// like nothing's happened
reaction.users.remove(user);
}
break;
// close: anyone i.e. any admin and the member
// created the ticket
case '⛔':
channel.send('Deleting this ticket in 5 seconds...');
setTimeout(() => channel.delete(), 5000);
break;
}
});
Have a good day!
For now there is no official wrapper so here is an unofficial library that you can use and also here is a small exemple. You can join their discord on the link provided for more help.
let button = new MessageButton()
.setLabel("I like")
.setStyle("blurple")
.setEmoji("🍕")
.setID("like_button")
what you will add is the above code and in the .send() funtion it will be this channel.send(`${message.author}`, {embed: embed, component: button})
and that's basically it.
So I wanted a command intomy bot, which iis able to give server roles if you react on the message. By google/youtube I done this. My problem is, that if I react on the message my algorith won't step into my switch also if I react to the costum emoji it won't even detect it that I reacted for it. Probably somewhere the return value is different but I was unable to find it yet. Sy could check on it?
const { MessageEmbed } = require('discord.js');
const { config: { prefix } } = require('../app');
exports.run = async (client, message, args) => {
await message.delete().catch(O_o=>{});
const a = message.guild.roles.cache.get('697214498565652540'); //CSGO
const b = message.guild.roles.cache.get('697124716636405800'); //R6
const c = message.guild.roles.cache.get('697385382265749585'); //PUBG
const d = message.guild.roles.cache.get('697214438402687009'); //TFT
const filter = (reaction, user) => ['🇦' , '🇧' , '🇨' , '<:tft:697426435161194586>' ].includes(reaction.emoji.name) && user.id === message.author.id;
const embed = new MessageEmbed()
.setTitle('Available Roles')
.setDescription(`
🇦 ${a.toString()}
🇧 ${b.toString()}
🇨 ${c.toString()}
<:tft:697426435161194586> ${d.toString()}
`)
.setColor(0xdd9323)
.setFooter(`ID: ${message.author.id}`);
message.channel.send(embed).then(async msg => {
await msg.react('🇦');
await msg.react('🇧');
await msg.react('🇨');
await msg.react('697426435161194586');
msg.awaitReactions(filter, {
max: 1,
time: 15000,
errors: ['time']
}).then(collected => {
const reaction = collected.cache.first();
switch (reaction.emoji.name) {
case '🇦':
message.member.addRole(a).catch(err => {
console.log(err);
return message.channel.send(`Error adding you to this role **${err.message}.**`);
});
message.channel.send(`You have been added to the **${a.name}** role!`).then(m => m.delete(30000));
msg.delete();
break;
case '🇧':
message.member.addRole(b).catch(err => {
console.log(err);
return message.channel.send(`Error adding you to this role **${err.message}.**`);
});
message.channel.send(`You have been added to the **${b.name}** role!`).then(m => m.delete(30000));
msg.delete();
break;
case '🇨':
message.member.addRole(c).catch(err => {
console.log(err);
return message.channel.send(`Error adding you to this role **${err.message}.**`);
});
message.channel.send(`You have been added to the **${c.name}** role!`).then(m => m.delete(30000));
msg.delete();
break;
case '<:tft:697426435161194586>':
message.member.addRole(d).catch(err => {
console.log(err);
return message.channel.send(`Error adding you to this role **${err.message}.**`);
});
message.channel.send(`You have been added to the **${d.name}** role!`).then(m => m.delete(30000));
msg.delete();
break;
}
}).catch(collected => {
return message.channel.send(`I couldn't add you to this role!`);
});
});
};
exports.help = {
name: 'roles'
};
As of discord.js v12, the new way to add a role is message.member.roles.add(role), not message.member.addRole. Refer to the documentation for more information.
You need to use roles.add() instead of addRole()
Mate, You cannot use the id of emoji in codes(except when you are sending a message). so, the custom emoji has to be replaced by a real emoji that shows a box in your editor and works perfectly in discord. If you can find it, then this might be complete as discord API cannot find the emoji <:tft:697426435161194586>. you can get an emoji by using it in discord and opening discord in a browser and through inspect element, get the emoji.
Else, you will have to use different emoji.
Is there anything remotely wrong with this code?
no errors pop up and there isn't a reaction once the bot sends the messages.
any help would be appreciated, thank you in advance!
const a = msg.guild.roles.get('666712822985654322'); //Verified User
// the role constants are in the same chronological order as below.
const filter = (reaction,user) => ['668236468384169986'].includes(reaction.emoji.name);
const embed = new Discord.RichEmbed()
.setColor(0x00FF00)
.setTitle('Rules')
.setDescription(`
In order to gain access to the rest of the server you must read and abide by these rules:
By reacting with :white_check_mark: you agree to these rules
Roles:
:white_check_mark: ${a.toString()}`)
.setThumbnail(msg.author.avatarURL)
.addField('Rule #1:You do not talk about fight club', 'Second Rule: You do not TALK about fight club')
.setFooter("Use \'!command list\' to get aquainted with Peb 3000");
msg.channel.send(embed).then(async message => {
await message.react('668236468384169986'); //white check mark
message.awaitReaction(filter, {})
.then(collected =>{
const reaction = collected.first();
switch(reaction.emoji.name) {
case('\:white_check_mark:'):
message.member.addRole(a).catch(err => {
console.log(err);
return message.channel.send(`Error adding you to this role: **${err.message}**`);
});
message.channel.send(`You have been added to the **${a.name}** role!`).then(m => m.delete(3000));
break;
}
}).catch(collected => {
return msg.collected.send(`I couldn't add you to this role!`)
})
});
I'd recommend reading both An Idiot's Guide - Using Emojis as well as Discord.js Guide - Reactions, as your current approach for Unicode emojis won't work.
In your case, :white_check_mark: should be ✅ or an equivalent.
The collected options will triggeret when collector end collect, you no provide any options to stop collector, so its will never happen.
The 1 way to give member role on react follow this code. But when bot restart, you need again use this command and create collector.
const roleToAdd = msg.guild.roles.get('666712822985654322'); //Verified Role
if(!roleToAdd) return
let embed = new Discord.RichEmbed()
.setColor(0x00FF00)
.setTitle('Rules')
.setDescription(`
In order to gain access to the rest of the server you must read and abide by these rules:
By reacting with :white_check_mark: you agree to these rules
Roles:
:white_check_mark: ${a.toString()}`)
.setThumbnail(msg.author.avatarURL)
.addField('Rule #1:You do not talk about fight club', 'Second Rule: You do not TALK about fight club')
.setFooter("Use \'!command list\' to get aquainted with Peb 3000");
msg.channel.send(embed).then(message => {
const filter = (reaction, user) => reaction.emoji.name === '✅' && user.id === msg.author.id && reaction.message.id = message.id
const collector = message.createReactionCollector(filter, {});
collector.on('collect', r => {
if(r.emoji.name === '✅') {
let member = message.guild.members.get(reaction.users.last().id)
member.addRole(roleToAdd)
.then( member => {
message.channel.send(`You have been added to the **${roleToAdd.name}** role!`).then(m => m.delete(3000));
})
.catch(console.error)
}
})
collector.on('end', collected => console.log(`Collected ${collected.size} items`));
})
The way number 2 its listen reactionadd event. After restart its will work.
bot.on('messageReactionAdd', (reaction, user) => {
if(reaction.message.id === 'YOUR MESSAGE ID' && reaction.emoji.name === 'youreactionname') {
let meber = reaction.message.guild.members.get(user.id)
member.addRole('yourRole')
}
.catch(console.error)
});