How do I check if a user has their DM's open? | discord.js v 14 - javascript

I am making a bot that can dm a user. If the dm's of the user are off it says the message is successfully sent but in the console it returns an error.
So, what can I do to check if a user's dm is open?
The code I'm trying to run:
const rec = interaction.options.getUser('user')
const user = interaction.user.id
try {
rec.send({ embeds:[ new EmbedBuilder().setDescription(`<#${user}> says to you: ${message} `).setColor("#f05c51")
.then(interaction.reply(({ content: 'Successfully sent', ephemeral: true })))
] })
} catch (error) {
interaction.reply(({ content: `Could not send message, maybe dm's off? -> ${error}`, ephemeral: true }))
}

You can't. You need to use .catch()
rec.send({ embeds: [YOUREMBED] })
.then(message => console.log(`Sent message: ${message.content}`))
.catch(console.error);

I used unhandledRejection to know if my bot can't send a message to a specific user, also can use it all of unhandledRejection errors
process.on('unhandledRejection', async(error) => {
const admin = client.channels.cache.get('-----')
const embed = new MessageEmbed()
.setDescription(`\`\`\`\j\s\n${error.message || error.name || error }\n\`\`\``)
.setColor('RANDOM')
.setTimestamp()
admin.send({embeds: [embed]})
console.log(error)
});
You can also try it on your code.

Related

Edit is not a function

