如何通过Discord机器人从旧消息/命令提取内容,实现建议嵌入的编辑与反应统计
解决Discord.py嵌入消息编辑中的重复内容与反应统计问题
你目前遇到了两个核心问题:approve命令里建议内容重复显示,以及需要准确统计原消息的✅/❌反应数并迁移旧嵌入内容到新嵌入中。我来帮你一步步解决这些问题:
问题1:建议内容重复的根源
你当前的approve命令直接复用了原嵌入对象(embed = msg.embeds[0]),但原嵌入本身已经包含了提交者信息(在description里)和建议内容(第一个field)。之后你又通过add_field重复添加了这两项内容,自然会导致显示重复。正确的做法是创建一个全新的嵌入对象,完全脱离原嵌入的旧字段。
问题2:精准统计指定反应的数量
你之前的代码统计了所有反应的总数,但我们需要分别提取✅和❌的用户投票数。可以通过遍历消息的reactions,匹配对应的emoji来获取各自的count,还要注意减去机器人自身添加的反应(避免统计无效数据)。
修正后的完整Approve命令
@commands.command() async def approve(self, ctx, channel: discord.TextChannel, msgID: int): try: # 获取目标消息 msg = await channel.fetch_message(msgID) # 提取原嵌入的内容 original_embed = msg.embeds[0] # 1. 提取提交者信息:处理原description,去掉前缀只保留用户 # 原description格式是 "**__submitter:__**\n {用户}" submitter_info = original_embed.description.split('\n')[1].strip() # 进阶方案:从原footer提取UID,即使用户改名也能准确获取用户对象 # submitter_id = int(original_embed.footer.text.split(': ')[1]) # submitter = self.bot.get_user(submitter_id) or submitter_info # 2. 提取建议内容 suggestion_content = original_embed.fields[0].value # 3. 统计✅和❌的有效投票数(减去机器人自身的反应) upvote_num = 0 downvote_num = 0 for reaction in msg.reactions: emoji_str = str(reaction.emoji) if emoji_str == "✅": upvote_num = reaction.count - 1 # 减去机器人的初始反应 elif emoji_str == "❌": downvote_num = reaction.count - 1 # 4. 创建全新的嵌入,彻底避免旧字段残留 new_embed = discord.Embed(title="Suggestion accepted", color=discord.Colour.green()) new_embed.description = "*Here are all the important information*" # 添加投票结果字段 new_embed.add_field(name="Results", value=f"✅: {upvote_num} / ❌: {downvote_num}", inline=False) # 添加建议内容 new_embed.add_field(name="Suggestion", value=suggestion_content, inline=False) # 添加提交者信息 new_embed.add_field(name="Submitter", value=submitter_info, inline=False) # 添加审批人信息 new_embed.add_field(name="Approved by", value=ctx.author.mention, inline=False) # 可选:保留原建议的提交时间戳 new_embed.timestamp = original_embed.timestamp # 替换原消息的嵌入,并清除旧反应 await msg.edit(embed=new_embed) await msg.clear_reactions() # 给审批人发送成功反馈(仅自己可见) await ctx.send(f"Successfully approved suggestion #{msgID}!", ephemeral=True) except Exception as e: # 捕获错误并反馈,方便调试 await ctx.send(f"Failed to approve suggestion: {str(e)}", ephemeral=True)
关键修改点说明
- 全新嵌入对象:不再复用原嵌入,从头构建新的
discord.Embed,彻底避免旧字段的重复显示。 - 精准提取提交者:通过
split('\n')拆分原description,只保留用户信息部分;进阶方案通过原footer的UID获取用户对象,即使用户改名也能准确显示。 - 反应数优化:分别匹配✅和❌,并减去1(排除机器人自身添加的初始反应),得到真实的用户投票数。
- 错误处理升级:替换原本的
pass为具体的错误反馈,方便你快速定位问题。
对Suggest命令的小优化(可选)
你的suggest命令里字符串格式化有个多余空格(f "**__submitter:__**"),虽然不影响功能,但可以修正为f"**__submitter:__**\n {ctx.author}",保持代码规范。
内容的提问来源于stack exchange,提问作者Dominik
相关产品推荐
相关产品推荐

