Get last message sent to channel - node.js

I already have a variable containing a specific channel, but how can I obtain the last message sent to the channel? I want to make my bot only perform an action if the last message to the channel wasn't by it.

If you already have the specific channel stored in a variable, it's quite easy. You can call the MessageManager#fetch() method on that specific channel and get the latest message.
Example:
let channel // <-- your pre-filled channel variable
channel.messages.fetch({ limit: 1 }).then(messages => {
let lastMessage = messages.first();
if (!lastMessage.author.bot) {
// The author of the last message wasn't a bot
}
})
.catch(console.error);
 
However if you don't have the complete channel object saved in a variable but only the channel ID, you'll need to fetch the correct channel first by doing:
let channel = bot.channels.get("ID of the channel here");

Recently I believe they've changed from channel.fetchMessages() to channel.messages.fetch()
channel.messages.fetch({ limit: 1 }).then(messages => {
let lastMessage = messages.first();
// do what you need with lastMessage below
})
.catch(console.error);

There is a property containing the object of the last writte message. So the most short version of getting last Message is:
let lm = channel.lastMessage;
Of course #Tyler 's version is still working. But my IDE says that he don't know first(). So may this will be deprecated some day?!? I don't know.
Anyway, in both ways you retrieve an object of the message. If you want to have e.g. the text you can do this
let msgText = lm.content; // channel.lastMessage.content works as well

Related

Discord.JS - Return original owner ID via a reply message using NodeJS

