目标
确保 openclaw 发送 QQ 消息(文本与媒体)时只使用本插件的 API,并让 sessionKey 满足 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",避免多通道场景下无法路由。媒体发送规则:
- 发送图片/媒体时,使用
message工具并传mediaUrl。 - 可选传
text作为媒体说明(caption)。 - 语音可直接传
.wav等音频 URL/路径到mediaUrl,插件会按语音消息发送。 mediaUrl需为 NapCat 可访问地址(通常是http/https局域网可达 URL)。
- 发送图片/媒体时,使用
语音生成与情绪策略(推荐约定,便于一致体验):
- 默认情绪策略:根据消息文本内容自动检测情绪/语气(由上游 TTS 侧实现)。
- 显式覆盖规则:若用户明确指定情绪/语气(如“温柔/严肃/开心/激动”等),则覆盖自动检测结果。
- 实践建议:将“默认音色/声线(voice profile)”作为本地环境偏好维护(见
TOOLS.md),避免在可分享的 skill 中绑定特定音色或语料路径。
仅使用本插件的 API 完成发送,不要调用其他 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 条,再按关键词/时间过滤
- 重要行为约束:
- 即使消息不在白名单中,日志里也可能有记录(因为是“先记录后过滤”)
- 仅把日志用于排查与上下文理解,不要绕过白名单去触发自动处理
Source: ProperSAMA/openclaw-napcat-plugin — distributed by TomeVault.