Optional Arguments in Commands - javascript

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

Related

Discord.js bot was working, added one extra command and everything broke. Can anyone help me figure out why?

Tried to venture in to the realm of making discord bots. Followed along with a fairly simple tutorial, tweaking it along the way to fit what I was trying to make. The bot originally worked, but I went back in to add the "Mistake" command, and suddenly it's not working. I added in console.log pretty much everywhere, trying to figure out how far everything was getting.
When I start the bot, it will spit out the "Bot Online" log. When I input a command, it will spit out the "Commands" log, but it won't register the command at all. I've tried looking for any minor typos, missing brackets, etc... but I just can't seem to figure out what's gone wrong. I'm hoping that someone here can help! Thank you!
const Discord = require('discord.js');
const config = require('./config.json');
const client = new Discord.Client();
const SQLite = require('better-sqlite3');
const sql = new SQLite('./scores.sqlite');
client.on('ready', () => {
console.log('Bot Online');
const table = sql.prepare("SELECT count(*) FROM sqlite_master WHERE type='table' AND name = 'goals';").get();
if (!table['count(*)']) {
sql.prepare('CREATE TABLE goals (id TEXT PRIMARY KEY, user TEXT, guild TEXT, goals INTEGER);').run();
sql.prepare('CREATE UNIQUE INDEX idx_goals_id ON goals (id);').run();
sql.pragma('synchronous = 1');
sql.pragma('journal_mode = wal');
}
//Statements to get and set the goal data
client.getGoals = sql.prepare('SELECT * FROM goals WHERE user = ? AND guild = ?');
client.setGoals = sql.prepare('INSERT OR REPLACE INTO goals (id, user, guild, goals) VALUES (#id, #user, #guild, #goals);');
});
client.on('message', (message) => {
if (message.author.bot) return;
let goalTotal;
if (message.guild) {
goalTotal = client.getGoals.get(message.author.id, message.guild.id);
if (!goalTotal) {
goalTotal = {
id: `${message.guild.id}-${message.author.id}`,
user: message.author.id,
guild: message.guild.id,
goals: 0,
};
}
}
if (message.content.indexOf(config.prefix) !== 0) return;
const args = message.content.slice(config.prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
console.log('Commands');
if (command === 'Goals') {
console.log('Goals');
return message.reply(`You Currently Have ${goalTotal.goals} Own Goals.`);
}
if (command === 'OwnGoal') {
console.log('Own Goal');
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) return message.reply('You must mention someone.');
let userscore = client.getGoals.get(user.id, message.guild.id);
if (!userscore) {
userscore = {
id: `${message.guild.id}-${user.id}`,
user: user.id,
guild: message.guild.id,
goals: 0,
};
}
userscore.goals++;
console.log({ userscore });
client.setGoals.run(userscore);
return message.channel.send(`${user.tag} has betrayed his team and now has a total of ${userscore.goals} own goals.`);
}
if (command === 'Mistake') {
console.log('Mistake');
const user = message.mentions.users.first() || client.users.cache.get(args[0]);
if (!user) return message.reply('You must mention someone.');
let userscore = client.getGoals.get(user.id, message.guild.id);
if (!userscore) {
return message.reply('This person has no Rocket Bot activity.');
}
if (userscore === 0) {
return message.reply('This player currently has no goals.');
}
if (userscore > 0) {
userscore.goals--;
}
console.log({ userscore });
client.setGoals.run(userscore);
return message.channel.send(`${user.tag} was falsely accused and now has a total of ${userscore.goals} own goals.`);
}
if (command === 'Leaderboard') {
console.log('Leaderboard');
const leaderboard = sql.prepare('SELECT * FROM goals WHERE guild = ? ORDER BY goals DESC;').all(message.guild.id);
const embed = new Discord.MessageEmbed()
.setTitle('Rocket Bot Leaderboard')
.setAuthor(client.user.username, client.user.avatarURL())
.setDescription('Total Goals Scored Against Own Team:')
.setFooter('Rocket Bot')
.setThumbnail('https://imgur.com/a/S9HN4bT')
.setColor('0099ff');
for (const data of leaderboard) {
embed.addFields({
name: client.users.cache.get(data.user).tag,
value: `${data.goals} goals`,
inline: true,
});
}
return message.channel.send({ embed });
}
if (command === 'RocketHelp') {
console.log('Help');
return message.reply(
'Rocket Bot Commands:' +
'\n' +
'!Goals - See How Many Goals You Have Scored Against Your Own Team' +
'\n' +
'!OwnGoal - Tag Another Player With # To Add One To Their Total' +
'\n' +
'!Mistake - Tag Another Player With # To Subtract One From Their Total' +
'\n' +
'!Leaderboard - Show The Current Leaderboard'
);
}
});
client.login(config.token);
You are improperly splitting the message content. You added g to the regex by accident.
Correct line:
const args = message.content.slice(config.prefix.length).trim().split(/ +/);
Because of improper args split, it could not find any command at all, hence no console log was invoked after Commands.

