Embed keeps adding the same fields. Discord.js - javascript

I have some commands like user-info in a command handler, here is my code
const Discord = require("discord.js");
const Uembed = new Discord.MessageEmbed();
const randomcolor = Math.floor(Math.random() * 16777214) + 1;
const moment = require("./IGNORE/moment.min.js");
module.exports = {
name: "user-info",
description: "Shows info about a user.",
execute(message, args) {
if (message.deletable) message.delete();
Uembed.setTitle(`${message.author.tag}'s information. `);
Uembed.setColor(randomcolor);
Uembed.setAuthor(message.author.tag, message.author.displayAvatarURL());
Uembed.setThumbnail(message.author.avatarURL());
Uembed.setFooter(
`Requested by : ${message.author.tag}`,
message.author.displayAvatarURL()
);
Uembed.addFields(
{ name: `Username:`, value: `${message.author.username}`, inline: true },
{ name: `Tag:`, value: `${message.author.discriminator}`, inline: true },
{ name: `ID:`, value: `${message.author.id}` },
{ name: `Last message:`, value: `${message.author.lastMessage + 1}` },
{
name: `Joined this server:`,
value: `${moment(message.member.joinedAt).format(
"MMMM Do YYYY, h:mm:ss a"
)}`,
},
{
name: `Account created:`,
value: `${moment(message.author.createdAt).format(
"MMMM Do YYYY, h:mm:ss a"
)}`,
}
);
message.channel.send(Uembed).then((m) => m.delete({ timeout: 60000 }));
},
};
I already tried to put it out of the execute function, but it didn't work either.

Found it! You just need to put this code after the Message.send().
Uembed.fields = [];
It sets the embed fields to an empty array, so it kind of resets the embed fields.

Related

When purging messages by user and term, the wrong embed is sent

