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

discord.py离线/重启后,如何监听历史消息的on_message_edit事件?

问题解答

核心结论

discord.py 默认不会对机器人加入服务器前或离线期间发送的消息编辑触发on_message_edit,因为该事件依赖本地缓存中存储的消息原始副本做对比,而历史消息默认不会被加载到缓存中,且fetch_message()确实不会自动将消息存入内部缓存。

解决方案

1. 手动将目标消息加入缓存

机器人启动时,主动拉取需要监控的历史消息并手动添加到缓存,让后续的on_message_edit能正常触发:

async def preload_target_messages(guild_id, channel_id, target_msg_ids):
    guild = client.get_guild(guild_id)
    channel = guild.get_channel(channel_id)
    
    for msg_id in target_msg_ids:
        try:
            msg = await channel.fetch_message(msg_id)
            # 将消息手动加入缓存(discord.py v2.x 写法)
            client.cache.messages.add(msg)
        except discord.NotFound:
            print(f"消息 {msg_id} 不存在或无法获取")

# 在机器人就绪时执行缓存预加载
@client.event
async def on_ready():
    # 替换为你的服务器ID、频道ID和需要监控的消息ID列表
    await preload_target_messages(123456789, 987654321, [111222333, 444555666])
  • 注意:discord.py v1.x 的缓存写法为client.messages.add(msg),请根据实际版本调整。

2. 使用不依赖缓存的原始事件监听

直接使用on_raw_message_edit事件,它会接收Discord推送的所有消息编辑原始载荷,完全不依赖本地缓存,适合处理历史消息的编辑:

@client.event
async def on_raw_message_edit(payload):
    # 从载荷中获取基础信息
    channel_id = payload.channel_id
    msg_id = payload.message_id
    
    channel = client.get_channel(channel_id)
    if not channel:
        return
    
    try:
        # 获取编辑后的完整消息
        new_msg = await channel.fetch_message(msg_id)
        # 从载荷中提取编辑前的旧数据(仅保留最近一次编辑记录)
        old_embed_data = payload.data.get('embeds')
        
        # 处理Embed更新逻辑
        if new_msg.embeds:
            current_embed = new_msg.embeds[0]
            print(f"消息 {msg_id} 的Embed已更新:{current_embed.title}")
            
            # 如果需要对比旧Embed内容
            if old_embed_data:
                old_embed = discord.Embed.from_dict(old_embed_data[0])
                print(f"编辑前的Embed标题:{old_embed.title}")
                
    except discord.NotFound:
        print(f"无法获取消息 {msg_id}")
  • 优势:无需提前缓存消息,能监听所有消息的编辑事件,包括机器人离线期间发生的编辑。
  • 限制:Discord API仅保留最近一次的编辑记录,无法获取更早的历史版本;若需要完整的编辑轨迹,需自行在首次获取消息时保存初始状态,后续对比自己存储的版本。

3. 针对特定Embed消息的优化

如果仅需监控固定的Embed消息,可将这些消息的ID存储在配置文件或数据库中:

  • 机器人启动时批量拉取并保存初始Embed状态
  • 结合on_raw_message_edit监听后续编辑,对比本地保存的初始状态获取更新数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:12:36