Home > OS >  How to edit images in embeds (discord.py)
How to edit images in embeds (discord.py)

Time:02-05

I have a command that generates a random color palette and it works pretty well. Then I wanted to add a button to it, a button that'd generate a new palette. I added the button, wrote a callback, but the callback just won't work, because the interaction.response.edit_messsage() shows an error:

TypeError: edit_message() got an unexpected keyword argument 'file'

I know what that means, I cannot have a file=file line there, but if I don't no image is sent in the embed... Embeds just need that to work properly (assuming that you're generating an image from scratch, it's simpler if you provide a link).

I have no clue what I could do to get the desired functionality now. Previously I'd create images, send them in a secret channel, get those images' links and use them in the embed. It worked then, but it was painfully slow.

Here's the code that I currently have:

@bot.tree.command(name="palette", description="Generates a random color palette")
async def palette(interaction: discord.Interaction):
    async def get_color_palette():
        try:
            response = requests.post("http://colormind.io/api/", json={"model": "default"}).json()
            colors = response["result"]
            colors = [tuple(x) for x in colors]
        except requests.exceptions.RequestException as e:
            return None, f"An error occurred while getting the color palette: {e}"

        return colors, None

    async def create_image(colors):
        # create an image with a black background
        wide = 300
        tall = int(wide / 5)
        image = Image.new("RGB", (wide, tall), (0, 0, 0))
        draw = ImageDraw.Draw(image)

        # draw squares with those colors
        x, y = 0, 0
        width, height = wide / 5, tall
        for color in colors:
            draw.rectangle((x, y, x   width, y   height), fill=color)
            x  = width

        # save the image
        image_data = BytesIO()
        image.save(image_data, "PNG")
        image_data.seek(0)
        return image_data

    colors, error = await get_color_palette()

    if error:
        return await interaction.response.send_message(embed=discord.Embed(description=error))

    image = await create_image(colors)
    file = discord.File(image, "color_palette.png")
    embed = discord.Embed()
    embed.set_author(
        name="Here's your random color palette:",
        icon_url="https://media.discordapp.net/attachments/1060711805028155453/1061825040716402731/logo_beter.png")
    embed.set_image(
        url="attachment://color_palette.png")
    embed.set_footer(
        text="Generated with colormind.io")

    button = discord.ui.Button(label="Generate again", style=discord.ButtonStyle.gray)
    view = View()
    view.add_item(button)

    async def button_callback(interaction):
        colors, error = await get_color_palette()

        if error:
            return await interaction.response.send_message(embed=discord.Embed(description=error))

        image = await create_image(colors)
        file = discord.File(image, "color_palette.png")
        embed = discord.Embed()
        embed.set_author(
            name="Here's your random color palette:",
            icon_url="https://media.discordapp.net/attachments/1060711805028155453/1061825040716402731/logo_beter.png")
        embed.set_image(
            url="attachment://color_palette.png")
        embed.set_footer(
            text="Generated with colormind.io")

        await interaction.response.edit_message(file=file, embed=embed, view=view)

    button.callback = button_callback

    await interaction.response.send_message(file=file, embed=embed, view=view)

How can I achieve that? Any tips for the future?

CodePudding user response:

That first comment is not true; you can attach the image you wanted to edit with the attachments argument of the Example

  • Related