"Could not find the channel where this message came from in the cache!" when attempting to edit or delete a DM message - discord.js

I am trying to edit a message that was sent in a DM. Here is the code that does this:
async execute(interaction){
//function...
//member and gameData are defined
//remove the message containing the buttons and send a new one
//build new embed
const gmEmbed = new EmbedBuilder()
.setTitle(`Approved Join Request`)
.setDescription(`${member.user.tag} has successfully joined ${gameData.gameName}.`)
.setColor(0x33ff88);
try {
await interaction.message.edit({ embeds: [gmEmbed] });
}
catch (e) {
console.log(`[WARN] Unable to edit a DM to ${interaction.user.tag} accepting a player:\n${e}`);
}
//rest of function...
}
And this is what happens when the interaction is created and this function is run:
[WARN] Unable to followup a DM to username redacted accepting a player:
Error [ChannelNotCached]: Could not find the channel where this message came from in the cache!
In index.js I have the client logging in with const client = new Client({ intents: [..., GatewayIntentBits.DirectMessages] }); but I'm not sure if that's relevant to this issue.
How can I edit a message in a DM?
Edit 1: interaction.message.fetch().then(message => message.edit(...)) doesn't work. interaction.channel returns null. I believe the gateway intent should allow this, but it doesn't seem to. Also, strangely it seems to work sometimes, seemingly the first time the function is called for that interaction.

You can use interaction.editReply() to edit the reply to an interaction.
// ...
try {
await interaction.editReply({ embeds: [gmEmbed] });
} catch (e) {
console.log(`[WARN] Unable to edit a DM to ${interaction.user.tag} accepting a player:\n${e}`);
}

Related

Discordjs 14.7.1 Skips First Reaction

Problem is the Discord bot is skipping the first reaction emoji.
If I un-react and re-react with the same emoji, then the bot registers it.
I've been trying to figure this out for a while, and am stumped as to what I am missing in my logic or if I need to find another solution.
Intention:
Discord bot gathers and prints out all reactions to a message by a user
Relevant Information:
Discordjs 14.7.1
Discord Developer Website:
Presence Intent: Enabled
Server Members Intent: Enabled
Message Content Intent: Enabled
Code:
const { Client, Events, GatewayIntentBits, Partials } = require('discord.js');
const { token } = require('./includes/config.json');
// create a new discord client
const client = new Client({
intents: [
GatewayIntentBits.DirectMessageReactions,
GatewayIntentBits.DirectMessageTyping,
GatewayIntentBits.DirectMessages,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.Guilds,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel,
Partials.GuildMember,
Partials.Message,
Partials.Reaction,
Partials.User,
]
});
// ready
client.once(Events.ClientReady, () => {
console.log('Ready!');
});
// if partial, fetch full
client.on(Events.MessageReactionAdd, async (reaction, user) => {
if (reaction.partial) {
try {
await reaction.fetch();
} catch (error) {
console.error(error);
return;
}
}
// define the message component
const message = reaction.message;
// all userReactions by user.id
const userReactions = await message.reactions.cache.filter(reaction => reaction.users.cache.has(user.id));
// print emojis
try {
for (const reaction of userReactions.values()) {
console.log(`Emoji: ${reaction.emoji}`);
}
} catch(error) {
console.error(error);
}
})
// login
client.login(token);
Problem:
The bot is not registering the first reaction placed
Example:
- I react to a message in this order: 😄❤️🔥
- the logfile shows:
Emoji: ❤️
Emoji: ❤️
Emoji: 🔥
Expected result:
Emoji: 😄
Emoji: 😄
Emoji: ❤️
Emoji: 😄
Emoji: ❤️
Emoji: 🔥
Observations:
I noticed that the bot works fine for all messages sent after it is running
The problematic behaviour is experienced only for messages sent before the bot was running
Conclusion:
MessageReactionAdd() does get called, as tested by placing 'console.log(test output); statements. I learned that it works on cached messages only, which I thought was mitigated by fetching the full reaction. Such was not the case. I tried testing by forcing a message fetch manually by channel.id and message.id, it still did not work.
My Solution:
Used an sqlite database to keep track of reactions.
From within MessageReactionAdd() I was able to check for the reactions I was interested in logging, and added them to an sqlite database.
Within an equivalent MessageReactionRemove() section, I was able to check for removal of the reactions and delete the pertinent row from the database.
Thank you for reading and assisting. :)

