Discord.JS how to transfer args - javascript

I need to transfer arguments from one command to another.
Command that I need to transfer args (Order) from:
const invite = await message.channel.createInvite()
if(cmd === `${prefix}order`){
if(!args) return message.reply("Please specify what you would like to order.")
console.log(args)
baseOrderNumber++;
var order = args.join(" ")
let orderEmbed = new Discord.MessageEmbed()
orderIcon = "https://i.imgur.com/Le0Eist.png"
orderEmbed.setTitle("New Order")
orderEmbed.setColor("#FF2D00")
orderEmbed.setThumbnail(orderIcon)
orderEmbed.addField("Order Number", baseOrderNumber)
orderEmbed.addField("Order", order)
orderEmbed.addField("Customer", message.author)
orderEmbed.addField("Server Invite", invite)
bot.channels.cache.get('723838675489914891').send(orderEmbed)
let eekowo = fs.writeFileSync('orderAuthors.txt', message.author.tag, order);
}
Command I need to transfer to:
if(cmd === `${prefix}deliver`){
if(!args[1]) message.reply("Please provide an order number.")
let eekowo2 = fs.readFileSync('orderAuthors.txt', 'utf8')
deliverEmbed = new Discord.MessageEmbed()
deliverIcon = message.guild.iconURL
deliverEmbed.addField("Invite", invite)
deliverEmbed.addField("Customer", eekowo2)
deliverEmbed.addField("Items", orderEmbed.order)
message.author.send(deliverEmbed)
}
Is this possible? and if so; how?

You have a couple options:
If you are using a command handler, then you can require() the other command file, and call the function containing it's code through module.exports, and pass in args as an parameter.
If you're not using a command handler, and all commands are in your index(or bot).js file, take the code of the 2nd command, and copy it into a function in the global scope, then call the function in its place in the normal part of the if statement, and the first command, passing in args as a parameter to both, in addition to all other necessary information, such as "message".
Copy the code you want to run into the first command. (not recommended, but possible)
My recommendation would be to take option 1, but it appears as though you aren't using a command handler, so here's a possible application of #2:
// 1st command
const invite = await message.channel.createInvite()
if (cmd === `${prefix}order`) {
if (!args) return message.reply("Please specify what you would like to order.")
console.log(args)
baseOrderNumber++;
var order = args.join(" ")
let orderEmbed = new Discord.MessageEmbed()
orderIcon = "https://i.imgur.com/Le0Eist.png"
orderEmbed.setTitle("New Order")
orderEmbed.setColor("#FF2D00")
orderEmbed.setThumbnail(orderIcon)
orderEmbed.addField("Order Number", baseOrderNumber)
orderEmbed.addField("Order", order)
orderEmbed.addField("Customer", message.author)
orderEmbed.addField("Server Invite", invite)
bot.channels.cache.get('723838675489914891').send(orderEmbed)
let eekowo = fs.writeFileSync('orderAuthors.txt', message.author.tag, order);
Deliver(message, Discord, args);
}
// 2nd command
if (cmd === `${prefix}deliver`) {
Deliver(message, Discord, args);
}
// In the global scope
function Deliver(message, embed, args) {
if (!args[1]) message.reply("Please provide an order number.")
// ^ If this is an error check, you may want to put return here, before the reply
let eekowo2 = fs.readFileSync('orderAuthors.txt', 'utf8')
deliverEmbed = new Discord.MessageEmbed()
deliverIcon = message.guild.iconURL
deliverEmbed.addField("Invite", invite)
deliverEmbed.addField("Customer", eekowo2)
deliverEmbed.addField("Items", orderEmbed.order)
message.author.send(deliverEmbed)
}
}

Related

Why does bulkDelete not work with no error?

I've tried to look for typo and other inaccuracies and tried to add permission requirement for the prune command but still, the ping pong and the "not a valid number" replies work but not the prune when I enter the amount.
Details: I'm trying to make a Discord bot that can prune based on input. I use DJS v12 and follow(ed) this guide https://v12.discordjs.guide/creating-your-bot/commands-with-user-input.html#number-ranges
if (!msg.content.startsWith(prefix) || msg.author.bot) return;
if (!msg.member.hasPermission("BAN_MEMBERS")) {
msg.channel.send("You don\'t have permission.");
}
const args = msg.content.slice(prefix.length).trim().split('/ +/');
const cmd = args.shift().toLowerCase();
if (cmd === `ping`) {
msg.reply('pong.');
} else if (cmd === `prune`) {
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES")) return;
const amount = parseInt(args[0]) + 1;
if (isNaN(amount)) {
return msg.reply('Not a valid number.');
} else if (amount <= 1 || amount > 100) {
return msg.reply('Please input a number between 1 and 99.');
}
msg.channel.bulkDelete(amount, true).catch(err => {
console.error(err);
msg.channel.send('Error!');
});
}
});
The reason why your prune command doesn't work, is because of your command parsing. args is always null whereas cmd always contains the whole string.
So if you enter $prune 3, your args will be empty and cmd contains prune 3. That's why your if here:
else if (cmd === `prune`)
doesn't match (if you specified arguments) and your prune command never gets executed.
To fix that, you have change your command parsing:
const cmd = msg.content.split(" ")[0].slice(prefix.length);
const args = msg.content.split(" ").slice(1);
Note: Also you seem to have a typo in your question:
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES") return;
// Missing ")" here ----^
So change that line to
if (!msg.guild.me.hasPermission("MANAGE_MESSAGES")) return;

