Alright so heres my issue. I'm trying to delete a message that only contains an embed. However, the message wont delete. Here is what I've tried:
const embedMsg = message.embeds.find(msg => msg.title == 'Castle League Mafia');
if(embedMsg) {
message.delete();
return;
}
And I've just tried message.delete() once players is equal to 1 and that doesn't work either. It deletes my message (the one with the command for sending the embed)
Here is the place where I'm trying to do it: https://pastebin.com/DbuFx8Gs
Heres my full code: https://pastebin.com/6EJVTBFJ
Try this code here
// when you send the embed
const embed = message.channel.send(Embed)
// if (blah blah blah)
if (1 == 1) { // for testing
embed.delete()
}
in your case this should work
require('dotenv').config();
const discord = require("discord.js");
const client = new discord.Client();
const prefix = '!'
const footer = "Mafia Bot V1.0 - Spoon";
var players = 0;
client.login(process.env.BOT_TOKEN);
client.on('ready', () => {
console.log("Bot is logged in!");
client.user.setActivity('Mafia', {type: 'PLAYING'}).then(presence => console.log(`Activity set to ${presence.activities[0].name}`)).catch(console.error);
});
client.on('message', message => {
// Start Command
var embedMsg;
if (message.content === prefix + "newgame") {
let newEmbed = new discord.MessageEmbed()
.setTitle("Castle League Mafia")
.setDescription("**Everything here is going to be changed**\nReact to this message to join the mafia game!\n\n6 players in total are needed to play.\n\nIf you are the mafia, you will recieve a DM. If you do not recieve a DM, you are innocent.\n\n**" + players + "/6 Players**")
.setColor("PURPLE")
.setTimestamp()
.setFooter(footer);
embedMsg = message.channel.send(newEmbed);
}
// Add join reaction
if(message.author.bot) {
if(message.embeds) {
if(embedMsg) {
message.react('βοΈ');
return;
}
}
}
// When players react
client.on("messageReactionAdd", (reaction, user) => {
if(reaction.emoji.name === "βοΈ" && !user.bot) {
players += 1;
// When players join
switch (players) {
case 1:
console.log(players + " players are ready to play!");
if(embedMsg) {
embedMsg.delete();
return;
}
let startEmbed = new discord.MessageEmbed()
.setTitle("Game has started!")
.setDescription("**Mafia has been messaged!**")
.setColor("PURPLE")
.setTimestamp()
.setFooter(footer);
message.channel.send(startEmbed);
break;
case 2:
console.log(players + " players are ready to play!");
break;
case 3:
console.log(players + " players are ready to play!");
break;
default:
break;
}
return;
}
});
client.on("messageReactionAdd", (reaction, user) => {
if(reaction.emoji.name === "π΅") {
}
});
client.on("messageReactionRemove", (reaction, user) => {
if(reaction.emoji.name === "βοΈ" && !user.bot) {
players -= 1;
console.log(players + " players are ready to play!");
return;
}
})
});
Related
I'm pretty trash at coding so I need a little bit of help. I'm trying to code my discord bot to delete someone's messages for one minute after they click a react emoji. It sounds simple but for my tiny pea brain, it's not. This is what I have got so far. It deletes all messages from different users and guilds it's in, forever. I want it so it only delete messages in one channel for one minute.
client.once('message', async userMessage => {
if (userMessage.content.startsWith(''))
{
botMessage = await userMessage.channel.send('Who here likes goats?')
await botMessage.react("π")
await botMessage.react("π")
const filter = (reaction, user) => {
return (
["π", "π"].includes(reaction.emoji.name) && user.id === userMessage.author.id
);
};
botMessage
.awaitReactions(filter, { max: 1, time: 60000, errors: ["time"] })
.then((collected) => {
const reaction = collected.first();
if (reaction.emoji.name === "π") {
userMessage.channel.send(`${userMessage.author}, how dare you. I guess no on here likes me. Hmmm, because of that I shall now eat all your messages! BAAAAAHAHAHHAHAHA!`)
setTimeout(() => {
client.on("message", async msg => {
if (author.msg.content.startsWith("")) {
userMessage.channel = await msg.delete();
}
});
}, 2000);
} else {
userMessage.reply("Thanks!");
}
})
.catch((_collected) => {
userMessage.channel.send("Hehe")
});
}
});
Btw, the code is in discord.js!
Your problem is this chunk of code
setTimeout(() => {
client.on("message", async msg => {
if (author.msg.content.startsWith("")) {
userMessage.channel = await msg.delete();
}
});
}, 2000);
This is not how you use events.
A) Your message event is nested within another which could cause memory leaks.
B) To get the content you need to use msg.content, author.msg Is not a thing.
C) I assume your intention here: msg.content.startsWith("") is to always fire the if statement, in that case why not do if (true).
Here's how I would do it:
Create a Set in the namespace which will hold id's of users who's messages should be deleted
const toDelete = new Set();
If they react with a π add them to the set.
if (reaction.emoji.name === "π") {
userMessage.channel.send('Your message here');
if (!toDelete.has(userMessage.author.id)) {
toDelete.add(userMessage.author.id);
}
}
On each message event check if the author of the message has their id in the set, If so delete their message
client.once('message', async userMessage => {
if (toDelete.has(userMessage.author.id)) {
return userMessage.delete()
.catch(console.error);
}
if (userMessage.content.startsWith('')) {
// Rest of your code
I think your problem in understanding how everything works.
I took everything from discord.js documentation.
Type reaction command to see how it works.
const Discord = require("discord.js");
require("dotenv").config();
const TOKEN = process.env.TOKEN||"YOUR TOKEN";
const PREFIX = process.env.PREFIX||"YOUR PREFIX";
const bot = new Discord.Client();
bot.on("ready", async function(e) {
console.log("Loaded!");
})
bot.on("message", async function(message) {
if (message.author.bot) return;
if (!message.content.startsWith(PREFIX)) return;
let args = message.content.slice(PREFIX.length).trim().split(/\s+/);
let command = args.splice(0, 1).toString().toLowerCase();
if (command == "reaction") {
message.delete();
let msg = await message.channel.send("Click on the reaction");
await msg.react("π");
await msg.react("π");
let filter = (reaction, user) => {
return ["π", "π"].includes(reaction.emoji.name) && user.id == message.author.id;
}
msg.awaitReactions(filter, {max: 1, time: 10000, errors: ["time"]}).then(collected => {
let reaction = collected.first();
if (reaction.emoji.name == "π") {
return message.channel.send("downvote");
}
return message.channel.send("upvote");
}).catch(e => {
message.channel.send("user didn't vote");
})
}
})
bot.login(TOKEN);
I have been following the Worn Off Keys Discord.JS guide to get to know discord.js better, even though I understand JS fairly well. I got to a problem though when coding the reaction roles. I cloned the code for a special file from the WOK Discord JS repository. I usually clone the files and then adapt them to my liking, adding and removing some parts. But this time when I ran the code to test the basic clone out, I got an error saying TypeError [EMOJI_TYPE]: Emoji must be a string or GuildEmoji/ReactionEmoji I couldn't find any place where I could fix this, as it worked in the tutorial video with the exact same code.
Here is my code for the special reaction roles file:
const firstMessage = require('./first-message')
module.exports = (client) => {
const channelId = '870818745109585920'
const getEmoji = (emojiName) => client.emojis.cache.find((emoji) => emoji.name === emojiName)
const emojis = {
red_circle: 'CrackShot / Sniper',
orange_circle: 'Scrambler / Shotgun',
yellow_circle: 'Whipper / P90',
green_circle: 'RPEGG / RPG',
blue_circle: 'Free Ranger / Semi-Auto',
purple_circle: 'EGG-K / AK-47',
white_circle: 'TriHard / AUG',
black_circle: 'Cluck-9mm / Pistol'
}
const reactions = []
let emojiText = '**GUN ROLES**\n\n'
for (const key in emojis) {
const emoji = getEmoji(key)
reactions.push(emoji)
const role = emojis[key]
emojiText += `${emoji} = ${role}\n`
}
firstMessage(client, channelId, emojiText, reactions)
const handleReaction = (reaction, user, add) => {
if (user.id === '869698265698947102') {
return
}
const emoji = reaction._emoji.name
const { guild } = reaction.message
const roleName = emojis[emoji]
if(!roleName) {
return
}
const role = guild.roles.cache.find((role) => role.name === roleName)
const member = guild.members.cache.find((member) => member.id === user.id)
if (add) {
member.roles.add(role)
} else {
member.roles.remove(role)
}
}
client.on('messageReactionAdd', (reaction, user) => {
if (reaction.message.channel.id === channelId) {
handleReaction(reaction, user, true)
}
})
client.on('messageReactionRemove', (reaction, user) => {
if (reaction.message.channel.id === channelId) {
handleReaction(reaction, user, false)
}
})
}
The first-message file that you see there is:
const addReactions = (message, reactions) => {
message.react(reactions[0])
reactions.shift()
if (reactions.length > 0) {
setTimeout(() => addReactions(message, reactions), 750)
}
}
module.exports = async (client, id, text, reactions = []) => {
const channel = await client.channels.fetch(id)
channel.messages.fetch().then((messages) => {
if (messages.size === 0) {
channel.send(text).then((message) => {
addReactions(message, reactions)
})
} else {
for (const message of messages) {
message[1].edit(text)
addReactions(message[1], reactions)
}
}
})
}
And all I added from those files to the main index.js file is const roleClaim = require('./role-claim') and later inside the client.on(ready)etc. part I added roleClaim(client) to run the bot code. Any suggestions? Sorry for the giant amounts of text. Please help.
The problem is that you don't have emojis with names like red_circle, orange_circle, etc. client.emojis.cache only contains custom emojis the bot has access to.
So, when you use getEmoji() to get the emoji you'll receive undefined. You don't check the emoji value inside that function and just add it to an array (reactions.push(emoji)). Later, when you try to add the reaction (addReactions()), you try to react with undefined. As it's not an emoji, you receive the error.
A solution would be to use emojis available, and you could also simplify the for loop
let emojis = {
'π΄': 'CrackShot / Sniper',
'π ': 'Scrambler / Shotgun',
'π‘': 'Whipper / P90',
'π’': 'RPEGG / RPG',
'π΅': 'Free Ranger / Semi-Auto',
'π£': 'EGG-K / AK-47',
};
let emojiText = '**GUN ROLES**\n\n';
let reactions = [];
Object.entries(emojis).forEach(([emoji, role]) => {
reactions.push(emoji);
emojiText += `${emoji} = ${role}\n`;
});
console.log(emojiText)
console.log(reactions)
module.exports = (client) => {
let channelId = '870818745109585920';
let emojis = {
'π΄': 'CrackShot / Sniper',
'π ': 'Scrambler / Shotgun',
'π‘': 'Whipper / P90',
'π’': 'RPEGG / RPG',
'π΅': 'Free Ranger / Semi-Auto',
'π£': 'EGG-K / AK-47',
};
let reactions = [];
let emojiText = '**GUN ROLES**\n\n';
Object.entries(emojis).forEach(([emoji, role]) => {
reactions.push(emoji);
emojiText += `${emoji} = ${role}\n`;
});
firstMessage(client, channelId, emojiText, reactions);
function handleReaction(reaction, user, add) {
if (user.id === '869698265698947102') return;
let emoji = reaction._emoji.name;
let { guild } = reaction.message;
let roleName = emojis[emoji];
if (!roleName) return;
let role = guild.roles.cache.find((role) => role.name === roleName);
let member = guild.members.cache.find((member) => member.id === user.id);
// TODO: check if role and member exist
if (add) {
member.roles.add(role);
} else {
member.roles.remove(role);
}
}
client.on('messageReactionAdd', (reaction, user) => {
if (reaction.message.channel.id === channelId) {
handleReaction(reaction, user, true);
}
});
client.on('messageReactionRemove', (reaction, user) => {
if (reaction.message.channel.id === channelId) {
handleReaction(reaction, user, false);
}
});
};
const { Client, RichEmbed } = require("discord.js");
const chalk = require("chalk");
const { token, prefix } = require("../config/config.js");
const client = new Client();
client.on("ready", () => {
console.log(chalk.red("Witamy w konsoli bota Island"));
console.log(chalk.green(`Zalogowano jako ${client.user.tag}!`));
});
client.on("message", (msg) => {
const { author, guild } = msg;
if (author.bot || !guild) {
return;
}
if (msg.content === "-info") {
msg.channel.send("Witam, jestem botem stworzonym przez Rewera");
}
});
client.on("message", (msg) => {
const { author, guild } = msg;
if (author.bot || !guild) {
return;
}
if (msg.content === "-komendy") {
msg.channel.send("JuΕΌ wkrΓ³tce, zostanΔ
dodane. SΔ
w trakcie tworzenia");
}
if (msg.content === "-wersja") {
msg.channel.send("Wersja: ALPHA 0.04");
}
if (msg === "-tworca") {
const botAuthor = "Rewer";
const botVersion = "v1.1";
msg.channel.send(
"Autorem bota jest: **${botAuthor}**! Wersja *${botVersion}*. "
);
}
if (message.content.startsWith("$kick")) {
if (!message.member.roles.find("name", "Admin"))
return;
// Easy way to get member object though mentions.
var member = message.mentions.members.first();
// Kick
member.kick().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully kicked :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
// Error handler
client.on("debug", () => {});
client.on("warn", () => {});
client.on("error", () => {});
client.login(token);
I have a problem with this code after adding the kick player command. The rest of the bot doesn't work and neither does this command
I don't know what to do with it when I remove the kick code. The bot magically starts working.
Anyone have any ideas on how to fix it, I'm a beginner so please understand
When you handle the message event you pass "msg" as the argument
client.on("message", (msg) => {
So you should use "msg" throughout
However in you kick command you start using "message"
if (message.content.startsWith("$kick")) {
and if (!message.member.roles.find("name", "Admin"))
You must change "message" to "msg" to match the name you gave the variable at the start
client.on("message", (msg) => {
making a discord bot in javascript with visual studio code but for some reason getting an error. I'll show you the code that is relevant first.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
classes I'm working with
Here is the index.js:
const { Client, Collection } = require("discord.js");
const { config } = require("dotenv");
const fs = require("fs");
const client = new Client({
disableEveryone: true
});
client.commands = new Collection();
client.aliases = new Collection();
client.categories = fs.readdirSync("./commands/");
config({
path: __dirname + "/.env"
});
["command"].forEach(handler => {
require(`./handlers/${handler}`)(client);
});
client.on("ready", () => {
console.log(`Hi, ${client.user.username} is now online!`);
client.user.setPresence({
status: "online",
game: {
name: "you get boostedβ€οΈ",
type: "Watching"
}
});
});
client.on("message", async message => {
const prefix = "!";
if (message.author.bot) return;
if (!message.guild) return;
if (!message.content.startsWith(prefix)) return;
if (!message.member) message.member = await message.guild.fetchMember(message);
const args = message.content.slice(prefix.length).trim().split(/ +/g);
const cmd = args.shift().toLowerCase();
if (cmd.length === 0) return;
let command = client.commands.get(cmd);
if (!command) command = client.commands.get(client.aliases.get(cmd));
if (command)
command.run(client, message, args);
});
client.login(process.env.TOKEN);
Here is tempmute:
bot.on('message', message => {
let args = message.content.substring(PREFIX.length).split(" ");
switch (args[0]) {
case 'mute':
var person = message.guild.member(message.mentions.users.first() || message.guild.members.get(args[1]));
if(!person) return message.reply("I CANT FIND THE USER " + person)
let mainrole = message.guild.roles.find(role => role.name === "Newbie");
let role = message.guild.roles.find(role => role.name === "mute");
if(!role) return message.reply("Couldn't find the mute role.")
let time = args[2];
if(!time){
return message.reply("You didnt specify a time!");
}
person.removeRole(mainrole.id)
person.addRole(role.id);
message.channel.send(`#${person.user.tag} has now been muted for ${ms(ms(time))}`)
setTimeout(function(){
person.addRole(mainrole.id)
person.removeRole(role.id);
console.log(role.id)
message.channel.send(`#${person.user.tag} has been unmuted.`)
}, ms(time));
break;
}
});
Here is the help.js which lists all commands
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
module.exports = {
name: "help",
aliases: ["h"],
category: "info",
description: "Returns all commands, or one specific command info",
usage: "[command | alias]",
run: async (client, message, args) => {
if (args[0]) {
return getCMD(client, message, args[0]);
} else {
return getAll(client, message);
}
}
}
function getAll(client, message) {
const embed = new RichEmbed()
.setColor("RANDOM")
const commands = (category) => {
return client.commands
.filter(cmd => cmd.category === category)
.map(cmd => `- \`${cmd.name}\``)
.join("\n");
}
const info = client.categories
.map(cat => stripIndents`**${cat[0].toUpperCase() + cat.slice(1)}** \n${commands(cat)}`)
.reduce((string, category) => string + "\n" + category);
return message.channel.send(embed.setDescription(info));
}
function getCMD(client, message, input) {
const embed = new RichEmbed()
const cmd = client.commands.get(input.toLowerCase()) || client.commands.get(client.aliases.get(input.toLowerCase()));
let info = `No information found for command **${input.toLowerCase()}**`;
if (!cmd) {
return message.channel.send(embed.setColor("RED").setDescription(info));
}
if (cmd.name) info = `**Command name**: ${cmd.name}`;
if (cmd.aliases) info += `\n**Aliases**: ${cmd.aliases.map(a => `\`${a}\``).join(", ")}`;
if (cmd.description) info += `\n**Description**: ${cmd.description}`;
if (cmd.usage) {
info += `\n**Usage**: ${cmd.usage}`;
embed.setFooter(`Syntax: <> = required, [] = optional`);
}
return message.channel.send(embed.setColor("GREEN").setDescription(info));
}
ERROR:
Error message, bot not defined.
Overall trying to get a temporary mute function to work and I want to add it to the available commands which pops up when you hit !help. Table looks like this:
!help
I think the tempmute simply doesn't work because you use bot.on() instead of client.on(), which was defined in the index.js. I can't help you for the rest but everything is maybe related to this.
I'm setting up a bot, who will await for a user's reaction to write a short message. Currently, the bot responds itself to his reaction! Why?
const { Client, RichEmbed, Discord } = require('discord.js');
const config = require('./config.json');
const client= new Client();
client.on('ready', () => {
console.log('je suis pret!');
client.user.setActivity("/help pour appeler de l'aide (avec le code NOMAD bien sur)", { type: 'WATCHING' });
})
client.on('messageReactionAdd', (reaction, user) => {
console.log(`${user.username} reacted with "${reaction.emoji.name}".`);
});
client.on('messageReactionRemove', (reaction, user) => {
console.log(`${user.username} removed their "${reaction.emoji.name}" reaction.`);
});
client.on('message', async message => {
if (message.author.bot) return;
if (message.content.toLowerCase().startsWith('!rea')) {
try {
const sentMessage = await message.channel.send('Select a number.');
for (let n = 1; n <= 5; n++) await sentMessage.react(`${n}β£`);
const filter = (reaction, user) => ['1', '2', '3', '4', '5'].includes(reaction.emoji.name.slice(0, 1)) && user.id === message.author.id;
const collected = await sentMessage.awaitReactions(filter, { maxMatches: 1, time: 60000 });
if (collected.size === 0) {
await sentMessage.clearReactions();
await message.channel.send('Your time ran out.');
} else {
const reaction = collected.first();
switch(reaction.emoji.name.slice(0, 1)) {
case '1':
await message.channel.send('You chose `one`.');
break;
}
}
} catch(err) {
console.error(err);
}
}
});
client.login(config.token);
I found the problem: the bot considers the first message: "!rea", so if I add the reaction below !rea, it answers!
How can I fix this, because I want that he considered the embed reactions!
Thank you for your help
Your client's message event is emitted by any message, including those sent by itself.
To prevent bots (and therefore your client as well) from triggering the code, add a condition checking the author's User.bot property at the beginning of the callback, and return if it's true.
if (message.author.bot) return; // Stop if the author is a bot.
// Continue with your code.
Additionally, you're collecting reactions on the wrong message, and on every one. message outside of your first then() callback is the one the bot received.
To make things much more simple and readable, we can use the await keyword (note that it can only be used asynchronous context, like in a function declared as async).
Combining these changes...
client.on('message', async message => {
if (message.author.bot) return;
if (message.content.toLowerCase().startsWith('!rea')) {
try {
const sentMessage = await message.channel.send('Select a number.');
for (let n = 1; n <= 5; n++) await sentMessage.react(`${n}β£`);
const filter = (reaction, user) => ['1', '2', '3', '4', '5'].includes(reaction.emoji.name.slice(0, 1)) && user.id === message.author.id;
const collected = await sentMessage.awaitReactions(filter, { maxMatches: 1, time: 60000 });
if (collected.size === 0) {
await sentMessage.clearReactions();
await message.channel.send('Your time ran out.');
} else {
const reaction = collected.first();
switch(reaction.emoji.name.slice(0, 1)) {
case '1':
await message.channel.send('You chose `one`.');
break;
}
}
} catch(err) {
console.error(err);
}
}
});