如何在discord.js中无需数据库实现各Guild自定义关键词告警?
无需数据库实现Discord服务器独立关键词告警
完全可以不用数据库实现各服务器(Guild)独立设置关键词的功能,核心思路是用本地文件持久化存储各服务器的配置,结合机器人内存缓存提升效率,以下是具体实现方案:
核心方案思路
通过「内存字典缓存+本地JSON/YAML文件持久化」的方式,将每个服务器的关键词列表以服务器ID为键存储,机器人启动时加载文件数据到内存,修改配置时同步写入文件,避免数据库依赖。
具体实现步骤(以discord.py为例)
1. 初始化存储结构
- 定义本地存储文件(如
guild_keywords.json),用于持久化各服务器的关键词数据 - 内存中维护一个字典,键为服务器ID(整数),值为该服务器的关键词列表
2. 机器人启动加载数据
启动时读取本地文件,将数据加载到内存字典;若文件不存在则初始化空字典。
3. 实现关键词管理命令
给服务器管理员提供添加/删除关键词的命令,操作后立即将内存数据同步到本地文件。
4. 消息监听与告警触发
监听所有消息,根据消息所在服务器ID匹配对应的关键词列表,检测到匹配项时发送告警。
代码示例
import json from discord.ext import commands from discord import Intents # 初始化机器人,需要开启消息内容意图 intents = Intents.default() intents.message_content = True bot = commands.Bot(command_prefix='/', intents=intents) # 本地存储文件路径 GUILD_KEYWORDS_FILE = "guild_keywords.json" # 内存缓存的服务器关键词字典 guild_keywords = {} # 启动时加载本地数据 @bot.event async def on_ready(): global guild_keywords try: with open(GUILD_KEYWORDS_FILE, 'r', encoding='utf-8') as f: # JSON键只能是字符串,转成整数类型的服务器ID raw_data = json.load(f) guild_keywords = {int(gid): kw_list for gid, kw_list in raw_data.items()} except FileNotFoundError: guild_keywords = {} print(f"Bot在线,已加载{len(guild_keywords)}个服务器的关键词配置") # 保存内存数据到本地文件的工具函数 def save_keywords(): # 把整数ID转回字符串存入JSON json_data = {str(gid): kw_list for gid, kw_list in guild_keywords.items()} with open(GUILD_KEYWORDS_FILE, 'w', encoding='utf-8') as f: json.dump(json_data, f, indent=2) # 关键词管理命令(仅服务器管理员可操作) @bot.command(name="keyword") @commands.has_permissions(manage_guild=True) async def manage_keyword(ctx, action: str, keyword: str): guild_id = ctx.guild.id # 初始化当前服务器的关键词列表(若不存在) if guild_id not in guild_keywords: guild_keywords[guild_id] = [] if action.lower() == "add": if keyword not in guild_keywords[guild_id]: guild_keywords[guild_id].append(keyword) save_keywords() await ctx.send(f"✅ 成功添加关键词:`{keyword}`") else: await ctx.send(f"❌ 关键词`{keyword}`已存在") elif action.lower() == "remove": if keyword in guild_keywords[guild_id]: guild_keywords[guild_id].remove(keyword) save_keywords() await ctx.send(f"✅ 成功移除关键词:`{keyword}`") else: await ctx.send(f"❌ 关键词`{keyword}`不存在") else: await ctx.send("⚠️ 无效操作,请使用 `add` 或 `remove`") # 消息监听与告警触发 @bot.event async def on_message(message): # 忽略机器人自身消息 if message.author.bot: return guild_id = message.guild.id # 当前服务器无关键词配置则跳过 if guild_id not in guild_keywords or not guild_keywords[guild_id]: await bot.process_commands(message) return # 检查消息是否包含关键词(忽略大小写) content = message.content.lower() for kw in guild_keywords[guild_id]: if kw.lower() in content: # 发送告警到当前频道(可修改为指定告警频道) await message.channel.send( f"⚠️ 检测到触发关键词:`{kw}`\n" f"发送者:{message.author.mention}\n" f"消息内容:{message.content}" ) break # 必须调用此方法才能让命令正常工作 await bot.process_commands(message) # 替换为你的机器人Token bot.run("YOUR_BOT_TOKEN")
方案优缺点
- 优点:无需数据库,实现成本低,适合小型机器人;数据存储在本地,访问速度快;配置修改实时同步。
- 缺点:仅支持单实例机器人(分布式部署需额外处理文件同步);本地文件损坏可能导致数据丢失(可定期备份文件解决)。
内容的提问来源于stack exchange,提问作者badwolf
相关产品推荐
相关产品推荐

