How to fetch a message from the entire guild - discord.js

I would like to know how to find a message with its id from the entire guild and not just the current channel.
I have tried
message.guild.channels.fetchMessage(message_ID)
client.channels.fetchMessage(message_ID)
message.channel.guild.fetchMessage(message_ID)
message.fetchMessage(message_ID)
message.guild.fetchMessage(message_ID)
I want it to look through the entire guild and find the message by ID then send what the message has said. Also, I have tried to have it look for the channel that I want the message from but that didn't work either.
If it's possible to get more specific with the code, it should look into a channel called #qotd-suggestions with the ID of 479658126858256406 and then find the message there and then send the message's content.
Also, the message_ID part of fetchMessages gets replaced with what I say after the command so if I say !send 485088208053469204 it should send Message content: "Wow, the admins here are so lame."

There's no way to do that with a Guild method, but you can simply loop through the channels and call TextChannel.fetchMessage() for each of them.
In order to do that, you could use Collection.forEach() but that would be a little more complex if you want to work with vars, so I suggest you to convert Guild.channels to an Array with Collection.array().
Here's an example:
async function findMessage(message, ID) {
let channels = message.guild.channels.filter(c => c.type == 'text').array();
for (let current of channels) {
let target = await current.fetchMessage(ID);
if (target) return target;
}
}
You can then use this function by passing the message that triggered the command (from which you get the guild) and the ID you're looking for. It returns a Promise<Message> or, if the message is not found, Promise<undefined>. You can get the message by either using await or Promise.then():
let m = await findMessage(message, message_ID); // Message or undefined
// OR
findMessage(message, message_ID).then(m => {/* your stuff */});

Related

How do I fetch all reactions from a specific message? [Discord.js]