I've been scouring the internet and have yet to find a way of doing this.
Simply put;
Person 1 posts a message in a Discord channel i.e. "Thanks"
Person 2 replies to Person 1's message with a prefix command and a channel ID
I then want the bot to grab the following information;
Original messageID (Person 1's message)
Original message Content (The message itself)
Replier messageID (Person 2)
Replier message Content (which holds the commands)
I have read a few bits and pieces and found I apparently could do this with references and 'resolved' but below returns an undefined for reference.
if (message.reference?.resolved) {
var old_message = await message.channel.fetch_message(message.reference.messageId)
}
Turns out messageCreate works, message is deprecated.
client.on('messageCreate', async (message) => {
if (message.author.bot) return;
var reply = message.reference;
var old_message = await message.channel.messages.fetch(reply.messageId)

(discord.js v13) If channel exists

I'm making a ticketing system with buttons. I trying to if user opened a ticket, user can't open a new ticket. Im tried some code:
//ticket channel is created with **"help: " + interaction.user.username** name
if (interaction.guild.channels.fetch('channel name'))
//working with only id
if (interaction.guild.channels.cache.get(c=>c.name==='channel name'))
//reacted nothing
The discord.js channels cache is a Discord.Collection of values, meaning that it is a JS map with some extra quality of life methods added by Discord.js. Discord Collections are keyed using the snowflake id with the value being whatever object is being stored with that id (in this case the channel you want). This means that the method fetch on the collection of channels can always only be passed an ID as stated here in the docs. This would also mean that the Map.get() method you try to use in the second attempt will not return anything as the channel is not keyed by its name, its keyed by a snowflake id.
You can use a piece of code like this one I used in a discord moderation bot to find and return a channel by name if it exists in the cache.
/**
* Get the log channel for the provided guild.
* #param {Discord.Guild} guild The guild to get the log channel for.
*/
#getLogChannel = (guild) => {
const guildLogChannel = guild.channels.cache
.find(channel => channel.name === 'guild-logs');
if (!guildLogChannel) return false;
return guildLogChannel;
}
If the channel has not yet been cached you have no other option than to pass that channel into the interaction as an option, fetch the channel by its snowflake id, or fetch all channels for all guilds the bot is in inside your client.on('ready', () => {}) handler. The last option is what I chose to do for the bot that the above code snippet is taken from.

How edit messages in Discord.js V12 using message ID

There is the way to edit a message on DiscordJS
To do this, we just need to pass it to the function, the client variable.
exports.myNewFunction = async function myNewTestFunction(client)
First, in order to edit a message using the Discord.JS API, we will need to find the server's GuildID.
const guild = client.guilds.cache.get(`Your Guild ID`);
Now, we're going to need to find the channel the message is on. For this, we will use the channel ID
const channel = guild.channels.cache.find(c => c.id === `Your message Channel` && c.type === 'text');
Finally, let's go to the editing part of the message. For this, we will only need to provide the ID of the message that you want to be edited.
channel.messages.fetch(`Your Message ID`).then(message => {
message.edit("New message Text");
}).catch(err => {
console.error(err);
});

Welcoming of Bot not working because of "Cannot read property 'find' of undefined"

Ok so I want my bot to welcome new users in a channel for welcoming, so I used find. Here is what I got so far:
client.on('guildMemberAdd', member => {
let guild = member.guild;
guild.channel.find('name','welcome','welcoming','greeting','general').send(`AYYY! Welcome ${member.user} to our Discord Server! Check out the FAQ, Info, and/or The Rules channels (if there is) for some documentation and support to help you get ready!`);
});
Expected result: Welcomes the user in the channel that was used find on.
Actual Result: Cannot read property 'find' of undefined.
I tried a lot of things, but the results are the same. Also, channels didn't not work, only channel.
I also don't believe you can use .find() to return multiple channels, since it always returns the first element it finds in the array.
You can, however, create another array that is a filter of guild.channels.cache based on channel names and then use .forEach() on that array to send a message to each of them like so:
function channelNamesFilter(channel) {
let channelNames = ['name','welcome','welcoming','greeting','general'];
if(channelNames.includes(channel.name)) {
return true;
}
return false;
}
let filteredChannels = guild.channels.cache.filter(channelNamesFilter);
filteredChannels.forEach(element => element.send('AYYY! Welcome ${member.user.name} to our Discord Server! Check out the FAQ, Info, and/or The Rules channels (if there is) for some documentation and support to help you get ready!'));
Notice too how I changed ${member.user} to ${member.user.name}, the first one is an object the second one is its name property in string form.
It's guild.channels with a s and you have to use the cache so your code would be:
client.on('guildMemberAdd', member => {
let guild = member.guild;
guild.channels.cache.find('name','welcome','welcoming','greeting','general').send(`AYYY! Welcome ${member.user} to our Discord Server! Check out the FAQ, Info, and/or The Rules channels (if there is) for some documentation and support to help you get ready!`);
});
Edit:
You can't find multiple channels. You have to put only one name.

Is there a way to obtain Discord message ID upon posting msg to channel from node server?

Using Discord.js in an Express/Node.js app, I'm trying to build a bot that grabs external data periodically and updates Discord with an embed msg containing some elements of that data. I'm trying to add a feature that will check if that data was deleted from the external source(no longer existing upon the next grab), then delete the specific msg in Discord that contains that data that was sent.
Some of the msgs posted in Discord may have duplicate data items, so I want to delete by specific msg ID, but it seems that msg ID is assigned when posted to Discord.
Is there a way to programmatically grab or return this msg ID when sending from Discord.js, rather than manually copy/pasting the msg ID from the Discord GUI? In other words, I need my bot to know which message to delete if it sees that msg's source data is no longer being grabbed.
// FOR-LOOP TO POST DATA TO DISCORD
// see if those IDs are found in persistent array
for (var i = 0; i < newIDs.length; i++) {
if (currentIDs.indexOf(newIDs[i]) == -1) {
currentIDs.push(newIDs[i]); // add to persistent array
TD.getTicket(33, newIDs[i]) // get ticket object
.then(ticket => { postDiscord(ticket); }) // post to DISCORD!
}
}
// if an ID in the persistent array is not in temp array,
// delete from persistent array & existing DISCORD msg.
// message.delete() - need message ID to get msg object...
// var msg = channel.fetchMessage(messageID) ?
Let me refer you to:
https://discord.js.org/#/docs/main/stable/class/Message
Assuming you are using async/await, you would have something like:
async () => {
let message = await channel.send(some message);
//now you can grab the ID from it like
console.log(message.id)
}
If you are going to use .then for promises, it is the same idea:
channel.send(some message)
.then(message => {
console.log(message.id)
});
ID is a property of messages, and you will only get the ID after you receive a response from the Discord API. This means you have to handle them asynchronously.

Resources