npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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站空间