I've been working to create a Purge Command in JavaScript based off this Purge Command written in TypeScript for reconlx's DJS v13 command handler (I modified a few bits to make all the handlers and whatnot function in DJS v14), however, there are some bugs and a few things I'm losing my mind over.
Firstly, everytime the command is enacted, this little nuisance of a message appears with the success confirmation embeds, and I don't really know how to deal with it.
Secondly, when I purge specifically by user and term, the wrong embed is sent and my bot will purge as normal. According to the source code, it (referring to my bot) should be sending the cleanPurge embed, but it instead sends the userPurge embed. Purging specifically by user works as intended, just with the annoying "thinking" message as an unwanted bonus.
Thirdly, when purging by term, I can only purge if I enact the command right after a message with the specified term. Here's an example (if you don't understand my wording).
// It is okay to purge during these situations
// cat in a hat
// cat in a hat
// cat in a hat
// /purge [amount: 3] {term: cat}
// The command will purge only if it is enacted right after the message with the specific term, however...
// The command won't purge during these situations
// cat in a hat
// cat in a hat
// cat in a hat
// SHITPOST
// /purge [amount: 3] {term: cat}
// The message "SHITPOST" is in-between the last message with the term "cat" and when I enact my command,
// therefore, for some reason, I can't purge any messages with my specified keyword before the message "SHITPOST".
// I can purge messages with the term "cat" AFTER the message "SHITPOST" until another message gets in the way.
// If you have no idea what I mean, a link to my bot's demo is below.
Purging without specifics DOESN'T bring up the "{Bot} is thinking..." message and works as intended.
If you're confused, here's a link to a demo of my bot's bugs
Any questions, please feel free to ask me, and sorry if my wording is shit.
Source code for purge.js
const { EmbedBuilder, ApplicationCommandOptionType, PermissionsBitField } = require("discord.js");
const { Command } = require("reconlx");
const ms = require("ms");
module.exports = new Command({
name: "purge",
description: "Deletes a specified number of messages",
userPermissions: PermissionsBitField.Flags.ManageMessages,
options: [
{
name: "amount",
description: "Number of messages to purge",
type: ApplicationCommandOptionType.Integer,
min_value: 1,
max_value: 100,
required: true,
},
{
name: "user",
description: "Purge this member's messages",
type: ApplicationCommandOptionType.User,
required: false,
},
{
name: "term",
description: "Purge messages with this specific term",
type: ApplicationCommandOptionType.String,
required: false,
},
{
name: "reason",
description: "Reason for purging",
type: ApplicationCommandOptionType.String,
required: false,
},
],
run: async ({ interaction }) => {
const amount = interaction.options.getInteger("amount");
const user = interaction.options.getUser("user");
const term = interaction.options.getString("term");
const reason = interaction.options.getString("reason") || "Unspecified";
const channel = interaction.channel
const messages = await interaction.channel.messages.fetch({
limit: amount + 1,
});
if (user) {
const userMessages = messages.filter((m) => m.author.id === user.id);
const purged = await interaction.channel.bulkDelete(userMessages, true);
const userPurge = new EmbedBuilder()
.setColor("#2F3136")
.setTitle(`🧹 PURGED!`)
.addFields(
{
name: `Cleared ${purged.size} message${
purged.size > 1 ? "s" : ""
}!`,
value: `Any messages from \`${user.tag}\` have been deleted from ${channel}!`
},
{
name: `User`,
value: `\`${user.tag}\``,
inline: true
},
{
name: `Term`,
value: `\`Unspecified\``,
inline: true
},
{
name: `Reason(s)`,
value: `\`${reason}\``,
inline: true
},
)
interaction.channel.send({ embeds: [userPurge] });
} else if (term) {
const filteredTerm = messages.filter((m) =>
m.content.toLowerCase().includes(term)
);
const purged = await interaction.channel.bulkDelete(filteredTerm, true);
const termPurge = new EmbedBuilder()
.setColor("#2F3136")
.setTitle(`🧹 PURGED!`)
.addFields(
{
name: `Cleared ${purged.size} message${
purged.size > 1 ? "s" : ""
}!`,
value: `Any messages with the term ||\`${term}\`|| have been deleted from ${channel}!`
},
{
name: `User`,
value: `\`Unspecified\``,
inline: true
},
{
name: `Term`,
value: `||\`${term}\`||`,
inline: true
},
{
name: `Reason(s)`,
value: `\`${reason}\``,
inline: true
},
)
interaction.channel.send({ embeds: [termPurge] });
} else if (term && user) {
const memberMessages = messages.filter((m) => m.author.id === member.id && m.content.toLowerCase().includes(term));
const purged = await interaction.channel.bulkDelete(memberMessages, true);
const cleanPurge = new EmbedBuilder()
.setColor("#2F3136")
.setTitle(`🧹 PURGED!`)
.addFields(
{
name: `Cleared ${purged.size} message${
purged.size > 1 ? "s" : ""
}!`,
value: `Any messages from \`${user.tag}\` with the term ||\`${term}\`|| have been deleted from ${channel}!`
},
{
name: `User`,
value: `\`${user.tag}\``,
inline: true
},
{
name: `Term`,
value: `||\`${term}\`||`,
inline: true
},
{
name: `Reason(s)`,
value: `\`${reason}\``,
inline: true
},
)
interaction.channel.send({ embeds: [cleanPurge] });
} else {
const purged = await interaction.channel.bulkDelete(messages, true);
const purge = new EmbedBuilder()
.setColor("#2F3136")
.setTitle(`🧹 PURGED!`)
.addFields(
{
name: `Cleared ${purged.size - 1} message${
purged.size > 1 ? "s" : ""
}!`,
value: `The specified number of messages have been deleted from ${channel}!`
},
{
name: `User`,
value: `\`Unspecified\``,
inline: true
},
{
name: `Term`,
value: `\`Unspecified\``,
inline: true
},
{
name: `Reason(s)`,
value: `\`Unspecified\``,
inline: true
},
)
interaction.channel.send({ embeds: [purge] });
}
},
});
Your video is still processing, so I couldn't watch it, but:
In the "cat"/"cat"/"cat"/"shitpost" situation, you'd need amount=4, because you're only fetching N + 1 messages. If you need want your bot to purge N last matching messages even if there are more in between (e.g. in a "a"/"b"/"a"/"b"/"a"/"b" situation where you want to purge all "b"s), you'd need to fetch more messages until you've purged enough. Another "good enough" option might be to fetch e.g. amount * 2 messages and hope it's enough.
In any case, you could start by de-quadriplicating your message filtering and embed building:
{
run: async ({ interaction }) => {
const { options, channel } = interaction;
const amount = options.getInteger("amount");
const user = options.getUser("user");
const term = options.getString("term");
const reason = options.getString("reason") || "Unspecified";
const lastNMessages = await channel.messages.fetch({
limit: amount + 1,
});
const filteredMessages = lastNMessages.filter((message) => {
if (user && message.author.id !== user.id) {
return false;
}
if (term && !message.content.toLowerCase().includes(term)) {
return false;
}
return true;
});
const purged = await channel.bulkDelete(filteredMessages, true);
const title = `Cleared ${purged.size} message${purged.size > 1 ? "s" : ""}!`;
const message = [
`${purged.size} messages`,
user ? ` from \`${user.tag}\`` : "",
term ? ` containing \`${term}\`` : "",
` have been deleted from ${channel}!`,
].join("");
const userPurge = new EmbedBuilder()
.setColor("#2F3136")
.setTitle(`🧹 PURGED!`)
.addFields(
{
name: title,
value: message,
},
{
name: `User`,
value: user ? `\`${user.tag}\`` : "Unspecified",
inline: true,
},
{
name: `Term`,
value: term ? `||\`${term}\`||` : `\`Unspecified\``,
inline: true,
},
{
name: `Reason(s)`,
value: `\`${reason}\``,
inline: true,
},
);
await channel.send({ embeds: [userPurge] });
},
}

