Discord.js - Message edit/delete logger error - node.js

I'm trying to add a code to my bot that logs whenever a user edits/deletes a message. The bot sends an embed to a specified channel with the information of the event. However, there's this error that I've been stuck on for a long while now, with no identified solution.
Here's the error that follows:
RangeError [EMBED_FIELD_VALUE]: MessageEmbed field values may not be empty.
Here's the code:
client.on("messageUpdate", message => {
var messages = []
if(messages.includes(message.id)){return;}
channel = message.guild.channels.cache.get('channelID')
const channel9 = client.channels.cache.find(channel => channel.id === 'id');
const ediembed = new Discord.MessageEmbed()
.setColor(1752220)
.setTitle(":pencil: Message Edited")
.addFields (
{name: "__Channel:__", value: `<\#${message.channel.id}>`},
{name: "__Message Author:__", value: `${message.author.tag} - <\#${message.author.id}>`},
{name: "__Original Message:__", value: message.content}
)
.setTimestamp()
.setThumbnail(message.author.avatarURL())
.setFooter("super cool api")
channel9.send(ediembed)
}
)

2 fixes,
1: you dont need to get channel
2: try sending to channel a different way
client.on("messageUpdate", (message) => {
var messages = [];
if (messages.includes(message.id)) {
return;
}
const ediembed = new Discord.MessageEmbed()
.setColor(1752220)
.setTitle(":pencil: Message Edited")
.addFields(
{ name: "__Channel:__", value: `<\#${message.channel.id}>` },
{
name: "__Message Author:__",
value: `${message.author.tag} - <\#${message.author.id}>`,
},
{ name: "__Original Message:__", value: message.content }
)
.setTimestamp()
.setThumbnail(message.author.avatarURL())
.setFooter("super cool api");
client.channels.cache.get("CHANNEL ID").send(ediembed);
});

Related

Trying to catch response but why wont it send?

I am currently working on a command right now that I would like the server owner to use. When done it sends the embed and will wait for the server owner to paste we will say the channel id. I want to label this to call in another command but at the moment it sends the embed but when I send a channel ID nothing happens. No message is sent but it also does not break the bot. I am still able to send the command again and again.
Please do not mind the slop, I am new to all this and trying to learn as I go any tips would be appreciated!
EDIT: I am using version 12 (12.5.3)
const { prefix } = require('../config.json');
const Discord = require('discord.js');
const client = new Discord.Client();
module.exports = {
name: 'setchannel',
description: 'command to assign bot to channel',
execute(message, args) {
if(message.channel.type == "dm") {
const keepinservercommandembed = new Discord.MessageEmbed()
.setColor('#FF0000')
.setTitle('**Im Sorry!**')
.addFields(
{ name: `**Can` + `'t accept: ${prefix}setchannel**`, value: 'Please keep this command to the server!' },
)
message.channel.send(keepinservercommandembed);
}
else {
const messagesender = message.member.id;
const serverowner = message.guild.owner.id;
const setchannelembed = new Discord.MessageEmbed()
.setColor('#FF0000')
.addFields(
{ name: `**Let's get searching!**`, value: `Hello ${message.guild.owner}, what channel would you like me to post group finding results?` },
)
const notownerembed = new Discord.MessageEmbed()
.setColor('#FF0000')
.addFields(
{ name: `**Whoops!**`, value: `Sorry only ${message.guild.owner} can use this command.` },
)
if(messagesender == serverowner) {
message.delete ();
const filter = m => m.content.message;
const collector = message.channel.createMessageCollector(filter, { time: 15000 });
message.channel.send(setchannelembed).then(() => {
collector.on('collect', m => {
message.channel.send(`${m.content}`)
});
});
}
else {
message.delete ();
message.channel.send(notownerembed);
}
}
}
}
After comparing your code to my similiar discord.js v13 code and checking out the v12 docs, I think I found the problem.
I don't think m.content.message is a function. If your aim is for someone to paste the channel ID, the filter code would be:
const filter = m => m.author.id === message.guild.owner.id;
To filter out other people who may be entering an ID (assuming the input is valid).
Use the filter as follows:
message.channel.createMessageCollector({filter: filter, time: 15000 });
To filter out invalid inputs:
collector.on('collect', m => {
if (isNaN(m)) return; //all channel id's in discord are integers (numbers)
else message.channel.send(`${m.content}`);
});

