Discord.js中实现JSON文件持续追加存储用户消息数据的问题求助
解决JSON文件追加存储的问题
嘿,我来帮你搞定这个数据追加的问题!你当前代码的核心问题是每次用fs.writeFile直接覆盖了整个文件,而且全局的obj数组每次重启或者新消息过来时都是空的,根本没从已有的JSON文件里读取之前的数据。咱们一步步改:
先说说原来代码里的几个小坑
now变量是在全局定义的,所有消息的时间都会是机器人启动的时间,不是消息实际发送的时间,得移到消息事件里。message.channel.messages.channel.lastMessage.cleanContent这行写错了,直接用message.cleanContent就行,因为message就是当前触发事件的消息对象。- 每次处理违规消息时,没有读取已有的JSON数据,直接往空数组里加新内容再写回去,自然就覆盖了之前的记录。
修改后的完整代码
const fs = require("fs").promises; // 用promise版的fs,异步操作更顺手 const { Client, Intents } = require("discord.js"); const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); const { badWords } = require("../badWordList.json"); client.on("message", async (message) => { if (message.author.bot) return; // 忽略机器人消息 // 检查消息是否包含违规词 const hasBadWord = badWords.some(word => message.content.toLowerCase().includes(word.toLowerCase()) ); if (!hasBadWord) return; // 没有违规词就直接返回 // 这里才获取消息发送的时间,每次消息都用当前时间 const now = new Date(); const newRecord = { name: message.author.username, date: `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`, // 注意月份是从0开始的,要加1 message: message.cleanContent }; try { // 先读取已有的JSON文件,如果不存在就初始化空数组 let existingData = []; try { const fileContent = await fs.readFile("myjsonfile.json", "utf8"); existingData = JSON.parse(fileContent).table || []; // 兼容原来的结构,取table数组 } catch (readErr) { // 如果文件不存在或者读取失败,就用空数组 if (readErr.code !== "ENOENT") { console.error("读取JSON文件出错:", readErr); } } // 把新记录追加到数组里 existingData.push(newRecord); // 写回文件,注意保持原来的结构(table字段包裹数组) await fs.writeFile("myjsonfile.json", JSON.stringify({ table: existingData }, null, 2)); console.log("违规消息已追加到文件"); } catch (writeErr) { console.error("写入JSON文件出错:", writeErr); } });
关键改动说明
- 使用Promise版的fs:
fs.promises让异步操作可以用async/await,比回调函数更清晰,避免嵌套地狱。 - 读取现有数据:每次处理违规消息时,先尝试读取已有的
myjsonfile.json,如果文件不存在(第一次运行)就初始化空数组。 - 修正时间和消息内容:把
now移到消息事件内部,确保每个消息的时间都是发送时的;修正了获取消息内容的错误写法。 - 优雅的错误处理:用try-catch包裹读写操作,既处理文件不存在的情况,也能捕获其他读写错误,不会轻易崩溃。
- 格式化JSON输出:
JSON.stringify的第三个参数2让生成的JSON文件有缩进,更易读。
这样修改后,每次有违规消息时,都会把新记录追加到已有的JSON数组里,再也不会覆盖原有数据啦!
内容的提问来源于stack exchange,提问作者fardin
相关产品推荐
相关产品推荐