joinedAtTimeStamp is showing Nan discord.js

I was coding a userInfo command but when I use the command, the joinedAtTimeStamp is showing <t:NaN:R> in the embed. It's the only problem in this code.
My code:
const { MessageEmbed, ContextMenuInteraction } = require("discord.js");
module.exports = {
name: "userInfo",
aliases: ["user"],
permissions: ["SEND_MESSAGES", "ATTACH_FILES"],
description: "user",
async execute(message, args, cmd, client, Discord, profileData) {
const target = message.mentions.users.first();
if(!args[0]) {
const response2 = new MessageEmbed()
.setColor("RANDOM")
.setAuthor({name: message.author.tag, iconURL: message.author.displayAvatarURL({dynamic: true})})
.setThumbnail(message.author.displayAvatarURL({dynamic: true}))
.addFields(
{name: "ID", value: message.author.id},
{name: "Joined Server", value: `<t:${parseInt(message.author.joinedTimestamp / 1000)}:R>`, inline: true},
{name: "Account Created", value: `<t:${parseInt(message.author.createdTimestamp / 1000)}:R>`, inline: true},
);
message.reply({embeds:[response2]});
}
const response = new MessageEmbed()
.setColor("RANDOM")
.setAuthor({name: target.tag, iconURL: target.displayAvatarURL({dynamic: true})})
.setThumbnail(target.displayAvatarURL({dynamic: true}))
.addFields(
{name: "ID", value: target.id},
{name: "Joined Server", value: `<t:${parseInt(target.joinedTimestamp / 1000)}:R>`, inline: true},
{name: "Account Created", value: `<t:${parseInt(target.createdTimestamp / 1000)}:R>`, inline: true},
);
message.reply({embeds: [response], ephemeral: true})
}
}
I am using discord.js v13 and node 16.
message.author is a User and it doesn't have a joinedTimestamp property, only GuildMembers have. message.member represents the author of the message as a guild member, so you can use that as it will have a joinedTimestamp property.
The reason you see NaN instead of the correct value is because parseInt will return NaN if you try to parse undefined:
console.log('undefined:', parseInt(undefined / 1000, 10));
console.log('3459192421512:', parseInt(3459192421512 / 1000, 10));
The following code should work as expected
.addFields(
{ name: 'ID', value: message.author.id },
{
name: 'Joined Server',
value: `<t:${parseInt(message.member.joinedTimestamp / 1000, 10)}:R>`,
inline: true,
},
{
name: 'Account Created',
value: `<t:${parseInt(message.author.createdTimestamp / 1000, 10)}:R>`,
inline: true,
},
);
As for target, it's the same issue; message.mentions.users.first() is a User. You could create a new variable, e.g. targetMember and assign message.mentions.members.first(), so it will be a GuildMember:
const target = message.mentions.users.first();
const targetMember = message.mentions.members.first();
And then, just replace target:
.addFields(
{ name: 'ID', value: target.id },
{
name: 'Joined Server',
value: `<t:${parseInt(targetMember.joinedTimestamp / 1000, 10)}:R>`,
inline: true,
},
{
name: 'Account Created',
value: `<t:${parseInt(target.createdTimestamp / 1000, 10)}:R>`,
inline: true,
},
);
PS: It's a good idea to use the radix in parseInt. That's why I added 10 as the second parameter in parseInt.
Could you verify the type of target.joinedTimestamp?
It could be that the double conversion you are doing here:
parseInt(target.joinedTimestamp / 1000)
destroyed your number.
(You are converting whatever target.createdTimestamp is to number, dividing it by 100 (making it a floating point number) and then discarding the floating point by converting back to int.)

