一个基于 napcat-sdk 的 QQ 私聊客服催回复机器人。
它的目标很简单:客户发来私聊消息后,如果客服迟迟没有回复,机器人就把消息整理后推送到内部群里提醒;如果超时更久,再按里程碑继续催办;客服处理完成后,再自动结束监控并存档会话。
当前仓库已经实现了完整的消息监听、好友申请自动处理、群内快捷指令、夜间免打扰、状态持久化与会话归档。本文档基于当前代码现状整理,尽量保留原有使用视角。
- QQ 私聊作为客服入口
- 需要把未回复客户集中提醒到内部群
- 希望减少人工盯聊天窗口的成本
- 希望通过群内引用命令、贴表情、戳一戳来快速处理会话
- 希望保留客服响应耗时和会话记录,方便追踪
- 自动通过好友申请,并在内部群发送通过通知
- 好友通过后延迟发送欢迎消息,支持纯文本或结构化消息段
- 监听非白名单用户的私聊消息
- 对新消息做 1 分钟防抖,避免客户连续补充消息时频繁提醒
- 将待处理客户最近消息整理为合并转发并发送到内部群
- 提醒时可随机
@当前排班内可用成员;若当前无人值班,则直接发送提醒 - 按里程碑进行超时催办
- 支持夜间免打扰:夜间延后提醒,次日指定时间汇总发送
- 支持在通知群引用机器人消息后执行
.say/.more/.bye/.close/.list/.help - 支持通过配置的表情映射触发
say/more/bye/close/cancel - 支持
.say两段式回复:先输入.say,再发送下一条群消息作为要转发给客户的内容 - 支持客服直接私聊回复客户后自动结束会话
- 支持内部群戳一戳查看运行状态面板
- 支持状态持久化:程序重启后自动恢复待回复客户、监听消息和夜间延后通知
- 支持会话归档:每次会话结束后自动保存聊天记录到本地
JSONL - 支持统计已完结会话的最短、最长、平均和中位回复耗时
- 客户发送私聊消息,机器人将其加入待回复队列。
- 如果客户在 1 分钟内继续发消息,计时会重置,并合并到同一轮待处理会话。
- 超过 1 分钟仍未回复时,机器人向内部群发送“新客户提醒”。
- 机器人会根据
milestones配置继续发送“超时催办”。 - 客服可以直接私聊回复客户,也可以在内部群引用消息执行命令,或使用配置好的表情快捷处理。
- 会话结束后,客户会从待回复队列中移除,回复耗时会计入统计,并异步写入本地归档。
- 若开启夜间模式,夜间时段的新客户提醒和里程碑提醒会暂存,并在次日指定时间汇总发送。
除 .list 和 .help 外,其余命令都应当 引用(回复) 一条由机器人发送、且仍在监听窗口内的消息。通常引用的是合并转发消息,也可以是机器人发出的操作反馈消息。
| 指令 | 用途 | 示例 | 是否需要引用 |
|---|---|---|---|
.say <内容> |
向客户发送私聊消息 | .say 您好,请问有什么可以帮您? |
是 |
.say |
进入“等待发送内容”状态,触发者的下一条群消息会被转发给客户 | .say |
是 |
.more |
获取客户最近 100 条历史消息,并以合并转发形式返回 | .more |
是 |
.bye |
向客户发送结束语并关闭会话 | .bye |
是 |
.close |
关闭会话,但不发送结束语 | .close |
是 |
.list |
列出当前待回复客户及等待时长 | .list |
否 |
.help |
显示帮助信息 | .help |
否 |
补充说明:
.say转发时会去掉群消息中的Reply段,其余消息段会原样发送给客户,因此文本、图片等消息段都可用。.say进入等待状态后,机器人会给提示消息贴上cancel表情;贴该表情即可取消本次发送。.list最多展示前 20 条待回复客户记录。- 如果引用的是已过期或无法识别的机器人消息,机器人会返回“操作已过期”或“无法识别的消息”。
机器人会自动给可操作的消息贴上预设表情,群成员可以直接点表情触发动作。表情与命令的对应关系由 emoji_mapping 控制。
默认示例:
| 动作 | 默认 QQ 表情 ID | 说明 |
|---|---|---|
say |
123 |
进入发送消息流程 |
more |
289 |
拉取最近历史消息 |
bye |
124 |
发送结束语并关闭会话 |
close |
75 |
直接关闭会话 |
cancel |
96 |
取消等待中的 .say |
- 注意: 表情快捷操作只支持 单客户 消息;如果一条合并转发里包含多个客户,机器人不会直接执行快捷关闭或快捷回复。
- 客户发消息后自动进入队列(白名单用户除外)。
- 若客户刚通过好友申请,在
processed_friend_requests_expire窗口期内发来的消息会被忽略,避免欢迎阶段误入队列。 - 客服直接私聊回复客户,会话自动结束。
- 客户在私聊窗口戳一戳机器人时,如果该客户当前在待回复队列中,机器人会发送结束语并结束会话。
在配置文件中可以设定夜间时段(例如 23:30 到 07:00)和次日汇总时间。夜间时段内:
- 新客户提醒不会立刻发送,而是暂存到内存中的延后通知队列
- 里程碑超时提醒也不会立刻发送,而是一起延后
- 到达
summary_time附近的 10 分钟窗口内,机器人会把夜间积累的客户汇总后统一发送 - 汇总消息仍会带合并转发内容,方便客服次日直接处理
注意:
- 夜间汇总按客户聚合,不区分“新客户提醒”还是“第几个里程碑提醒”。
- 夜间延后通知会写入状态文件,因此程序重启后仍可恢复。
项目使用根目录下的 config.yaml 作为配置文件。仓库当前没有单独的 config.example.yaml,请直接按实际环境修改现有配置。
# WebSocket 连接
ws_url: "ws://127.0.0.1:3001"
ws_token: "your_ws_token"
# 内部通知群号
internal_group_id: 123456789
# 白名单(这些 QQ 不会进入待回复队列)
whitelist:
- 100000
- 100001
# 超时里程碑(分钟)
milestones:
- 15
- 30
- 60
- 120
- 180
- 360
- 720
- 1440
- 2880
- 4320
# 最多监听多少条机器人发出的可操作消息
monitored_forward_limit: 15
# 会话结束语
closing_message: |-
本次会话暂时结束。感谢您的支持与信任,再见。(请勿回复)
# 新好友通过后发送的欢迎消息
welcome_message: |-
[自动回复]您好,感谢您添加好友。
如有问题可直接留言,我们会在工作时间尽快回复。
# 群内命令防抖(秒)
debounce_seconds:
say: 5
more: 5
bye: 5
close: 5
list: 5
# 好友申请去重窗口(秒)
processed_friend_requests_expire: 5
# 通过好友后,延迟多久再发送欢迎消息
friend_welcome_delay: 5
# 欢迎消息失败重试
friend_welcome_retries: 3
friend_welcome_retry_interval: 3
# 好友数阈值,达到后在群通知中附带警告
friend_count_limit: 3000
# 回复耗时统计最多保留多少条样本
reply_duration_maxlen: 1000
# 值班时间表:QQ -> 星期 -> 时间段列表
availability:
123456789:
monday:
- ["09:00", "12:00"]
- ["13:00", "18:00"]
tuesday: []
wednesday: []
thursday: []
friday: []
saturday: []
sunday: []
# 机器人消息监听有效期(秒)
max_listen_age: 86400
# 夜间免打扰配置
night_mode:
start: "23:30"
end: "07:00"
summary_time: "07:00"
# 状态持久化文件
state_file: "archives/state.json"
# 会话归档目录
archive_dir: "archives"
# 构造合并转发时,最多回看多久以内的历史消息(秒)
recent_message_max_age: 86400
# 表情映射:动作 -> QQ 表情 ID
emoji_mapping:
close: 75
more: 289
bye: 124
say: 123
cancel: 96closing_message 和 welcome_message 除了支持字符串,也支持结构化消息段列表。当前代码内置支持的类型有:text、image、face、at、poke。
welcome_message:
- type: text
data:
text: "您好,感谢您添加好友。"
- type: image
data:
file: "https://example.com/welcome.png"| 配置项 | 说明 |
|---|---|
ws_url / ws_token |
NapCat WebSocket 地址与令牌 |
internal_group_id |
接收提醒、执行命令、查看状态的内部群号 |
whitelist |
不参与待回复监控的 QQ 号 |
milestones |
超时催办节点,单位为分钟 |
monitored_forward_limit |
同时保留多少条可引用的机器人消息映射 |
debounce_seconds |
各群命令的防抖窗口 |
processed_friend_requests_expire |
好友申请去重窗口;也用于刚通过好友时的消息忽略窗口 |
friend_welcome_delay |
通过好友后延迟多久再发送欢迎消息 |
friend_welcome_retries / friend_welcome_retry_interval |
欢迎消息失败重试策略 |
friend_count_limit |
好友数量告警阈值 |
reply_duration_maxlen |
回复耗时统计样本上限 |
availability |
当前可用成员时间表;用于提醒时随机 @ 一位值班成员 |
max_listen_age |
机器人消息保持可操作状态的最长时间 |
night_mode |
夜间免打扰起止时间与汇总时间 |
archive_dir |
会话归档目录 |
state_file |
运行状态持久化文件 |
recent_message_max_age |
构造提醒合并转发时回看的消息时间窗口 |
emoji_mapping |
表情 ID 到快捷动作的映射 |
- Python
3.14+ - 可用的 NapCat / OneBot WebSocket 服务
- 一个用于接收提醒和执行命令的内部 QQ 群
推荐使用 uv:
uv sync如果你习惯使用 pip,也可以在满足当前 Python 版本要求的前提下安装项目依赖:
pip install -e .uv run python main.py或:
python main.py启动后程序会:
- 加载
config.yaml - 恢复
state_file中的运行状态 - 启动每 60 秒执行一次的巡检任务
- 连接 NapCat WebSocket,并在断开后自动重连
- 首次连通后向内部群发送“机器人已启动”通知
- 初始化当前好友数缓存
- 客户首次发消息后不会立刻提醒
- 只有当“距离最后一条客户消息已满 1 分钟”时,才会推送到内部群
- 如果客户在等待期间继续发消息,会重置计时并清空已上报的里程碑
机器人会根据 milestones 的配置,在客户持续未获回复时逐级催办。每个客户每个里程碑只提醒一次;如果客户又发来新消息,该轮会话的里程碑记录会重置。
以下行为会让客户从待回复队列中移除:
- 客服直接私聊回复客户
- 在内部群执行
.say - 在内部群执行
.bye - 在内部群执行
.close - 在内部群点击配置好的
bye/close表情快捷操作 - 客户在私聊窗口戳一戳机器人,且该客户当前仍在待回复队列中
在内部群戳一戳机器人,会返回状态面板,包括:
- 运行时长
- 当前待回复客户数
- 已完结会话数
- 最短、最长、平均、中位回复耗时
- 当前监听中的机器人消息数量
state_file会保存待回复客户、监听消息映射、命令防抖时间、夜间延后通知和最近一次夜间汇总日期- 每次会话结束后,机器人会异步拉取该客户会话窗口内的消息并追加写入
archives/<qq>_<yyyymmdd>.jsonl - 归档采用
JSONL,适合后续脚本分析或导入其他系统
如果你使用 Claude Code、Codex 或其他编码代理来修改这个项目,建议先阅读 napcat-sdk 的专用说明:
这样通常能更快对齐:
napcat-sdk的核心对象和消息段类型NapCatClient的使用方式- 事件模型和
Reply/Text/NodeReference/NodeInline等常见段类型 user_id/group_id等字段的类型注意事项
- 多客户合并转发目前不能直接执行
.say/.more/.bye/.close,需要手动处理。 - 可操作消息的监听依赖
monitored_forward_limit和max_listen_age;超出窗口后再引用旧消息,机器人可能返回“操作已过期”。 .say的等待输入状态保存在内存中,程序重启后不会恢复。- 夜间汇总按客户聚合,不保留原始通知类型和里程碑层级。
- 状态文件和归档目录会随使用时间持续增长,需要自行定期清理。
.
├── main.py
├── config.yaml
├── pyproject.toml
├── uv.lock
├── README.md
├── archives/
└── src/
├── __init__.py
├── config.py
├── group_msg.py
├── main.py
├── message_sender.py
├── models.py
├── monitor.py
├── new_user.py
├── private_msg.py
├── state.py
└── utils.py
各模块职责:
src/main.py:程序入口、事件分发、启动通知、重连逻辑src/config.py:配置加载、全局状态初始化、NapCat 客户端实例src/private_msg.py:处理客户私聊消息、客服私聊回复、私聊戳一戳src/new_user.py:好友申请自动通过、欢迎消息发送、好友数提醒src/group_msg.py:群命令、群表情快捷操作、群戳一戳状态面板src/message_sender.py:提醒消息构造、合并转发、会话关闭、状态统计src/monitor.py:每 60 秒巡检一次,负责新客户提醒、里程碑催办、夜间汇总和过期清理src/state.py:状态保存、状态恢复、会话归档src/utils.py:时长格式化、值班成员判断、夜间时段判断src/models.py:TypedDict 类型定义
- 支持多客户合并转发下的拆分处理
- 为归档和状态提供清理、导出或检索工具
- 增加更细粒度的权限控制和群内角色区分
- 补充测试与更明确的部署说明
- 提供独立的
config.example.yaml,避免直接修改真实配置
暂未声明。