awaitMessages inside async function discord.js - node.js

I am fairly new to async and I am trying to get the response from a user to a bot via a private message. I have done this before in sync, but not async. I have working code that properly awaits reactions that I worked into the following code, but it doesn't seem to work the same way (obviously) as I am getting (node:10080) UnhandledPromiseRejectionWarning: TypeError: msg.awaitMessages is not a function as an error when I run it.
I've looked around in trying to find awaitMessages to work for a private message inside an async function but it looks to be more complicated than putting something like the answer to this question Await reply in private message discord.js
async function cardExists() {
let matchedcards = []
let msg = await message.author.send(`Please provide the cardnames that you would like to add to '${userdeckname}'.\n\n**NOTE:** Please separate each card with a comma and space, like so "Pact of Darkness, Aquos Slam, Karmic Balance"`)
const filter = m => m.author.id === message.author.id
const reply = await msg.awaitMessages(filter, { max: 1 })
.catch(console.error);
let cardsToAdd = reply.first()
let usercardnamearray = cardsToAdd.content.split(", ")
I simply want the question to be asked, and await the user to reply in a private message to the discord bot. Some code that runs after the snippet above (once cardsToAdd is declared) ends up checking if each card in the list exists in a mysql database and pushes the cards that succeed to an array to be used later and sends the cards that fail to the private chat.
Thanks for your help in advance!

Use msg.channel.awaitMessages instead of msg.awaitMessages according to the official documentation.

Related

Slack bot ALWAYS gives missing_scope error

I'm new to Slack bots so I went through their documentation and followed some tutorials on the internet but nothing seems to help. I'm trying to add a simple bot to a workspace I've just created, all I want is to make the bot post a message once it starts. Here is my code:
const SlackBot = require('slackbots');
const botToken = 'xoxp-XXXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXX'
const bots = async () => {
const bot = await new SlackBot({
token: botToken,
name: 'orderbot'
});
console.log('adding event listener...');
await bot.on('start', () => {
console.log('posting message...');
bot.postMessage('general', 'Feeling hungry?');
});
};
bots();
And in the OAuth & Permissions page, I've added ALL permissions to the token's scopes. Running the bot, here is my output:
adding event listener...
/home/mohammed/OrderBot/node_modules/vow/lib/vow.js:105
throw e;
^
Error: missing_scope
at /home/mohammed/OrderBot/node_modules/slackbots/index.js:46:33
So apparently, the error is coming from the .on listener which is quite confusing and I can't understand why this is happening. What exactly am I missing?
It seems like the module slackbots which I was using is not working properly (at least for me). I solved this issue by using #slack/web-api instead.

How to get info from website and display it as message with Discord bot?

So I have this site https://spsknm.edupage.org/substitution/ and I want to display the part "Chýbajúci učitelia: ..." in Discord with a bot. I managed to scrape all the HTML from that URL but I can't find that specific string there. It's probably because they use some kind of script to display it.
The second idea I came up with was to screenshot that URL through some Node.js package, save it to Github and then display it in Discord as attachment. But this doesn't work too.
const captureWebsite = require('capture-website');
(async () => {await captureWebsite.file('https://spsknm.edupage.org/substitution/', 'suplovanie.png');})();
const suplovanie = new Attachment("./suplovanie.png");
msg.channel.send(suplovanie);
Any help please?
You need to put all in an async function. For example:
(async () => {
const captureWebsite = require('capture-website');
await captureWebsite.file('https://spsknm.edupage.org/substitution/', 'suplovanie.png');})();
const suplovanie = new Attachment("./suplovanie.png");
msg.channel.send(suplovanie);
})();
Now, it will wait for the capture, and then send the message.

Error snap.data is not a function with firebase cloud function and onCreate