Server info embeds doesn't show on discord server, only says interaction failed and no error in terminal, how to fix?

I was trying to make an embed info command with "info user" and "info server" subcommand. When I try to show the owner's user tag in the embeds it shows undefined so I was told to change get(ownerId) to fetch, but was then told to resolve the promise. Same goes with the member, where I was trying to see how many bots there are in the server, it always show 1 whereas there were 5. Now the terminal doesn't show error when I do the info server command, but in the discord channel it shows interaction failed. The info user command works perfectly. How should I fix this?
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageEmbed } = require("discord.js");
const moment = require("moment");
module.exports = {
data: new SlashCommandBuilder()
.setName('info')
.setDescription('returns info based on input')
.addSubcommand(subcommand =>
subcommand
.setName("user")
.setDescription("get the information of a member mentioned")
.addUserOption(option => option.setName("member").setDescription("Tag a member")))
.addSubcommand(subcommand =>
subcommand
.setName("server")
.setDescription("info about this server")),
async execute(interaction, client, user, members) {
if (interaction.options.getSubcommand() === "user") {
const user = interaction.options.getUser("member");
if (user) {
const member = interaction.guild.members.cache.get(user.id)
const userEmbed = new MessageEmbed()
.setTitle(`${user.username}'s Information:`)
.setDescription(`This is a member in ${interaction.guild.name} :raised_hands:`)
.setAuthor(user.username, user.displayAvatarURL())
.setThumbnail(client.user.displayAvatarURL())
.addFields(
{ name: `Username`, value: `This member's username is ${user.username}`, inline: true },
{ name: `Tag`, value: `This member's tag is #${user.discriminator}`, inline: true },
{ name: `Joined Discord`, value: new Date(user.createdTimestamp).toDateString(), inline: true },
{ name: `Joined server`, value: new Date(member.joinedTimestamp).toDateString(), inline: true },
{ name: `Is this member a bot?`, value: `${user.bot}`, inline: true },
{ name: `Nickname`, value: member.nickname || "None", inline: true },
{ name: `Role count`, value: `${member.roles.cache.size - 1}`, inline: true },
)
.setImage(user.displayAvatarURL())
.setTimestamp()
.setColor("#F2A4D3")
.setFooter(client.user.tag, client.user.displayAvatarURL());
if (interaction.guild.members.cache.get(user.id).roles.cache.has("869759848747786262")) {
userEmbed.addFields({ name: `Boost status`, value: `This member has been boosting our server since ${new Date(member.premiumSinceTimestamp).toDateString()} :grin:`, inline: true }, { name: `\u200B`, value: `\u200B`, inline: true })
} else {
userEmbed.addFields({ name: `Boost status`, value: `This noob isn't boosting our server :neutral_face:`, inline: true }, { name: `\u200B`, value: `\u200B`, inline: true })
}
await interaction.reply({ embeds: [userEmbed] });
} else {
const user = interaction.user
const member = interaction.guild.members.cache.get(user.id)
const selfEmbed = new MessageEmbed()
.setTitle(`Your User Information (narcissistic much??):`)
.setDescription(`You're in ${interaction.guild.name} :raised_hands:`)
.setAuthor(user.username, user.displayAvatarURL())
.setThumbnail(client.user.displayAvatarURL())
.addFields(
{ name: `Username`, value: `Your username is ${user.username}`, inline: true },
{ name: `Tag`, value: `Your tag is #${user.discriminator}`, inline: true },
{ name: `Joined Discord`, value: `You joined discord on ${new Date(user.createdTimestamp).toDateString()}`, inline: true },
{ name: `Joined server`, value: `You joined this server on ${new Date(member.joinedTimestamp).toDateString()}`, inline: true },
{ name: `Are you a bot?`, value: `${user.bot}`, inline: true },
{ name: `Nickname`, value: member.nickname || "None", inline: true },
{ name: `Role count`, value: `${member.roles.cache.size - 1}`, inline: true },
)
.setImage(user.displayAvatarURL())
.setTimestamp()
.setColor("#F2A4D3")
.setFooter(client.user.tag, client.user.displayAvatarURL());
if (interaction.guild.members.cache.get(user.id).roles.cache.has("869759848747786262")) {
selfEmbed.addFields({ name: `Boost status`, value: `OOO you've been boosting our server since ${new Date(member.premiumSinceTimestamp).toDateString()}, so swag :grin:`, inline: true }, { name: `\u200B`, value: `\u200B`, inline: true })
} else {
selfEmbed.addFields({ name: `Boost status`, value: `You're not boosting our server, get nitro and boost it right now you idiot :neutral_face:`, inline: true }, { name: `\u200B`, value: `\u200B`, inline: true })
}
await interaction.reply({ embeds: [selfEmbed] });
//await interaction.reply(`Username: ${user.username}\nYour ID: ${user.id}`);
}
} else if (interaction.options.getSubcommand() === "server") {
const server = interaction.guild;
const user = await client.users.fetch(interaction.guild.ownerId);
const members = await interaction.guild.members.fetch();
const channels = interaction.guild.channels.cache;
const emojis = interaction.guild.emojis.cache;
const date = new Date(interaction.guild.createdTimestamp).toDateString();
const serverEmbed = new MessageEmbed()
.setTitle(`${server.name}'s Information`)
.setAuthor(server.name, server.iconURL())
.setThumbnail(client.user.displayAvatarURL())
.addFields(
{ name: `Owner`, value: `<#${interaction.guild.ownerId}>, ${user.tag}` },
{ name: `Server ID`, value: `${server.id}`, inline: true },
{ name: `Total Members`, value: `${server.memberCount}`, inline: true },
//{ name: `Online`, value: `${server.members.cache.filter(member => member.user.presence.status = "online").size}`, inline: true},
{ name: `Time created`, value: `${moment(interaction.guild.createdTimestamp).format("LT")}, ${moment(interaction.guild.createdTimestamp).format("LL")}, ${moment(interaction.guild.createdTimestamp).fromNow()}`},
//{ name: `Time created`, value: `${moment(interaction.guild.createdTimestamp.toLocale()).format("LT)")}, ${moment(date).format("LL")}`},
{ name: `Emojis`, value: `${emojis.size}`},
{name: `Regular emojis`, value: `${emojis.filter(emoji => !emoji.animated).size}`},
{name: `Animated emojis`, value: `${emojis.filter(emoji => emoji.animated).size}`},
{name: `Human`, value: `${members.filter(member => !member.user.bot).size}`},
{name: `Bots`, value: `${members.filter(member => member.user.bot).size}`},
{name: `Text channels`, value: `${channels.filter(channel => channel.type === "text").size}`},
{name: `Voice channels`, value: `${channels.filter(channel => channel.type === "voice").size}`},
{name: `Boost`, value: `${interaction.guild.premiumSubscriptionCount || "0"}`},
{name: `Online`, value: `${members.filter(member => member.presence.status === "online")}`},
)
.setImage(server.iconURL())
.setTimestamp()
.setColor("#F2A4D3")
.setFooter(client.user.tag, client.user.displayAvatarURL());
await interaction.reply({ embeds: [serverEmbed] });
} else {
await interaction.reply("No sub command was used.");
}
},
};

