Discord JS - interactionCreate and messageCreate - javascript

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 😃

Related

Are google devs just wrong with their Puppeteer code: custom-event.js?

When I try the custom-event.js on https://try-puppeteer.appspot.com/ no response is displayed on the log. Surely this demo can be improved by showing some result of the code run ?!?
I've seen the popular answers on Puppeteer: How to listen to object events and the much less appreciated https://stackoverflow.com/a/66713946/2455159 (0 votes!).
NONE OF THE FIRST EXAMPLES work on try-puppeteer and the SECOND ONE DOES !
I get the idea,
First, you have to expose a function that can be called from within
the page. Second, you listen for the event and call the exposed
function and pass on the event data.
-- but that snippet didn't work (for me ) applied to the https://www.chromestatus.com/features custom event.
What's the bottom line for observing custom events with puppeteer?
There is a difference between the first two examples and the last one: the first ones just illustrate the subscription on an event, but they do not fire this event, so there is no observable reaction there (this can be confusing as a reader would expect the sites to fire the events but they do not). The third example does fire the event.
You can get the first two examples observable even on https://try-puppeteer.appspot.com/ if you add this lines accordingly.
await page.evaluate(() => { document.dispatchEvent(new Event('app-ready')); });
await page.evaluate(() => { document.dispatchEvent(new Event('status')); });
Ok, cracked it, so that a single or some multiple events are detected by Puppeteer. A couple things weren't apparent to me about how puppeteer works:
puppeteer page ≈ a browser tab
that js can be attached to that 'tab'
puppeteer must browse the test url after setup of the 'tab' (timing is critical)
So now combining previous answers, in Node or on try-puppeteer:
// in node wrap with an asynch iife
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Expose a handler to the page
await page.exposeFunction('onCustomEvent', ({ type, detail }) => {
console.log(`Event fired: ${type}, detail: ${detail}`);
});
// listen for events of type 'status' and
// pass 'type' and 'detail' attributes to our exposed function
await page.evaluateOnNewDocument(() => {
window.addEventListener('status', ({ type, detail }) => {
window.onCustomEvent({ type, detail });
});
});
await page.goto('https://puppet.azurewebsites.net/puppeteer/soEvntSingle.html');
// await page.goto('https://puppet.azurewebsites.net/puppeteer/soEvnt.html');
// await page.waitFor(3000);
await browser.close();
Detects the events fired from that webpage. Where with devTools you'll see the event is fired by a CustomEvent.
<script>
var event = new CustomEvent('status', { detail: 'ok' });
window.addEventListener('status', function(e) {
console.log('status: ', e.detail);
});
window.dispatchEvent(event);
// setTimeout(window.dispatchEvent, 1000, event);
</script>
Switching on commented lines and commenting out respective lines gets Puppeteer to monitor for repeated firing of an event. Then page soEvnt.html fires the CustomEvent 'status' event every second ad nauseam. The Puppeteer test has to terminate at some stage, to report to the terminal (or test infrastructure like Jest) so monitoring is set for 3 seconds.
!Google you can come to me for help any time!

How to stop a event (mineflayer)

(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.

Mineflayer: make bot only reply once

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')}})

Embed Issue: "RichEmbed field values may not be empty."

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}`);

HapiJS start longer background process

How should I implement a PHP exec like call to a system function with HapiJS? The user submits a processing job that needs to run in the background for some time.
I somehow need to return a job id / session id to the user, run the job asynchronously, allow the user to check back for completion and reroute when completed...
I bet there are existing solutions for that, yet I'd highly welcome a pointer into the right direction.
Check out node's child process documentation: here
To do what you are describing I would spawn a process without a callback and then use a little trick: trying to kill a process that isn't running causes an error see here
const exec = require('child_process').exec;
//Launch the process
const child = exec('ls');
const pid = child.pid;
//later in another scope when you are looking to see if it is running
try {
process.kill(pid, 0);
}
catch (e) {
console.log("it's finished");
}

Categories