Unable to receive interactionCreate Event in DiscordJS

I am trying to implement Slash Commands to my Discord bot but when i try to recieve interaction create events nothing is getting detected with no errors
client.on('interactionCreate', async (interaction) => {
The Slash Commands do get added and i can edit their name and stuff but im unable to recieve any interaction create events, it does detect normal messages but doesnot detect any interactionCreate stuff,
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.DIRECT_MESSAGES]
});
);
Those are the intents i have provided to the client
Screenshot
Those are the permissions i gave to the bot when i invited it to my server
await rest.put(
Routes.applicationGuildCommands(clientID, devGuildID), {
body: commandList
},
);
console.log('Successfully registered application commands for development guild');
rest.get(Routes.applicationCommands(clientID))
.then(data => console.log(data));
When i use this i get "[]" as an output when i console.log

Check The Status Of Another Discord Bot

So i need a bot that tracks another bot's status. like if its online it will say in a channel (with an embed) "The Bot Is Online" And The Same if it goes offline and whenever someone does !status {botname} it shows the uptime/downtime of the bot and 'last online' date
if someone can make it happen i will really appricate it!
also i found this github rebo but it dosen't work, it just says the bot is online and whenever i type !setup {channel} it turns off
The Link to the Repo: https://github.com/sujalgoel/discord-bot-status-checker
Also uh it can be any language, i don't really want to add anything else 😅.
Again, Thanks!
First of all, you would need the privileged Presence intent, which you can enable in the Developer Portal.
Tracking the bot's status
In order to have this work, we have to listen to the presenceUpdate event in discord.js. This event emits whenever someone's presence (a.k.a. status) updates.
Add this in your index.js file, or an event handler file:
// put this with your other imports (and esm equivalent if necessary)
const { MessageEmbed } = require("discord.js");
client.on("presenceUpdate", async (oldPresence, newPresence) => {
// check if the member is the bot we're looking for, if not, return
if (newPresence.member !== "your other bot id here") return;
// check if the status (online, idle, dnd, offline) updated, if not, return
if (oldPresence?.status === newPresence.status) return;
// fetch the channel that we're sending a message in
const channel = await client.channels.fetch("your updating channel id here");
// create the embed
const embed = new MessageEmbed()
.setTitle(`${newPresence.member.displayName}'s status updated!`)
.addField("Old status", oldPresence?.status ?? "offline")
.addField("New status", newPresence.status ?? "offline");
channel.send({ embeds: [embed] });
});
Now, whenever we update the targeted bot's status (online, idle, dnd, offline), it should send the embed we created!
!status command
This one will be a bit harder. If you don't have or want to use a database, we will need to store it in a Collection. The important thing about a Collection is that it resets whenever your bot updates, meaning that even if your bot restarts, everything in that Collection is gone. Collections, rather than just a variable, allows you to store more than one bot's value if you need it in the future.
However, because I don't know what you want or what database you're using, we're going to use Collections.
In your index.js file from before:
// put this with your other imports (and esm equivalent if necessary)
const { Collection, MessageEmbed } = require("discord.js");
// create a collection to store our status data
const client.statusCollection = new Collection();
client.statusCollection.set("your other bot id here", Date.now());
client.on("presenceUpdate", async (oldPresence, newPresence) => {
// check if the member is the bot we're looking for, if not, return
if (newPresence.member !== "your other bot id here") return;
// check if the status (online, idle, dnd, offline) updated, if not, return
if (oldPresence?.status === newPresence.status) return;
// fetch the channel that we're sending a message in
const channel = await client.channels.fetch("your updating channel id here");
// create the embed
const embed = new MessageEmbed()
.setTitle(`${newPresence.member.displayName}'s status updated!`)
.addField("Old status", oldPresence?.status ?? "offline")
.addField("New status", newPresence.status ?? "offline");
channel.send({ embeds: [embed] });
// add the changes in our Collection if changed from/to offline
if ((oldPresence?.status === "offline" || !oldPresence) || (newPresence.status === "offline")) {
client.statusCollection.set("your other bot id here", Date.now());
}
});
Assuming that you already have a prefix command handler (not slash commands) and that the message, args (array of arguments separated by spaces), and client exists, put this in a command file, and make sure it's in an async/await context:
// put this at the top of the file
const { MessageEmbed } = require("discord.js");
const bot = await message.guild.members.fetch("your other bot id here");
const embed = new MessageEmbed()
.setTitle(`${bot.displayName}'s status`);
// if bot is currently offline
if ((bot.presence?.status === "offline") || (!bot.presence)) {
const lastOnline = client.statusCollection.get("your other bot id here");
embed.setDescription(`The bot is currently offline, it was last online at <t:${lastOnline / 1000}:F>`);
} else { // if bot is not currently offline
const uptime = client.statusCollection.get("your other bot id here");
embed.setDescription(`The bot is currently online, its uptime is ${uptime / 1000}`);
};
message.reply({ embeds: [embed] });
In no way is this the most perfect code, but, it does the trick and is a great starting point for you to add on. Some suggestions would be to add the tracker in an event handler rather than your index.js file, use a database rather than a local Collection, and of course, prettify the embed messages!

