Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I decided to use this discord.js guide to create my economy discord bot. Apparently something went wrong as I was about to run the bot. It had this error message and it said :
Reflect.defineProperty(currency, 'add', {
^
ReferenceError: currency is not defined
I have no idea what was wrong with it. Here's my index.js:
const Discord = require('discord.js');
const { prefix, token } = require('./config.json');
const client = new Discord.Client();
Reflect.defineProperty(currency, 'add', {
/* eslint-disable-next-line func-name-matching */
value: async function add(id, amount) {
const user = currency.get(id);
if (user) {
user.balance += Number(amount);
return user.save();
}
const newUser = await Users.create({ user_id: id, balance: amount });
currency.set(id, newUser);
return newUser;
},
});
Reflect.defineProperty(currency, 'getBalance', {
/* eslint-disable-next-line func-name-matching */
value: function getBalance(id) {
const user = currency.get(id);
return user ? user.balance : 0;
},
});
client.once('ready', () => {
console.log('Ready!');
});
});
client.on('message', async message => {
if (message.author.bot) return;
currency.add(message.author.id, 1);
if (!message.content.startsWith(PREFIX)) return;
const input = message.content.slice(PREFIX.length).trim();
if (!input.length) return;
const [, command, commandArgs] = input.match(/(\w+)\s*([\s\S]*)/);
if (command === 'balance') {
const target = message.mentions.users.first() || message.author;
return message.channel.send(`${target.tag} has ${currency.getBalance(target.id)}💰`);
} else if (command === 'inventory') {
const target = message.mentions.users.first() || message.author;
const user = await Users.findOne({ where: { user_id: target.id } });
const items = await user.getItems();
if (!items.length) return message.channel.send(`${target.tag} has nothing!`);
return message.channel.send(`${target.tag} currently has ${items.map(t => `${t.amount} ${t.item.name}`).join(', ')}`);
} else if (command === 'transfer') {
const currentAmount = currency.getBalance(message.author.id);
const transferAmount = commandArgs.split(/ +/).find(arg => !/<#!?\d+>/.test(arg));
const transferTarget = message.mentions.users.first();
if (!transferAmount || isNaN(transferAmount)) return message.channel.send(`Sorry ${message.author}, that's an invalid amount`);
if (transferAmount > currentAmount) return message.channel.send(`Sorry ${message.author} you don't have that much.`);
if (transferAmount <= 0) return message.channel.send(`Please enter an amount greater than zero, ${message.author}`);
currency.add(message.author.id, -transferAmount);
currency.add(transferTarget.id, transferAmount);
return message.channel.send(`Successfully transferred ${transferAmount}💰 to ${transferTarget.tag}. Your current balance is ${currency.getBalance(message.author.id)}💰`);
} else if (command === 'buy') {
const item = await CurrencyShop.findOne({ where: { name: { [Op.like]: commandArgs } } });
if (!item) return message.channel.send('That item doesn\'t exist.');
if (item.cost > currency.getBalance(message.author.id)) {
return message.channel.send(`You don't have enough currency, ${message.author}`);
}
const user = await Users.findOne({ where: { user_id: message.author.id } });
currency.add(message.author.id, -item.cost);
await user.addItem(item);
message.channel.send(`You've bought a ${item.name}`);
} else if (command === 'shop') {
const items = await CurrencyShop.findAll();
return message.channel.send(items.map(i => `${i.name}: ${i.cost}💰`).join('\n'), { code: true });
} else if (command === 'leaderboard') {
return message.channel.send(
currency.sort((a, b) => b.balance - a.balance)
.filter(user => client.users.cache.has(user.user_id))
.first(10)
.map((user, position) => `(${position + 1}) ${(client.users.cache.get(user.user_id).tag)}: ${user.balance}💰`)
.join('\n'),
{ code: true }
);
}
});
client.login(`[TOKEN]`);
I presume the only probelm of this code is Reflect.defineProperty(currency, 'add', { as it can't define what is currency. I hope someone can help...
You're attempting to use the currency variable but you haven't defined it so JavaScript is rightfully complaining because it doesn't know what currency is.
The following line from the guide is missing from your code:
const currency = new Discord.Collection();
You have to define currency.
Basic js-
Related
The purpose of this application is to make an API call to google places API, gather info about a restaurant, then display to the user.
The application works for the most part but every maybe 5-10 API calls on average the app crashes.
The error:
The code:
// State and global variables //
const [searchResponse, setSearchResponse] = useState("");
const [secondarySearchResponse, setsecondarySearchResponse] = useState("");
const [information, setInformation] = useState("");
const [secondaryInformation, setSecondaryInformation] = useState("");
const [itemFilter, setFilter] = useState("");
const [place_id, setPlaceId] = useState("");
const [dataReady, setDataReady] = useState(false);
const [locationHad, setLocationHad] = useState(false);
const pos = useRef(null);
const key = "AIzaSyD1ZTsmbDBBlMpmaogO_hlj93zzbDDtAoc";
var num = Math.floor(Math.random() * 20 + 1);
// Use Effects
// Gets users current location
useEffect(() => {
navigator.geolocation.getCurrentPosition((position) => {
pos.current = position;
console.log("Location had. Ready for API call.");
setLocationHad(true);
});
}, []);
// Once we have clicked our button and made our api call, we get the place_id and save it so we can make a secondary api call using place_id
useEffect(() => {
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined) {
setPlaceId(searchResponse.results[num].place_id);
console.log("place_id set");
} else {
console.log("error in setting place_id");
}
}, [searchResponse]);
// One place_id is set we make secondary api call
useEffect(() => {
if (place_id !== "") {
fetchSecondaryInfo();
} else {
console.log("no place id!");
}
}, [place_id]);
// Now that we have made both api calls we save the relavent info into state that we will pass down to child components
useEffect(() => {
if (searchResponse !== "") {
console.log(searchResponse.results[num].name);
setInformation({
name: searchResponse.results[num].name,
open_now: searchResponse.results[num].opening_hours.open_now,
rating: searchResponse.results[num].rating,
price: searchResponse.results[num].price_level,
location: {
lat: searchResponse.results[num].geometry.location.lat,
lng: searchResponse.results[num].geometry.location.lng,
},
});
console.log("info set!");
} else {
console.log("no info to set!");
}
}, [searchResponse]);
// And again for the secondary info (I broke this dwown into to seperate useEffects trying to figure out what was causing my error...)
useEffect(() => {
if (secondarySearchResponse !== "") {
setSecondaryInformation({
phone_number: secondarySearchResponse.result.formatted_phone_number,
daily_hours: secondarySearchResponse.result.opening_hours.weekday_text,
address: secondarySearchResponse.result.formatted_address,
});
setDataReady(true);
console.log("secondary info set!");
} else {
console.log("no secondary info to set!");
}
}, [secondarySearchResponse]);
// Function that makes api call
async function fetchInfo() {
if (locationHad) {
if (itemFilter === "") {
var url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${pos.current.coords.latitude},${pos.current.coords.longitude}&radius=12000&type=restaurant&key=${key}`;
} else {
var url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/nearbysearch/json?keyword=${itemFilter[0]}&location=${pos.current.coords.latitude},${pos.current.coords.longitude}&radius=12000&type=restaurant&key=${key}`;
}
await fetch(url)
.then((response) => response.json())
.then((data) => setSearchResponse(data))
.then(console.log("api request fired."));
} else {
console.log("location not yet identified!");
}
}
// Function that makes secondary api call
async function fetchSecondaryInfo() {
if (place_id !== "") {
const secondary_url = `https://secure-dawn-88985.herokuapp.com/https://maps.googleapis.com/maps/api/place/details/json?fields=formatted_phone_number,opening_hours,formatted_address&place_id=${place_id}&key=${key}`;
await fetch(secondary_url)
.then((response) => response.json())
.then((data) => setsecondarySearchResponse(data))
.then(console.log("secondary api request fired."));
} else {
console.log("place_id not had in secondary fetch.");
}
}
As for the place_id error I put in the a specific line of code to avoid this error:
useEffect(() => {
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined
) {
console.log(searchResponse.results[num].place_id);
setPlaceId(searchResponse.results[num].place_id);
console.log("place_id set");
} else {
console.log("error in setting place_id");
}
}, [searchResponse]);
So I do not understand how its possible to even throw this error with that line in there.
As for the name error I put in a specific line to console log the object before it reads the properties but it doesn't print in the console before throwing the error:
useEffect(() => {
if (searchResponse !== "") {
console.log(searchResponse.results[num].name);
setInformation({
name: searchResponse.results[num].name,
open_now: searchResponse.results[num].opening_hours.open_now,
rating: searchResponse.results[num].rating,
price: searchResponse.results[num].price_level,
location: {
lat: searchResponse.results[num].geometry.location.lat,
lng: searchResponse.results[num].geometry.location.lng,
},
});
console.log("info set!");
..........
I appreciate any input, suggestions, critiques, etc.
The error message shows that the error is being thrown on this line:
searchResponse.results[num].place_id !== undefined
This will throw if searchResponse.results[num] doesn't exist.
To be concise, try using optional chaining (and initialize searchResponse to undefined or null). Do
const [searchResponse, setSearchResponse] = useState();
and change
if (
searchResponse !== "" &&
searchResponse.results[num].place_id !== undefined) {
setPlaceId(searchResponse.results[num].place_id);
to
const possiblePlaceId = searchResponse?.results[num]?.place_id;
if (possiblePlaceId) {
setPlaceId(possiblePlaceId);
I'm using the Axios in React to register a user into MongoDb database.
But before I register a user, I check if that user already exists in the database, but since axios.post() is asynchronous, the rest of the code precending this response executes and user with same Id is regsitered again.
How do I solve this. PFB my code:
const validateRegister = (values) => {
let errors={};
const patternName = new RegExp('^[a-zA-Z ]{3,20}$')
const patternPhone = new RegExp('^[0-9]{9,10}$')
const patternEmail = new RegExp('^[a-zA-Z0-9._:$!%-]+#[a-zA-Z0-9.-]+.[a-zA-Z]$')
const patternPassword = new RegExp('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{8,})')
if(!values.name || !patternName.test(values.name)){
errors.name="Please enter a valid name"
}
if(!values.phone || !patternPhone.test(values.phone)){
errors.phone="Please enter a valid Phone number of 9-10 digits"
}
if(!values.email || !patternEmail.test(values.email)){
errors.email="Please enter a valid email address"
}
if(!values.password || !patternPassword.test(values.password)){
errors.password="Please enter a strong password to continue. A strong password has: Atleast 8 characters in length, 2 letters in upper case, 1 special character (!##$&*), 2 number (0-9), 3 letters in lower case"
}
if(!values.isTermsAndConditionsAccepted){
errors.isTermsAndConditionsAccepted = "Please Accept the Terms and conditions"
}
//Check if the user already exist
if(values.phone){
let formData = new FormData();
formData.append('phone', values.phone);
console.log('inside user check')
axios.post('http://localhost:3001/doesUserExistByPhone', formData).then(response => {
//Success - then create account
}).catch(errorResponse=>{
console.log(errorResponse)
if(errorResponse.response.status===409){
console.log('User already exist');
errors.phone="User Already exist. If you've already registered. Please try to Login.";
return errors;
}
else if(errorResponse.response.status===500){
errors.phone = "Unable to register user, contact SwapiFi Support";
return errors;
}
})
}
console.log('Errors found before creating user: ', errors);
return errors;
}
export default validateRegister
I invoke this Validator from another js file:
const useFormRegister = (submitForm) => {
const [errors, setErrors] = useState({});
const [dataIsCorrect, setDataIsCorrect] = useState(false);
const [values, setValues] = useState({
name: "",
phone: "",
email: "",
password: "",
isTermsAndConditionsAccepted: false
})
const handleValueChangeEvent = (event) => {
setValues({
...values,
[event.target.name] : event.target.value,
})
}
const handleRegisterEvent = (event) => {
console.log('Register button clicked');
event.preventDefault();
setErrors(validation(values));
console.log('Errors-Phone:', errors)
setDataIsCorrect(true);
}
useEffect(() => {
console.log('No. of errors:', Object.keys(errors).length)
{Object.entries(errors).map(([key, value]) => (
console.log("Error, ", key, ':', value)
))}
if(Object.keys(errors).length === 0 && dataIsCorrect){
submitForm(true);
let formData = new FormData();
{Object.entries(values).map(([key, value]) => (
formData.append(key, value)
))}
console.log(formData)
axios.post('http://localhost:3001/registerUser', formData).then(response => {console.log(response)}).catch(error=>{console.log(error)})
}
}, [errors])
return {handleValueChangeEvent, handleRegisterEvent, values, errors};
}
export default useFormRegister
You probably don't want to fire off a check synchronously. Look into async/await syntax. You can write code that "looks" synchronous but will actually execute asynchronously. This will allow you to do something like:
const checkUserExists = async (user) => {
const repsonse = await axios('/check/user/endpoint');
const user = await response.json();
return !!user;
}
const registerUser = async (user) => {
const repsonse = await axios('/register/user/endpoint');
const data = await response.json();
// do stuff here
}
and now you can implement whatever logic you need around these functions
useEffect(()=>{
async function deal(){
let data = await axios.get("http://localhost:8000")
setDeal(..)
}
deal()
},[])
I'm developing a discord.js moderation bot, but when I run it I get this error.
Here is the code:
var Discord = require('discord.js')
const fs = require("fs")
const { PREFIX } = require("../../config")
const db = require('quick.db')
const { stripIndents } = require("common-tags");
module.exports = {
config: {
name: "help",
description: "Help Menu",
usage: "1) m/help \n2) m/help [module name]\n3) m/help [command (name or alias)]",
example: "1) m/help\n2) m/help utility\n3) m/help ban",
aliases: ['h']
},
run: async (bot, message, args) => {
let prefix;
if (message.author.bot || message.channel.type === "dm") return;
try {
let fetched = await db.fetch(`prefix_${message.guild.id}`);
if (fetched == null) {
prefix = PREFIX
} else {
prefix = fetched
}
} catch (e) {
console.log(e)
};
if(message.content.toLowerCase() === `${prefix}help`){
var log = new Discord.MessageEmbed()
.setTitle("**Help Menu: Main**")
.setColor(`#d9d9d9`)
.addField(`**👑Moderation**`, `[ \`${prefix}help mod\` ]`, true)
.addField(`**⚙️Utility**`, `[ \`${prefix}help utility\` ]`, true)
message.channel.send(log);
}
else if(args[0].toLowerCase() === "mod") {
var commandArray = "1) Ban \n2) Kick\n3) Whois\n4) Unban\n5) Warn\n6) Mute\n7) Purge\n8) Slowmode \n9) Nick \n10) Roleinfo"
var commandA2 = "11) Rolememberinfo\n12) Setmodlog\n13) Disablemodlog\n14) Lock (Lock the channel)\n15) Unlock (Unlock the channel)\n16) Lockdown (Fully Lock the whole server. [FOR EMRGENCIES ONLY]) \n17) Hackban\\forceban <id>"
pageN1 = "**\n💠Commands: **\n`\`\`js\n" + commandArray + "\`\`\`";
pageN2 = "**\n💠Commands: **\n`\`\`js\n" + commandA2 + "\`\`\`";
let pages = [pageN1, pageN2]
let page = 1
var embed = new Discord.MessageEmbed()
.setTitle('**Help Menu: [Moderation]👑**')
.setColor("#d9d9d9") // Set the color
.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
.setDescription(pages[page-1])
message.channel.send({embed}).then(msg => {
msg.react('⬅').then( r => {
msg.react('➡')
// Filters
const backwardsFilter = (reaction, user) => reaction.emoji.name === '⬅' && user.id === message.author.id
const forwardsFilter = (reaction, user) => reaction.emoji.name === '➡' && user.id === message.author.id
const backwards = msg.createReactionCollector(backwardsFilter, {timer: 6000})
const forwards = msg.createReactionCollector(forwardsFilter, {timer: 6000})
backwards.on('collect', (r, u) => {
if (page === 1) return r.users.remove(r.users.cache.filter(u => u === message.author).first())
page--
embed.setDescription(pages[page-1])
embed.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
msg.edit(embed)
r.users.remove(r.users.cache.filter(u => u === message.author).first())
})
forwards.on('collect', (r, u) => {
if (page === pages.length) return r.users.remove(r.users.cache.filter(u => u === message.author).first())
page++
embed.setDescription(pages[page-1])
embed.setFooter(`Page ${page} of ${pages.length}`, bot.user.displayAvatarURL())
msg.edit(embed)
r.users.remove(r.users.cache.filter(u => u === message.author).first())
})
})
})
}
else if(args[0].toLowerCase() === "util") {
var embed = new Discord.MessageEmbed()
.setTitle('**Help Menu: [Utility]**')
.setColor("#d9d9d9") // Set the color
.setDescription("```js" + `1) Prefix [${prefix}help prefix for more info]\n 2) Help [${prefix}help for more info]` + "```")
} else {
const embed = new Discord.MessageEmbed()
.setColor("#d9d9d9")
.setAuthor(`${message.guild.me.displayName} Help`, message.guild.iconURL())
.setThumbnail(bot.user.displayAvatarURL())
let command = bot.commands.get(bot.aliases.get(args[0].toLowerCase()) || args[0].toLowerCase())
if (!command) return message.channel.send(embed.setTitle("**Invalid Command!**").setDescription(`**Do \`${prefix}help\` For the List Of the Commands!**`))
command = command.config
embed.setDescription(stripIndents`
** Command -** [ \`${command.name.slice(0, 1).toUpperCase() + command.name.slice(1)}\` ]\n
** Description -** [ \`${command.description || "No Description provided."}\` ]\n
** Usage -** [ \`${command.usage ? `\`${command.usage}\`` : "No Usage"}\` ]\n
** Examples -** [ \`${command.example ? `\`${command.example}\`` : "No Examples Found"}\` ]\n
** Aliases -** [ \`${command.aliases ? command.aliases.join(" , ") : "None."}\` ]`)
embed.setFooter(message.guild.name, message.guild.iconURL())
return message.channel.send(embed)
}
}
}
If someone could help with this issue it would be great because I don't know what to do. I already searched on internet but I still don't know what I need to do to solve this error. All this code is for help function, when someone calls -pks help the bot should show embed telling all his functions
Here is my index.js file:
const { Client, Collection } = require('discord.js');
const { PREFIX, TOKEN } = require('./config');
const bot = new Client({ disableMentions: 'everyone' });
const fs = require("fs");
const db = require('quick.db');
bot.commands = new Collection();
bot.aliases = new Collection();
["aliases", "commands"].forEach(x => bot[x] = new Collection());
["console", "command", "event"].forEach(x => require(`./handler/${x}`)(bot));
bot.categories = fs.readdirSync("./commands/");
["command"].forEach(handler => {
require(`./handler/${handler}`)(bot);
});
bot.on('message', async message => {
let prefix;
try {
let fetched = await db.fetch(`prefix_${message.guild.id}`);
if (fetched == null) {
prefix = PREFIX
} else {
prefix = fetched
}
} catch {
prefix = PREFIX
};
try {
if (message.mentions.has(bot.user.id) && !message.content.includes("#everyone") && !message.content.includes("#here")) {
message.channel.send(`\nMy prefix for \`${message.guild.name}\` is \`${prefix}\` Type \`${prefix}help\` for help`);
}
} catch {
return;
};
});
bot.login(TOKEN);
This question already has answers here:
The useState set method is not reflecting a change immediately
(15 answers)
Closed 1 year ago.
state isn't reflecting change immediately causing me to have to fun onSubmit twice to get the form to submit
If you want to perform an action on state update, you need to use the useEffect hook, much like using componentDidUpdate in class components since the setter returned by useState doesn 't have a callback pattern
from Link to suggested question
But I'm Honestly confused on how to implement an on Submit into a use effect I'm sorry I'm new to react
const onSubmit = async(data) = > {
setNameError(nameValidation(data.name));
setphoneError(phoneNumberValidation(data.phoneNumber));
setEmailError(emailValidation(data.email));
setMessageError(messageValidation(data.message));
//Here is where I'm getting caught up, in react dev tools the above states are being set to false but below the noErrors Variable is still reading false after all conditions check true the no Errors is still getting the old values for some reason I even used a settimeout method.
let noErrors = (!nameError && !phoneError && !emailError && !messageError);
if (noErrors) {
try {
// const templateParams = {
// name: data.name,
// email: data.email,
// number: data.phoneNumber,
// message: data.message,
// };
// await emailjs.send(
// process.env.REACT_APP_SERVICE_ID,
// process.env.REACT_APP_TEMPLATE_ID,
// templateParams,
// process.env.REACT_APP_USER_ID
// );
reset();
toastifySuccess();
} catch (e) {
console.log(e);
}
}
};
const hasCharacter = /[a-zA-Z]/g;
export const nameValidation = function nameValidation(name) {
if (name.length > 30) {
return 'This field only accepts 30 characters';
}
if (name.length < 5) {
return 'This field requires five characters';
}
if (/\d/.test(name)) {
return ' This field cannot contain numbers';
}
if (!name.includes(' ')) {
return 'This Field Requires A Space';
}
return false;
};
export const phoneNumberValidation = (number) = > {
if (number.length !== 10) {
return 'A Phone Number Must be ten digits';
}
if (hasCharacter.test(number)) {
return 'A Phone Number Shouldnt Contain A Letter';
}
return false;
};
export const emailValidation = (email) = > {
if (email.length > 30) {
return 'This field only accepts 30 characters';
}
if (email.length < 5) {
return 'This field requires five characters';
}
if (!email.includes('#')) {
return 'Email Addresses require # Symbol';
}
return false;
};
export const messageValidation = (message) = > {
if (message.length > 500) {
return 'This field only accepts 500 characters';
}
if (message.length < 5) {
return 'This field requires five characters';
}
return false;
};
Here there are 2 ways to solve your issue.
Store error in local variable and use those variables to setState and check noError.
const onSubmit = async(data) = > {
const nameErr = nameValidation(data.name);
const phoneErr = nameValidation(data.phoneNumber);
const emailErr = nameValidation(data.email);
const messageErr = nameValidation(data.message);
setNameError(nameErr);
setphoneError(phoneErr);
setEmailError(emailErr);
setMessageError(messageErr);
let noErrors = (!nameErr && !phoneErr && !emailErr && !messageErr);
// rest of your code
}
use useEffect to calculate noErrors
const onSubmit = async(data) = > {
setNameError(nameValidation(data.name));
setphoneError(phoneNumberValidation(data.phoneNumber));
setEmailError(emailValidation(data.email));
setMessageError(messageValidation(data.message));
}
useEffect(() => {
const submitForm = async () => {
let noErrors = (!nameErr && !phoneErr && !emailErr && !messageErr);
if (noErrors) {
try {
// const templateParams = {
// name: data.name,
// email: data.email,
// number: data.phoneNumber,
// message: data.message,
// };
// await emailjs.send(
// process.env.REACT_APP_SERVICE_ID,
// process.env.REACT_APP_TEMPLATE_ID,
// templateParams,
// process.env.REACT_APP_USER_ID
// );
reset();
toastifySuccess();
} catch (e) {
console.log(e);
}
}
}
submitForm();
},[nameError, phoneError, emailError, messageError])
How do I take input from user multiple times, store it, and then send an embed with the inputs?
User types command ?start
Bot replies "Hi type your name here"
User types a name, then it is stored in a variable
Bot asks again "Type your favourite game now"
User types games, it is again stored in a variable
Then the variables are taken and then made into an embed
const embed = new Discord.MessageEmbed()
.setTitle("Hobbies")
.setThumbnail(messsage.author.user.displayAvatarURL())
.addDescription("<name>")
.addDescription("<game>")
.setTimestamp();
message.channel.send(embed);
to solve that i created little "Scripts", just predefined Routines for each state of the command
script.js
class Script {
constructor (user, options, callback) {
if (!user.send) {
throw "Invalid Userhandle";
}
this.user = user;
this.options = options;
this.state = 0;
this.callback = callback;
this.responses = [];
if (!!this.options.greeting) {
this.user.send(this.options.greeting)
.then()
.catch(() => console.log(JSON.stringify(this.options.greeting)));
}
};
interpretMessage(message) {
if (!this.options.validator[this.state] || typeof this.options.validator[this.state] !== 'function') {
if (!!this.callback) {
this.callback(this.user, this.responses, false);
return;
} else {
throw "Invalid User Gatherer Object";
}
}
const [msg, steps] = this.options.validator[this.state](message, this.responses);
this.user.send(msg)
.then()
.catch(() => console.error(msg));
if (steps > 0 || steps < 0) {
if (!!this.responses && !!this.responses[this.state]) {
this.responses[this.state] = message;
} else {
this.responses.push(message);
}
this.state += steps;
}
if (this.state >= this.options.validator.length) {
this.callback(this.user, this.responses, false);
}
};
};
module.exports = Script;
I use this Method only in private Messages, that's the reason for my naming:
msg_script.js
const Script = require('./classes/script');
let privateInfoGatherer = {};
let privateInfoGathererCallback = {};
function deletePrivateInfoGatherer(usr, out) {
if (!usr || !usr.id) {
return;
}
privateInfoGathererCallback[usr.id](usr, out);
delete privateInfoGatherer[usr.id];
delete privateInfoGathererCallback[usr.id];
};
function PrivateInfoGatherer (usr, opts, callback) {
if (!usr || !usr.id || !opts || !callback) {
return;
}
privateInfoGatherer[usr.id] = new Script(usr, opts, deletePrivateInfoGatherer);
privateInfoGathererCallback[usr.id] = callback;
};
function checkPrivateMessage(msg, args) {
if (!msg || !msg.author || !privateInfoGatherer[msg.author.id] || msg.guild) {
return;
}
privateInfoGatherer[msg.author.id].interpretMessage(msg.content);
};
module.exports = {
provide: {
PrivateInfoGatherer: PrivateInfoGatherer,
},
events: {
message: checkPrivateMessage,
}
};
my final usage looked something like this:
const ressource = require('./classes/ressource');
function interpretAuth(msg, args, provider) {
const usr = msg.author;
const stage_1 = (msg) => {
let steps = msg.match("^([A-Za-z0-9_ ]{4,32})$") ? 1 : 0;
let ret;
if (msg === 'abort') {
steps = 100; // will result in ending the script
} else {
ret = steps === 1 ? 'And now your Password' : 'Gimme your username';
}
return [ret, steps];
};
const stage_2 = (msg) => {
let steps = msg.match("^([A-Za-z0-9\\!\\#\\#\\%\\&\\_\\(\\)\\*\\-\\$\\^\\[\\]]+)$") ? 1 : 0;
let ret;
if (msg === 'abort') {
steps = 100;
} else {
ret = steps === 1 ? 'I will check the Auth' : 'Your Password man...';
}
return [ret, steps];
};
const options = {
greeting: 'Ok for Authrole i need your login, so first your username pls',
validator: [
stage_1,
stage_2,
]
};
const callback = (usr, out) => {
const [username, password] = out;
// Now we have all, do what ever you want with it.
};
provider.PrivateInfoGatherer(usr, options, callback);
};