How can i edit and redesign my old embed messages - discord

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)

Related

Discordjs: Specifying channel for an interaction.reply

I am using Discordjs v13. I have created a slash command and I am able to "print" a message using
await interaction.reply(messageObj);
I need to send the reply to a different channel where the command was triggered, is this possible?
Something like:
interaction.setChannel(channelId).reply(...)
OR
interaction.reply({
channel: ....
....
})
What you want is not possible. The Discord API does not allow to specify the channel where the app interaction should be replied in: https://discord.com/developers/docs/interactions/receiving-and-responding#responding-to-an-interaction
However if you are concerned with the reply being shown to everyone, you can make the reply ephemeral. If you want to log interactions, you can reply to the interaction then send another message using the solution provided in the comments of your question.
this is actually possible in discordjs v14 and may be in v13 as well. Carl-bot does it with suggestions.but its not an actual reply
use
interaction.guild.channels.cache.get('channel-id').send('message')
this will send a message in a the select channel you may still want to
interaction.reply({Content:'replied in #channel' [embed], ephemeral: true })
so the user knows the reply was redirected . ephemeral: true makes the replay only visible to the user that evoked the interaction.
and if you need the message id for the new message use
const msg = await interaction.guild.channels.cache.get('channel-id').send('message');
to send the message and you can do something like const messageid = msg.id

Discord: Reading messages from one channel in a (non-admin perm) server, and posting it to another (with admin perms)

I am new to Discord API framework.
ServerFROM is a public server that I was invited to (non-admin perms). Hence I cannot add bots there. But I can view the content in ChannelFROM (a text channel in ServerFROM)
I have my own ServerTO (in which I have admin perms and so can do anything). Inside of which, I have the target ChannelTO
I want to deploy a listener on ChannelFROM, such when there is a new message (announcement) in ChannelFROM, I want it to be read and reposted in ChannelTO.
Something similar to what is done in this Stackoverflow issue, except that I cannot have some script run locally 24x7 on my machine. Maybe use Github Actions or something similar?
How can I go about doing it? Any ideas are appreciated. Maybe some form of a server, or just a custom Discord bot
And thanks in advance.
you can use Custom bot for that. I dont know other way
here's how i do it
1st : We Get the ID of the Channel that you wanted to listen
2nd : We make a Output or where the bot copy the message from and send it
3rd : Bot required a permission to view the channel and send message
or in the nutshell ( sorry if im bad at explaining )
client.on("messageCreate", message => {
if(message.author.bot) return;
if(message.channel.id === ID_HERE) // ChannelFROM in ID_HERE
{
let MSG = message.content
let Author = message.member.displayName
let Avatar = message.author.displayAvatarURL({dynamic: true})
const Embed = new MessageEmbed()
.setAuthor(Author , Avatar )
.setDescription(MSG)
.setColor("RANDOM")
client.channels.cache.get(ID_HERE).send({ embeds: [Embed] }) // SendTo in ID_HERE
}
})
you can remove if(message.author.bot) return; if you want it also read other bot message on that specific channel

Discord.py make discord bot react to message with several emotes

I know how to make a bot react to a message, but I am stuck with my project and I'm just running constantly into troubles. I want to do a command with the syntax -react [message ID] [emote1] [emote2] [emote 3] [emote ...] that reacts to the message belonging to the ID with the emotes I put after the ID.
I know how to make the bot react with the same emotes to always the same message, and tried to make it react to other messages with the code:
#client.command()
async def react(ctx, ID):
emotes = ['❤️', '🏠']
msg = message.fetch_message(ID)
for emote in emotes:
await ctx.msg.add_reaction(emoji=emote)
but this always puts out NameError: name 'message' is not defined in msg = message.fetch_message(ID), and additionally I have not the slightest idea how to make it work with own chosen emotes.
So, my main problems are:
How can I make the bot react to specific messages? (Solved)
How can I make it using own specified emotes?
Update: First problem solved, I simply needed to add
message_id = ID
msg = await ctx.fetch_message(message_id)
but I'm still stuck with making it react with user given emotes, not hard-coded ones.
You didn't define message variable, that's why it's throwing that error.
The ID arg is a string, ids must be integers
ctx doesn't have the attribute msg it's message
Also to implement the emojis you can simply pass them as a tuple and go through them using a for loop.
#client.command()
async def react(ctx, ID: int, *emojis):
message = ctx.fetch_message(ID)
for emoji in emojis:
await message.add_reaction(emoji)
# Or if you want to add the reactions to the message which invoked the command
await ctx.message.add_reaction(emoji)

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)
})

How to fetch a message from the entire guild

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 */});

Resources