I have a cloud function that sends a welcome email every time a new user registers in the database.
The function correctly executes everything, sends the emails and these are received by the recipient, so far, everything is fine.
It works when I manually write the email address in the function, but when I want it to get the data from the realtime database, it gives me the error:
TypeError: snap.data is not a function
This is the code of my function:
const functions = require('firebase-functions');
const nodemailer = require("nodemailer");
const transport = nodemailer.createTransport({
service: "Gmail",
auth: {
user: "MY_EMAIL",
pass: "MY_EMAIL_PASSWORD"
}
})
exports.welcomeMail = functions.database.ref('/paso1/{id}').onCreate((snap, context) => {
const _name = snap.data().name;
return sendWelcomeMail(_name)
});
// aux functions
function sendWelcomeMail(name) {
return transport.sendMail({
from: "JohnDoe <sender#test.com>",
to: "myfriendemail#gmail.com",
subject: "Hello",
html: `
<h1<Hello ${name} </h1>
<p>nice to seeyou</p>
`
})
.then(r => r)
.catch(e => e);
}
This is my realtime database:
I have reviewed the documentation several times, I have tested with snap.val().{uid}; but all without success, I cannot recover the "name" field from the database.
Using const _name = snap.val().name; I get the same error
I am not sure what is failing.
The method you're looking for is snap.val(), not snap.data(). You might be confusing Realtime Database with Firestore. Firestore uses data() to get the raw data out of a DocumentSnapshot, but that's different than Realtime Database.
You have a typo. You declare snap and then refer to it as snapshot. To fix this problem, make sure the declaration and use match.
You're also using snapshot.data(), while data() doesn't exist on a Realtime Database snapshot (you're probably confusing it with Cloud Firestore).
So combining those two fixes, this should be much closer:
exports.welcomeMail = functions.database.ref('/paso1/{id}')
.onCreate((snapshot, context) => { // this line changed
const _name = snapshot.val().name;
...
I finally found what the mistake was.
Indeed, as you have indicated to me, the correct way to extract the data from the realtime database is by using .val()
However, I told you in the comments to the answers that I kept returning error.
It didn't work because I wasn't initializing the firebase SDK as an ADMIN, necessary to access, among other things, the realtime database.
https://firebase.google.com/docs/admin/setup
I hope my mistake will save other programmers time.
Thanks to all for the help

TypeError: Cannot read property 'avatarURL' of null | Trying to export the help command

I've been cleaning my index.js file, and decided I wanted to have the help command somewhere a little more practical. Only problem: in the footer I have the bots avatar, but it comes up with TypeError: Cannot read property 'avatarURL' of null
//code in help.js
const Discord = require('discord.js');
const client = new Discord.Client();
var version = process.env.VERSION;
module.exports = {
name: 'help',
execute(message, args){
const Discord = require('discord.js');
const helpcommands = new Discord.RichEmbed()
.setTitle('Akasuki Command List')
.addField('Info Commands', 'userinfo, version, ping, invite, avatar')
.addField('Moderation Commands', 'kick, ban, clear')
.addField('Fun Commands', 'samwise, say')
.setColor(0xFF8AFF)
.setFooter(`Akasuki ${version}`, client.user.avatarURL)
message.channel.send(helpcommands);
}
}
//code in index.js
if (command === 'help') {
client.commands.get('help').execute(message, args);
}
I'm also wondering if there is a way to export multiple commands at once, or if all have to be done one-by-one?
If anyone can help me with this error I would be very grateful <3 Thank you for checking this out.
I've been cleaning my index.js file, and decided I wanted to have the help command somewhere a little more practical. Only problem: in the footer I have the bots avatar, but it comes up with TypeError: Cannot read property 'avatarURL' of null
The error TypeError: Cannot read property 'avatarURL' of null is clear. It's saying that you're attempting to access a property of an object that is null.
To debug this error, you can try logging the object in question: console.log(client.user); If null comes up, this may be due to not being logged in with your Discord.js client.
Based on your code, it seems that you've not logged in your Discord.js' Client instance. I'd recommend for you to checkout the login method, which is what you'd want to use to login to Discord. You want to login to Discord first before accessing your Client's user's properties.
Additionally, to view or create your bot applications, visit your Discord applications.
I'm also wondering if there is a way to export multiple commands at once, or if all have to be done one-by-one?
A simple way to export multiply commands is by using an array. You could define and export multiple commands like so:
module.exports = [
{
// command 1 ...
},
{
// command 2 ...
]
];
Then you could use a loop to access them.

How can I make a Discord Bot that finds the closest response to the command you entered

So I basically want my discord bot to respond with the closest response from a list, to what the user asked for.
I want to have a big list of all the possible responses that the bot can then scan through and find the closest match to what the user is asking for and send it to them.
So if I entered the command "/hep" it would automatically find the closest command which would be "/help".
I know there are tutorials that show you how to set this up in Java Scrip but I need help getting it to work with my Discord Bot
The bot works with discord.js
I'm fairly new to Discord Bots so any help would be awesome! (If I missed anything just let me know :)
One idea that I have implemented in my bots that would prove to be reliable to your question would be using a fuzzy search mechanic within your message checking. I use http://fusejs.io/ library for my fuzzy searches. You will need to handle making an array of commands first. Example:
const Fuse = require('fuse.js');
const commandarray = ['help','ping','commands','etc'];
var options = {
shouldSort: true,
threshold: 0.6,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 2,
keys: undefined
};
Then use the fuzzy search library to interact with your incoming messages that begin with your prefix and send them thru the fuzzy. Its response will be the closest match to your command. Meaning if you typed "!hep", the response from the fuzzy would be "help" and then you can proceed to interact with the sender by initiating the help command. Just make sure to only make it fuzzy search messages sent with a prefix first, dont let it search every message sent in a channel or it will do a command closest to every message on every word sent. something like:
const prefix = '!';
const fuse = new Fuse(commandarray, options);
client.on('message', message => {
if (message.content.startsWith(`${prefix}`)) {
const fuzzyresult = fuse.search(message);
(now fuzzyresult will return the index of the command thats in the array that is the closest match to the message sent on discord)
(now you grab your array of commands, input the index, and turn it into a string)
let cmdslice = commandarray.slice(fuzzyresult);
let cmdslice.length = 1;
let cmd = cmdslice.toString();
if (cmd === 'help') {
do this function
} else if (cmd === 'ping') {
do this function instead
} etc etc etc
}
});
This is a little messy but should help you achieve your request.

Resources