napcat

ProperSAMA/openclaw-napcat-plugin

Otheropenclawby ProperSAMA

Summary

OpenClaw plugin exposing 0 skills across napcat.

Install to Claude Code

openclaw plugin add ProperSAMA/openclaw-napcat-plugin

Run in Claude Code. Add the marketplace first with /plugin marketplace add ProperSAMA/openclaw-napcat-plugin if you haven't already.

README.md

OpenClaw NapCat Plugin

![OpenClaw Plugin](https://openclaw.ai)

这是一个给 OpenClaw 用的 QQ 通道插件。 它通过 NapCat(OneBot 11) 把 QQ 私聊、群聊接进 OpenClaw,让你可以直接在 QQ 里和 OpenClaw 对话。

如果你不是程序员,也没关系。你可以把它理解成:

  • OpenClaw = 大脑
  • NapCat = QQ 适配器
  • 这个插件 = 把两边接起来的桥

配好以后,你就可以:

  • 在 QQ 私聊里直接找 OpenClaw
  • 在 QQ 群里 @ 它让它回复
  • 给 QQ 群发送图片、语音,甚至上传文件

---

这插件能做什么?

目前支持:

  • 私聊消息收发
  • 群聊消息收发
  • 读取合并转发消息(CQ:forward
  • 按会话自动路由到 OpenClaw
  • 图片发送
  • 语音发送(WAV 等音频)
  • 群文件上传
  • 白名单控制(只允许指定 QQ 号触发)
  • 入站消息日志记录
  • 私聊处理中显示“正在输入”

适合的场景:

  • 想把 OpenClaw 接到自己的 QQ 上
  • 想让 OpenClaw 在 QQ 群里工作
  • 想做一个“QQ 上可直接对话”的私人工具助手

---

一句话理解安装流程

你需要把三件事接起来:

1. NapCat 正常运行 2. OpenClaw 安装这个插件 3. NapCat 把消息转发给 OpenClaw

只要这三步通了,基本就能用。

---

开始前,你需要准备什么

在安装前,最好先确认你已经有:

  • 一个能正常运行的 OpenClaw
  • 一个能正常运行的 NapCat
  • 能编辑 ~/.openclaw/openclaw.json
  • 能重启 OpenClaw Gateway

如果你对 NapCat 还不熟,可以先把 NapCat 单独跑起来,确认它本身没问题,再来接 OpenClaw。

---

最简单上手方式(推荐先这样配)

如果你只想尽快跑通,先按这个最小方案来。

第 1 步:安装插件

推荐直接按 npm 包名 安装:

openclaw plugins install @propersama/openclaw-napcat

如果你后面改成了自己的 npm scope,就把上面的包名替换成你实际发布的那个名字。

---

第 2 步:确认插件已启用

如果这是首次安装,通常 OpenClaw 会把它登记到插件列表里。 你也可以显式确认一下:

openclaw plugins enable napcat

---

第 3 步:放入 Skill(可选但推荐)

项目里有一个 skill/napcat-qq。 把它放到 OpenClaw 的 skill 目录里,可以让 OpenClaw 更稳定地使用这个 QQ 通道。

如果你已经有自己的技能目录管理方式,也可以按你的习惯来。

注意:

  • 通过 npm 安装插件时,skill/napcat-qq 会随包发布
  • 但其中的 scripts/qq-contact-search.js 默认不会随 npm 包一起安装
  • 如果你需要“按昵称 / 备注 / 群名搜索联系人”的能力,可以按下面“按昵称或备注找 QQ / 群”的说明,手动把这个脚本放回对应的 skill 目录

---

第 4 步:修改 OpenClaw 配置

打开:

~/.openclaw/openclaw.json

加入或修改下面这段:

{
  "channels": {
    "napcat": {
      "enabled": true,
      "url": "http://127.0.0.1:15150",
      "streaming_mode": false,
      "enablePrivateTypingStatus": true,
      "enableGroupMessages": true,
      "groupWhitelist": [],
      "groupMentionOnly": true
    }
  },
  "plugins": {
    "entries": {
      "napcat": {
        "enabled": true
      }
    }
  }
}

这是一个最小可用配置

它的意思是:

  • 启用 napcat 通道
  • NapCat 的 HTTP 服务地址是 http://127.0.0.1:15150
  • streaming_modetrue 时会改成流式回复,每处理一步就发一条 QQ 消息
  • enablePrivateTypingStatustrue 时,私聊里 OpenClaw 思考期间会尝试显示 QQ “正在输入”
  • 允许处理群消息
  • groupWhitelist 留空时不过滤群;填了之后只响应指定群
  • 但群里必须 @ 机器人 才会回复

---

第 5 步:重启 OpenClaw Gateway

openclaw gateway restart

---

第 6 步:在 NapCat 里添加网络配置

去 NapCat 的网络配置界面,新增并启用下面两项:

A. Http 服务器

  • Host: 0.0.0.0
  • Port: 15150

B. Http 客户端

  • Url: http://127.0.0.1:18789/napcat
  • 消息格式: String

如果 OpenClaw 和 NapCat 不在同一台机器上,这里不要写 127.0.0.1,要改成 OpenClaw 那台机器的真实 IP。

例如:

http://192.168.1.10:18789/napcat

---

第 7 步:测试

现在你可以测试:

私聊测试

直接给对应 QQ 发消息。

群聊测试

在群里发:

@机器人 你好

如果配置正确,OpenClaw 就会开始处理消息。

---

如果你只想让特定 QQ 号能用

你可以加白名单:

{
  "channels": {
    "napcat": {
      "enabled": true,
      "url": "http://127.0.0.1:15150",
      "allowUsers": ["123456789", "987654321"],
      "enableGroupMessages": true,
      "groupMentionOnly": true
    }
  }
}

这表示:

  • 只有 123456789987654321 这两个 QQ 号发来的消息会触发机器人
  • 其他人发消息时,插件会直接忽略

如果你比较在意权限控制,建议开启。

---

如果你只想让特定群能用

你可以配置群白名单:

{
  "channels": {
    "napcat": {
      "enabled": true,
      "url": "http://127.0.0.1:15150",
      "enableGroupMessages": true,
      "groupWhitelist": ["123456789", "987654321"],
      "groupMentionOnly": true
    }
  }
}

这表示:

  • groupWhitelist 为空时,不按群号过滤
  • groupWhitelist 不为空时,只处理白名单里的群消息
  • 它和 allowUsersenableGroupMessagesgroupMentionOnly 可以同时使用

---

群聊怎么工作?

群消息有 3 种常见模式:

模式 1:完全不处理群消息

{
  "enableGroupMessages": false
}

适合:只想做私聊助手。

---

模式 2:处理群消息,但必须 @ 机器人(推荐)

{
  "enableGroupMessages": true,
  "groupWhitelist": ["123456789", "987654321"],
  "groupMentionOnly": true
}

适合:大多数群聊场景。 这样不会因为群里有人聊天就一直触发机器人。 如果再配上 groupWhitelist,就可以进一步限制只在指定群里生效。

---

模式 3:处理所有群消息(一般不推荐)

{
  "enableGroupMessages": true,
  "groupWhitelist": ["123456789"],
  "groupMentionOnly": false
}

适合:你非常确定自己需要“全群监听”。 否则容易太吵,也更容易误触发。 如果只想监听少数几个群,建议同时配置 groupWhitelist

---

发消息时,目标怎么写?

如果你要让 OpenClaw 主动往 QQ 发消息,最好明确写目标格式。

私聊目标

可以写:

  • private:<QQ号>
  • session:napcat:private:<QQ号>

例如:

  • private:123456789
  • session:napcat:private:123456789

群聊目标

可以写:

  • group:<群号>
  • session:napcat:group:<群号>

例如:

  • group:123456789
  • session:napcat:group:123456789

一个容易踩坑的点

如果你只写纯数字,比如:

123456789

插件会默认把它当成 私聊 QQ 号。 所以如果你要发到群,一定要加 group: 前缀

---

图片和语音怎么发?

图片

插件支持把图片当作 QQ 图片消息发送。

语音

如果媒体链接是这些后缀之一,会自动按语音消息发送:

  • .wav
  • .mp3
  • .amr
  • .silk
  • .ogg
  • .m4a
  • .flac
  • .aac

---

voiceBasePath 是干什么的?

如果你传的是相对文件名,比如:

test.wav

插件会去拼接:

<voiceBasePath>/test.wav

例如:

{
  "channels": {
    "napcat": {
      "voiceBasePath": "/tmp/napcat-voice"
    }
  }
}

那么 test.wav 会被解释成:

/tmp/napcat-voice/test.wav

如果你经常发本地语音,这个配置会很方便。

---

OpenClaw 和 NapCat 不在同一台机器上怎么办?

这种情况最常见的问题是:

文字能发,图片发不出去。

因为文字可以直接通过接口发送,但图片/语音常常需要 NapCat 去“拿文件”或“拉链接”。

这时建议开启 媒体代理

推荐配置

{
  "channels": {
    "napcat": {
      "url": "http://192.168.1.20:15150",
      "mediaProxyEnabled": true,
      "publicBaseUrl": "http://192.168.1.10:18789",
      "mediaProxyToken": "change-me"
    }
  }
}

意思是:

  • NapCat 在 192.168.1.20:15150
  • OpenClaw 对 NapCat 可访问的地址是 192.168.1.10:18789
  • 插件会把媒体地址改写成 http://192.168.1.10:18789/napcat/media?...
  • NapCat 再去这个地址拿图片/语音

你要注意

  • publicBaseUrl 必须是 NapCat 那台机器真的能访问到的地址
  • 如果设置了 mediaProxyToken,两边的请求必须带上正确 token
  • 防火墙 / Docker 端口映射 / 局域网访问都要打通

如果你是跨机器部署,建议优先看这里。

---

群文件上传怎么用?

这个插件不只是能发图片,还支持把本地文件上传到 QQ 群文件。

比如:

  • PDF
  • 压缩包
  • 文档
  • 其他本地文件

基本用法

当满足下面两个条件时,插件会自动按“群文件上传”处理:

1. 目标是群:group:<群号> 2. 你传的是本地文件路径

例如:

{
  "action": "send",
  "channel": "napcat",
  "target": "group:123456789",
  "message": "这是本次日报文件",
  "filePath": "/tmp/daily-report.pdf"
}

---

Docker 部署时要特别注意

如果 NapCat 在 Docker 容器里,而文件在宿主机上,NapCat 默认是看不到宿主机文件路径的。

所以你需要提供一个“宿主机目录 ↔ 容器目录”的映射。

常见做法有两种:

方案 A:直接使用已挂载路径

如果某个宿主机目录本来就已经挂载进 NapCat 容器,可以配置:

  • groupFileHostPrefix
  • groupFileContainerPrefix

例如:

{
  "channels": {
    "napcat": {
      "groupFileHostPrefix": "/Users/yourname/shared",
      "groupFileContainerPrefix": "/app/shared"
    }
  }
}

这样插件会把宿主机路径自动换算成容器内路径。

---

方案 B:使用暂存目录(更通用)

如果原文件不在挂载目录里,可以让插件先复制到一个“上传暂存目录”,再让 NapCat 从容器内对应目录读取。

配置示例:

{
  "channels": {
    "napcat": {
      "groupFileStageHostDir": "/Users/yourname/Docker/napcat/plugins/openclaw-upload",
      "groupFileStageContainerDir": "/app/napcat/plugins/openclaw-upload"
    }
  }
}

插件会:

1. 把文件复制到宿主机暂存目录 2. 告诉 NapCat 去读取容器内对应路径 3. 上传完成后自动清理暂存文件

这个方案对 Docker 用户通常最省心。

---

额外可选项:群文件默认目录

{
  "channels": {
    "napcat": {
      "groupFileFolder": ""
    }
  }
}

它对应 NapCat 的 folder 参数。 如果你希望上传进群文件的某个固定目录,可以在这里设置。

---

日志功能有什么用?

插件支持把收到的消息写入日志,方便你排查问题。

默认是开启的:

{
  "enableInboundLogging": true,
  "inboundLogDir": "./logs/napcat-inbound"
}

日志会按用户或群分别记录。 这对下面这些情况特别有帮助:

  • 机器人为什么没回复?
  • 是不是消息根本没进来?
  • NapCat 发过来的原始内容到底长什么样?

如果你在排查群消息、@ 识别、白名单、解析失败之类的问题,这个日志非常有价值。

---

按昵称或备注找 QQ / 群

issue #3 对应的改动已经包含在仓库里:现在提供了一个简单的联系人搜索脚本,适合配合 skill/napcat-qq 一起用。

为了避免 OpenClaw 的安装安全扫描误判,这个脚本默认不会包含在 npm 发布包里。 如果你是通过 openclaw plugins install @propersama/openclaw-napcat 安装的插件,并且想启用联系人搜索,请手动从仓库复制这个文件到本地 skill 目录。

脚本路径:

skill/napcat-qq/scripts/qq-contact-search.js

你可以从仓库拿到这个文件后,放到本地的同名路径,例如:

~/.openclaw/skills/napcat-qq/scripts/qq-contact-search.js

用法:

node skill/napcat-qq/scripts/qq-contact-search.js 小明
node skill/napcat-qq/scripts/qq-contact-search.js 测试群 group
node skill/napcat-qq/scripts/qq-contact-search.js 老王 private

说明:

  • 第一个参数是关键词
  • 第二个参数可选:private / group / all
  • 默认会去 NapCat 的 get_friend_list / get_group_list 做简单模糊匹配
  • 可通过环境变量覆盖连接信息:
  • NAPCAT_URL
  • NAPCAT_TOKEN

返回结果是 JSON,里面的 candidates 会列出匹配到的联系人或群,供 skill 再决定是直接发送、让用户选号,还是继续追问。

---

完整配置示例

如果你想一次把常用项都配好,可以参考下面这份:

{
  "channels": {
    "napcat": {
      "enabled": true,
      "agentId": "main",
      "url": "http://127.0.0.1:15150",
      "allowUsers": ["123456789", "987654321"],
      "enableGroupMessages": true,
      "groupWhitelist": ["123456789", "987654321"],
      "groupMentionOnly": true,
      "mediaProxyEnabled": true,
      "publicBaseUrl": "http://127.0.0.1:18789",
      "mediaProxyToken": "change-me",
      "voiceBasePath": "/your/voice/path",
      "groupFileFolder": "",
      "groupFileHostPrefix": "",
      "groupFileContainerPrefix": "",
      "groupFileStageHostDir": "",
      "groupFileStageContainerDir": "",
      "enableInboundLogging": true,
      "inboundLogDir": "/your/inbound/log/dir"
    }
  },
  "plugins": {
    "entries": {
      "napcat": {
        "enabled": true
      }
    }
  }
}

---

配置项说明(按人话解释)

下面是主要配置项的作用。

| 配置项 | 类型 | 这是干什么的 | 默认值 | |---|---|---|---| | url | string | NapCat 的 HTTP 服务地址 | http://127.0.0.1:15150 | | agentId | string | 固定把消息交给哪个 OpenClaw agent 处理;留空时按 OpenClaw 路由(可配 bindings) | "" | | allowUsers | string[] | 只允许这些 QQ 号触发机器人;空数组表示不过滤 | [] | | enableGroupMessages | boolean | 是否处理群消息 | false | | groupWhitelist | string[] | 只允许这些群号触发机器人;空数组表示不过滤群 | [] | | streaming_mode | boolean | 是否启用流式传输模式;开启后会按处理步骤连续发送 QQ 消息 | false | | enablePrivateTypingStatus | boolean | 是否在私聊处理中调用 NapCat 的输入状态接口,显示 QQ “正在输入” | true | | groupMentionOnly | boolean | 群里是否必须 @ 机器人才处理 | true | | mediaProxyEnabled | boolean | 是否开启媒体代理,解决跨机器图片/语音发送问题 | false | | publicBaseUrl | string | OpenClaw 对 NapCat 可访问的地址 | "" | | mediaProxyToken | string | 媒体代理的访问令牌(可选) | "" | | voiceBasePath | string | 相对语音文件名的基础目录 | "" | | groupFileFolder | string | 群文件默认上传目录 | "" | | groupFileHostPrefix | string | 宿主机上已挂载进容器的目录前缀 | "" | | groupFileContainerPrefix | string | 上面那个目录在容器里的对应路径 | "" | | groupFileStageHostDir | string | 宿主机上的上传暂存目录 | "" | | groupFileStageContainerDir | string | 上面暂存目录在容器里的对应路径 | "" | | enableInboundLogging | boolean | 是否记录收到的消息日志 | true | | inboundLogDir | string | 入站日志目录 | ./logs/napcat-inbound |

---

如果想按群路由到不同 agent

现在 NapCat 插件会把会话信息作为 peer 传给 OpenClaw 的路由器,你可以在 openclaw.json 里用 bindings 为特定群指定 agent:

"bindings": [
  {
    "agentId": "xxx",
    "match": {
      "channel": "napcat",
      "peer": {
        "kind": "group",
        "id": "群号1"
      }
    }
  },
  {
    "agentId": "yyy",
    "match": {
      "channel": "napcat",
      "peer": {
        "kind": "group",
        "id": "群号2"
      }
    }
  }
]

---

常见问题

1. 私聊能用,群里没反应

先检查:

  • enableGroupMessages 有没有设成 true
  • groupWhitelist 有没有把当前群拦掉
  • groupMentionOnly 是否开启
  • 你在群里有没有真的 @ 到机器人
  • allowUsers 有没有把发消息的人拦掉

---

2. 消息到了 NapCat,但 OpenClaw 没回复

先检查:

  • NapCat 的 Http 客户端 URL 是否正确
  • OpenClaw Gateway 是否正在运行
  • 插件是否真的安装并启用
  • 查看 inboundLogDir 里的日志,看消息有没有进入插件

---

3. 文字能发,图片发不出去

大概率是下面这些问题:

  • OpenClaw 和 NapCat 不在同一台机器上
  • mediaProxyEnabled 没开
  • publicBaseUrl 填错了
  • NapCat 根本访问不到 OpenClaw 提供的媒体地址

---

4. 群文件上传失败

大概率是路径问题:

  • 你传的不是本地文件路径
  • NapCat 容器看不到这个文件
  • groupFileHostPrefix / groupFileContainerPrefix 没配置好
  • 或者 groupFileStageHostDir / groupFileStageContainerDir 没配置好

如果你是 Docker 部署,这一条最容易踩坑。

---

5. 纯数字 target 发错地方了

如果你只写纯数字目标,插件会默认按私聊处理。 要发群消息,请明确写:

group:<群号>

---

项目结构(给需要看代码的人)

openclaw-napcat-plugin/
├── index.ts              # 插件入口
├── openclaw.plugin.json  # 插件元数据
├── package.json          # 包信息
├── src/
│   ├── channel.ts        # 消息发送逻辑
│   ├── runtime.ts        # 运行时状态
│   └── webhook.ts        # 接收 NapCat webhook
└── skill/
    └── napcat-qq         # 配套 skill
        └── scripts/
            └── qq-contact-search.js   # 联系人搜索脚本,npm 包默认不包含,需按需手动安装

---

License

MIT License

---

致谢

Related plugins

Browse all →