Discord JS - ssh.exec (i think)

i've got an JS script and i really don't understand why it's not working. Here is the script:
if(params[1] == "info")
{
cmdexist = true;
let totalSeconds = (bot.uptime / 1000);
let days = Math.floor(totalSeconds / 86400);
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let uptime = `${days} days, ${hours} hours, ${minutes} minutes`;
var countservers = 0; bot.guilds.cache.forEach(g => { countservers++ });
message.channel.send(`Please wait... getting informations!`).then((message) => {
var ssh = new SSH({
host: ssh_host,
user: ssh_user,
pass: ssh_pass,
agent: process.env.SSH_AUTH_SOCK
});
ssh.exec('echo $PATH', {}).start();
ssh.exec('hostname', { out: function(serverhostname) {
ssh.exec('uptime -p', { out: function(serveruptime) {
ssh.exec('uptime -s', { out: function(serveruptimesince) {
ssh.exec('cat /etc/redhat-release', { out: function(serverversion) {
ssh.end();
serveruptime = serveruptime.slice(2);
const embed = new Discord.MessageEmbed()
.setTitle("Informations:")
.setThumbnail(bot.user.displayAvatarURL({dynamic : true, size : 2048}))
.setColor('#277ecd')
.addFields
(
{ name: "Developer:", value: `${developername}`, inline: false },
{ name: "Version:", value: `${version}`, inline: false },
{ name: "Invite link:", value: "", inline: false },
{ name: "Last update:", value: `${lastupdate}`, inline: false },
{ name: "BOT uptime:", value: `${uptime}`, inline: false },
{ name: "Last restart:", value: `${restartdate}`, inline: false },
{ name: "Currently in:", value: `${countservers} servers`, inline: false },
{ name: "Server hostname:", value: `${serverhostname}`, inline: false },
{ name: "Server uptime:", value: `${serveruptime}`, inline: false },
{ name: "Server uptime since:", value: `${serveruptimesince}`, inline: false },
{ name: "OS platform:", value: `${serverversion}`, inline: false },
)
.setFooter(copyright);
message.delete();
message.channel.send(embed);
}}); }}); }}); }});
});
}
When i write the command it says me Please wait... getting informations! but never pass.
I really don't understand why it's not working. It's hosted on "gaming VPS" and host , user , pass it's from MySQL VPS. Sorry for my bad english. :) Thanks in advance for help.

