Deleting an embed on discord js is not working - discord.js

This probably has a very simple fix, but I'm a very beginner programmer so I have no clue what to do. I am trying to delete an embed after 5 seconds, and the error is saying "msg.delete is not a function" This is my code. (I am using slash commands).
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, EmbedBuilder } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('br')
.setDescription('Battle to the death with your friends'),
async execute(message) {
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('joinbutton')
.setLabel('JOIN BATTLE ROYALE')
.setStyle(1),
);
var embed = new EmbedBuilder()
.setTitle(`BATTLE ROYALE STARTING`)
.setColor("0090FF")
.setDescription(`<#${message.user.id}> is starting a battle royale match. Use the button below to join!`)
.setFooter({text: message.user.username, iconURL: message.user.avatarURL()})
.setTimestamp()
message.reply({ embeds: [embed], components: [row] }).then(msg => msg.delete({timeout: 5000}))
},
};
I also have code in my index.js which I don't think could be the problem but I'm just gonna send it anyway.
var brdb = require('./models/br')
if(interaction.isButton())
{
if(interaction.customId == 'joinbutton')
{
var data = {
userid: interaction.user.id,
hp: 100
}
console.log(data)
}
}

This is because "message" is a CommandInteraction, not a Message. You should instead use message.deleteReply() as mentioned in the docs.

Related

Deleting old message when Discord.JS sends new message

I'm trying to make a music bot with DiscordJS. It sends a message again when it switches to new music. When it is too much, it causes pollution. How can I set the old message to be deleted and the new message to remain when I switch to a new song or skip a song?
Code:
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, Client } = require('discord.js');
const ms = require('ms');
/**
* #param {Client} client
*/
module.exports.run = async (client, player, track) => {
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('loop')
.setEmoji(`πŸ”`)
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('volume-')
.setEmoji(`πŸ”‰`)
.setStyle(ButtonStyle.Danger),
new ButtonBuilder()
.setCustomId('p/p')
.setEmoji(`⏯️`)
.setStyle(ButtonStyle.Secondary),
new ButtonBuilder()
.setCustomId('volume+')
.setEmoji(`πŸ”Š`)
.setStyle(ButtonStyle.Success),
new ButtonBuilder()
.setCustomId('skip')
.setEmoji(`⏭️`)
.setStyle(ButtonStyle.Secondary),
);
const embed = new EmbedBuilder()
.setAuthor({
name: `Now Playing`,
iconURL: track.info.requester.displayAvatarURL(),
})
.setColor('Blue')
.setDescription(
`
**Track**: [${track.info.title}](${track.info.uri})
`,
)
const channel = client.channels.cache.get(player.textChannel)
await channel?.send({ embeds: [embed], components: [row] })
};
When I switch to the new song, I want the old message to be deleted. I tried removing some lines but it didn't work.
You could store an object that contains channel IDs and message IDs somewhere else in your code:
let songMessages = {
'channel-id-here':'message-id-here',
'another-channel-id':'another-message-id',
// etc
}
Instead of sending a new message at the bottom of your run() function, you could first check for an existing message in the current channel, and if there is one, you can delete it.
// assuming you're able to access the songMessages object globally
const channel = client.channels.cache.get(player.textChannel)
if(songMessages[channel.id]) {
let oldMessage = await channel.messages.fetch(songMessages[channel.id])
await oldMessage.delete()
}
let message = await channel?.send({ embeds: [embed], components: [row] })
songMessages[channel.id] = message.id
You'll have to make sure you remove the data from the object after the bot stops playing music as well.

Discord JS - forEach looped embed

