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

如何将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:02:40