How do I use Repl.it's database?

I need my bot to save user violations to a database when a user uses a command. For example, when #violate #user red light pass is used, the bot should save the red light pass to the database for the mentioned user. I'm using Repl.it's database and this is my code:
client.on("message", async message => {
if (message.content.toLowerCase().startsWith("#violations")) {
let violation = await db.get(`wallet_${message.author.id}`)
if (violation === null) violation = "you dont have any tickets"
let pembed = new Discord.MessageEmbed()
.setTitle(`${message.author.username} violations`)
.setDescription(`المخالفات المرورية : ${violation}`)
.setColor("RANDOM")
.setFooter("L.S.P.D")
message.channel.send(pembed)
}
if (message.channel.id === '844933512514633768') {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
console.log(args);
const command = args.shift().toLowerCase();
if (command == 'red light pass') {
const member = message.mentions.members.first(); //
let light = "red lightpass"
await db.set(`wallet_${memeber}`, light)
}
}
})
First of all, in `wallet_${memeber}`, memeber is not defined. You probably intended to use `wallet_${member}`.
I believe the issue is you're using the key `wallet_${message.author.id}` (e.g. 'wallet_12345') to get the violation/ticket, but then `wallet_${member}` (e.g. 'wallet_<#12345>') (e.g. 'wallet) to set the violation. Interpolating a GuildMember in a string calls its toString method, which creates a string of the mention of the member, not the id.
Also, it's good practice to use === instead of == as == casts the items being compared so things like 3 == '03' and [] == false are true.
The final code should like this:
if (command === "red light pass") {
const member = message.mentions.members.first();
const light = "red lightpass";
// Note how I've changed this to member.id (which is just a shortcut for
// member.user.id) from memeber
await db.set(`wallet_${member.id}`, light);
}

Optional Arguments in Commands

