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
相关产品推荐
相关产品推荐

