Having trouble adding reactions discord.Js - 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()

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 ban user on pinging someone?

I'm trying to make a discord bot on, when pinging the owner, auto bans the author that pinged the player. The issue is, it bans the player for saying anything, how would I make it that it'd only ban if they pinged the owner?
Here's the code.
const Discord = require('discord.js');
const client = new Discord.Client();
const prefix = '<#329005206526361610>'
client.once('ready', () => {
console.log("Wary's Defender Bot is up");
});
function getUserFromMention(mention) {
if (!mention) return;
if (mention.startsWith('!')) {
mention = mention.slice(1);
}
if (mention.startsWith('<#329005206526361610') && mention.endsWith('>')) return {
// mention = mention.slice(2, -1),
return: client.users.cache.get(mention)
}
}
client.on('message', _message => {
// if(!_message.content.users.has('#warycoolio')) return;
const user = getUserFromMention(_message.content);
if(user) return;
console.log('found target')
var member = _message.author
var rMember = _message.guild.member(_message.author)
// ban7, 'lol.'
rMember.ban({ days: 7, reason: 'They deserved it'}); {
// Successmessage
console.log('target dead.')
}
});
You can do this by checking _message.mentions.users with .has() and passing in the guild owner's id.
Use .has() instead of checking message content, this will automatically check the Message#mentions collection.
Dynamically get the guild owner's id using Guild#ownerID.
client.on('message', _message => {
if (_message.mentions.users.has(_message.guild.ownerID)) {
_message.author.ban({ days: 7, reason: 'They deserved it'});
}
});
You could just do a quick check to see if the mentions include a mention to the owner of the server, and then ban the user.
client.on("message", _message => {
if (_message.mentions.users.first().id === "owner id") {
message.author.ban()
}
})

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

Call Exports.run async from a member phrase

Please help me understand how can i call that ping.js from user input, like if a user type ping it will Trigger cuz of the aliases but if a user types a full phrase it won't trigger.
Or in a non headic question how can i implent this to work -> if (message.content.includes('ping'))
Sorry in advance and thanks a lot
ping.js
const Discord = require('discord.js')
const colors = require('../lib/colors.json')
exports.run = async (client, message, args, level) => {
try {
const pingEmbed = new Discord.RichEmbed()
.setColor(colors.default)
.setFooter('ping)
.addField(`${message.author.id}`, 'hey')
const msg = await message.channel.send(pingEmbed)
const embed = new Discord.RichEmbed()
.setColor(colors.default)
.addField('...',
`${msg.createdTimestamp - message.createdTimestamp}ms`)
msg.edit(embed)
} catch (err) {
message.channel.send('There was an error!\n' + err).catch()
}
}
exports.conf = {
enabled: true,
aliases: ['ping'],
guildOnly: false,
permLevel: 'User'
}
exports.help = {
name: 'ping,
category: 'tools,
description: 'ping pong',
usage: 'ping'
}
If you want to check whether a message contains any of the aliases you can just use Array.some() like this:
let aliases = ['your', 'command', 'aliases']
client.on('message', message => {
if (aliases.some(trigger => message.content.includes(trigger))) {
// The message includes at least one of your keywords
}
})
In this example is just declared aliases, but you can use the array from your command and integrate this method in your normal command handler.

Resources