Discord.js中使用quick.db为各服务器创建ID黑名单数组
Discord机器人分服务器本地成员黑名单实现方案
现有quick.db代码失效原因
quick.db的push方法仅能对已存在且类型为数组的键生效,你当前的代码没有做数组初始化判断:第一次调用时对应服务器的黑名单键不存在,直接调用push不会自动创建数组结构,只会存入单个值,后续再调用就会因为值类型不是数组无法追加内容。
quick.db方案修复代码
补全数组初始化、重复值校验逻辑即可正常按服务器存储黑名单数组:
const db = require("quick.db") module.exports.run = async (discord, bot, message, args, p) => { const blacklistKey = `black_${message.guild.id}` // 键不存在或值不是数组时,先初始化为空数组 if (!db.has(blacklistKey) || !Array.isArray(db.get(blacklistKey))) { db.set(blacklistKey, []) } const targetUserId = args[0] const currentBlacklist = db.get(blacklistKey) // 避免重复添加同个用户ID if (!currentBlacklist.includes(targetUserId)) { db.push(blacklistKey, targetUserId) } const finalBlacklist = db.get(blacklistKey) message.channel.send(`当前服务器黑名单:${finalBlacklist.join(', ')}`) } module.exports.help = { name: 'black', aliases: [''], description: '添加用户到当前服务器黑名单' }
其他可替代的分服务器存储方案
- 独立JSON文件存储
无需依赖第三方数据库包,直接以服务器ID为名单独生成JSON文件存储对应黑名单数组,逻辑透明无隐式类型转换问题,适合小规模机器人使用。核心实现代码:const fs = require('fs/promises') const path = require('path') // 存放所有服务器黑名单文件的目录 const BLACKLIST_STORE_PATH = path.join(__dirname, 'server_blacklists') // 启动时自动创建存储目录 fs.mkdir(BLACKLIST_STORE_PATH, { recursive: true }).catch(console.error) module.exports.run = async (discord, bot, message, args, p) => { const serverBlPath = path.join(BLACKLIST_STORE_PATH, `${message.guild.id}.json`) let blacklist = [] try { const rawContent = await fs.readFile(serverBlPath, 'utf8') blacklist = JSON.parse(rawContent) } catch (err) { // 文件不存在时默认使用空数组 blacklist = [] } const targetUserId = args[0] if (!blacklist.includes(targetUserId)) blacklist.push(targetUserId) await fs.writeFile(serverBlPath, JSON.stringify(blacklist, null, 2)) message.channel.send(`当前服务器黑名单:${blacklist.join(', ')}`) } - 结构化SQLite本地存储
如果后续需要扩展黑名单字段(比如封禁原因、操作人、封禁时间、到期时间),可以使用better-sqlite3操作本地SQLite数据库,建一张带guild_id、user_id、reason、created_at字段的黑名单表,查询时按当前服务器ID筛选即可,数据一致性比键值存储更稳定,适合功能复杂度高的中大型机器人。 - 内存缓存+定期落盘
如果对读写响应速度要求高,且可以接受极端情况下少量数据丢失,可以在内存中维护一个以服务器ID为键、对应用户ID数组为值的Map结构,运行时直接操作内存数组,每隔固定时间将Map内容序列化写入本地文件备份,读写效率远高于频繁读写磁盘的方案。
实现注意点:所有方案都需要做重复值校验,避免同个用户被重复加入黑名单;移除黑名单时直接对数组做过滤,删除目标用户ID后重新存储即可。
内容的提问来源于stack exchange,提问作者user18632107
相关产品推荐
相关产品推荐