So, I want to make a command for my bot which can fetch all reactions from a given message ID and store these three categories into arrays, for each reaction:
the name of the reaction (eg. :smile:)
the users who reacted (eg. RandomUser#4654, ILikePotatoes#1639)
and how many people reacted with this emoji (eg. Count: 2)
I've tried using the ReactionCollector, but it doesn't work for reactions added prior to the event being called. I've also tried using an external module called discord-fetch-all but all it does is either sending Promise { <Pending> } or undefined when I use .then().
PS: I've already set up a command handler that takes a message ID for argument.
Thank you in advance for helping.
You can get the specific message you want to be check for reactions by using:
const messageReacted = client.channels.cache.get('channelId').messages.fetch('messageId')
Then, you can go through each reaction in the message's cached reactions by using forEach
Then, in the .forEach, you can get the emoji name by using reaction._emoji.name, the number of users who used this reaction by reaction.count and all the users who reacted on the message by fetching them: await reaction.users.fetch().
Your final code might look something like:
const messageReacted = await client.channels.cache
.get('channelId')
.messages.fetch("messageId");
messageReacted.reactions.cache.forEach(async(reaction) => {
const emojiName = reaction._emoji.name
const emojiCount = reaction.count
const reactionUsers = await reaction.users.fetch();
});

How can i edit and redesign my old embed messages

ive been texted something on my discord server before as embed. and now i just wanted to edit my old embed messages to redesign how its look by rewrite something and change colors.
how can i edit a specific embed messages by message id? i know it can edit itself by using :
first_embed = Embed(title='embed 1')
new_embed = Embed(title='embed 2')
msg = await ctx.send(embed=first_embed)
await msg.edit(embed=new_embed)
but i don't really know how to make it works. how it can edit at message ids? like checking its own id?
I am not 100% sure if I understand your question correctly, but to edit messages you could fetch them like this:
message = await ctx.fetch_message(message ID)
Or you can just use the integrated message converter in the arguments of the command.
#bot.command()
async def edit_embed(ctx, message: discord.Message):
#define the new embed here
await message.edit(embed=new_embed)
The user has to supply the message ID or message URL directly as an argument and discord.py will automatically convert it to a message object. Keep in mind that if you use the message ID, you will have to use the command in the same channel as the message you want to edit.
You have to make a new command to edit embeds and get the embed message's ID and the stuff you want to change as parameters. Then you can to Embed.copy() or Embed.to_dict() to get embed's data and then update the data you got as parameter.
An example would be:
#bot.command()
async def editembed(ctx, channel: discord.Chanel, msg_id, title, color):
msg = await channel.fetch_message(msg_id)
embed = msg.embeds[0].to_dict()
embed["title"] = title
embed["color"] = color
await msg.edit(embed = discord.Embed.from_dict())
Note: bot has no fetch message attribute so you have to either get it from channel or context (while using context you have to send the command on the same channel as the message to be edited)

I want a discord bot send a dm to somebody by their id

if (message.content === "!test"){
client.users.cache.get('id').send('message');
console.log("message sent")
}
This method doesn't work and I wasn't able to find any other methods that worked
Is there a spelling mistake or this method is outdated?
I've actually encountered this error myself once. There are two problems you might be facing here:
The user isn't cached by discord.js yet
There isn't a DMChannel open for that user yet
To solve the first one, you have to fetch the user before doing anything with it. Remember this is a Promise, so you'll have to either await for it to complete or use .then(...).
const user = await client.users.fetch('id')
Once you've fetched your user by their ID, you can then create a DMChannel which, again, returns a promise.
const dmChannel = await user.createDM()
You can then use your channel like you normally would
dmChannel.send('Hello!')
Try to create a variable like this:
var user = client.users.cache.find(user => user.id === 'USER-ID')
And then do this:
user.send('your message')

(Discord.js) Trying to get a channel id based on the name of the channel, and post a message in it

I'm trying to set up a server with a bunch of text channels named after users so that I can read their DMs to the bot. I can't figure out how to find if a text channel with that person's tag exists already, and I'm not sure if this is the correct code to do this.
Here is the code I'm trying to use:
try{
var txtChannel = client.guilds.cache.get(dmServerID).channels.find(channel => channel.name === (mesage.author.tag.replace('#','-')) && channel.type === "text");
}
catch(e){
client.guilds.cache.get(dmServerID).channels.create(message.author.tag.replace('#', '-'), 'text');
}
txtChannel.send(message.author.tag + ": " + message.content);
After running this code, it gives me an error that reads: Cannot read property 'send' of undefined.
I would also like to know if I am able to create the text channels inside of a category.
First of all, use let over var.
The error is caused by the fact that you declare txtChannel inside the try so it is not available outside that block of code.
Also, you forgot channels.cache (if you are using discord.js v12).
Here is what the code should look like:
let txtChannel = null;
// Already get the guild from the cache since we are gonna use it a bit
const guild = client.guilds.cache.get(guildID);
// Find a text channel that includes in the name the tag of the user
txtChannel = GUILD.channels.cache.find(c => c.type === "text" && c.name.includes(message.author.tag.replace('#','-'));
// If the channel doesn't exist we create the channel, using await to wait until the channel gets successfully created
if(!txtChannel) txtChannel = await GUILD.channels.create(message.author.tag);
// At the end we send the message in the gotten / created channel
txtChannels.send("the message to send");
Note that this code needs to be inside an async function, you can read more about that here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

how to send a message to every channel in every guild?

similar to this question however I want to be able to send it to every channel it has access to!
inside the on message event after I verify myself by ID and the issued command I was using this code:
const listedChannels = [];
msg.guild.channels.forEach(channel => {
//get all channels
client.channels.get(channel.id).send("you like bred? (message) ");
//send a message to every channel in this guild
});
however I get the error that .send is not a function...
I have been told to use .send after getting the ID of the channels
If you are looping through all of the channels, you simpily need to send your content to the channel, which you've already gotten from msg.guild.channels.forEach(channel => {//code}).
Replace what you have inside the .forEach block with;
channel.send("You like bred? (message)");
Although this will send You like bred? (message)
If you're trying to get a response back, perhaps look at this answer that explains collecting responses via reactions to a discord message.
The following explanation pertains only to v11 (stable).
Client.channels is a Collection of Channels your bot is watching. You can only send messages to text channels, and this Collection will include DM channels as well. For this reason, we can use Collection.filter() to retrieve a new Collection of only text channels within a guild. Finally, you can iterate over the channels and call TextChannel.send() on each. Because you're dealing with Promises, I'd recommend a Promise.all()/Collection.map() combination (see hyperlinked documentation).
For example...
// assuming "client" is your Discord Bot
const channels = client.channels.filter(c => c.guild && c.type === 'text');
Promise.all(channels.map(c => c.send('Hello, world!')))
.then(msgs => console.log(`${msgs.length} successfully sent.`))
.catch(console.error);
You can use client.channels for this. Check if channel type is guild text channel and then try send a message.
client.channels.forEach(channel => {
if(channel.type === 'text') channel.send('MSG').catch(console.error)
})

Resources