1
votes

I want the bot fetch a message(embed) and send it to channel where command is invoked. Following code works fine for normal text message:

@bot.command()
async def fetch(ctx):
    channel = bot.get_channel(736984092368830468)
    msg = await channel.fetch_message(752779298439430164)
    await ctx.send(msg.content)

For sending embeds I tried:

@bot.command()
async def fetch(ctx):
    channel = bot.get_channel(736984092368830468)
    msg = await channel.fetch_message(752779298439430164)
    await ctx.send(msg.embeds.copy())

It sends this instead of sending embed:

enter image description here

How do I make the bot copy and send embed?

2
msg.embeds.copy() actually returns an Embed object (you can see it in the module's source code). I have not tried it yet, but seems like ctx.send() has a parameter called embed. Maybe you should try await ctx.send(embed=msg.embeds.copy())Nicholas Obert
that doesn't work , gives error - discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'list' object has no attribute 'to_dict' @NicholasObertuser13878676
Hi @Deadshot if mine or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and therefore how to solve this problem, if they ever came across it.Nicholas Obert

2 Answers

2
votes

The problem is that you are trying to send a list of discord.Embed objects as a string in your await ctx.send(msg.embeds.copy())
The ctx.send() method has a parameter called embed to send embeds in a message.

await ctx.send(embed=msg.embeds[0])

Should do the trick. This way you are sending an actual discord.Embed object, instead of a list of discord.Embeds

You should not need the .copy() method in

await ctx.send(embed=msg.embeds[0].copy())

although you can use it

The only downside of using the index operator [0] is that you can only access one embed contained in your message. The discord API does not provide a way to send multiple embeds in a single message. (see this question).

A workaround could be iterating over every embed in the msg.embeds list and send a message for every embed.

for embed in msg.embeds:
    await ctx.send(embed=embed)

This unfortunately results in multiple messages being sent by the bot, but you don't really notice.

1
votes

You have to select the first embed like this and use [copy] if you want to change into it before sending again.(https://discordpy.readthedocs.io/en/latest/api.html?highlight=embed#discord.Embed.copy)

@bot.command()
async def fetch(ctx):
    channel = bot.get_channel(736984092368830468)
    msg = await channel.fetch_message(752779298439430164)
    await ctx.send(embed=msg.embeds[0])