目标
确保 openclaw 发送 QQ 消息(文本与媒体)时只使用本插件的 API,并让 sessionKey 满足 napcat 插件要求。
工作流
NapCat 群聊可见回复(硬性规则):
- 当当前会话来自 NapCat 群聊,任何希望群里成员看到的文本回复都必须调用
message工具:action: "send"。 - 调用时必须显式指定
channel: "napcat",并使用当前群的目标:target: "session:napcat:group:<群号>"(或target: "group:<群号>")。 - 不要把普通最终回复当作群消息;群聊里的普通最终回复可能不会投递到 QQ。
- 发送成功后,后续内部/最终回复保持简短,不重复已发送到群里的内容。
- 当当前会话来自 NapCat 群聊,任何希望群里成员看到的文本回复都必须调用
识别消息类型:私聊或群聊。
若用户未提供 QQ 号或群号,而是使用昵称、备注或群名指代目标,先调用搜索脚本:
node scripts/qq-contact-search.js <关键词> [private|group|all]- 若搜索结果为 1 个,直接采用该目标继续发送。
- 若搜索结果多于 1 个,列出候选让用户选择编号后再发送。
- 若没有结果,再询问更精确的昵称/备注/群名,或直接补充 QQ 号 / 群号。
校验并构造 sessionKey:
- 私聊:
session:napcat:private:<QQ号> - 群聊:
session:napcat:group:<群号>
- 私聊:
目标写法说明(重要):
- 群聊优先使用
target: group:<群号>或target: session:napcat:group:<群号>。 - 纯数字
target会被当作私聊用户 ID,容易导致“无法获取用户信息”。
- 群聊优先使用
调用 message 工具时必须显式指定
channel: "napcat",避免多通道场景下无法路由。通过 NapCat/QQ 发送文字时使用纯文本,不要使用 Markdown 标题、加粗、表格、代码块或 Markdown 链接语法。若需要表达层级,用普通换行和简短前缀即可。
媒体发送规则:
- 发送图片/媒体时,使用
message工具并传mediaUrl。 - 可选传
text作为媒体说明(caption)。 - 语音可直接传
.wav等音频 URL/路径到mediaUrl,插件会按语音消息发送。 mediaUrl需为 NapCat 可访问地址(通常是http/https局域网可达 URL)。
- 发送图片/媒体时,使用
语音生成与情绪策略(推荐约定,便于一致体验):
- 默认情绪策略:根据消息文本内容自动检测情绪/语气(由上游 TTS 侧实现)。
- 显式覆盖规则:若用户明确指定情绪/语气(如“温柔/严肃/开心/激动”等),则覆盖自动检测结果。
- 实践建议:将“默认音色/声线(voice profile)”作为本地环境偏好维护(见
TOOLS.md),避免在可分享的 skill 中绑定特定音色或语料路径。
仅使用本插件的 API 完成发送,不要调用其他 QQ 发送途径。
QQ 消息表情回应
- NapCat 通道支持
message工具的react动作,可对 QQ 消息添加或撤销表情回应。 - 回应当前触发消息时可以省略
messageId;回应其他消息时必须显式提供messageId。 emoji优先填写单个 Unicode Emoji;也可直接填写 QQ 数字表情 ID。- 只保证 QQ 表情回应面板支持的 Emoji 可用;不支持的 Emoji 不要反复重试。
- 撤销机器人自己的回应时使用同一个
emoji并传remove: true。 - 只在轻量确认、表达情绪且无需额外文字时使用,避免对同一条消息连续添加多个回应。
入站上下文
- 当消息来自 NapCat 入站通道时,当前上下文会提供机器人自己的 QQ 号字段:
SelfId、BotId、BotQQ、NapCatSelfId。 - 模型可见正文
BodyForAgent会带有[NapCat context: bot QQ=<机器人QQ号>]前缀;需要判断“我现在用的是哪个 QQ 号”时优先读取这些上下文,不要猜。
交互规则
- 若用户未提供 QQ 号或群号,优先尝试用昵称/备注/群名搜索;搜索无结果时再询问并明确补全后发送。
- 若搜索返回多个候选,先让用户确认具体对象再发送。
- 若用户提供了 sessionKey 但格式不符合规则,改写为正确格式并说明已规范化。
- 若用户含糊描述(如“发消息给他”),优先确认私聊/群聊与目标 ID。
入站日志读取(排查/取证)
当用户要求“查看收到的消息”“排查某个 QQ/群的消息”时,按下面步骤执行:
- 先确认日志目录配置:
- 默认目录:
./logs/napcat-inbound - 若插件配置了
channels.napcat.inboundLogDir,优先使用该目录
- 默认目录:
- 根据会话类型选择日志文件:
- 私聊:
qq-<QQ号>.log - 群聊:
group-<群号>.log
- 私聊:
- 日志为 JSON Lines(一行一条消息),常用字段:
ts、message_type、user_id、group_id、message_id、raw_message、sender
- 读取日志时优先给出最近消息,再按用户要求扩展范围:
- 例如先看最后 50 条,再按关键词/时间过滤
- 重要行为约束:
- 即使消息不在白名单中,日志里也可能有记录(因为是“先记录后过滤”)
- 仅把日志用于排查与上下文理解,不要绕过白名单去触发自动处理