discord.py消息对象持久化存储求助:能否不依赖ID或内存保留
除了你提到的存储ID重新查找、保持内存常驻这两种方式,还有以下几种可行的实现思路:
利用Discord的Webhook持久化
如果消息是通过Webhook发送的,直接存储Webhook的URL和消息ID即可,后续通过Webhook API就能直接编辑消息,不需要依赖客户端内存对象。这种方式无需客户端在线,只要拥有合法的Webhook权限就能操作。序列化消息核心信息到CSV(而非完整对象)
完整的msg对象包含大量无法序列化的属性(比如客户端连接实例、异步上下文等),没法直接存入CSV。但你可以提取消息的核心可序列化字段:channel_id、message_id、guild_id(服务器内消息需此字段),将这些信息存入CSV。重启后,通过client.get_channel(channel_id)获取频道对象,再用channel.fetch_message(message_id)重新获取消息实例进行编辑,本质是ID查找的规范化实现。使用轻量级数据库替代CSV
CSV适合简单数据存储,但如果后续需要频繁查询、更新消息记录,改用SQLite这类轻量级数据库会更可靠。可以创建表存储消息ID、所属频道、创建时间等信息,重启后直接查询数据库获取所需ID,再执行编辑操作。这种方式比CSV更适合长期维护和复杂场景。利用Discord Bot的持久化存储插件
部分Discord Bot框架(比如discord.py的第三方扩展)提供内置持久化存储功能,能自动管理需要留存的消息信息,无需手动处理文件读写。不过这种方式依赖特定扩展,需根据你使用的框架选择。
代码示例(序列化核心字段到CSV)
修改你的代码,将必要信息存入CSV:
import csv import asyncio from discord import Client client = Client(intents=...) @client.event async def on_message(ctx): if ctx.author == client.user: return msg = await ctx.channel.send(content="hi") # 提取可序列化的核心信息 msg_data = { "channel_id": str(ctx.channel.id), "message_id": str(msg.id), "guild_id": str(ctx.guild.id) if ctx.guild else None } # 写入CSV with open("message_records.csv", "a", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["channel_id", "message_id", "guild_id"]) # 文件为空时写入表头 if f.tell() == 0: writer.writeheader() writer.writerow(msg_data) await asyncio.sleep(5) await msg.edit(content="HI") # 重启后编辑消息的示例函数 async def edit_saved_message(client, channel_id, message_id, new_content): channel = client.get_channel(int(channel_id)) if not channel: channel = await client.fetch_channel(int(channel_id)) msg = await channel.fetch_message(int(message_id)) await msg.edit(content=new_content)
注意事项
- 不要尝试序列化完整的
msg对象,它包含大量与运行时绑定的非序列化数据,存入文件也无法复用。 - 存储ID时建议转成字符串,避免CSV存储时出现数值精度丢失问题(Discord的ID是64位整数,部分工具处理时会出错)。
内容的提问来源于stack exchange,提问作者user19167602

