How do I cache messages? - discord.js

How can I cache messages in discord.js? I wanted to make a reaction roles system, but the event for adding reactions works only for cached messages.
I put this code in the "ready" function:
bot.channels.cache.get(channel id).messages.cache.get(message id)
This does not work, the event still does not fire.
Am I doing something wrong?

You can forcefully cache messages through MessageManager#fetch.
// with promises
bot.channels.cache
.get('channel id')
.messages.fetch('message id')
.then(() => {
console.log(`The message has been cached`);
});
// with async/await (make sure your function is async)
await bot.channels.cache.get('channel id').messages.fetch('message id');
console.log(`The message has been cached`);

Related

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!

Make the code below .then fire even if there is an error

I have a kick command in my discord.js bot, and I wanted to make the bot send a DM to the person that got kicked. I can not do it like this:
user.send(message)
target.kick(reason).then((m) => {
// do the other stuff here
});
With this code, the DM does not get sent.
This is what I did instead:
user.send(message).then((msg) => {
target.kick(reason).then((m) => {
// do the other stuff here
});
});
Now the issue is that if the target blocks the bot, the bot can not DM them, making the code to kick them not run.
How can I solve this?
You can use .finally, which runs regardless if the promise is fulfilled or rejected.
user.send(message).finally(() => {
target.kick(reason).then((m) => {
// do the other stuff here
});
});

How to use the awaitMessages function in discord.js

I have some code for discord.js that sends a user a DM when they join the server. They then have to enter the password given to them, and it will then give them a role that allows them access to channels.
const Discord = require('discord.js');
const client = new Discord.Client();
client.once('ready', () => {
console.log('Ready!');
});
client.on('guildMemberAdd', guildMember => {
console.log("Joined");
guildMember.send("Welcome to the server! Please enter the password given to you to gain access to the server:")
.then(function(){
guildMember.awaitMessages(response => message.content, {
max: 1,
time: 300000000,
errors: ['time'],
})
.then((collected) => {
if(response.content === "Pass"){
guildMember.send("Correct password! You now have access to the server.");
}
else{
guildMember.send("Incorrect password! Please try again.");
}
})
.catch(function(){
guildMember.send('You didnt input the password in time.');
});
});
});
client.login("token");
The thing is, I don't really know how to use the awaitResponses function. I do not know how to call it, because all the tutorials I find use it with message.member.
When I run my code, I get these three errors:
UnhandledPromiseRejectionWarning: TypeError: guildMember.awaitMessages is not a function
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.
I do not know what lines these are referring to, so I am very confused.
Here's a quick rundown on how awaitMessages works:
First of all, the .awaitMessages() function extends GuildChannel, meaning you had already messed up a little bit by extending the GuildMember object instead. - You could easily fetch a channel using
const channelObject = guildMember.guild.channels.cache.get('Channel ID Here'); // Gets a channel object based on it's ID
const channelObject = guildMember.guild.channels.cache.find(ch => ch.name === 'channel name here') // Gets a channel object based on it's name
awaitMessages() also gives you the ability to add a filter for a certain condition an input must have.
Let's take the freshly new member as an example. We could simply tell the client to only accept input from members who have the same id as the guildMember object, so basically only the new Member.
const filter = m => m.author.id === guildMember.id
Now, finally, after we've gathered all of the resources needed, this should be our final code to await Messages.
const channelObject = guildMember.guild.channels.cache.get('Channel ID Here');
const filter = m => m.author.id === guildMember.id
channelObject.awaitMessages(filter, {
max: 1, // Requires only one message input
time: 300000000, // Maximum amount of time the bot will await messages for
errors: 'time' // would give us the error incase time runs out.
})
To read more about awaitMessages(), click here!

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.

How to know the inviter of the bot ? discord.js

I want to know who is the inviter of the bot but I don't find anything on the documentation or on forum.
If someone has an idea :/
EDIT
Recently discord added an entry in guild audit logs that log everytime someone adds a bot into the server, so you can use it to know who added the bot.
Example:
// client needs to be instance of Discord.Client
// Listen to guildCreate event
client.on("guildCreate", async guild => {
// Fetch audit logs
const logs = await guild.fetchAuditLogs()
// Find a BOT_ADD log
const log = logs.entries.find(l => l.action === "BOT_ADD" && l.target.id === client.user.id)
// If the log exits, send message to it's executor
if(log) log.executor.send("Thanks for adding the bot")
})
Old Anwser
The discord API doesn't allow this.
But, you can send a message to the Owner of the guild using the property guild.owner to get it
client.on('guildCreate', guild => {
guild.owner.send('Message here').catch(e => {
// Can't message to this user
})
})

Resources