Trying to make a discord bot that will send a message to a specific channel on startup. I have the message sent to the specific channel on startup, however, when I try to edit it a error is thrown saying message.edit is not a function. I am following the direct steps from the documentation and it is not working. Why and how do I fix this issue?
let message: any;
if (isTextChannel(channel) && !isStageChannel(channel)) {
message = channel.send({ embeds: [ playerCountEmbedLoading() ] });
}
setInterval(() => {
if (isTextChannel(channel) && !isStageChannel(channel)) {
return message.edit({ embeds: [ playerCountEmbed() ] })
}
You're not awaiting the promise returned from sending the message.
message = await channel.send({ embeds: [ playerCountEmbedLoading() ] });
Source
Documentation
You should do type checking before defining the message. In this example I will use a typegaurd to filter out non text based channels.
Also, Channel.send() returns a promise containing the sent message. You need to await the promise.
import { ChannelTypes } from "discord.js";
if (channel.type !== ChannelTypes.GuildText) return console.warn("Channel is not a text channel");
let message = await channel.send({ embeds: [ playerCountEmbedLoading() ] });
setInterval(async() => {
try {
await message.edit({ embeds: [ playerCountEmbed() ] })
} catch (err) {
console.error(err);
}
}, ...);
Lastly, why use TypeScript if you're going to type a variable as any when you know exactly what it needs to be? Take advantage of the language you utilize by typing your variables.
import type { Message } from "discord.js";
let message: Message;

MongoDB findOneAndDelete() will not delete the specified query-- I can't quite figure out why?

I'm trying to write a Discord.JS bot that lists and removes specific channels/threads using MongoDB's Model and Schema functionality. I've gotten everything else figured out, the actual message deletion, channel deletion, and everything else I needed for the remove function, but for some reason prompting MongoDB to delete the ChatListing schema using ids specified doesn't work.
case 'remove':
modal.setTitle('Remove a Listing');
const listingIDInput = new TextInputBuilder()
.setCustomId('listingIDInput')
.setLabel(`What's the ID of your listing?`)
.setPlaceholder('EX... 14309')
.setMinLength(5)
.setStyle(TextInputStyle.Short)
.setRequired(true);
const rmrow = new ActionRowBuilder().addComponents(listingIDInput);
modal.addComponents(rmrow);
await interaction.showModal(modal);
try {
await interaction.awaitModalSubmit({ time: 120_000 }).then( (interaction) => {
const listingToRemove = interaction.fields.getTextInputValue('listingIDInput');
ChatListing.findOne({ GuildID: guild.id, ListingID: listingToRemove }, async(err, data) =>{
if(err) throw err;
if(!data) return;
if(data.MemberID == member.id) {
const channel = await guild.channels.cache.get(data.Channel);
const msg = await channel.messages.fetch(data.MessageID);
msg.delete();
var id = data._id;
ChatListing.findByIdAndDelete({_id: mongoose.Types.ObjectId(id)});
embed.setTitle('Listing successfully removed.')
.setColor('Green')
.setDescription('⚠️ | Your chat listing has been removed successufully. We\'re sorry to see it go! | ⚠️')
.setTimestamp();
await interaction.reply({ embeds: [embed], ephemeral: true });
} else {
embed.setTitle('You aren\'t the owner of the listing!')
.setColor('Red')
.setDescription('You aren\'t capable of removing this listing because you aren\'t the user that posted it.')
.setTimestamp();
await interaction.reply({ embeds: [embed], ephemeral: true });
}
});
});
} catch (err) {
console.error(err);
}
break;
This is just the snippet in the switch case used for the slash command I've built around this functionality, and the case for listing removal.
It doesn't cause any errors in the console, however when I check the database, the test listing I put up is still there and doesn't seem to go.
Is there anything I'm doing wrong? Wherever I've looked I can't quite seem to find anything that solves this problem for me. Is the reason it's not working because it's listed within a ChatListing.findOne() function? If so, how can I modify it to work outside of that function and still keep the removal functionality?
Try using findOneAndDelete and use the returned Promise to handle success or failure:
ChatListing.findOneAndDelete({_id: mongoose.Types.ObjectId(id)})
.then(() => {
embed.setTitle('Listing successfully removed.')
.setColor('Green')
.setDescription('⚠️ | Your chat listing has been removed successufully. We\'re sorry to see it go! | ⚠️')
.setTimestamp();
interaction.reply({ embeds: [embed], ephemeral: true });
})
.catch(error => {
console.error(error);
});

Suggestion message not working. Does not seem to find the message

I have been trying to make a channel on my discord so that as soon as someone sends a message, it deletes it, then send an embed with the information. But it does not work, it should look like this:
But it looks like this:
Here is my index.js:
client.on('message', message => {
if (message.channel.id !== "823027303129808896") return;
let content = message.content;
const delMSG = message;
const Embed = new Discord.MessageEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarURL())
.setTitle("Nouvelle suggestion!")
.setDescription("**Suggestion:**\n" + content)
.setColor("#00ff44")
.setFooter("Eclezia", "https://i.imgur.com/GhHHBgn.png")
.setTimestamp();
message.guild.channels.cache.get("823027303129808896").send(Embed).then((m) => {
m.react("<:yes:821050283734859816>")
m.react("<:no:821050300730572802>")
})
delMSG.delete();
})
And here is the error I get:
throw new DiscordAPIError(request.path, data, request.method, res.status);
^
DiscordAPIError: Unknown Message
at RequestHandler.execute (D:\EcleziaBot\node_modules\discord.js\src\rest\RequestHandler.js:154:13)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async RequestHandler.push (D:\EcleziaBot\node_modules\discord.js\src\rest\RequestHandler.js:39:14) {
method: 'put',
path: '/channels/823027303129808896/messages/823046250542399539/reactions/yes%3A821050283734859816/#me',
code: 10008,
httpStatus: 404
}
EDIT: Look at the marked answer.
There are a couple of things:
Make sure you're returning if the message's author is the bot using if (message.author.bot) return; (I think it was your main issue)
You don't need to create new variables content and delMSG as message is available until your last line of code
You don't need to get the channel if you're sending in the same channel. Instead of message.guild.channels.cache.get("823027303129808896") you can use message.channel
I would move the message.delete() inside the .then()
Here is the full code:
client.on('message', (message) => {
const channelID = '823027303129808896';
if (message.author.bot) return;
if (message.channel.id !== channelID) return;
const embed = new Discord.MessageEmbed()
.setAuthor(message.author.tag, message.author.displayAvatarURL())
.setTitle('Nouvelle suggestion!')
.setDescription('**Suggestion:**\n' + message.content)
.setColor('#00ff44')
.setFooter('Eclezia', 'https://i.imgur.com/GhHHBgn.png')
.setTimestamp();
message.channel
.send(embed)
.then((msg) => {
message.delete();
msg.react('<:yes:821050283734859816>');
msg.react('<:no:821050300730572802>');
})
.catch(console.log);
});

Discord.js Ban command

I am trying to get a ban command but keep getting errors and I don't know why my code is not working. I am using discord.js v12
bot.on('message', message =>{
if(message.content.startsWith(`${prefix}ban`)){
const args = message.content.trim().split(/ +/g);
const bUser = message.guild.member(message.mentions.users.first())
if(!message.guild.member(message.author).hasPermission("ADMINISTRATOR")) {return message.reply("You do not have enough permission for this command!")};
if(!message.guild.member(bot.user).hasPermission("ADMINISTRATOR")) {return message.reply("The bot does not have enough permissions for this commands")};
if(message.mentions.users.size === 0) {return message.reply("You need to ping a user!")};
if (!message.guild) return;
let banReason = args.join(" ").slice(27);
const banembed = {
color: "RANDOM",
title: `Ban`,
description: `${bUser} has been banned by ${message.author}`,
fields: [{
name: "Ban Reason",
value: `${banReason}`,
}],
}
bUser.send({ embed: banembed }).
then(
bUser.ban({ reason: banReason })
(message.channel.send({ embed: banembed })
)
)
};
});
Thank you for taking time to read this!
For bUser.ban({ reason: banReason }) :
The correct syntax is:
bUser.ban(banReason);
the correct syntax is:
message.guild.members.ban(user,{reason: "your reason"});
i also suggest doing this asynchronious with an await for example
(in an async)
try{
await message.guild.members.ban(user,{reason: ReasonString});
}catch (error){
console.log(error);
}

Discord.js UnhandledPromiseRejectionWarning: DiscordAPIError: Cannot send an empty message

Ok, so I just started working on a discord bot and implemented a command handler, and I immediately ran into some problems.
const Discord = require("discord.js");
module.exports = {
name: "kick",
description: "Kicks the mentioned user",
execute(message, args) {
const user = message.mentions.users.first();
if (user) {
const member = message.guild.member(user);
try {
const kickEmbed = new Discord.RichEmbed()
.setTitle("You were Kicked")
.setDescription("You were kicked from Bot Testing Server.");
user.send({ kickEmbed }).then(() => {
member.kick();
});
} catch (err) {
console.log("failed to kick user");
}
}
}
};
when i execute the kick command in my server, I get the following error
UnhandledPromiseRejectionWarning: DiscordAPIError: Cannot send an empty message
I can't seem to find anything wrong with the code so, where's the error
When sending an embed that uses the Discord Rich Embed builder you don't need to use the curly brackets.
Instead of user.send({ kickEmbed }) you should do user.send(kickEmbed). I ran into that issue before and it helped in my case.

Categories