Why is my script not letting my bot add reactions to the embed message it is sending? (discord.js)

I am a big novice with JavaScript coding so if you can make this a pre simple explanation that'd be MUCH appreciated.
So basically I have made this small script in order to send a poll to another channel using the arguments I have made the user put in and then format it and send it as an embedded message
The script is sending the whole thing formated however the final step of not adding the reactions is the issue.
(they are custom reactions which I have already defined you'll see below)
if (args.length >= 1) {
message.delete().then(() => {
const pollEmbed = new Discord.RichEmbed()
.setColor('#ABDFF2')
.setTitle("** " + pollArgs[0] + " **")
.setDescription(pollArgs[1])
.addField('*Click on the reactions below to cast your opinion on this poll!*', 'If you would like to start your own poll: !help in <#726235250136580106>')
.setTimestamp()
.setThumbnail(message.author.displayAvatarURL)
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL)
let yes = message.guild.emojis.find('name', "yes")
let no = message.guild.emojis.find('name', "no")
suggestionschannel.send(pollEmbed).then(message.react(yes, no));
In case you need to see the full code here it is:
const Discord = require("discord.js");
const client = new Discord.Client();
module.exports.run = async (bot, message, args) => {
const suggestionschannel = message.guild.channels.find("name", "suggestions");
let pollArgs = args.slice(0).join(" ").split('|');
if (args.length >= 1) {
message.delete().then(() => {
const pollEmbed = new Discord.RichEmbed()
.setColor('#ABDFF2')
.setTitle("** " + pollArgs[0] + " **")
.setDescription(pollArgs[1])
.addField('*Click on the reactions below to cast your opinion on this poll!*', 'If you would like to start your own poll: !help in <#726235250136580106>')
.setTimestamp()
.setThumbnail(message.author.displayAvatarURL)
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL)
let yes = message.guild.emojis.find('name', "yes")
let no = message.guild.emojis.find('name', "no")
suggestionschannel.send(pollEmbed).then(message.react(yes, no));
})
} else {
message.delete().catch();
const pollErrEmbed = new Discord.RichEmbed()
.setColor('FF6961')
.setTitle("**error!**")
.addField("use the correct format: !polls-start <title> | <message>", "If you need help do: `!polls-help`.")
.setTimestamp()
.setFooter(message.author.tag + " | Peace Keeper", message.author.displayAvatarURL)
message.reply(pollErrEmbed).then(msg => msg.delete(10000));
}
}
module.exports.help = {
name: "polls-start"
}
Your code seems good only one tiny edit!
Instead of
suggestionschannel.send(pollEmbed).then(message.react(yes, no));
You would need to use
suggestionschannel.send(pollEmbed).then(message => {
message.react(yes);
message.react(no);
});
Also remember about Updating Discord.js to v12, as soon v11 support is going to end!

I am trying to make a discord.js avatar command, and the mentioning portion doesn't work correctly

I have an avatar command in my discord bot. When the user uses h.avatar, it outputs their avatar, which works fine. Whenever they try to use h.avatar #user, nothing happens.
Here is my code:
} if (message.content.startsWith(config.prefix + "avatar")) {
if (!message.mentions.users.size) {
const avatarAuthor = new Discord.RichEmbed()
.setColor(0x333333)
.setAuthor(message.author.username)
.setImage(message.author.avatarURL)
message.channel.send(avatarAuthor);
let mention = message.mentions.members.first();
const avatarMention = new Discord.RichEmbed()
.setColor(0x333333)
.setAuthor(mention.user.username)
.setImage(mention.user.avatarURL)
message.channel.send(avatarMention);
You have a check if (!message.mentions.users.size) { which makes the command run only if you do not mention somebody. You either need to use an else { in your code or do:
if (message.content.startsWith(config.prefix + 'avatar')) {
const user = message.mentions.users.first() || message.author;
const avatarEmbed = new Discord.RichEmbed()
.setColor(0x333333)
.setAuthor(user.username)
.setImage(user.avatarURL);
message.channel.send(avatarEmbed);
}
The const user = message.mentions.users.first() || message.author; tries to get the user that was mentioned but if it does not find anyone it will use the author's used.
This can also be used like this:
if (!message.mentions.users.size) {
message.channel.send('Nobody was mentioned');
return;
}
// continue command here, after guard clause
There's nothing like avatarUrl unless you have defined it.
Use this code to get the url of a user:
message.channel.send("https://cdn.discordapp.com/avatars/"+message.author.id+"/"+message.author.avatar+".jpeg");
Just replacemessage.author with the user who is mentioned
These is the updated version of the answer that works
if (message.content.startsWith(config.prefix + 'avatar')) {
const user = msg.mentions.users.first() || msg.author;
const avatarEmbed = new MessageEmbed()
.setColor(0x333333)
.setAuthor(`${user.username}'s Avatar`)
.setImage(
`https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=256`
);
msg.lineReply(avatarEmbed);
}
This uses discord's avatar url, and msg.lineReply(avatarEmbed); is a function that sends the embed as a reply to the message
My
if (msg.content.startsWith(prefix + 'avatar')) {
const user = msg.mentions.users.first() || msg.author;
const avatarEmbed = new MessageEmbed()
.setColor('')
.setAuthor(`${user.username}'s Avatar`)
.setImage(
`https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png?size=256`
);
msg.reply(avatarEmbed);
}
if(message.content.startsWith(prefix+'av')){
if(message.mentions.users.size){
let member=message.mentions.users.first()
if(member){
const emb=new Discord.MessageEmbed().setImage(member.displayAvatarURL()).setTitle(member.username)
message.channel.send(emb)
}
else{
message.channel.send("Sorry none found with that name")
}
}else{
const emb=new Discord.MessageEmbed().setImage(message.author.displayAvatarURL()).setTitle(message.author.username)
message.channel.send(emb)
}
}
if (message.content.startsWith(prefix + 'avatar')) {
let user = message.mentions.users.first();
if(!user) user = message.author;
let color = message.member.displayHexColor;
if (color == '#000000') color = message.member.hoistRole.hexColor;
const embed = new Discord.RichEmbed()
.setImage(user.avatarURL)
.setColor(color)
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!!!

discord.js - put code into embed

I have the following code:
("...............🚗......").then(sentMessage => sentMessage.edit("............🚗.........")).then(sentMessage => sentMessage.edit("........🚗............")).then(sentMessage => sentMessage.edit(".....🚗...............")).then(sentMessage => sentMessage.edit("..🚗..................")).then(sentMessage => sentMessage.edit("🚗....................")).then(sentMessage => sentMessage.edit("😮....🚗..............")).then(sentMessage => sentMessage.edit(".😧..🚗......................")).then(sentMessage => sentMessage.edit("..:tired_face:.:red_car:......................")).then(sentMessage => sentMessage.edit("...:ghost::red_car:......................")
How can I put this into a discord.js embed with the following code:
message.channel.send({
"embed": {
"title": "Car",
"description": - i want the above code to be here -,
"color": 16763981,
"footer": {
"text": "Have a fun ride!"
}
}
})
}
Is this possible in discord.js? If so, please help me out! Have no clue how to achieve this.
:) Will
I don't know what exactly you are trying to do. I guess what you made is an animation, if not, and you just want to print litterally this piece of code in your embed, just put this piece of code inside backticks
description: `("...............🚗......")
.then(sentMessage => sentMessage.edit("............🚗........."))
.then(sentMessage => sentMessage.edit("........🚗............"))
.then(sentMessage => sentMessage.edit(".....🚗..............."))
.then(sentMessage => sentMessage.edit("..🚗.................."))
.then(sentMessage => sentMessage.edit("🚗...................."))
.then(sentMessage => sentMessage.edit("😮....🚗.............."))
.then(sentMessage => sentMessage.edit(".😧..🚗......................"))
.then(sentMessage => sentMessage.edit("..:tired_face:.:red_car:......................"))
.then(sentMessage => sentMessage.edit("...:ghost::red_car:......................")`,
Then it looks like this :
If you want to make an animation, you're gonna have to use the bot to delete and rewrite the embed for each step of your animation (You can't just edit an embed if I'm not wrong)
Try to be more specific on what you really want to display
If I'm understanding you correctly, you want to send the first snippet of code into the description field and edit it, trying to make it be an animation?
I haven't tried editing an embedded message before but this is how I would go around it.
const sendCarAnimation = async (message) => {
// define the steps here
const animationSteps = [
"...............🚗......",
"............🚗.........",
"........🚗............",
".....🚗...............",
"..🚗..................",
"🚗....................",
"😮....🚗..............",
".😧..🚗......................",
"..:tired_face:.:red_car:......................",
"...:ghost::red_car:......................"
];
// generate an embed using the RichEmbed functionality
const embed = new Discord.RichEmbed()
.setTitle('Car')
.setDescription(animationSteps[0])
.setColor(16763981)
.setFooter('Have a fun ride!')
// initialize the message with the first embed
let messageState = await message.channel.send(embed);
// loop through and edit the message
let isFirst = true;
for(let currentStep of animationSteps) {
if(isFirst) {
isFirst = false;
continue;
}
embed.setDescription(currentStep);
messageState = await messageState.edit(embed);
}
}
NOTE: This will take a lot of requests to do and you will most likely get rate limited by discord for doing this. So I don't think this is a good idea. Here's their documentation on it. You can probably pull off some tricky code using the Discord.js's
client.on('rateLimit', (rateLimitInfo) => {});
event. Documentation link to this as well. Good luck!
Instead of deleting it and sending it again you can create a variable of the lastMessage (you might have to make a delay before selecting it) then do message.edit()
Got it! What I did to solve it was on startup, to grab the right channel using channel = client.user.guilds.cache.get("Guild id here").channels.cache.get("channel id"), built an embed that just said old, and then sent the embed.
I did include an array of animation steps like Emil Choparinov, and a msgProgress variable. The bot detects when a message is sent, and checks if (msg.content === ''). if true, it will set the recievedEmbed constant to msg.embeds[0].
Then, a new const, embed, is set to a new Discord.MessageEmbed, using the old embed as a starting point, and setting the title to animationSteps[msgProgress]. It then calls msg.edit(embed), and changes the msgProgress variable by 1.
There is also a client.on('messageUpdate', msg => {}), and it has the same code, except at the start, it checks if msg progress > 9, and if so, it returns. Here is the code:
require('dotenv').config();
const Discord = require('discord.js');
const client = new Discord.Client();
var channel;
const genericEmbed = new Discord.MessageEmbed()
.setTitle("old");
const animationSteps = [
"...............:red_car:......",
"............:red_car:.........",
"........:red_car:............",
".....:red_car:...............",
"..:red_car:..................",
":red_car:....................",
":open_mouth:....:red_car:..............",
".:cold_sweat:..:red_car:......................",
"..:tired_face:.:red_car:......................",
"...:ghost::red_car:......................"
];
var msgProgress = 0;
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
channel = client.guilds.cache.get("753227876207165570").channels.cache.get("753227876207165573");
console.log(channel);
const firstEmbed = new Discord.MessageEmbed()
.setTitle("old");
channel.send(firstEmbed);
});
client.on('message', msg => {
if (msg.content === '') {
console.log("good");
channel = msg.channel;
const receivedEmbed = msg.embeds[0];
const embed = new Discord.MessageEmbed(receivedEmbed)
.setTitle(animationSteps[msgProgress]);
msg.edit(embed);
msgProgress++;
}
});
client.on('messageUpdate', msg => {
if (msgProgress > 9) {
return;
}
if (msg.content === '') {
console.log("good");
channel = msg.channel;
const receivedEmbed = msg.embeds[0];
const embed = new Discord.MessageEmbed(receivedEmbed)
.setTitle(animationSteps[msgProgress]);
msg.edit(embed);
msgProgress++;
}
});
client.login(process.env.DISCORD_TOKEN);
Hope this helped! 😃

Categories