I'm quite new to Javascript, normally a Python person. I've looked at some other answers but my embed does not add the fields as expected. The embed itself is sent.
My Discord bot follows the guide provided by the devs (primary file, slash commands, command files). I am trying to loop through the entries in an SQLite query and add them as fields.
My command file is below.
const { SlashCommandBuilder } = require('#discordjs/builders');
const { MessageEmbed } = require('discord.js')
const sqlite = require('sqlite3').verbose();
module.exports = {
data: new SlashCommandBuilder()
.setName('rank')
.setDescription('Rank all points.'),
async execute(interaction) {
const rankEmbed = new MessageEmbed()
.setColor('#0099ff')
.setTitle('Rank Board')
let db = new sqlite.Database('./databases/ranktest.db', sqlite.OPEN_READWRITE);
let queryall = 'SELECT name, points FROM pointstable ORDER BY points DESC'
db.all(queryall, [], (err, rows) => {
if (err) {
console.log('There was an error');
} else {
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, true);
});
}
})
return interaction.reply({embeds: [ rankEmbed ] });
}
}
I would also like to convert row.name - held as Discord IDs - to usernames i.e. MYNAME#0001. How do I do this by interaction? I was able to obtain the User ID in another command by using interaction.member.id, but in this case I need to grab them from the guild. In Python I did this with await client.fetch_user but in this case the error await is only valid in async functions and the top level bodies of modules is thrown.
Thanks.
OK I've solved the first aspect, I had the return interaction.reply in the wrong place.
Relevant snippet:
rows.forEach((row) => {
console.log(row.name, row.points)
rankEmbed.addField('\u200b', `${row.name}: ${row.points}`, false);
})
return interaction.reply({embeds: [rankEmbed ]} );
Would still appreciate an answer to the converting row.name (user ID) to user name via fetch.
I've solved the second aspect also. Add the below into the loop.
rows.forEach((row) => {
let client = interaction.client
const uname = client.users.cache.get(row.name);
rankEmbed.addField('\u200b', `${uname}: ${row.points}`, false);

How to stop commands when breaking when :"overloaded"

I have a few commands that follow this same code, just some things changed, the code is for -dog command, which works fine within moderation (not spamming the command, maybe running it every 5 seconds) but when it does get spammed it will often spit a odd error into the terminal, I was wondering if there is anyway to fix this or improve it. Thanks!
Language: Discord.js V12
const Discord = require('discord.js');
const url = 'https://www.reddit.com/r/lookatmydog/hot/.json?limit=100'
module.exports = {
name: 'dog',
description: 'sends a dog!',
execute(message, args) {
https.get(url, (result) => {
var body = ''
result.on('data', (chunk) => {
body += chunk
})
result.on('end', () => {
var response = JSON.parse(body)
var index = response.data.children[Math.floor(Math.random() * 99) + 1].data
if (index.post_hint !== 'image') {
var text = index.selftext
const textembed = new Discord.MessageEmbed()
.setTitle(subRedditName)
.setColor('RANDOM')
.setDescription(`[${title}](${link})\n\n${text}`)
.setURL(`https://reddit.com/${subRedditName}`)
message.channel.send(textembed)
}
var image = index.preview.images[0].source.url.replace('&', '&')
var link = 'https://reddit.com' + index.permalink
var subRedditName = index.subreddit_name_prefixed
if (index.post_hint !== 'image') {
const textembed = new Discord.RichEmbed()
.setTitle(subRedditName)
.setColor('RANDOM')
.setDescription(`[${title}](${link})\n\n${text}`)
.setURL(`https://reddit.com/${subRedditName}`)
message.channel.send(textembed)
}
console.log(image);
const imageembed = new Discord.MessageEmbed()
.setTitle('Here is a dog, how nice!')
.setImage(image)
.setColor('RANDOM')
message.channel.send(imageembed)
}).on('error', function (e) {
console.log('Got an error: ', e)
})
})
},
}```
The error I got writing this was:
```C:\Users\-\Desktop\Corn Flakes\commands\Fun\dog.js:26
.setDescription(`[${title}](${link})\n\n${text}`)
^
ReferenceError: title is not defined
at IncomingMessage.<anonymous> (C:\Users\manof\Desktop\Corn Flakes\commands\Fun\dog.js:26:45)
at IncomingMessage.emit (events.js:327:22)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)```

Bot readout for who used a command

Wanting to have a readout channel for my bot to keep track of what happens, just like a second console log. Want to be able to have it read out in the message the username of the person who used the command. Any ideas? Also, in a similar note, is there a way to copy the console readout and possibly just paste that instead?
var Scraper = require('images-scraper');
const google = new Scraper({
puppeteer: {
headless: true
},
})
module.exports = {
name: 'image',
description: 'Google image scraper',
async execute(message, args){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const image_query = args.join(' ');
if(!image_query) return message.channel.send('Please enter a valid image search.');
const image_results = await google.scrape(image_query, 1);
message.channel.send(image_results[0].url);
readout.send('Image sent');
}
}
I think you want
message.author.username (It gives username who sent the message)
or message.member (it gives user as a guildmember)
Just access the author property of the message object and include it via a template string into the message:
readout.send(`Image sent to ${message.author.username}`);
Ended up doing an embed system in a separate channel on my discord.
const Discord = require('discord.js');
module.exports = {
name: 'suggestionlog',
description: 'logs suggestion',
execute(message){
const readout = message.guild.channels.cache.find(c => c.name === 'bot-readout');
const embed = new Discord.MessageEmbed()
.setColor('FADF2E')
.setTitle(message.channel.name)
.setAuthor(message.author.username, message.author.displayAvatarURL({ dynamic: true }))
.setDescription(message);
readout.send(embed)
.catch((err)=>{
throw err;
});
}
}

Having trouble adding reactions discord.Js

I want to make a confessions bot where it sends the confession to a private group so it can be reviwed before it is set to the public channel. but when I try to add reactions(to use as aprove or disaprove) it seams to want to add the reactions to the message that was deleted.
const discord = require("discord.js");
module.exports = {
name: 'confessions',
description: "comando para as pesoas confessarem anonimamente",
execute(message, args){
let cf = args.join(' ')
message.dlete()
const cfAdm = message.guild.channels.cache.get('767082831205367809')
let embed = new discord.MessageEmbed()
.setTitle('**CONFISSÃO**')
.setDescription(cf)
.setColor('#000000')
cfAdm.send(embed);
message.react('πŸ‘').then(r => {
message.react('πŸ‘Ž');
});
}
}
Try changing
cfAdm.send(embed);
message.react('πŸ‘').then(r => {
message.react('πŸ‘Ž');
to
cfAdm.send(embed)
.then( function (message) {
message.react('πŸ‘').then(() => message.react('πŸ‘Ž'));
And you also made a typo with message.dlete() it needs to be message.delete()

Resources