一个通过 Napcat WebSocket 接收消息、按“用户 × 关键词”计数,并在达到阈值时发送提醒(管理员私聊 + 指定群聊)的轻量脚本。支持持久化存储、管理员私聊配置与管理命令。
- 关键词计数:在指定群组中统计每位用户触发的关键词次数(精确子串匹配)。
- 阈值提醒(一次性):某关键词首次被任何人跨越阈值时触发提醒(管理员私聊 + 指定群聊)。后续不再重复提醒该词。
- 管理员私聊命令:查看、删除、批量新增阈值、单词添加、三种清空操作。
- 持久化存储:将计数、阈值、已触发标记写入本地 JSON 文件(原子写入)。
- 日志与重启保留:启动时加载历史数据,退出时保存。
/Users/…/napcat-keyword/
├── data/
│ └── counters.json # 持久化数据
├── index.js # 主程序
├── package.json
└── package-lock.json
- Node.js ≥ 16
- 依赖:ws
安装依赖:
npm install
启动:
npm start
推荐使用配置文件 config.json 进行集中配置,环境变量仍可覆盖配置文件(并有默认值作为回退)。
配置优先级:环境变量 > config.json > 默认值
示例 config.json:
{
"wsHost": "127.0.0.1",
"wsPort": 3001,
"wsToken": "PCedy>,a_c|nMLFp",
"targetGroupId": 496434599,
"keywords": ["白月光"],
"httpHost": "127.0.0.1",
"httpPort": 3000,
"httpToken": "_qKBVOK@Xs{0y#I}",
"adminUserId": 228676723,
"dataDir": "data",
"storageFile": "data/counters.json"
}你也可以通过环境变量临时覆盖其中任意字段,例如:
- WS_HOST、WS_PORT、WS_TOKEN
- TARGET_GROUP_ID、KEYWORDS(逗号分隔)
- HTTP_HOST、HTTP_PORT、HTTP_TOKEN
- ADMIN_USER_ID
- DATA_DIR、STORAGE_FILE
如果需要使用自定义配置文件路径,设置环境变量 CONFIG_FILE 指向该文件。
- 仅处理来自 TARGET_GROUP_ID 的群聊消息用于计数。
- 管理员的私聊消息优先处理命令,不参与计数。
- 达到阈值后会同时向管理员私聊和目标群聊发送提醒文本。
单行与多行均支持,示例以中文命令为准:
-
查看:
- 发送 “查看”,返回“带序号”的关键词列表(包含阈值与已触发标记)。
-
删除第 n 个关键词:
- 发送 “-n”,例如 “-2” 表示删除列表中的第 2 个关键词。
- 删除后会同步清理各用户该词的计数与总计,并返回更新后的列表。
-
添加新关键词(单行):
- 发送单行非命令文本,即添加为新关键词。
- 若该词已存在则提示不重复添加,并返回当前列表。
-
批量新增关键词与阈值(偶数行):
- 每两行一组:第一行是关键词,第二行是正整数阈值。
- 行数必须为偶数;已存在的关键词不会覆盖阈值,会提示并跳过。
-
清空命令(新增三种):
- 全部清空:删除持久化文件并清空内存状态(counters、thresholds、triggeredKeywords)。
- 清空已触发:仅清空 triggeredKeywords,保留计数与阈值。
- 清空计数:清空所有人的计数(total/per 置零),并清空 triggeredKeywords;thresholds 保留不变。
- 旧命令 “清空” 会提示使用以上三种新命令。
- 阈值按“关键词”维度设置,例如 “魔法” => 3。
- 某用户对该词的计数从未达到阈值到跨越阈值的时刻触发提醒。
- 同一个关键词的提醒仅触发一次(全局),由 triggeredKeywords 记录。
- 触发后会:
- 向管理员发送私聊文本:用户 X 的关键词「Y」累计达到 N,已触发阈值 T。
- 向目标群发送同样的文本提醒。
文件:data/counters.json
示例:
{
"counters": {
"228676723": { "total": 1, "per": { "魔法": 1 } },
"1811434818": { "total": 1, "per": { "魔法": 1 } }
},
"thresholds": { "魔法": 1 },
"triggeredKeywords": { "魔法": true }
}- counters:每个用户的总计与每词计数。
- thresholds:每个关键词的阈值。
- triggeredKeywords:记录哪些关键词已触发过提醒(防止重复提醒)。
- KEYWORDS:仅在内存中维护;启动时会将 thresholds 中存在的词并入 KEYWORDS。
- 私聊:
POST /send_private_msg?access_token=TOKEN- Body:
{"user_id":"QQ","message":[{"type":"text","data":{"text":"..."}}]}
- Body:
- 群聊:
POST /send_group_msg?access_token=TOKEN- Body:
{"group_id":"QQ群","message":[{"type":"text","data":{"text":"..."}}]}
- Body:
- Header:
Content-Type: application/json
- 日志包含:加载/保存、计数更新、提醒发送、WS 连接状态等。
- 退出(SIGINT)时会打印最终计数并进行同步保存。
- 不在日志中打印令牌;请妥善保管 WS_TOKEN 与 HTTP_TOKEN。
- 仅统计 TARGET_GROUP_ID 的群消息,避免误统计其它群。
- 关键词匹配为精确子串匹配;如需最长匹配或词边界,可在后续改进。
- counters.json 不存在:首次运行会创建;“全部清空”会删除该文件,下次保存会重新生成。
- 阈值不触发:需满足“从未达到到跨越阈值”的条件;触发一次后同词不再提醒,除非通过“清空已触发/清空计数”重置。
- 已有关键词批量设置阈值:不会覆盖,需先删除或通过新增逻辑调整。
本项目用于学习与实践,可自由使用与修改。