could anyone explain to me why am I getting this error when I'm trying to get my role from a reaction: UnhandledPromiseRejectionWarning: TypeError: reaction.users.last is not a function? Thanks, I've attached the code too.
Code:
const Discord = require('discord.js');
const client = new Discord.Client();
const config = require('./config.json');
client.on('ready', () => {
console.log('Ready!');
});
client.on('message', async (message) => {
if (message.content === 'l!verify') {
const reactmessage = await message.channel.send(
'Am intrebat 100 de Romani, vrei rolul de GUEST?'
);
await reactmessage.react('👌');
const filter = (reaction, user) => reaction.emoji.name === '👌' && !user.bot;
const collector = reactmessage.createReactionCollector(filter, {
time: 15000,
});
collector.on('collect', async (reaction) => {
const user = reaction.users.last();
const guild = reaction.message.guild;
const member = guild.member(user) || (await guild.fetchMember(user));
member.addRole(config.roleid);
});
}
});
client.login(config.token);
MessageReaction.users returns a ReactionUserManager, not a Collection. Make sure to use the cache property.
const user = reaction.users.cache.last();
Related
My reaction role file:
module.exports = {
name: "rr",
desc: "make a reaction role --> <",
async run(message, client) {
const jsEmoji = "🍏";
const pythonEmoji = "🍍";
let embedMessage = await message.channel.send("react for a role");
embedMessage.react(jsEmoji);
embedMessage.react(pythonEmoji);
client.on("messageReactionAdd", (user, reaction) => {
console.log("he reacted");
});
},
};
my bot file:
const intents = new Discord.Intents(32767);
I initialized my client here
const client = new Discord.Client({ intents: intents });
const fs = require("fs");
const commandFolders = fs.readdirSync("./Commands");
client.commands = new Discord.Collection();
commandFolders.forEach((folder) => {
const commandFiles = fs
.readdirSync(`./Commands/${folder}`)
.filter((file) => file.endsWith(".js"));
commandFiles.forEach((file) => {
const command = require(`./Commands/${folder}/${file}`);
client.commands.set(command.name, command);
});
});
client.on("messageCreate", (message) => {
if (message.author.bot || !message.content.startsWith(config.prefix)) return;
const [command, ...args] = message.content
.substring(config.prefix.length)
.split(/\s+/);
I tried getting access to the client here and passing it into the run function but that didnt work.
client.commands.forEach((cmd) =>
command === cmd.name
? client.commands.get(cmd.name).run(message, args, client)
: null
);
});
client.login(config.token);
My Error:
client.on("messageReactionAdd", (user, reaction) => {
^
TypeError: client.on is not a function
Is there another way to get access to my client?
your arguments are wrong on command file.
You should use async run(client, message, args)
Here's a full code for you:
module.exports = {
name: "rr",
desc: "make a reaction role --> <",
async run(client, message, args) {
const jsEmoji = "🍏";
const pythonEmoji = "🍍";
let embedMessage = await message.channel.send("react for a role");
embedMessage.react(jsEmoji);
embedMessage.react(pythonEmoji);
client.on("messageReactionAdd", (user, reaction) => {
console.log("he reacted");
});
},
};
I want my bot to delete an embed it sends out when someone uses a cuss word. I want it to delete that embed in 5-6 seconds take 5 or 6 so it takes up less space in the area.
const Discord = require('discord.js');
const { Client, MessageEmbed } = require('discord.js');
const bot = new Client();
const token = 'tokenhere';
bot.on('ready', () =>{
bot.user.setActivity('YOU', { type: 'WATCHING' });
console.log('This bot is online!');
});
bot.on('message', message=>{
const user = message.author;
const swearWords = ["fuck", "dick", "pussy", "vagina", "bsdk", "saale", "kutte", "bitch", "die", "mf", "bish", "fag","ass","nigga","nigger","fack"];
if (swearWords.some(word => message.content.toLowerCase().includes(word)) ) {
const embed = new MessageEmbed()
.setTitle('Chat F!lter')
.setColor(0xff0000)
.setDescription('<#' + message.author.id + '> You have been caught being toxic! , You are muted for a minute');
message.channel.send(embed);
const role = message.guild.roles.cache.find(x => x.name == 'muted');
message.member.roles.add(role);
setTimeout(() => {message.member.roles.remove(role)}, 60*1000);
}});
bot.login(token);
message.channel.send() returns a promise, you can resolve the promise and then use the <message>.delete({ timeout: 'time-goes-here' }) method, so your code would look like this.
const Discord = require('discord.js');
const { Client, MessageEmbed } = require('discord.js');
const bot = new Client();
const token = 'token-goes-here';
bot.on('ready', () =>{
bot.user.setActivity('YOU', { type: 'WATCHING' });
console.log('This bot is online!');
});
bot.on('message', message=>{
const user = message.author;
const swearWords = ["fuck", "dick", "pussy", "vagina", "bsdk", "saale", "kutte", "bitch", "die", "mf", "bish", "fag","ass","nigga","nigger","fack"];
if (swearWords.some(word => message.content.toLowerCase().includes(word)) ) {
const embed = new MessageEmbed()
.setTitle('Chat F!lter')
.setColor(0xff0000)
.setDescription('<#' + message.author.id + '> You have been caught being toxic! , You are muted for a minute');
// send and deleting the embed
message.channel.send(embed).then(msg => msg.delete({ timeout: 5000 })); // delete embed after 5 seconds (5000 ms)
const role = message.guild.roles.cache.find(x => x.name == 'muted');
message.member.roles.add(role);
setTimeout(() => {message.member.roles.remove(role)}, 60*1000);
}});
bot.login(token);
I want to make my bot to delete only user's messages in a certain channel and not the bot's. I tried doing it using the code below but it kept on deleting the both the bot's messages and mine.
const Discord = require("discord.js");
const client = new Discord.Client();
const { MessageEmbed } = require("discord.js");
const avalibleFormats = ['png', 'gif', 'jpeg', 'jpg']
client.on("ready", () => {
console.log("I am ready!");
});
client.on("message", message => {
if (message.channel.id == '829616433985486848') {
message.delete();
}
if (message.channel.id !== '829616433985486848') {
return;
}
let image = getImage(message)
if (!image) {
return;
}
let embed = new MessageEmbed();
embed.setImage(image.url)
embed.setColor(`#2f3136`)
message.channel.send(embed)
});
const getImage = (message) => message.attachments.find(attachment => checkFormat(attachment.url))
const checkFormat = (url) => avalibleFormats.some(format => url.endsWith(format))
client.login(token);
Well, you only say that if the channel id is 829616433985486848, delete the message. you should also check if the author is a bot using the message.author.bot property:
const avalibleFormats = ['png', 'gif', 'jpeg', 'jpg'];
const checkFormat = (url) => avalibleFormats.some((format) => url.endsWith(format));
const getImage = (message) => message.attachments.find((attachment) => checkFormat(attachment.url));
client.on('message', (message) => {
const certainChannelId = '829616433985486848';
// if the channel is not 829616433985486848, return to exit
if (message.channel.id !== certainChannelId)
return;
// the rest of the code only runs if the channel is 829616433985486848
const image = getImage(message);
// if author is not a bot, delete the message
if (!message.author.bot)
message.delete();
if (!image)
return;
const embed = new MessageEmbed()
.setImage(image.url)
.setColor('#2f3136');
message.channel.send(embed);
});
Actually, if the message is posted by a bot, you don't even need to run anything in there so you can check that right at the beginning and exit early:
client.on('message', (message) => {
if (message.author.bot || message.channel.id !== '829616433985486848')
return;
const image = getImage(message);
if (image) {
const embed = new MessageEmbed()
.setImage(image.url)
.setColor('#2f3136');
message.channel.send(embed);
}
message.delete();
});
If you want it to work in multiple channels, you can create an array of channel IDs and use Array#includes() to check if the current channel ID is in that array:
client.on('message', (message) => {
const channelIDs = ['829616433985486848', '829616433985480120', '829616433985485571'];
if (message.author.bot || !channelIDs.includes(message.channel.id))
return;
const image = getImage(message);
if (image) {
const embed = new MessageEmbed()
.setImage(image.url)
.setColor('#2f3136');
message.channel.send(embed);
}
message.delete();
});
Whenever I try to use a function like client.users.cache.size or client.guilds.size, they keep giving me an error like "TypeError: Cannot read property 'guilds' of undefined" or "TypeError: Cannot read property 'cache' of undefined".
I was also trying to use let guilds = client.guilds.cache.array().join('\n') but it also throws the same error.
Command's code:
const Discord = require('discord.js');
module.exports = {
name: 'stats',
description: 'Views the bot\'s stats',
execute(client, message) {
const embed = new Discord.MessageEmbed
.setDescription(`In ${client.guilds.size} servers`)
.setTimestamp()
.setFooter(message.member.user.tag, message.author.avatarURL());
message.channel.send(embed)
}
}
Bot's main file:
const path = require('path');
const fs = require("fs");
const { token, prefix } = require('./config.json');
const Discord = require('discord.js');
const db = require ('quick.db');
const client = new Discord.Client
client.commands = new Discord.Collection();
const isDirectory = source => fs.lstatSync(source).isDirectory();
const getDirectories = source => fs.readdirSync(source).map(name => path.join(source, name)).filter(isDirectory);
getDirectories(__dirname + '/commands').forEach(category => {
const commandFiles = fs.readdirSync(category).filter(file => file.endsWith('.js'));
for(const file of commandFiles) {
const command = require(`${category}/${file}`);
client.commands.set(command.name, command);
}
});
client.on("ready", () => {
console.log(`ready!.`);
console.log(token);
// Activities
const activities_list = [
`Serving Tacos | .help`,
`Preparing Orders | .help`
];
setInterval(() => {
const index = Math.floor(Math.random() * (activities_list.length - 1) + 1);
client.user.setActivity(activities_list[index]);
}, 10000);
});
//Joined Guild
client.on("guildCreate", (guild) => {
const EmbedJoin = new Discord.MessageEmbed()
.setColor('#FFFF33')
.setTitle(`Joined Guild: ${guild.name}!`)
.setTimestamp()
console.log(`Joined New Guild: ${guild.name}`);
client.channels.cache.get(`746423099871985755`).send(EmbedJoin)
});
//Left Guild
client.on("guildDelete", (guild) => {
const EmbedLeave = new Discord.MessageEmbed()
.setColor('#FFFF33')
.setTitle(`Left Guild: ${guild.name}.`)
.setTimestamp()
console.log(`Left Guild: ${guild.name}`);
client.channels.cache.get(`746423099871985755`).send(EmbedLeave)
});
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const commandName = args.shift().toLowerCase();
const command = client.commands.get(commandName)
|| client.commands.find(cmd => cmd.aliases && cmd.aliases.includes(commandName));
if (!command) return;
if (command.guildOnly && message.channel.type === 'dm') {
return message.reply('I can\'t execute that command inside DMs!');
}
if (command.args && !args.length) {
let reply = `${message.author}, wrong usage`;
if (command.usage) {
reply += `\nThe proper usage would be: \`${prefix}${command.name} ${command.usage}\``;
}
return message.channel.send(reply);
}
try {
command.execute(message, args);
} catch (error) {
console.error(error);
message.reply('there was an error trying to execute that command!');
}
});
process.on("error", () => {
console.log("Oops something happened!");
});
client.login(token);
In your code, client.guilds returns a manager, so you have to use client.guilds.cache.size. The rest of the code works fine.
const Discord = require('discord.js');
module.exports = {
name: 'stats',
description: 'Views the bot\'s stats',
execute(message, args, client) {
const embed = new Discord.MessageEmbed
.setDescription(`In ${client.guilds.cache.size} servers`)
.setTimestamp()
.setFooter(message.member.user.tag, message.author.avatarURL());
message.channel.send(embed)
}
}
In your main bot file you're only passing the message and the args (in this order) to command.execute(). You can add the client too, and update the parameters in your command's code to match this order.
try {
command.execute(message, args, client);
} catch (error) {
...
}
How do I make it so that when someone reacts with the first emoji in this command, the bot deletes the message and sends it to another channel?
Current Code:
const Discord = require("discord.js");
module.exports.run = async (bot, message, args) => {
if (!message.member.hasPermission("MANAGE_MESSAGES"))
return message.channel.send("You are not allowed to run this command.");
let botmessage = args.join(" ");
let pollchannel = bot.channels.cache.get("716348362219323443");
let avatar = message.author.avatarURL({ size: 2048 });
let helpembed = new Discord.MessageEmbed()
.setAuthor(message.author.tag, avatar)
.setColor("#8c52ff")
.setDescription(botmessage);
pollchannel.send(helpembed).then(async msg => {
await msg.react("715383579059945512");
await msg.react("715383579059683349");
});
};
module.exports.help = {
name: "poll"
};
You can use awaitReactions, createReactionCollector or messageReactionAdd event, I think awaitReactions is the best option here since the other two are for more global purposes,
const emojis = ["715383579059945512", "715383579059683349"];
pollchannel.send(helpembed).then(async msg => {
await msg.react(emojis[0]);
await msg.react(emojis[1]);
//generic filter customize to your own wants
const filter = (reaction, user) => emojis.includes(reaction.emoji.id) && user.id === message.author.id;
const options = { errors: ["time"], time: 5000, max: 1 };
msg.awaitReactions(filter, options)
.then(collected => {
const first = collected.first();
if(emojis.indexOf(first.emoji.id) === 0) {
msg.delete();
// certainChannel = <TextChannel>
certainChannel.send(helpembed);
} else {
//case you wanted to do something if they reacted with the second one
}
})
.catch(err => {
//time up, no reactions
});
});