如何解决Discord.py机器人离线或重启后Embed字段丢失的问题
How to Permanently Save Embed Fields in Discord.py Bot
嗨,这个问题我之前也碰到过!核心原因是你现在的cne Embed对象只存在机器人的内存里,一旦机器人重启或者离线,内存里的东西就全清了。要实现永久保存,得把这些字段数据存到硬盘上的持久化存储里,比如JSON文件或者数据库,下面给你两种实用的方案:
方案1:用JSON文件存储(简单易上手)
JSON文件是最轻量化的持久化方式,适合数据量不大的场景。思路是每次添加字段时把信息写入JSON文件,机器人启动时再从文件读取数据重建Embed字段。
修改后的代码示例
import discord from discord.ext import commands import json import os # 定义存储字段的JSON文件路径 FIELD_STORAGE = "cs_notes_fields.json" # 初始化Embed cne = discord.Embed(title="Computer Science - Notes") def load_saved_fields(): """从JSON文件加载已保存的字段数据""" if os.path.exists(FIELD_STORAGE): with open(FIELD_STORAGE, "r", encoding="utf-8") as f: return json.load(f) return [] # 机器人启动时,加载保存的字段并添加到Embed saved_fields = load_saved_fields() for field in saved_fields: cne.add_field(name=field["title"], value=f"[Click here]({field['link']})", inline=False) @commands.slash_command(description="Add a file to collection.") async def add(self, ctx, subject, collection, title, link): global cne if subject == "Computer Science" and collection == "Notes": # 先把字段添加到当前Embed cne.add_field(name=title, value=f"[Click here]({link})", inline=False) # 再把字段信息保存到JSON文件 current_fields = load_saved_fields() current_fields.append({"title": title, "link": link}) with open(FIELD_STORAGE, "w", encoding="utf-8") as f: json.dump(current_fields, f, indent=4) await ctx.respond("Successfully added the note to the collection!")
方案2:用SQLite数据库(适合大数据量)
如果你的机器人需要管理大量字段,或者需要后续对字段进行查询、修改、删除操作,用数据库会更灵活。SQLite是Python自带的轻量数据库,不用额外安装服务。
修改后的代码示例
import discord from discord.ext import commands import sqlite3 # 初始化数据库连接 conn = sqlite3.connect("bot_persistent_data.db") cursor = conn.cursor() # 创建存储字段的表(第一次运行自动创建) cursor.execute('''CREATE TABLE IF NOT EXISTS cs_notes (title TEXT NOT NULL, link TEXT NOT NULL)''') conn.commit() # 初始化Embed cne = discord.Embed(title="Computer Science - Notes") def load_fields_from_db(): """从数据库加载已保存的字段""" cursor.execute("SELECT title, link FROM cs_notes") return cursor.fetchall() # 机器人启动时加载字段 for title, link in load_fields_from_db(): cne.add_field(name=title, value=f"[Click here]({link})", inline=False) @commands.slash_command(description="Add a file to collection.") async def add(self, ctx, subject, collection, title, link): global cne if subject == "Computer Science" and collection == "Notes": cne.add_field(name=title, value=f"[Click here]({link})", inline=False) # 将字段插入数据库 cursor.execute("INSERT INTO cs_notes VALUES (?, ?)", (title, link)) conn.commit() await ctx.respond("Successfully added the note to the collection!")
注意事项
- 如果你用JSON方案,要确保机器人有读写当前目录的权限
- 数据库方案记得在机器人关闭时调用
conn.close(),避免数据损坏
内容的提问来源于stack exchange,提问作者star
相关产品推荐
相关产品推荐

