koishi-plugin-ydc
v0.0.23
Published
大餐bot
Readme
koishi-plugin-ydc
记录群友「大餐」瞬间,支持审核、去重、随机推荐(吃什么)、罪证回放(个人大餐记录),以及每周/每月「大餐王」统计。
适用于 Koishi v4(>= 4.17.9),需要启用数据库服务;图片处理依赖 sharp。
特色功能
- 智能去重:基于图片 URL、用户 ID 和文件名的三重去重机制
- 待审核机制:防止误报和恶意上报,管理员审核后入库
- 批量审核:支持单个 ID、多个 ID 以及范围表达式(如
114-514)批量通过/拒绝 - 灰度处理:当用户已退群时,「吃什么」命令会将其大餐图片转为灰度显示
- 小图模式:可选的 200px 缩略图回复,减少刷屏
- @机器人触发:支持通过
@机器人 命令的方式调用所有命令 - 锁机制保护:防止并发操作导致的数据异常
核心功能
| 功能 | 命令 | 说明 |
|------|------|------|
| 上报大餐 | ydc [@用户] | 引用包含图片的消息,记录大餐(需审核) |
| 随机推荐 | csm | 从当前群历史大餐中随机返回一张 |
| 罪证回放 | dccr @用户 [-nr] | 查看指定用户的大餐记录(默认随机,-nr 为最新) |
| 大餐王 | dcw [--new] | 查看周王/月王统计(--new 生成新统计) |
| 数据统计 | dcstatistics / dcstat | 显示已入库和待审核的记录总数 |
| 待审核列表 | review [-n 数量] | 查看待审核记录(默认 10 条)⚡ |
| 通过审核 | accept [id...] / ac | 通过待审核(支持范围如 114-514)⚡ |
| 拒绝审核 | deny [id...] / dn | 拒绝待审核 ⚡ |
⚡ 需要 master 或 readers 权限
安装
在 Koishi 插件市场搜索并安装「koishi-plugin-ydc」。或使用包管理器安装:
npm i koishi-plugin-ydc sharp
# 或者使用 pnpm / yarn注意:sharp 为 peer 依赖,Linux 环境若安装失败,请确保具备构建依赖或系统库。详见「常见问题」。
配置项
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| master | string | "" | 主人账号 ID,拥有所有权限 |
| self | string | "" | 机器人账号 ID,用于解析 @机器人 触发的命令 |
| readers | string[] | [] | 其他审核人账号 ID 列表,可执行审核相关命令 |
| dataDir | string | "ydc_files" | 本地图片存储目录(相对 Koishi 工作目录) |
| smallReply | boolean | false | 启用小图回复模式(200px),减少刷屏 |
注意:master 和 self 为必填项,否则部分功能无法正常使用。
使用指南
1. 上报大餐(群聊)
步骤:
- 在群里引用一条包含图片的消息
- 发送命令:
ydc- 默认判定发图人为大餐人ydc @某人- 指定大餐人(适用于图片不是大餐人本人发的情况)
智能去重:
- 检查维度:图片 URL + 用户 ID + 文件路径
- 已入库:提示「早就被记录了」
- 待审核中:提示「早就被记录到待审核了」
小图模式(需开启 smallReply 配置):
- 去重提示时显示 200px 缩略图,减少刷屏
2. 审核流程(仅 master 和 readers)
查看待审核:
review # 默认显示前 10 条
review -n 20 # 显示前 20 条批量通过:
accept 1 # 通过单条
accept 1 2 3 # 通过多条
accept 114-514 # 通过范围(从 114 到 514)
accept 1 2 10-20 # 混合使用
ac 1 2 3 # 使用别名批量拒绝:
deny 4 5 # 拒绝指定记录
dn 4 5 # 使用别名工作流程:
- 图片先保存到临时目录(
ydc_files/tmp/)并记录到pending_dc_table - 审核通过后:
- 图片复制到正式目录(
ydc_files/<群ID>/<用户ID>/<文件名>) - 记录写入
dc_table正式表 - 从
pending_dc_table删除
- 图片复制到正式目录(
3. 日常查询(群聊)
随机吃什么:
csm # 从当前群历史大餐中随机返回一条- 显示:大餐人 @、日期、图片
- 特殊处理:用户已退群时图片自动转为灰度
个人罪证回放:
dccr @用户 # 随机返回该用户一条大餐记录
dccr -nr @用户 # 返回最新一条(no-random)- 显示:罪证日期、图片、其他罪证数量
大餐王统计:
生成统计(仅 master 和 readers):
dcw --new # 统计过去一周/一月的大餐王查看统计(所有人):
dcw # 显示当前群最近一次统计结果- 统计范围:过去 7 天(周王)、过去 30 天(月王)
- 显示:时间范围、用户 @、次数
数据概览:
dcstatistics # 显示已入库/待审核总条数
dcstat # 简写技术细节
数据库表结构
插件使用 Koishi 的 Minato ORM,创建三张数据表:
dc_table(正式大餐记录):
| 字段 | 类型 | 说明 |
|------|------|------|
| id | unsigned(8) | 自增主键 |
| user | string(128) | 大餐人用户 ID |
| channelId | string(128) | 频道/群 ID |
| stamp | timestamp | 大餐发生时间 |
| url | string(2048) | 图片原始 URL |
| path | string(512) | 本地存储文件名 |
pending_dc_table(待审核记录):
- 结构与
dc_table完全相同 - 审核通过后数据迁移至
dc_table并删除
dc_king(大餐王统计):
| 字段 | 类型 | 说明 |
|------|------|------|
| guild_id | string | 群 ID(主键) |
| content | json | 统计数据(weekly_king 和 monthly_king) |
content JSON 结构:
{
weekly_king: {
id: string, // 用户 ID
times: number, // 次数
start: Date, // 统计开始时间
end: Date // 统计结束时间
},
monthly_king: {
id: string,
times: number,
start: Date,
end: Date
}
}文件存储结构
相对于配置的 dataDir(默认 ydc_files/):
ydc_files/
├── tmp/ # 临时目录(待审核图片)
│ └── <文件名>
└── <群ID>/
└── <用户ID>/
└── <文件名> # 正式存储的图片图片处理
使用 sharp 库进行图片处理:
- 待审核显示:resize(200) + JPEG 格式
- 去重提示(小图模式):resize(200) + JPEG 格式
- 退群用户:grayscale() + JPEG 格式(灰度处理)
- 正常显示:JPEG 格式(保持原始尺寸)
锁机制
- ydc_lock:防止并发上报大餐导致的重复记录
- dcking_gen_lock:防止并发生成大餐王统计
去重逻辑
三重检查机制(AND 关系):
- 图片 URL 相同
- 用户 ID 相同
- 文件路径相同
分别检查 dc_table 和 pending_dc_table。
特殊功能实现
范围表达式解析(accept 命令):
- 支持单个 ID:
1 - 支持多个 ID:
1 2 3 - 支持范围:
114-514(自动展开为 114, 115, ..., 514) - 支持混合:
1 2 10-20 30
@机器人触发解析:
- 监听所有消息(
ctx.on('message')) - 检查首个元素是否为
<at id="机器人ID"> - 自动提取命令并通过
session.execute()执行
使用示例
场景 1:上报大餐
用户A: [发送午餐照片]
用户B: [引用A的消息] ydc @A
机器人: @A 的大餐 [小图] 已经被添加到待审核场景 2:审核流程
管理员: review -n 5
机器人: 共有15条大餐待审核
机器人: id: 12
guild: 123456789
user: 987654321
image: [200px缩略图]
...
以上
管理员: accept 12-14 18 # 通过 12、13、14、18 共4条
机器人: 4/4条大餐记录已加入场景 3:今日吃什么
用户: csm
机器人: @A 在2025年1月15日吃了如下大餐
[大餐图片]
不来一份吗?场景 4:退群用户
用户: csm
机器人: @B 在2024年12月1日吃了如下大餐
[灰度图片]
(此人已不在群中)场景 5:查罪证
用户: dccr @A
机器人: @A 于2025年1月10日的罪证在此:
[大餐图片]
除此之外还有5条罪证场景 6:大餐王统计
管理员: dcw --new
机器人: 生成本月大餐王...
机器人: 新的大餐王已诞生
用户: dcw
机器人: 一周大餐王(2025年1月19日~2025年1月26日):
@A 大餐7次
一月大餐王(2024年12月27日~2025年1月26日):
@B 大餐23次依赖与环境
必需依赖
- Koishi: ^4.17.9
- sharp: ^0.33.4(peer 依赖,需单独安装)
- 数据库服务:需在 Koishi 中启用任意数据库插件(如 SQLite、MySQL 等)
sharp 安装说明
sharp 是图片处理核心依赖,安装时注意:
Linux 环境:
# 优先使用预编译二进制(通常会自动下载)
npm install sharp
# 如果需要从源码构建,确保系统具备:
# - Python 3
# - g++ / make / pkg-config
# - libvips 开发库(某些发行版需要)
# Debian/Ubuntu
sudo apt-get install build-essential python3 libvips-dev
# RHEL/CentOS
sudo yum install gcc-c++ make python3 vips-devel其他平台:
- macOS / Windows:通常可以直接安装,无需额外配置
运行环境要求
- Node.js >= 18(Koishi v4 要求)
- 足够的磁盘空间用于存储图片(取决于使用量)
常见问题
Q: 为何提示「只能在群聊中使用」?
A: ydc、csm、dcw 等命令需要群聊上下文才能工作,请在群内执行。
Q: 图片去重的依据是什么?
A: 插件通过三重检查判定去重:
- 图片 URL 相同 AND
- 用户 ID 相同 AND
- 文件路径相同
只有三者完全匹配才会被判定为重复。
Q: 如何减少刷屏?
A: 在插件配置中启用 smallReply 选项,插件在提示去重/待审核时会发送 200px 的缩略图。
Q: 为什么 accept 命令通过的数量和实际入库数量不一致?
A: 可能原因:
- 部分 ID 对应的记录不存在
- 使用了错误格式的 ID(如包含非数字字符)
- 范围表达式解析错误(确保格式为
起始-结束,如114-514)
Q: 退群用户的图片为什么变成灰色?
A: 这是 csm 命令的特殊处理,通过检测用户是否仍在群中:
- 仍在群:显示原图并提示「不来一份吗?」
- 已退群:图片转为灰度并标注「(此人已不在群中)」
Q: @机器人触发命令失效?
A: 请检查:
self配置项是否填写了正确的机器人账号 ID- 消息格式是否为:
@机器人 命令 参数(@ 必须在开头)
Q: 审核权限设置不生效?
A: 请检查:
master配置项是否填写了主人账号 IDreaders数组是否正确添加了审核人账号 ID- 账号 ID 格式是否正确(字符串类型)
Q: 数据库报错「表不存在」?
A: 请确保:
- Koishi 已启用数据库服务
- 插件已成功启动(会自动创建表)
- 检查 Koishi 日志是否有表创建失败的错误
Q: 图片存储路径可以修改吗?
A: 可以通过 dataDir 配置项修改,路径是相对于 Koishi 工作目录的。建议使用相对路径以保持可移植性。
Q: 如何清理历史数据?
A:
- 数据库记录:使用 Koishi 的数据库管理工具或直接操作数据库
- 本地图片:手动删除
dataDir目录下的文件 - 注意:删除前请做好备份!
许可证
WTFPL
贡献者
- yoki
- xboHodx
版本历史
当前版本:0.0.23
主要更新
- ✅ 支持范围表达式批量审核(如
accept 114-514) - ✅ 退群用户图片灰度显示
- ✅ 修复 accept 命令失败时的错误处理
- ✅ 修复消息发送失败不中断记录删除的问题
详细更新日志请查看 git 提交历史。
提示:如有问题或建议,欢迎在 GitHub 仓库提交 Issue 或 PR。