CMD sending multiple embeds instead of one

I made a leaderboard command for my discord bot (v13) but it sends multiple embeds with each user's info individually instead of one whole message. I'm not sure how else to structure this so any help is appreciated.
const profileModel = require("../models/profileSchema");
module.exports = {
name: "leaderboard",
description: "Checks the leaderboard",
aliases: ['lb'],
async execute(client, message, args, cmd, Discord, profileData){
const lbData = await profileModel.find({}).sort({
reputation: -1,
}).limit(5);
for (let counter = 0; counter < lbData.length; ++counter) {
const { userID, health = 0 } = lbData[counter]
const Embed = new Discord.MessageEmbed()
.setColor('#fffffa')
.setTitle('Challenge Leaderboard')
.addFields(
{ name: '\u200b', value: `**${counter + 1}.** <#${userID}> - ${reputation} reputation\n` })
message.channel.send({ embeds: [Embed] });
}
}
}
The reason is the way you send the embed
Inside your for loop you create a new ebed every time and add the fields, where you need to create the embed outisde the for loop, add the field in the for loop and then send the embed
It would look something like:
const Embed = new Discord.MessageEmbed()
.setColor('#fffffa')
.setTitle('Challenge Leaderboard')
for (let counter = 0; counter < lbData.length; ++counter) {
const { userID, health = 0 } = lbData[counter]
Embed.addField({ name: '\u200b', value: `**${counter + 1}.** <#${userID}> - ${reputation} reputation\n` })
}
message.channel.send({ embeds: [Embed] });

Sending a message into all servers where bot is

