Ayo! I'm having issues with outputting an embed. The only issue that puzzles me is I don't have a field without anything and it goes through and sends it in Discord and THEN errors out.
It does the same thing when I'm detecting edits, this code is within my bot.on("message", async message => {}). Maybe that's the issue but I don't see why and where I would put it if else.
//-- Logging Deleted Messages --\\
bot.on("messageDelete", (messageDelete) => {
let deletionEmbed = new Discord.RichEmbed()
.setDescription("📝 Deleted Message 📝")
.setColor("#e56b00")
.addField("User:", `${message.author}`)
.addField("Message:", `${messageDelete}`);
let logchannel = message.guild.channels.find(`name`, "server-log");
if (!logchannel) return message.channel.send("Couldn't find a logging channel!");
logchannel.send(deletionEmbed);
});
This is the error message:
if (!/\S/.test(value)) throw new RangeError('RichEmbed field values may not be empty.');
RangeError: RichEmbed field values may not be empty.
The most important issue first: you have the messageDelete event handler inside your message event. That will make a new event listener for each message that your bot receives: it'll either crash your bot because of memory issues or spam like crazy.
You need to use this outside of your message event:
bot.on("messageDelete", (oldMessage, newMessage) => {...});
Inside that handler, use these:
.addField("User:", `${newMessage.author.tag}`)
.addField("Message:", `${oldMessage.content}`);
Related
I've been trying to use interactionCreate event, but somehow it's not working. I'm not sure why, and I didn't find exact documentation about this event, only that it's used for executing slash commands. However for this purpose I use messageCreate event, and it's working fine.
const Event = require('../handlers/Event.js');
module.exports = new Event('messageCreate', (client, message) => {
if (!message.content.startsWith(client.prefix) || message.author.bot) return;
const args = message.content.substring(client.prefix.length).split(/ +/);
try {
const command = client.commands.find(cmd => cmd.name == args[0] || cmd.alias == args[0]);
command.run(message, args, client);
} catch (error) {
message.channel.send('Wrong command.');
}
});
What's wrong with my interactionCreate event?
const Event = require('../handlers/Event.js');
module.exports = new Event('interactionCreate', async (interaction) => {
if (!interaction.isCommand()) return;
if (interaction.commandName === 'join') {
await interaction.reply('join');
}
});
"An Interaction is the message that your application receives when a user uses an application command or a message component." Discord Interactions
The messageCreate listener will trigger for everything else pretty much.
In your case, what are you trying to do that will trigger the interaction? built in slash command perhaps?
Application commands are commands that an application can register to Discord, the built in slash commands I believe don't match this description. So for you to see an interaction firing you will either have to register an applicationCommand yourself (ApplicationCommandBuilder) or perhaps create an embed message with a button (DiscordButtons) and click the button which should trigger an interaction
I solved this problem just now. I have the same problem but maybe for a different reason. It's nothing about the code in my situation.
Before I use discord.js, I use the original API here.
And I set the INTERACTIONS ENDPOINT URL as the tutorial described
enter image description here
Then I started to use discord.js. But interactionCreate cannot work.
I re-set INTERACTIONS ENDPOINT URL to be nothing. Everything is OK now.
Maybe you should wrap the entire code into one event .
I believe that your event code was created twice , is not good for listening multiple event at the same time, to do that you should have to considering to declare one new event but iterate trough the event file.
This what i use on my project last month in my index.js.
Note that i wasnt use slash command at the moment but i use that for the button and any other component interaction, but slash command can be use that too.
const eventFiles = fs.readdirSync('./event').filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const event = require(`./event/${file}`);
client.on(event.name, (...args) => event.execute(...args, any parameter here));
}
That could be the cleanest way to listen event at the same time.
I hope this help 😃
This question is a mix of discord js and javascript confusion. I am making a bot for a discord server and it needs to take the last message of the day (sent right before 12am) and react to it with a cookie. My current approach is to use setInterval() to check the time of day every couple of seconds and if it's exactly 12am, fetch the last message and react to it with a cookie. However, for some reason, the bot keeps reacting multiple times (because it can react with a random cookie emoji each time), which is not intended. My solution for that was to check the current reactions on the message and then react only if there are none, but somehow, I can't get that solution to work.
Code:
function cookieReaction(messages, cookies) {
let cookieCount;
let cookieMessage = messages.first();
const filter = (reaction, user) => user.id === client.user.id
// Check for "cookie" reactions (reactions from bot that are cookie emojis)
cookieMessage.awaitReactions(filter, {time: 1000}).then(collected => {
console.log(`${cookieMessage.content} has ${collected.size} cookies`);
this.cookieCount = collected.size;
console.log(`Cookie count inside is: ${this.cookieCount}`);
}).catch(console.error);
// If the message has no "cookie" reactions, then react with a random cookie emoji
console.log(`Cookie count outside is: ${cookieCount}`);
if(!this.cookieCount) cookieMessage.react(cookies[Math.floor(Math.random() * cookies.length)]).catch(console.error);
}
When I try getting the value of cookieCount outside the anonymous function (the function after cookieMessage.awaitReactions()), it keeps returning undefined. I've also tried with and without the this keyword, and tried moving the cookieMessage.react() statement inside the anonymous function but that just results in even more weird behaviour. In short, I just can't seem to get the value of collected.size as a condition for the if statement outside the anonymous function. Any approaches to solve this problem are welcome.
EDIT - UPDATED CODE:
async function cookieReaction(messages, cookies) {
let cookieCount;
let cookieMessage = messages.first();
const filter = (reaction, user) => user.id === client.user.id
// Check for "cookie" reactions (reactions from bot that are cookie emojis)
await cookieMessage.awaitReactions(filter, {time: 1000}).then(collected => {
console.log(`${cookieMessage.content} has ${collected.size} cookies`);
cookieCount = collected.size;
console.log(`Cookie count inside is: ${cookieCount}`);
}).catch(console.error);
// If the message has no "cookie" reactions, then react with a random cookie emoji
console.log(`Cookie count outside is: ${cookieCount}`);
if(cookieCount == 0) cookieMessage.react(cookies[Math.floor(Math.random() * cookies.length)]).catch(console.error);
}
The cookieCount now stores the correct value, but the bot is still reacting to a message even when the if statement says it shouldn't.
So I'm working on a bot for a game me and my friends made and wanted to include a secret command. When it is triggered, it will count down (while sending some messages at certain intervals) then do a certain action.
In order to get the timing correct, I've used the setTimeout feature, but now I'm running into a problem: For some reason, I can't send a message from inside a function. Is there a way to get around this restriction? Alternatively, is there another way to complete the command after a certain delay?
if(command === 'purge') {
console.log('Starting first message/countdown')
message.channel.send('WARNING: PURGE PRECEPT INITATED. THIS SERVER WILL BE DELETED IN: 60 SECONDS.')
setTimeout(purge1, 15000);
}
function purge2() {
console.log('Starting third message/countdown')
message.channel.send('WARNING: PURGE PRECEPT INITIATED. THIS SERVER WILL BE DELETED IN: 30 SECONDS.');
setTimeout(purge3, 15000)
}
Not quite sure how to format code, sorry. Yes I do have the other stuff (Readying client, login, etc.) but that is the main part relevant to the question.
The reason it doesn't work is message is not defined within the function so what you should do is:
Add a message parameter in the function and then pass it when you call the function, for example:
client.on('message', async message => {
SendHello(message);
}
function SendHello(message){
message.channel.send('Hello');
}
(new to js)
I am making a discord to minecraft bot which uses discord.js on one file and mineflayer for the minecraft bot. When a command is run in discord, it makes the bot run it and runs a function which detects the right line in chat, problem is even after it detects the message, it constantly stays on and reads every line, forever. Meaning if someone else types what its detecting it interferes and thinks thats the right chat line..
Im not sure how to make it stop either, after running the event once, or after finding the line in chat, I would probably need it to stop after running it once incase the line doesnt show up for some reason.
function balOutput() {
bot.on('message', jsonMsg => {
if (Array.isArray(jsonMsg.json.extra)) {
var message = '';
jsonMsg.json.extra.forEach(function(element) {
message = message + element.text;
});
if (message.toLowerCase().includes('\'s balance')) {
var msg = message;
fs.writeFile('output.txt', msg, err => {
if (err) throw err;
});
} else if (message.toLowerCase().includes('is not locally online')) {
var msg = 'That player is not online!';
fs.writeFile('output.txt', msg, err => {
if (err) throw err;
});
}
}
continue;
});
}
That function is called once the discord command goes through and it runs it in minecraft. It does work for the one time but then other messages ruin it. The problem is I cant just use regex and make it detect that message of a player saying it because, some other commands need to run with the exact same output but be placed in different spots, so I need it not to trigger the bot.on('message') in the baloutput function... Pretty much I need to close that event after running it once.
I’m not entirely sure what jsonMsg represents, as Discord.js’s message event passes a Message object as its first argument, and that doesn’t have a .json property, while you are expecting jsonMsg.json.extra to be an array, and that seems to be the case sometimes.
However, whenever you call your balOutput function, it seems you are adding yet another listener callback function to bot’s message event. That could be causing the behaviour you’re faced with, where things only work the first time. You’ll want to add just one callback.
You may also want to look into using a normal for loop, rather than a .forEach(), from which you can break out of with break; the moment your if condition is first met.
Im new to js, and mineflayer so I was wondering how I can make the bot.on('chat') run once, for say the first message in chat. This example the bot just replys to every single message sent, saying the same message back.
I dont know how I would fix this, I have tried putting it in a function so its only called then, but it seems to just like open a listener and keep saying messages even after the function is done running.
var bot = mineflayer.createBot({
host: "localhost",
port: 25565,
username: "",
password: "",
version: "1.8.9"
});
bot.on('chat', function(username, message) {
if (username === bot.username) return;
bot.chat(message);
});
Any method of making it only reply to the message when called on, or only running that event once could help. Thanks!
N.B. It is 2019; please use let/const over var in modern NodeJS environments and => instead of unnamed functions when a bound "this" isn't used. i.e., const bot = mineflayer...
The on handler runs every time the 'chat' event is fired. Using bot.once would not allow you to keep checking whether you've actually responded or not. You are new to js so I would not dive into the API for removing event listeners.
Given these constraints, let's keep it simple. You could have an external boolean flag that also allows you to easily toggle on/off as you wish at a later time during runtime by having something before if (responded) return; in the following code.
Your code could look something like this:
let responded = false;
bot.on('chat', (username, message) => {
if (responded) return;
if (username === bot.username) return;
bot.chat(`Received ${message}`);
responded = true;
return;
});
instead of using any stupid functions or statements just do bot.once('chat', (message)=>{bot.chat(message)}) or use if statements like bot.on('chat', (username,message)=>{if(message === 'hi'){bot.chat('hi')}})