How can i make my bot respond with a react for every action for my help command . discord.js

i don't know how to make my bot to react with a white check mark after the author receiving the message and also reacting with a cross mark when the author doesn't receive the message in dms. this is my code:
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
if (message.content.startsWith(prefix + 'help')) {
const founder = client.users.get('my id');
message.author.send(`
[❖---------- there's a room called log ----------❖]
1- 🚀 fast connection host
2- 🔰 easy commands
3- ⚠️ working on it everyday
4- 💸 free for anyone
5- ⚛️ anti-hack
6- Made by one developer : ${founder.username}#${founder.discriminator}
`);
}
});
User.send() returns a Promise that gets fulfilled when the message is sent correctly and gets rejected when the bot is unable to send it: you can use Promise.then() and Promise.catch() to perform different actions based on what happened.
Here's an example:
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return
if (message.content.startsWith(prefix + 'help')) {
message.author.send('Your message').then(dmMessage => {
// The message has been sent correctly, you can now react to your original message with the tick
message.react('✔️')
}).catch(error => {
// There has been some kind of problem, you should react with the cross
message.react('❌')
})
}
})
Basically, if it fails to send in somebody's DM, it will throw an error. Therefore, to react with a cross mark if they don't receive it, just catch the error like so.
client.on('message', message => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
if (message.content.startsWith(prefix + 'help')) {
const founder = client.users.get('my id');
try {
message.author.send(`
[❖---------- there's a room called log ----------❖]
1- 🚀 fast connection host
2- 🔰 easy commands
3- ⚠️ working on it everyday
4- 💸 free for anyone
5- ⚛️ anti-hack
6- Made by one developer : ${founder.username}#${founder.discriminator}
`);
message.react('✅');
} catch {
message.react('❌');
}
}
});
Here, if the DM sends, it reacts with a check mark, and if an error is thrown (it happens when it isn't sent) it reacts with a cross mark.
Hope this helps.

Permission Error Handler - Bot Crashes how to use try catch properly

I want it so my bot can only send embeds in specific channels with the permissions granted but if a user sends the message in a channel where the permissions are not granted the bot stops working and cuts off. I am trying to make it so a try catch works so even if an error is thrown it continues to work, the error I am getting is "UnhandledPromiseRejectionWarning: DiscordAPIError: Missing Permissions - I want to be able to ignore this error.
function catchErr (err, emessage, a){
console.log("Someone tried to use the embed in the");}
let args = message.content.slice(PREFIX.length).split(' ');
switch(args[0]){
case 'discordbot ':
try {
const discordbot = new Discord.MessageEmbed()
.setTitle('My Discord Bot*')
.addFields(
{ name: 'Test Bot:', value: 'Test' },
message.channel.send(discordbot );
} catch (err) {
catchErr(err, message);
}
.send returns a Promise, if you want to catch errors you can either go for Promise.catch or use async / await (this requires your top level function to be async)
// Using Promise.catch
const catchErr = err => {
console.log(err)
}
message.channel.send(embed).catch(catchErr)
// Using async / await
try {
await message.channel.send(embed)
} catch(err) {
catchErr(err)
}
function sendMessage(message,content){
const permissions = message.channel.permissionsFor(message.client.user);
if (permissions.has("SEND_MESSAGES")){
if(content){
message.channel.send(content);
}
}
else{
console.log("[ERR] no msg perms")
message.author.send("I can't send messages on this channel or guild!, Try another channel or contact the server staff to check bot's permissions.");
}
}

Resources