How do I send one message per guild that my bot is in? It doesn't matter which channel it will be, but I don't know how to code it.
I finally came up with that idea:
client.guilds.cache.forEach(guild => {
const Embed = new discord.MessageEmbed();
const Channels = guild.channels.cache.map(channel => `${channel.id} | ${channel.name}`).join(", ")
Embed.setTitle(`Channels for ${guild.name}`);
Embed.setDescription(Channels);
message.channel.send(Embed);
});
but it doesn't work.
I'm working with commands handler so it has to be done with module.exports:
module.exports = {
name: "informacja",
aliases: [],
description: "informacja",
async execute(message) {
client.guilds.cache.forEach(guild => {
const Embed = new discord.MessageEmbed();
const Channels = guild.channels.cache.map(channel => `${channel.id} | ${channel.name}`).join(", ")
Embed.setTitle(`Channels for ${guild.name}`);
Embed.setDescription(Channels);
message.channel.send(Embed);
});
};
My code is not working at all
When I run it - nothing happens, no errors, no messages, just nothing.
tried to logged everything, but still nothing came up.
I also tried to log everything using console.log() but nothing is working
I remind: I need to send one message to all servers where my bot is, but only one channel
You could find a channel on each server where the client can send a message then send:
client.guilds.cache.forEach(guild => {
const channel = guild.channels.cache.find(c => c.type === 'text' && c.permissionFor(client.user.id).has('SEND_MESSAGES'))
if(channel) channel.send('MSG')
.then(() => console.log('Sent on ' + channel.name))
.catch(console.error)
else console.log('On guild ' + guild.name + ' I could not find a channel where I can type.')
})
This is a very simple boilerplate to start with, you can later check channel with id, or smth like that
client.channels.cache.forEach(channel => {
if(channel.type === 'text') channel.send('MSG').then('sent').catch(console.error)
})
v13 code
const Discord = require('discord.js')
const {
MessageEmbed
} = require('discord.js')
const fs = require('fs')
module.exports = {
name: "send",
description: "Send message to all guilds bot joined",
usage: `!send <text>`,
category: "dev",
run: async (client, message, args) => {
client.guilds.cache.map((guild) => {
const channel = guild.channels.cache.find(
(c) => c.type === "GUILD_TEXT" && c.permissionsFor(guild.me).has("SEND_MESSAGES")
);
channel.send('your_text')
})
}}
v12 code
const Discord = require('discord.js')
const {
MessageEmbed
} = require('discord.js')
const fs = require('fs')
module.exports = {
name: "send",
description: "Send message to all guilds bot joined",
usage: `!send <text>`,
category: "dev",
run: async (client, message, args) => {
client.guilds.cache.map((guild) => {
const channel = guild.channels.cache.find(
(c) => c.type === "text" && c.permissionsFor(guild.me).has("SEND_MESSAGES")
);
channel.send('your_text')
})
}}

I just created a snipe command for my bot but it doesn't quite work

My messageDelete event handler:
client.on("messageDelete", message => {
snipe.set(message.channel.id, {
title: Date.now(),
content: message.content,
author: message.author,
image: message.attachments.first() ? message.attachments.first().proxyURL : null,
});
});
My snipe.js code:
require('discord-reply');
const Discord = require('discord.js')
const moment = require('moment')
module.exports = {
name: 'snipe',
aliases: [],
category: 'Fun',
utilisation: '{prefix}snipe',
description: 'Displays the last deleted message in the current channel!',
execute(client, message) {
const snipe = require('.././../index.js')
const msg = snipe.get(message.channel.id);
const timeAgo = moment(msg.title).fromNow();
if (!msg) return message.channel.send("Theres Nothing To Snipe here...");
if (msg.image) {
const embed1 = new Discord.MessageEmbed()
.setAuthor(msg.author.tag, msg.author.displayAvatarURL({ dynamic: true }))
.setTitle(`Message deleted by ${msg.author.tag}! (${timeAgo})`)
.setDescription(msg.content)
.setColor(0x3498DB)
.setTimestamp()
.setImage(msg.image)
.setFooter("Sniped by " + message.author.tag);
message.lineReply(embed1);
}
else {
const embed = new Discord.MessageEmbed()
.setAuthor(msg.author.tag, msg.author.displayAvatarURL({ dynamic: true }))
.setTitle(`Message deleted by ${msg.author.tag}! (${timeAgo})`)
.setDescription(msg.content)
.setColor(0x3498DB)
.setTimestamp()
.setFooter("Sniped by " + message.author.tag);
message.lineReply(embed);
}
},
}
I am getting the following error in my console when I try running the command
(node:6928) UnhandledPromiseRejectionWarning: TypeError: snipe.get is not a function
Can anyone help? I'm pretty sure my code is correct as I used the same thing in my old bot. Any help would be appreciated.
From what I assume your snipe is a Map/Collection since you are using get/set on it, you may want to export the map to use it in your command file by binding it to your client like so
const snipe = new Map();
Aliter
const { Client, Collection } = require("discord.js");
const snipe = new Collection()
const client = new Client();
// Binding to Client
client.snipe = snipe // aliter declare it directly as client.snipe = new Collection()
Then you may access your collection since you are already exporting client like so
client.snipe.set()
client.snipe.get()

Cannot read property 'toDateString' of undefined

Im trying to make a discord bot that can show when a certain member joins the server, and the date of when they joined Discord. I have tried using toDateString to show thw number of days from the joining of the server and the current date. Here's the full code:
const Discord = require("discord.js");
const { MessageEmbed } = require("discord.js");
const { Color } = require("../../config.js");
module.exports = {
name: "userinfo",
aliases: ["memberinfo", "whois"],
description: "Show User Information!",
usage: "Userinfo | <Mention User>",
run: async (client, message, args) => {
//Start
let member = message.mentions.users.first() || message.author;
const statuses = {
online: "Online",
dnd: "Do Not Disturb",
idle: "Idle",
offline: "Offline/Invisible"
};
const embed = new MessageEmbed()
.setTitle(member.username + " Information!")
.setColor(Color)
.setThumbnail(member.displayAvatarURL())
.addField("Full Name", member.tag, true)
.addField("ID", `${member.id}`, true)
.addField("Status", statuses[member.presence.status], true)
.addField(
`Roles Count`,
message.guild.members.cache.get(member.id).roles.cache.size ||
"No Roles!",
true
)
.addField(`Avatar Url`, `[Link](${member.displayAvatarURL()})`, true)
.addField("Joined Server At", member.joinedAt.toDateString())
.addField("Joined Discord At", member.createdAt.toDateString())
.setFooter(`Requested by ${message.author.username}`)
.setTimestamp();
message.channel.send(embed);
//End
}
};
Instances of GuildMember do not have a createdAt property (see here). You want to access the user property of the guild member to get User.createdAt
addField("Joined Discord At", member.user.createdAt.toDateString())
member.createdAt is undefined
Must make it member.user.createdAt
.addField("Joined Discord At", member.createdAt.toDateString())
And change member var to #GuildMember
let member = message.mentions.members.first() || message.member;

Resources