Input prompt with options yeoman

I'm new to programming, and I'm creating a generator with yeoman-generator. How do I go through an array of objects and select the option I choose? I tried it but it didn't work. can you help me?
prompting() {
const prompts = [
{
type: 'checkbox',
name: 'database',
message: 'Select Database support:',
choices: [
{
name: 'H2',
value: 'h2',
}, {
name: 'HSQLDB',
value: 'hsqldb'
}, {
name: 'Apache Derby',
value: 'derby'
},
]
return this.prompt(prompts).then(answers => {
this.database = answers.database;
const hasDataBase = db => this.database.indexOf(db) !== -1;
this.h2 = hasDataBase('h2');
this.hsqldb = hasDataBase('hsql');
this.derby = hasDataBase('derby');
});
}
]}
This is the format it can take (from their example page https://yeoman.io/authoring/user-interactions.html). I tested this myself and it works.
var Generator = require('yeoman-generator');
module.exports = class extends Generator {
async prompting() {
const prompts = await this.prompt([
{
type: 'checkbox',
name: 'database',
message: 'Select Database support:',
choices: [
{
name: 'H2',
value: 'h2',
}, {
name: 'HSQLDB',
value: 'hsqldb'
}, {
name: 'Apache Derby',
value: 'derby'
}
]
}]);
this.log("database", prompts.database);
}
};

Categories