cat339
cat339

Reputation: 27

Is it possible to change the sent file in discord python?

I need to change embed with local file (photo) from my machine. To send embed, you need to send the file along with it, but it cannot be changed. When i try to do this:

My Code:

embed = discord.Embed(title = "Title here", description = "",
                              timestamp = datetime.utcnow(),
                              color = 0x26ad00)

file = discord.File(f"images/{msg.id}.png")
embed.set_image(url = f"attachment://{msg.id}.png")
await msg.edit(file = file, embed = embed)

I get the following error:

TypeError: Object of type File is not JSON serializable

There is no such error when using a link from the internet directly (without file from link). I think I need to upload my photos to the internet with a photo API or something else but it is very slow, is there a solution to this problem?

Upvotes: 2

Views: 2389

Answers (5)

RDMCz
RDMCz

Reputation: 1

discord.Message.edit does not accept the file parameter, but you can use the attachments parameter. Parameter is set to a list of files/attachments, that the edited message will have:

embed = discord.Embed(title="Title here", description="",
                              timestamp=datetime.utcnow(),
                              color=0x26ad00)

file = discord.File(f"images/{msg.id}.png")
embed.set_image(url=f"attachment://{msg.id}.png")
await msg.edit(embed=embed, attachments=[file])

If you use slash commands, you can do the same thing with discord.Interaction.edit_original_response or discord.InteractionResponse.edit_message

Upvotes: 0

Honza Javorek
Honza Javorek

Reputation: 8816

Per documentation, you need to clear the existing attachments:

await message.edit(
    files=[File('blah/blah/smurfs-having-a-party.jpg')],
    attachments=[],
)

(The code is py-cord, I hope it's the same in discord.py)

Docs:

Upvotes: 1

Leo Aqua
Leo Aqua

Reputation: 26

Guys i found the solution!

message = await message.channel.send('Live') 
while True:
    mss().shot(output="foo.png") #mss is used to make a screenshot but the basic concept is you have to update the image file but keep the filename
    await message.add_files(discord.File(fp="foo.png"))
    

If this doesn't work make sure you have intents.message_content enabled

Upvotes: 0

OrnarasUS
OrnarasUS

Reputation: 1

async def edit_attachments(message: discord.Message, files: File):
    await message.remove_attachments(message.attachments)
    await message.add_files(files)

Upvotes: 0

Lukas Thaler
Lukas Thaler

Reputation: 2720

You cannot change the attachments to a message after it has been sent. Discord simply doesn't allow it. If you check the discord.py documentation for discord.Message.edit, you'll see that the file parameter is not accepted. Your error is caused by discord.py trying to convert the file to a JSON to be sent with the API request


That said, there is a workaround to change the image. As you noted, the URL you provide to discord.Embed.set_image does not have to point to an attachment - it can point to any image that can be accessed by Discord. If you were to send a message containing the new image somewhere (say in a secret channel only you and your bot have access to), you could then use the URL for that attachment in your edit somewhat like this:

# you need to define secret_channel before this (example below)
secret_channel = bot.get_channel(12345)  # where 12345 would be your secret channel id
file = discord.File(f"images/{msg.id}.png")
temp_message = await secret_channel.send(file = file)
attachment = temp_message.attachments[0]

embed = discord.Embed(title = "Title here", description = "",
                      timestamp = datetime.utcnow(),
                      color = 0x26ad00)
embed.set_image(url = attachment.url)
await msg.edit(embed = embed)

Upvotes: 2

Related Questions