So I'm making a discord bot, and I want to have a file called createcommand.js, so when you run it with node createcommand.js is starts asking for user input. So it ask "what should the name be" and then it creates a file from the input with the name, the it will ask "what should it send" and then it will add the command in the file. I've tried with https://pastebin.com/UARJcExh
#!/usr/bin/env node
const fs = require('file-system');
const ncp = require('ncp');
const init = async function () {
const modulee = require('../index.js')
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
})
const name =
readline.question(`Welcome, what should the name of the command be?`, (input) =>{
js.name = input
let config = {}
readline.question(`What should it output`, (input) => {
js.output = input;
readline.close();
})
})
}
var js = `
exports.run = async (client, message, args, level) => {
message.channel.send(output)
};
exports.conf = {
enabled: true,
guildOnly: false,
aliases: [],
permLevel: "User"
};
exports.help = {
name: "support",
category: "Miscelaneous",
description: "",
usage: name
};
module.exports = config;`;
fs.appendFile(`${js.name}`, js ,function (err) {
if (err) {
throw new Error(err);
}})
init();
. But it doesn't work.
Related
What would be the best way to use nodemailer with Cypress? I've been playing with the code bellow for the while now but with no avail. I am getting an error "cy.task('sendMail') failed with the following error:
sendAnEmail is not a function
Because this error occurred during a after all hook we are skipping all of the remaining tests."
Thanks for any tips and advices.
//Cypress config file
const { defineConfig } = require("cypress");
const sendAnEmail = require("nodemailer")
module.exports = defineConfig({
pageLoadTimeout: 180000,
e2e: {
setupNodeEvents(on, config) {
on('task', {
sendMail (message) {
return sendAnEmail(message);
}
})
},
},
});
//Nodemailer file
const sendAnEmail = (message) => {
function sendAnEmail()
const nodemailer = require('nodemailer');
const sgTransport = require('nodemailer-sendgrid-transport');
const options = {
auth: {
user: "glorioustester123#outlook.com",
pass: "********."
}
}
const client = nodemailer.createTransport(sgTransport(options));
const email = {
from: 'glorioustester123#outlook.com',
to: 'some.email#gmail.com',
subject: 'Hello',
text: message,
html: '<b>Hello world</b>'
};
client.sendMail(email, function(err, info) {
return err? err.message : 'Message sent: ' + info.response;
});
}
//The Cypress test file
/// <reference types = "cypress" />
after(() => {
cy.task('sendMail', 'This will be output to email address')
.then(result => console.log(result));
})
//zadanie A
it("navstiv stranku a vyhladaj a elementy v casti Framework Support", ()=>{
cy.visit('https://sortablejs.github.io/Sortable/#cloning')
cy.get('.col-6').find('a')
})
//zadanie B
it("navstiv stranku a vyhladaj prvy a element casti v Framework Support", ()=>{
cy.visit('https://sortablejs.github.io/Sortable/#cloning')
cy.get('[href="https://github.com/SortableJS/Vue.Draggable"]')
cy.get('.col-6').contains('a')
//contains najde prvy vyskyt, v tomto pripade to pasuje do zadania
})
//zadanie C
it("navstiv stranku vyhladaj posledny a element v casti Framework Support ", ()=>{
cy.visit('https://sortablejs.github.io/Sortable/#cloning')
cy.get('[href="https://github.com/SortableJS/ember-sortablejs"]')
})
You nodemailer file needs adjusting a bit. The is no export which is why the message sendAnEmail is not a function
const nodemailer = require('nodemailer');
const sgTransport = require('nodemailer-sendgrid-transport');
export function sendAnEmail(message)
const options = {
...
}
const client = nodemailer.createTransport(sgTransport(options));
const email = {
...
};
client.sendMail(email, function(err, info) {
return err? err.message : 'Message sent: ' + info.response;
});
}
Also, in cypress.config.js import it with a relative path
const { defineConfig } = require("cypress");
const sendAnEmail = require("./nodemailer")
and to be a clean-coder, us a different name from the npm package (something like
const sendAnEmail = require("./send-an-email")
I'm getting this error message on heroku and I think I'm getting it cause of Procfile.
I'm using Worker at the moment, but I'm trying to figure out how to have heroku access both index.js and ping.js. Unless I'm reading the error message completely wrong and this could be a different issue. Any help is appreciated!
EDIT:
Here's my code for index.js
const Discord = require('discord.js');
const music = require('#koenie06/discord.js-music');
const fs = require('fs');
const { dir } = require('console');
const bot = new Discord.Client({
shards: "auto",
intents: [
Discord.Intents.FLAGS.GUILDS,
Discord.Intents.FLAGS.GUILD_MESSAGES,
Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Discord.Intents.FLAGS.DIRECT_MESSAGES,
Discord.Intents.FLAGS.GUILD_VOICE_STATES
]
});
bot.commands = new Discord.Collection();
bot.aliases = new Discord.Collection();
//Command handler and aliases
fs.readdirSync('./commands/').forEach(dir => {
//in the commands folder, we gonna check for the category
fs.readdir(`./commands/${dir}`, (err, files) => {
//console log error(catch error)
if(err)throw err;
//checking if the files ends with .js if its a javascript file
var jsFiles = files.filter(f => f.split('.').pop() === 'js');
//if there is no commands in the file it will return
if(jsFiles.length <= 0) {
console.log("Can't find any commands");
return;
}
jsFiles.forEach(file => {
//console the loaded commands
var fileGet = require(`./commands/${dir}/${file}`);
console.log(`[COMMAND HANDLER] - File ${file} was loaded`);
//gonna let the commands run
try {
bot.commands.set(fileGet.help.name, fileGet);
// it search in the commands folder if there is any aliases
fileGet.help.aliases.forEach(alias => {
bot.aliases.set(alias, fileGet.help.name);
})
} catch(err) {
//catch error in console
return console.log(err);
}
})
})
})
/**
* ECHO STUFF
*/
//slash command to echo
bot.on('ready', async () => {
bot.user.setPresence({ activities: [{ name: "Tedi", type: "WATCHING"}] });
console.log("bye");
const data = {
name: 'echo',
description: 'Echo your text',
options: [{
name: 'text',
type: 'STRING',
description: 'The user input',
required: true,
}],
};
const command = await bot.guilds.cache.get('872986148681703444')?.commands.create(data);
})
bot.on('messageCreate', async message => {
if(message.author.bot || message.channel.type == 'DM') return
let prefix = '~'
let messageArray = message.content.split(' ');
let cmd = messsageArray[0];
let args = messageArray.slice(1);
//it will make the cmd work with his original name and his aliases
let commands = bot.commands.get(cmd.slice(prefix.length)) || bot.commands.get(bot.aliases.get(cmd.slice(prefix.length)));
if(commands) {
if(!message.content.startsWith(prefix)) return
commands.run(bot, message, args, prefix);
}
})
//interactionCreate for echo slash command
bot.on('interactionCreate', async interaction => {
/**
* isButton() used to check if its a button
* isCommand() used to check if its a slash command
* isSelectMenu() used to check if its a dropdown menu
* isMessageComponent()
*/
if(interaction.isCommand()) {
if(interaction.commandName === 'echo') {
const text = interaction.options.getString('text');
await interaction.reply({ content: text, ephemeral: false}); //if ephemeral if true, it would make the slash command private
}
}
})
bot.login(process.env.token);
Here is my ping.js
const Discord = require("discord.js");
module.exports.run = async (Client, message, args, prefix) => {
message.channel.send("pong")
}
module.exports.help = {
name: "ping",
aliases: ["p"]
}
This error is not because of Heroku, it's basically because there is a file in your command handler that doesn't have a name while handling it, as example like this code over here:
const Discord = require("discord.js");
module.exports.run = async (Client, message, args, prefix) => {
message.channel.send("pong")
}
module.exports.help = {
// here the name isn't included
aliases: ["p"]
}
// so just check if you have a file without a name while handling it and put a name, and if you don't want aliases make it `aliases: []`
This command handler should be like thisCommands Folder commands > Subfolder e.g. Moderation > kick.jsThats how it works, also thank you for watching my videos, I'm UltraX :)
I want to change the value of conf.perms.commands in my mercyxrd.js config file as seen in the below command,
please help me on how to do this (:
const conf = require("../../mercyxrd.js")
const Discord = require('discord.js')
const fs = require('fs');
class roller extends Command {
constructor(client) {
super(client, {
name: "roles",
aliases: ["roles"],
usage: "roles",
description: "bu komut hakkında bilgi bulunmuyor."
});
}
async run(message, args, perm) {
if(message.author.id !== "411621794131476480") return
let embed = new Discord.MessageEmbed()
if(!args[0]) return message.channel.send(embed.setDescription(`specify an argument`))
if(args[0] == "register-auth") {
let rol = message.mentions.roles.first() || message.guild.roles.cache.get(args.splice(1)[0]) || message.guild.roles.cache.find(r=>r.name===args.splice(1).join(''));
if(!rol) return message.channel.send(embed.setDescription(`please specify a role`)).then(x=>x.delete({timeout: 9000}))
//In this part, I want to change the value in my config file. conf.perms.commands
message.channel.send(`${rol} designated as the registration role.`)
}
}};
module.exports = roller;
Here I have a file, mail.js, that sends an email
const nodemailer = require('nodemailer')
const mailGun = require('nodemailer-mailgun-transport')
const auth = {
auth: {
api_key: process.env.MAILGUN_API_KEY,
domain: process.env.DOMAIN
}
}
const transporter = nodemailer.createTransport(mailGun(auth))
const mailTo = (name, email) => {
const mailOptions = {
from: 'example#icloud.com',
to: 'cm#example.com',
subject: 'Welcome!',
text: `Hey, ${name}! Thanks for joining Task Manager!`
}
transporter.sendMail(mailOptions)
}
module.exports = mailTo
I am trying to do Jest tests and I need to mock the nodemailer and mailGun functions so I don't get an email every time I run a test. So I made a __mocks__ folder and put my 2 mock modules in it at __mocks__/nodemailer.js and __mocks__/nodemailer-mailgun-transport.js. Here are those files
//nodemailer.js
module.exports = {
createTransport() {
},
sendMail() {
}
}
//nodemailer-mailgun-transport.js
module.exports = {
mailGun() {
}
}
And here are my tests
const request = require('supertest')
const jwt = require('jsonwebtoken')
const mongoose = require('mongoose')
const app = require('../src/app')
const User = require('../src/models/user')
const userOneId = mongoose.Types.ObjectId()
const userOne = {
_id: userOneId,
name: 'Jon',
email: 'jon#example.com',
password: 'JonTest123',
tokens: [{
token: jwt.sign({ _id: userOneId }, process.env.JWT_SECRET)
}]
}
beforeEach(async () => {
await User.deleteMany()
await new User(userOne).save()
})
test('Should signup a new user', async() => {
const response = await request(app).post('/users').send({
name: 'Caleb',
email: 'caleb#example.com',
password: 'TestPass637!'
}).expect(201)
//Assert that the database was changed correctly
const user = await User.findById(response.body.user._id)
expect(user).not.toBeNull()
//Assertions about the response
expect(response.body).toMatchObject({
user: {
name: 'Caleb',
email: 'caleb#example.com'
},
token: user.tokens[0].token
})
expect(user.password).not.toBe('TestPass637!')
})
And I have Jest setup to look for the __mocks__ file in the tests directory, which is where I have it
But when I run my tests, I get
TypeError: mailGun is not a function
Why doesn't it recognize the mailGun() function?
The nodemailer-mailgun-transport should return a function so that you can pass the auth to it. In your test code mailGun refers to the default output, not a property.
//nodemailer-mailgun-transport.js
module.exports = (auth) => {
// do something with auth, if you want
}
i made a discord bot with discord.js and tried to do a help command to show the user all available commands.
example command: avatar.js
module.exports.run = async(bot, message, args) => {
let msg = await message.channel.send("doing some magic ...");
let target = message.mentions.users.first() || message.author;
await message.channel.send({files: [
{
attachment: target.displayAvatarURL,
name: "avatar.png"
}
]});
msg.delete();
}
module.exports.help = {
name: "avatar",
description: "show the avatar of a user",
usage: "[#user]"
}
Then i tried to send a message with the complete list of the commands like:
command 1
description
usage
command 2
description
usage
...
help.js
const fs = require("fs");
const Discord = require("discord.js");
module.exports.run = async(bot, message, args, con) => {
fs.readdir("./cmds/", (err, files) => {
if(err) console.error(err);
let jsfiles = files.filter(f => f.split(".").pop() === "js");
if(jsfiles.length <= 0) {
console.log("No commands to load!");
return;
}
var namelist = "";
var desclist = "";
var usage = "";
let result = jsfiles.forEach((f, i) => {
let props = require(`./${f}`);
namelist = props.help.name;
desclist = props.help.description;
usage = props.help.usage;
});
message.author.send(`**${namelist}** \n${desclist} \n${usage}`);
});
}
module.exports.help = {
name: "help",
description: "show all commands",
usage: ""
}
my code is kinda working but it only sends the first command.
Im pretty new to javascript and i can't find a solution to this.
I tried to google everything on foreach maps discord collections and stuff but i cant find a example where the results get combined together.
If anybody can help me or give me a hint where i can search for something like this. Would be awesome.
The reason your code is only sending the one command is because your code only calls message.author.send('...' once. You successfully set the variables namelist, desclist, and usage with data from every file, but your .forEach(... loop just overwrites all of the data when it moves to the next files.
Try to send data inside each iteration of the .forEach(... loop like this:
var namelist = "";
var desclist = "";
var usage = "";
let result = jsfiles.forEach((f, i) => {
let props = require(`./${f}`);
namelist = props.help.name;
desclist = props.help.description;
usage = props.help.usage;
// send help text
message.author.send(`**${namelist}** \n${desclist} \n${usage}`);
});
you should do this in an Array and it'll solve the problem, so it should look like this.
module.exports.run = async(bot, message, args, con) => {
fs.readdir("./cmds/", (err, files) => {
if(err) console.error(err);
let jsfiles = files.filter(f => f.split(".").pop() === "js");
if(jsfiles.length <= 0) {
console.log("No commands to load!");
return;
}
let result = jsfiles.forEach((f, i) => {
let props = require(`./${f}`);
let filesArray = [props.help.name, props.help.description, props.help.usage]
message.author.send(`**${filesArray[0]}** \n${filesArray[1]} \n${filesArray[2]}`);
});
});
}
sorry for the late response.
Here is my take on this.... it works for me.
const Discord = require('discord.js');
const fs = require("fs");
module.exports = {
name: 'help',
description: 'Lists available commands',
async run(client, message, args, con) {
fs.readdir("./commands/", (err, files) => {
if(err) console.error(err);
let jsfiles = files.filter(f => f.split(".").pop() === "js");
if(jsfiles.length <= 0) {
console.log("No commands to load!");
return;
}
var namelist = "";
var desclist = "";
let result = jsfiles.forEach((f, i) => {
let props = require(`./${f}`);
namelist = props.name;
desclist = props.description;
message.author.send(`**${namelist}** \n${desclist} \n`);
});
});
}
I'm using DiscordJS 12 so this may not work on 11.
const discord = require('discord.js')
module.exports = {
name: 'cmd-list',
async run(client, message, args) {
const commandFiles = readdirSync(join(__dirname, "<your commands folder name>")).filter(file => file.endsWith(".js")); // Get files
const cmdmap = commandFiles.map(files => `${files}`).join(' | Working\n')
const embed = new discord.MessageEmbed()
.setDescription(cmdmap)
message.channel.send(embed)
}
}
You can just use discord 's normal embed system like this:
const { Message, MessageEmbed } = require('discord.js');
Add this to the top of your code then type everything as the following to make a normal embed like this:
const embed = new MessageEmbed()
.setTitle(`Your title!`)
.setColor(5814783)
.setTimestamp()
.setThumbnail('')
.setDescription(`Your description`)
.addFields(
{ name: 'Field 1', value: `Filed 1 Value`},
{ name: 'Field 2', value: `Filed 2 Value` },
{ name: 'Field 3', value: `Filed 3 Value`, inline: true },
{ name: 'Field 4', value: `Filed 4 Value`, inline: true },
{ name: 'Field 5', value: `Field 5 Value`, inline: true },
)
message.channel.send(embed2)