如何将Discord Bot警告系统数据保存至JSON文件避免重启丢失
嘿,作为经常折腾Discord Bot的开发者,我来给你一步步拆解这个需求,完全新手友好,跟着做就行!
核心思路
我们要做的就是:Bot启动时从warnLevel.json读取已有积分数据,每次警告后更新数据并写回文件,这样Bot离线重启后数据也不会丢。
第一步:准备基础文件
首先确保你的项目文件夹里有warnLevel.json文件,初始内容可以是空对象:
{}
这个文件会用来存储用户ID和对应的警告积分(用ID而不是用户名,因为用户名可能改,ID是唯一不变的)。
第二步:导入必要模块
我们需要Node.js的fs模块(用来读写文件)和Discord.js的核心模块。在你的Bot主文件开头加上:
const fs = require('fs'); const { Client, GatewayIntentBits, SlashCommandBuilder } = require('discord.js');
第三步:启动时加载已有警告数据
在Bot启动的代码里,先读取warnLevel.json的内容,存到一个全局变量里:
// 初始化警告积分对象 let warnLevels = {}; // 启动Bot时加载已保存的数据 try { // 读取文件内容 const savedData = fs.readFileSync('./warnLevel.json', 'utf8'); // 把JSON字符串转成JavaScript对象 warnLevels = JSON.parse(savedData); } catch (err) { // 如果文件不存在或者读取失败,就输出提示,warnLevels保持空对象 console.log('未找到警告数据文件,将创建新的记录'); }
第四步:定义警告原因对应的积分规则
把不同原因对应的积分做成一个对象,方便后续调用,以后要加新原因直接在这里加就行:
const warnPointRules = { Insults: 15, // 辱骂加15分 Spam: 20, // 刷屏加20分 // 可以在这里扩展更多,比如 Advertising: 30 之类的 };
第五步:编写/warn命令的完整逻辑
接下来是核心的命令处理部分,我们先注册slash命令,然后处理交互:
// 注册/warn slash命令(如果是第一次用slash命令,记得先部署命令哦) const warnCommand = new SlashCommandBuilder() .setName('warn') .setDescription('给用户添加警告积分') // 添加用户选项 .addUserOption(option => option.setName('user') .setDescription('要警告的用户') .setRequired(true)) // 添加警告原因选项(下拉选择,避免输入错误) .addStringOption(option => option.setName('reason') .setDescription('警告原因') .setRequired(true) .addChoices( { name: '辱骂', value: 'Insults' }, { name: '刷屏', value: 'Spam' } // 这里对应上面的warnPointRules,加新原因时同步添加选项 )); // 处理命令交互 client.on('interactionCreate', async interaction => { // 只处理slash命令 if (!interaction.isChatInputCommand()) return; if (interaction.commandName === 'warn') { // 获取命令参数:用户和原因 const targetUser = interaction.options.getUser('user'); const warnReason = interaction.options.getString('reason'); const userId = targetUser.id; // 用用户ID作为键,保证唯一 // 检查这个原因有没有对应的积分规则 if (!warnPointRules[warnReason]) { return interaction.reply(`⚠️ 不支持的警告原因:${warnReason}`); } // 更新用户的警告积分:如果用户没有记录,初始为0,再加对应积分 const addPoints = warnPointRules[warnReason]; warnLevels[userId] = (warnLevels[userId] || 0) + addPoints; const currentPoints = warnLevels[userId]; // 把更新后的积分写回JSON文件 try { // JSON.stringify的第三个参数是格式化缩进,让文件更易读 fs.writeFileSync('./warnLevel.json', JSON.stringify(warnLevels, null, 2)); } catch (err) { console.error('保存警告数据失败:', err); return interaction.reply('❌ 保存警告数据时出错了,请稍后再试'); } // 检查积分是否达到100,达到就踢人 if (currentPoints >= 100) { // 先检查Bot有没有踢人的权限 if (!interaction.guild.members.me.permissions.has('KICK_MEMBERS')) { return interaction.reply('⚠️ 我没有踢人的权限,请先给我配置权限!'); } // 执行踢人操作 await interaction.guild.members.kick(userId, `警告积分达到${currentPoints}分,原因:${warnReason}`); await interaction.reply(`✅ 已踢出用户 ${targetUser.tag},其警告积分已达${currentPoints}/100分`); } else { // 没到100分就提示当前积分 await interaction.reply(`⚠️ 已警告用户 ${targetUser.tag},原因:${warnReason},当前积分:${currentPoints}/100`); } } });
第六步:关键注意事项
- 权限配置:确保你的Bot在服务器里有
KICK_MEMBERS权限,不然踢人会失败 - 文件路径:如果你的
warnLevel.json不在主文件同目录,要修改fs.readFileSync和fs.writeFileSync里的路径 - Slash命令部署:如果是第一次用slash命令,记得先部署命令到服务器(可以用简单的部署脚本完成,新手也能快速上手)
- 错误处理:代码里加了try-catch来处理文件读写错误,避免Bot因为文件问题崩溃
内容的提问来源于stack exchange,提问作者Sappeur
相关产品推荐
相关产品推荐

