You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py嵌入消息图片编辑:按钮回调edit_message参数报错求助

问题解决:Discord.py按钮更新嵌入消息中的图片

核心问题原因

interaction.response.edit_message()方法不支持传入file或files参数,它仅用于修改消息的文本、嵌入、视图等内容,无法附加新的文件附件。要更新嵌入中的图片,需要通过直接编辑原消息对象的方式实现。

修正后的代码实现

修改按钮回调函数的逻辑,先响应交互避免超时,再通过interaction.message.edit()更新消息(该方法支持files参数):

@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):
        # 创建黑色背景的图片
        wide = 300
        tall = int(wide / 5)
        image = Image.new("RGB", (wide, tall), (0, 0, 0))
        draw = ImageDraw.Draw(image)

        # 绘制颜色方块
        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

        # 保存图片到内存
        image_data = BytesIO()
        image.save(image_data, "PNG")
        image_data.seek(0)
        return image_data

    # 抽离嵌入创建逻辑,避免重复代码
    def create_palette_embed():
        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")
        return embed

    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 = create_palette_embed()

    button = discord.ui.Button(label="Generate again", style=discord.ButtonStyle.gray)
    view = discord.ui.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),
                ephemeral=True  # 发送临时消息,仅触发按钮的用户可见
            )

        image = await create_image(colors)
        file = discord.File(image, "color_palette.png")
        embed = create_palette_embed()

        # 先响应交互,防止Discord判定超时
        await interaction.response.defer()
        # 编辑原消息,传入新文件、嵌入和视图
        await interaction.message.edit(files=[file], embed=embed, view=view)

    button.callback = button_callback

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

相关技巧与注意事项

  • 交互响应规范:按钮回调必须在3秒内响应Discord的交互请求,使用await interaction.response.defer()可以延长处理时间,避免超时错误。
  • 代码复用:将重复的嵌入创建、图片生成逻辑抽离成单独函数,减少冗余代码,提升维护性。
  • 文件参数要求:message.edit()使用复数形式的files参数,传入文件对象列表,而非单个file参数。
  • 临时错误提示:错误消息使用ephemeral=True发送,仅触发按钮的用户可见,避免污染频道。
  • 视图复用:如果需要保持按钮可用,编辑消息时要重新传入视图对象(或复用原视图),否则按钮会失效。
  • 文件对象管理:每次生成图片后,确保BytesIO对象执行seek(0),将文件指针重置到开头,否则Discord无法读取完整的图片数据。

内容的提问来源于stack exchange,提问作者Imaginary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 15:25:23