How do I get info from an embed? - javascript

I've been making a suggestion command and I want it so that I can use a -approve <The message id> to edit the message. The problem is when I try to fetch info from it using
const Suggestionchannel = client.channels.cache.get("833796404383973442");
const messages = Suggestionchannel.messages.fetch({ limit: 100 })
it only fetches all the messages and not the embeds. I want it to fetch the embeds so I can get the data and edit the message by its id. With the data, I could display who made the suggestion and what the suggestion was while at the same time showing that it was approved. How would I get the info from an embed using a message id?
On a side note: I know I could use async and await to easily edit it while on the same code but I want it so that it's accessible. If I do that and restart the bot, I won't be able to approve the previous suggestions, only the new ones after I restart the bot.

First, you have to either await fetching the messages from the suggestion channel, or put it into a .then to not have messages be a Promise. Awaiting it wouldn't change anything in your ability to edit the message, you just have to make sure your message cache has the actual message in it.
Fetching the messages from a channel would return a Promise<Collection<Snowflake, Message>>. Once you resolve the message, you get a collection containing messages. On the Message class, there is a array called embeds. It contains all of the embeds part of the message, normally, if sent by a bot, only contains one MessageEmbed.
Another thing is, to make it easier for you, the fetch message also takes in a message ID, and if it's provided, it would fetch the message with that ID from the channel. Doing this would change what it returns to Promise<Message>
Implementing all of these changes in your code would look something like;
const Suggestionchannel = client.channels.cache.get("833796404383973442");
// make sure that your outer scope is asynchronous
const message = await Suggestionchannel.messages.fetch('INSERT MESSAGE ID OR VARIABLE HERE')
const embed = message.embeds[0]
//would be undefined if there is no embed
//would be a MessageEmbed if there is an embed

Related

Delete messages in a specific channel using channel id

I'm trying to make a command for my discord bot that sends embeds in different channels(using the id) and deletes the message that was sent before. I've googled a lot and I still can't find a working solution on how to delete messages in a specific channel using the channel ID. I only need 1 message to be deleted if that's easier but I don't know.
This is my code:
client.channels.cache.get('channelid').messages.fetch().then(message => message.delete())
client.channels.cache.get('channelid').send({ embeds: [FAQEmbed] }); // sends FAQ Embed
I replaced the id with channelid in case of anything. The embed works and it sends, but the message before doesn't get deleted.
Yes your code correct, but if you want to delete the message when bot replied.
use message.channel.id and message.id to return message and channel id
example:
client.channels.cache.get(message.channel.id).messages.fetch(message.id).then(message => message.delete())
hope this help you, but you need to defined the client as well

How would I go about editing a message sent by a a discord bot? But only when reacted to by a user with a certain role?

I'm trying to setup a bug report system. I have the token system and everything for it, however I need to know how to have the bot edit a message when it is reacted to by a user with a particular role, which for this sake is named 'Debugger'
The event you want to listen to is client.messageReactionAdd. Be aware, that it will not listen to non-cached messages. To listen to older messages, you must enable partials, like so:
//top of your code
const client = new Discord.Client({partials: [`MESSAGE`, `CHANNEL`, `REACTION`]});
.
.
.
This will allow you to receive events for partial messages. In order to get full message from partial, you need to fetch it:
client.on('messageReactionAdd', async msgReaction => {
let msg = msgReaction.message;
//note that messageReactionAdd event returns MessageReaction object, not Message.
//this line makes it simpler to write code.
if (msg.partial) await msg.fetch().catch();
//
//rest of your reaction handler goes here
//
});
You will be able to figure out the rest by reading the documentation.

Message Specific PFP. (like TupperBox)

I am looking to send a message that has a different profile picture than the bot. Basically, like Tupper Bot does. I can't seem to figure out how to do it anywhere, I've read the documentation and searched around.
You can use a webhook to do what you describe. If you already have a webhook link see here on how to use it. This works from external programs too.
If you don't, you can create a webhook with your bot and then send messages to it. In this example we will create a simple webhook and send a message to it.
First we should check if the channel already has a webhook. That way you don't create a new one everytime you use the command. You do that with the fetchWebhooks() function which returns a collection if there is a webhook present. If that is the case we will get the first webhook in the collection and use that. Note: if you have more then one webhook you can of course add additional checks after the initial one.
If there are no webhooks present, we create a new one with createWebhook(). You can pass additional options after the name.
let webhook;
let webhookCollection = await message.channel.fetchWebhooks();
if (webhookCollection.first()) {
webhook = webhookCollection.first();
} else {
webhook = await message.channel.createWebhook("new webhook", {
avatar: "https://i.imgur.com/tX5nlQ3.jpeg"
});
}
Note: in this example we use the channel the message came from but you can use any channel you want
Technically we can now send messages already.
webhook.send("this is a test");
What you can also do is create a webhookClient. Thats a little like the discord client you create when you start your bot. It takes the webhook ID and token as well as additional options you can set for clients.
const hookclient = new Discord.WebhookClient(webhook.id, webhook.token);
This lets you use a few additional methods like setInterval.
hookclient.setInterval(() => {
hookclient.send("This is a timer test");
}, 1000)
This lets you use the webhook without creating or fetching one first.

Select message by contents (discord.js)

I need to select a previously sent message (from a bot) in discord.js
async () => {
let fetched;
fetched = await receivedMessage.channel.messages.startsWith("Please use the command:")
fetched.delete()
}
I tried this, but it doesn't seem to work.I'm trying to get a message by it's contents, and then delete it.
Edit: So apparently... "You could fetch the last 100 messages using channel.messages.fetch with a limit option, then filter that collection by message.content.startsWith, and then passing that into channel.bulkDelete()"
Which in my opinion, sounds like the way to do it - I will try it out soon.
You don't need to use startsWith you can just check if the message was sent by a bot using message.author.bot.

Return the channel ID of a channel mentioned in a command

The title says all. I'm making a Discord bot in node.js, and one part that I'm trying to add is a .setup command, to make the bot less dependent on manually changing the value of client.channels.get().send(), allowing it to be more easily set up in the future.
Anyway, in my case, I'm trying to have the user reply to a message with a channel mention (like #welcome for example), and have the bot return that ID and save it to a variable.
Currently, I have this:
function setupChannel() {
client.channels.get(setupChannelID).send('Alright. What channel would you like me to send my reminders to?');
client.on('message', message => {
checkChannel = message.mentions.channels.first().id;
client.channels.get(setupChannelID).send('Ok. I\'ll send my reminders to that channel.');
});
}
message.mentions.channels returns undefined.
I know that the message.mentions.channels.first().id bit works when its a user instead of a channel, is there a different way of getting a channel mention in a message?
Here is the most easy and understandable way i found :
message.guild.channels.cache.get(args[0].replace('<#','').replace('>',''))
But it not really what we want we could use <#####9874829874##><<<547372>> and it will work. So i figured out this :
message.guild.channels.cache.get(args[0].substring(2).substring(0,18))
I like to just remove all non-integers from the message, as this allows for both IDs and mentions to be used easily, and it will return the ID for you from that, as mentions are just IDs with <# and > around them. To do this you would use
message.content.replace(/\D/g,'')
With this, your code would look like this:
function setupChannel() {
client.channels.get(setupChannelID).send('Alright. What channel would you like me to send my reminders to?');
client.on('message', message => {
checkChannel = message.content.replace(/\D/g,'');
client.channels.get(setupChannelID).send('Ok. I\'ll send my reminders to <#' + checkChannel + '>.');
});
}
From this you will always get an ID. And we can surround the ID to trun it into a mention.

Categories