EDIT
I doubt if you can find a correct answer below since this question is too general. And the answer posted by me will most likely only work for that cmd handler and the version this was written for is v12
--Original Question--
how do I make the options like ?d and ? f optional and the order want matter but it will create the embed on the given options
'example: .embed ?d description: this will create an embed with only a description'
I have already tried but I messed up here is the code [Removed for private reasons]
but this outputs this : [removed]
What you need to do is : go in your main file(like index.js) and set in top of code this :
const Discord = require('discord.js');
Then where command 'embed' is you need to set this :
if(command === 'embed'){
client.commands.get('embed').execute(message, args, Discord);
Then in your command folder you will make a file named embed.js . In embed.js you need to set this code:
module.exports = {
name: 'embed',
description: 'Embed Test',
execute(message, args, Discord){
const newEmbed = new Discord.MessageEmbed()
.setTitle('Your Title')
.setColor('RANDOM')
.setFooter('Some Footer here', 'another footer here' )
.setDescription('> ?testa\n' + '> ?testb\n' + '> testc');
message.delete();
message.channel.send(newEmbed);
}
});
And you get only the description after command and message with command ([prefix]embed) will delete after you post it !
Okay i fixed it my self : )
i splited the args by (?) and went through each value to see if the args have the needed options
here is what I did for future reference :
let text = args.join(' ')
const Embed = new Discord.MessageEmbed()
let errrors = []
if(!text) return message.channel.send('Error')
let tex = text.split('?')
tex.forEach(async e => { .........
if(e.toLowerCase().startsWith('d')) {
let description = e.replace('d', '')
if(description.length == 0) {
return await errrors.push('Description option was given but no description was given!!')
} else {
await Embed.setDescription(description)
}
} else if(e.toLowerCase().startsWith('t')) ........
}
// then
if(errrors.length > 0) {
let errr = errrors
Embed.setTitle('Following errors occured while constructing your embed')
Embed.setDescription(errr)
return message.channel.send(Embed)
} else {
message.channel.send(Embed)
}

Username and args connecting? \\ Discord.js

The [text] is being combined with the [username] (you can place any username where "realdonaldtrump" is. anything after that is the actual message.
I've tried numerous things, only thing I ever got to work was having trump being the default tweet and not being able to change it so it would've been >tweet [message] instead of >tweet [username] [message] but I'd like to have custom usernames. Any clue on how to remove the [username] from the [text]
Here's the code
exports.exec = async (client, message, args, level, settings, texts) => {
const user = args[0];
// Fires Error message that the command wasn't ran correctly.
if (!user) {
return client.emit('commandUsage', message, this.help);
}
// Fires Error message that the command wasn't ran correctly.
const text = args.join(" ");
// Below is a self-deletion message prior to image sending when it's fetching the actual image.
message.channel.send({
embed: {
color: 0,
description: `${message.author} Generating image.`
}
}).then(msg => {
msg.delete(5000).catch(() => { });
}).catch(e => {
});
// Above is a self-deletion message prior to image sending when it's fetching the actual image.
try {
const { body } = await snekfetch.get(`https://nekobot.xyz/api/imagegen?type=${user.toLowerCase() === "realdonaldtrump" ? "trumptweet" : "tweet"}&username=${user.startsWith("#") ? user.slice(1) : user}&text=${encodeURIComponent(text)}`);
message.channel.send("", { file: body.message });
// Below is a automatic logger
} catch (err) {
const errorlogs = client.channels.get('480735959944527886')
const embed = new discord.RichEmbed()
.setAuthor("ERROR", "https://i.imgur.com/Omg7uJV.png")
.setDescription(`${message.author} An error has occured using this command, this has automatically be logged and sent to ${client.channels.get('480735959944527886')} to be reviewed.`)
.setColor(0)
.setTimestamp()
message.channel.send({ embed });
errorlogs.send(`Error with \`$tweet\` command!\n\nError:\n\n ${err}`)
}
// Above is a automatic logger
};
You are concatenating your args to set your text variable
const text = args.join(" ");
But as args value is ["realdonaltrump", "yeeet"] in your example, it results in text having the value "realdonaldtrump yeet".
Just do as you did for the uservariable:
const text = args[1]
You might need to validate the value of the argument.
You can use string.replace method and it will replace the username with nothing:
const text = args.join(" ").replace(new RegExp(`${user}`), "")
Hope it helps!!!

Why doesn't kicking people work using discord.js

const Discord = require("discord.js"),
bot = new Discord.Client();
let pre = "?"
bot.on("message", async msg => {
var msgArray = msg.content.split(" ");
var args = msgArray.slice(1);
var prisonerRole = msg.guild.roles.find("name", "Prisoner");
let command = msgArray[0];
if (command == `${pre}roll`) {
if (!msg.member.roles.has(prisonerRole.id)) {
roll = Math.floor(Math.random()*6)+1;
msg.reply(`You rolled a ${roll}`)
} else {
msg.reply(`HaHa NOOB, you're in prison you don't get priveleges!`)
}
}
if (command == `${pre}kick`) {
var leaderRole = msg.guild.roles.find("name", "LEADER");
var co_leaderRole = msg.guild.roles.find("name", "CO-LEADER");
if (msg.member.roles.has(leaderRole.id) ||
msg.member.roles.has(co_leaderRole.id)) {
var kickUser = msg.guild.member(msg.mentions.users.first());
var kickReason = args.join(" ").slice(22);
msg.guild.member(kickUser).kick();
msg.channel.send(`${msg.author} has kicked ${kickUser}\nReason: ${kickReason}`);
} else {
return msg.reply("Ya pleb, you can't kick people!");
}
}
})
bot.login("token").then(function() {
console.log('Good!')
}, function(err) {
console.log('Still good, as long as the process now exits.')
bot.destroy()
})
Everything works except actually kicking the person. The message sends nut it doesn't kick people. For example, when I type in ?kick #BobNuggets#4576 inactive, it says
#rishabhase has kicked #BobNuggets
Reason: inactive
But it doesn't actually kick the user, which is weird, can you help me?
Change
msg.guild.member(kickUser).kick();
to
kickUser.kick();
also, make sure the bot is elevated in hierarchy
Use kickUser.kick();
I recommend using a command handler to neaten up your code. You don't want all your commands in one .js file.
Try something like this for the Ban command itself. I use this for my Bot:
client.on("message", (message) => {
if (message.content.startsWith("!ban")) {
if(!message.member.roles.find("name", "Role that can use this bot"))
return;
// Easy way to get member object though mentions.
var member= message.mentions.members.first();
// ban
member.ban().then((member) => {
// Successmessage
message.channel.send(":wave: " + member.displayName + " has been successfully banned :point_right: ");
}).catch(() => {
// Failmessage
message.channel.send("Access Denied");
});
}
});
That should work, set the role you want to use it (cAsE sEnSiTiVe) and change !ban to whatever you feel like using. If you change all "ban"s in this to kick, it will have the same effect. If this helped you, mark this as the answer so others can find it, if not, keep looking :)

Categories