koishi-plugin-at-forward
v1.1.2
Published
艾特转发:监控群内 @ 指定成员(可多个、可按群配置),私聊推送艾特时间并合并转发艾特内容
Readme
koishi-plugin-at-forward
群内 @ 监控转发:当有人艾特配置中监控的成员时,机器人私聊通知艾特时间,并用合并转发卡片还原艾特内容。
功能
- 支持多个全局监控对象、单个默认私聊对象
- 支持按群设置专属监控对象 / 专属私聊对象(覆盖或追加全局配置)
- 可选监控 @全体成员;忽略其他机器人消息;同消息多机器人去重
- QQ 上以合并转发卡片推送(其他平台自动降级纯文本)
- 【新人首语】新成员进群后自动抓取其前 N 句实质性发言并合并转发(默认关闭)
- 【未读统计】查询「我上次在群里说话之后,该群又发了多少条消息」,可选复用词云插件的聊天记录(默认关闭)
- 【新人活跃】联动 message-counter,只统计本日 / 本周 / 本月进群的新人,看他们在该周期发了多少条消息(默认关闭)
- 【新人活跃·自动推送】可设定每天 / 每周一 / 每月 1 号自动把榜单私聊发出(默认关闭)
- 控制台插件配置页内嵌运行状态面板与配置自检:直接指出「配了但不会生效」的组合
配置页
状态面板通过 ctx.slot({ type: 'plugin-details' }) 嵌在本插件的配置页里(插件名与描述下方、配置表单上方),不额外占用控制台侧栏。它只在当前配置的插件是 koishi-plugin-at-forward 时渲染。
面板读取的是插件真实运行数据(GET /at-forward/status,只含计数与开关状态,不含任何 QQ 号):
- 三个服务状态:数据库 / puppeteer / 在线机器人数量
- 四张功能卡:@ 提醒(监控对象数、私聊对象是否已设)、新人首语(条数 / 时限 / 群级开启数)、未读统计(已记录消息条数、数据源、保留天数)、新人活跃(累计 / 今日 / 本周 / 本月入群人数)
- 定时推送计划:三个时段各自的开关、时间与时间格式是否合法
- 配置自检:把容易踩的坑直接列成 ❌ / ⚠️ / ⓘ,例如
| 检查项 | 触发条件 |
| --- | --- |
| 没有监控对象 / 没有私聊对象 | 命中后无处可发 |
| 新人活跃选了 self 但未读统计没开 | 统计必然恒为 0 |
| message-counter 表不存在(插件未启用) | 提示会回退本插件记录,或「全是 0」 |
| 自动推送勾了周 / 月榜但未读统计没开 | 历史榜没有数据源 |
| 未读统计保留天数 < 8 / 32 天 | 覆盖不了上周 / 上月 |
| 自动推送范围是「仅配置群」但群规则里没群号 | 永远不推送任何群 |
| 推送时间不是合法 HH:mm | 该时段不会执行 |
| 出图模式选了 image 但无 puppeteer | 会一直降级纯文字 |
同一套自检也会附在 atf.状态 命令输出末尾。
表单里的分组
配置项较多,表单里每项的说明都以模块标签开头,便于在长表单里定位:
| 标签 | 覆盖配置 |
| --- | --- |
| 【@ 提醒】 | 监控对象、私聊对象、推送形式、@全体成员、去重等 |
| 【群专属规则】 | 群号、群级监控对象 / 私聊对象、合并方式 |
| 【新人首语】 | 开关、条数、时限、超时补发 |
| 【未读统计】 | 开关、数据源、保留天数、指令名与别名、列表范围 |
| 【新人活跃】 | 开关、数据源、周期、出图、保留天数 |
| 【自动推送】 | 三个时段、统一推送对象、范围、空榜 |
| 【排错】 | debug 日志 |
数值型配置都带范围校验(越界会直接报错,而不是静默算出怪结果):
| 配置 | 允许范围 |
| --- | --- |
| welcomeCount | 1 ~ 50 |
| welcomeTimeout | 0 ~ 10080(分钟,0=不限时) |
| statsKeepDays / newbieKeepDays | 0 ~ 3650(0=永久) |
| newbieMax | 1 ~ 100 |
新人首语
新成员进群后开始收集其发言,纯表情 / 图片 / 视频 / 语音不算,凑够条数(默认 5 句)后合并转发给私聊对象:一条文字摘要(新人 / 群 / 进群时间 / 发言区间)+ 一张合并转发卡片(每句话一个节点,发出者为新人本人)。
相关配置:
| 配置 | 说明 | 默认 |
| --- | --- | --- |
| welcomeEnabled | 全局开关 | 关闭 |
| welcomeCount | 抓取条数 | 5 |
| welcomeNotify | 专属私聊对象,留空=沿用默认私聊对象 | 空 |
| welcomeTimeout | 收集时限(分钟),0=不限时 | 120 |
| welcomePartial | 超时未凑够条数时是否仍发出已收集部分 | 关闭 |
按群覆盖(群专属规则内):welcomeMode(跟随全局 / 开 / 关,默认跟随)、welcomeCount(留空继承全局)、welcomeNotify(留空继承)。
新人活跃(联动 message-counter,默认关闭)
只统计在统计周期内进群的新人,看他们在这个周期里发了多少条消息。
- 周期:本日(今天 0 点之后入群)/ 本周(本周一 0 点之后)/ 本月(1 号之后)
- 发言数优先取 message-counter 的计数(
今日 / 本周 / 本月三档分别对应周期),拿不到时回退本插件记录(从入群时间之后精确计数)
| 配置 | 说明 | 默认 |
| --- | --- | --- |
| newbieEnabled | 总开关(关闭时不记录入群时间) | 关闭 |
| newbieSource | auto(优先 message-counter,无则本插件记录)/ messagecounter / self | auto |
| newbiePeriod | 默认周期 day / week / month(指令里可用 -d -w -m 临时覆盖) | week |
| newbieMax | 最多列出多少位新人(按发言数从多到少) | 20 |
| newbieShowZero | 是否列出「进群后一条没发」的新人 | 开 |
| newbieCommand / newbieAliases | 自定义指令名 / 别名 | atf.新人 / 新人榜、新人活跃 |
| newbiePrivateOnly | 仅私聊可用(群里使用完全无响应) | 关闭 |
| newbieKeepDays | 入群记录保留天数,0=永久 | 365 |
| newbieRender | 输出形式:auto(装了 puppeteer 就出图)/ image(总是出图)/ text(总是纯文字) | auto |
| newbieTheme | 图片配色:light / dark | light |
按群覆盖:群专属规则里可设 跟随全局 / 开启 / 关闭(关闭=不记录该群入群时间)。
出图:装了 puppeteer(同 message-counter 用的那个服务)时,单群详情会渲染成一张卡片图——排名徽章(前三金银铜)、等比柱状条、发言数与入群时间,深浅两套配色;渲染失败或没装 puppeteer 会自动回退成纯文字,不影响使用。多群概览始终是文字。
历史数据回填:入群时间只在功能开启后开始累积。想统计历史成员,管理员执行 atf.新人同步 群号,会读群成员列表里的 join_time 批量回填(依赖 OneBot 实现支持该字段,NapCat / LLOneBot 均可)。
定时自动推送
打开「自动推送」后,到点自动把榜单私聊发出,不需要有人敲命令。三个时段独立开关、时间各自可填(24 小时制 HH:mm):
| 配置 | 说明 | 默认 |
| --- | --- | --- |
| newbieAutoEnabled | 自动推送总开关 | 关闭 |
| newbieAutoDaily / newbieAutoDailyTime | 每天推送「本日」榜(当天进群的人今天发了多少条) | 关闭 / 22:00 |
| newbieAutoWeekly / newbieAutoWeeklyTime | 每周一推送「上周」榜(上周一 0 点 ~ 本周一 0 点进群的人) | 关闭 / 09:00 |
| newbieAutoMonthly / newbieAutoMonthlyTime | 每月 1 号推送「上月」榜 | 关闭 / 09:00 |
| newbieAutoUser | 统一推送对象(QQ 号)。留空=按群取,优先级「群专属私聊对象 → 全局默认私聊对象」 | 空 |
| newbieAutoSendEmpty | 周期内一个新人也没有时是否也发一条 | 关闭 |
| newbieAutoScope | config=只推「群专属规则」里的群;all=再加上机器人观察到发言的其它群 | config |
每个群各发一份自己的榜单,不是合并成一条。群级关闭(newbieMode: off)的群不参与推送。
统计口径要注意:
- 本日榜直接用 message-counter 的
todayPostCount,最准 - 上周 / 上月榜只能用本插件记录精确统计——message-counter 只存「当前周期」的计数,没有历史快照。所以必须同时开启「未读统计」,并把它的保留天数调够(周榜 ≥ 8 天,月榜 ≥ 32 天,
0=永久)。配置不到位时启动日志会给出明确警告 - 到点那一刻机器人必须在运行;错过时间点不会补发,同一任务同一天只发一次
- 配置改动即时生效,不用重启(调度器常驻,每次检查读实时配置)
验证配置是否正常:管理员执行 atf.新人推送 周(或 日 / 月),会立刻按该时段跑一次并真的私聊发送,不用等到点。
未读统计(可选,默认关闭)
私聊或群聊里用 atf.未读,会找出你在该群的最后一次发言,统计从那时起到现在群里一共发了多少条消息(相当于"爬楼量")。
数据源三选一,可选与词云插件(wordcloud-lili)联动:
| 配置 | 说明 | 默认 |
| --- | --- | --- |
| statsEnabled | 总开关 | 关闭 |
| statsSource | auto(本插件记录优先,没有再回退词云)/ self(只用自己的)/ wordcloud(只用词云记录) | auto |
| statsKeepDays | 本插件记录保留天数,到期自动清理,0=不清理 | 7 |
| statsShowSpeakers | 结果里附带期间发言人数 | 开 |
| statsAdminOnly | 仅允许配置里的私聊对象查询 | 关 |
按群覆盖:群专属规则里可设 跟随全局 / 开启 / 关闭(关闭=不记录该群消息)。
指令相关:
| 配置 | 说明 | 默认 |
| --- | --- | --- |
| statsCommand | 自定义指令名(填 未读 就是独立指令,填 atf.未读 就是子命令) | atf.未读 |
| statsAliases | 指令别名,可多个 | 爬楼 |
| statsPrivateOnly | 仅私聊可用:群里使用时完全无响应(不回复任何内容) | 开启 |
| statsListScope | 不带群号时列出哪些群:config=只列「群专属规则」里配置过的群;all=配置群 + 机器人观察到的其它群 | config |
| statsHideEmpty | 列表里隐藏「没有你发言记录」的群 | 关闭 |
atf.未读 这个默认名始终保留,自定义名是额外注册的一份,改了名字也不会让旧指令失效。
两种数据源的区别:本插件记录全部群消息(含表情、图片、视频);词云记录只含有文字的消息(受词云 recordMessages 与 guilds 配置限制),但能复用已有历史数据、省一份存储。查询结果的「数据来源」一行会写明用的是哪种。
命令
| 命令 | 说明 |
| --- | --- |
| atf.未读 [群号] | 查询我上次发言之后群里又发了多少条消息;不带群号=列出候选群(默认只列配置过的群,指令名与别名可自定义,默认仅私聊可用) |
| atf.新人 [-d/-w/-m] [-l] [群号] | 本日 / 本周 / 本月进群的新人,在该周期发了多少条消息(群里不带群号=统计当前群;加 -l 看上一周期,如 -w -l=上周) |
| atf.新人同步 [群号] | 从群成员列表回填入群时间,补历史数据(管理员) |
| atf.新人推送 [日/周/月] | 立即执行一次自动推送,验证配置用(管理员,会真的私聊发送) |
| atf.状态 | 查看当前监控配置(含新人首语 / 未读统计 / 新人活跃)+ 末尾附配置自检 |
| atf.观察 | 查看当前正在收集新人首语的成员与进度 |
| atf.测试 [QQ号] | 向私聊对象发一条模拟通知(管理员) |
注意
- 新人首语为内存态收集,机器人重启后正在进行的收集会丢失。
- 新人活跃的入群时间为持久化记录,重启不丢;但只有在开关开启期间进群的成员才有记录(历史数据用
atf.新人同步回填)。 - 自动推送的「上周 / 上月」榜依赖本插件记录,需开启「未读统计」并保证保留天数覆盖该周期;自动推送计划与空榜处理见
atf.状态。 - 机器人需与私聊对象互为 QQ 好友,否则临时会话发送失败(只记日志)。
- 修改配置后即时生效,无需重启。
反馈
QQ 群:1078815356 · B站空间
