karin plugin adapter for qqbot
npm install @karinjs/adapter-qqbotQQ机器人适配器插件,为 Karin 框架提供 QQ 机器人支持。
- ✅ 支持 QQ 群聊消息收发
- ✅ 支持 QQ 好友消息收发
- ✅ 支持 QQ 频道消息收发
- ✅ 支持 WebSocket 和 Webhook 两种连接方式
- ✅ 支持多种 Markdown 模板(原生、图文模板、纯文模板)
- ✅ 支持沙盒环境和正式环境
- ✅ 完整的 TypeScript 类型定义
- ✅ 自动消息签名验证
``bash`
pnpm add @karinjs/adapter-qqbot -w
`bash`
npm install @karinjs/adapter-qqbot
`bash`
yarn add @karinjs/adapter-qqbot
- 已安装并配置好 Karin 框架
- Node.js >= 16
- 有QQ开放平台的机器人应用
1. 安装插件
`bash`
pnpm add @karinjs/adapter-qqbot -w
2. 获取机器人信息
- 访问 QQ开放平台
- 创建机器人应用,获取 AppID 和 Secret
3. 创建配置
`json`
[
{
"appId": "你的AppID",
"secret": "你的Secret",
"event": { "type": 1 }
}
]
4. 配置回调地址
- 在QQ开放平台设置统一回调地址:https://你的域名/qqbot/webhook
- 必须使用HTTPS协议,端口必须为443(默认HTTPS端口)
- 该地址接收所有事件:群聊、C2C私聊、频道消息等
5. 启动服务
`bash`
npm start
完成!现在可以邀请机器人到群聊测试了。
1. 访问 QQ开放平台
2. 登录并创建新的机器人应用
3. 获取 AppID 和 Secret
4. 记录这些信息,后续配置需要用到
配置文件位置:@karinjs/@karinjs-adapter-qqbot/config/config.json
如果文件不存在,插件会自动创建一个空的配置文件。
#### 最简配置示例
`json`
[
{
"appId": "你的机器人AppID",
"secret": "你的机器人Secret"
}
]
#### 完整配置示例
`json`
[
{
"appId": "你的机器人AppID",
"secret": "你的机器人Secret",
"prodApi": "https://api.sgroup.qq.com",
"sandboxApi": "https://sandbox.api.sgroup.qq.com",
"tokenApi": "",
"sandbox": false,
"qqEnable": true,
"guildEnable": true,
"guildMode": 0,
"exclude": [],
"regex": [
{
"reg": "^/",
"rep": "#"
}
],
"markdown": {
"mode": 0,
"id": "",
"kv": [
"text_start",
"img_dec",
"img_url",
"text_end"
]
},
"event": {
"type": 1,
"wsUrl": "",
"wsToken": ""
}
}
]
#### 方式一:Webhook(推荐)
适用场景: 有公网IP或域名的服务器
1. 在配置文件中设置:
`json`
{
"event": {
"type": 1
}
}
2. 在QQ开放平台配置回调地址:
- 回调地址格式:https://你的域名/qqbot/webhookhttps://your-domain.com/qqbot/webhook
- 例如:
- ⚠️ 重要限制:
- 必须使用 HTTPS 协议
- 端口必须为 443(标准HTTPS端口)
- 不支持自定义端口(如:8080、:3000等)
> 重要说明: 这是统一的回调地址,QQ开放平台会将所有配置的事件类型(群聊、C2C私聊、频道消息等)都发送到这个地址。您不需要为不同的消息类型配置不同的回调地址。
#### 方式二:WebSocket
适用场景: 内网环境,需要通过中转服务连接
1. 在配置文件中设置:
`json`
{
"event": {
"type": 2,
"wsUrl": "wss://your-websocket-server/ws",
"wsToken": "你的ws认证token"
}
}
> 为什么需要反向代理?
>
> QQ开放平台对Webhook回调地址有严格要求:
> - 必须使用HTTPS协议(不支持HTTP)
> - 端口必须为443(标准HTTPS端口,不支持自定义端口)
> - 必须有有效的SSL证书
>
> 如果你的Karin服务运行在:
> - 内网服务器(如家用电脑、局域网服务器)
> - 云服务器的内网端口(如3000端口)
> - Docker容器内部
>
> 就需要通过反向代理将内网服务暴露到公网的443端口,并配置SSL证书。
#### 反向代理的目标
反向代理要代理的地址: http://127.0.0.1:3000/qqbot/webhook
这是Karin QQBot适配器监听的统一webhook接收地址,用于接收所有类型的QQ机器人事件,包括:
- 群聊消息(GROUP_AT_MESSAGE_CREATE)
- C2C私聊消息(C2C_MESSAGE_CREATE)
- 频道消息(GUILD_MESSAGE_CREATE)
- 频道私信(DIRECT_MESSAGE_CREATE)
- 其他机器人事件
QQ开放平台会将所有配置的事件都发送到这个统一的回调地址,然后由适配器内部根据事件类型进行分发处理。
#### 方案一:Nginx 反向代理(推荐)
1. 安装Nginx
`bashUbuntu/Debian
sudo apt update && sudo apt install nginx
2. 创建配置文件
创建
/etc/nginx/sites-available/karin-qqbot:`nginx
server {
listen 80;
server_name your-domain.com; # 替换为你的域名或公网IP
# QQ机器人webhook接收地址
location /qqbot/webhook {
# 代理到本地Karin服务
proxy_pass http://127.0.0.1:3000/qqbot/webhook;
# 必要的代理头设置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 关键配置:保持原始请求体用于签名验证
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
}
# 可选:为Karin的其他功能添加代理
location /karin/ {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
`获取免费SSL证书(Let's Encrypt):
`bash
1. 安装certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx2. 获取SSL证书(自动配置Nginx)
sudo certbot --nginx -d your-domain.com3. 测试自动续期
sudo certbot renew --dry-run4. 设置自动续期(可选)
sudo crontab -e
添加以下行:
0 12 * /usr/bin/certbot renew --quiet
`手动配置SSL证书:
如果你有其他SSL证书提供商的证书,按以下格式配置:
`nginx
ssl_certificate /path/to/your/certificate.crt; # 证书文件
ssl_certificate_key /path/to/your/private.key; # 私钥文件
`3. 启用配置
`bash
创建软链接启用站点
sudo ln -s /etc/nginx/sites-available/karin-qqbot /etc/nginx/sites-enabled/测试配置文件语法
sudo nginx -t重载配置
sudo systemctl reload nginx确保Nginx开机自启
sudo systemctl enable nginx
`4. 配置HTTPS(必需)
> ⚠️ 重要: QQ开放平台强制要求使用HTTPS协议和443端口,以下配置是必需的,不是可选的。
`nginx
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL证书配置(使用Let's Encrypt免费证书)
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# 如果没有SSL证书,可以使用以下命令获取Let's Encrypt免费证书:
# sudo apt install certbot python3-certbot-nginx
# sudo certbot --nginx -d your-domain.com
# SSL优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_prefer_server_ciphers on;
location /qqbot/webhook {
proxy_pass http://127.0.0.1:3000/qqbot/webhook;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 保持原始请求体
proxy_buffering off;
proxy_request_buffering off;
}
}HTTP自动跳转HTTPS(推荐配置)
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
`#### 方案二:宝塔面板配置
1. 创建网站
- 域名:填写你的域名
- 根目录:可以是任意目录(不会用到)
2. 配置SSL证书(必需)
- 进入网站设置 → SSL
- 申请Let's Encrypt免费证书或上传自有证书
- 开启"强制HTTPS"
3. 添加反向代理
有两种配置方式,选择其一:
方式一:代理整个域名到Karin服务
- 代理名称: Karin Service
- 目标URL:
http://127.0.0.1:3000
- 发送域名: $host
- 代理目录: /方式二:只代理webhook路径(推荐)
- 代理名称: QQBot Webhook
- 目标URL:
http://127.0.0.1:3000/qqbot/webhook
- 发送域名: $host
- 代理目录: /qqbot/webhook> 推荐使用方式一,这样整个域名都会指向您的Karin服务,QQ开放平台访问
https://your-domain.com/qqbot/webhook 时会被代理到 http://127.0.0.1:3000/qqbot/webhook。4. 高级设置
添加以下配置到反向代理的配置文件中:
`nginx
proxy_buffering off;
proxy_request_buffering off;
`> 重要提醒: 确保网站已启用HTTPS并强制跳转,QQ开放平台只接受HTTPS协议的回调地址。
#### 方案三:Caddy 服务器
1. 安装Caddy
`bash
参考官方文档安装Caddy
`2. 创建Caddyfile
`caddy
your-domain.com {
reverse_proxy /qqbot/webhook/* 127.0.0.1:3000
# 自动HTTPS
tls {
on_demand
}
}
`#### 方案四:Cloudflare Tunnel(内网穿透)
适用场景: 没有公网IP,通过Cloudflare暴露服务
1. 安装cloudflared
`bash
下载并安装cloudflared
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
`2. 登录Cloudflare
`bash
cloudflared tunnel login
`3. 创建隧道
`bash
cloudflared tunnel create karin-qqbot
`4. 配置DNS
`bash
cloudflared tunnel route dns karin-qqbot your-subdomain.your-domain.com
`5. 运行隧道
`bash
cloudflared tunnel run --url http://localhost:3000 karin-qqbot
`#### 方案五:frp 内网穿透
适用场景: 使用自建或第三方frp服务
客户端配置 (frpc.ini):
`ini
[common]
server_addr = your-frp-server.com
server_port = 7000
token = your_token[karin-qqbot]
type = http
local_ip = 127.0.0.1
local_port = 3000
custom_domains = your-domain.com
`$3
#### 官方限制条件
QQ开放平台对Webhook回调地址有以下强制要求:
| 要求项 | 限制 | 说明 |
|--------|------|------|
| 协议 | 必须HTTPS | 不支持HTTP协议 |
| 端口 | 必须443 | 不支持自定义端口(如:8080、:3000等) |
| SSL证书 | 必须有效 | 需要被浏览器信任的证书 |
| 域名 | 必须有域名 | 不支持IP地址直接访问 |
| 响应时间 | 3秒内 | 超时会重试 |
#### 正确的回调地址格式
✅ 正确格式:
-
https://your-domain.com/qqbot/webhook
- https://bot.your-company.com/qqbot/webhook❌ 错误格式:
-
http://your-domain.com/qqbot/webhook (不支持HTTP)
- https://your-domain.com:3000/qqbot/webhook (不支持自定义端口)
- https://123.456.789.10/qqbot/webhook (不支持IP地址)$3
#### 域名解析配置
确保域名正确解析到你的服务器:
`bash
检查域名解析
nslookup your-domain.com
dig your-domain.com
`#### 防火墙配置
Ubuntu/Debian (ufw):
`bash
开放HTTP和HTTPS端口
sudo ufw allow 80
sudo ufw allow 443如果直接暴露端口
sudo ufw allow 3000
`CentOS/RHEL (firewalld):
`bash
开放端口
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
`云服务器安全组:
- 阿里云:安全组规则添加入方向 80、443 端口
- 腾讯云:防火墙规则添加入站 80、443 端口
- AWS:Security Group 添加 HTTP、HTTPS 规则
$3
| 参数 | 说明 | 默认值 |
|------|------|--------|
|
appId | 机器人ID(必填) | "" |
| secret | 机器人密钥(必填) | "" |
| sandbox | 是否使用沙盒环境 | false |
| qqEnable | 是否启用QQ场景 | true |
| guildEnable | 是否启用频道场景 | true |
| guildMode | 频道模式(0公域,1私域) | 0 |
| event.type | 事件接收方式(0关闭,1webhook,2ws) | 0 |#### Markdown 模式说明
| 模式 | 说明 | 适用场景 |
|------|------|----------|
| 0 | 直接发送 | 简单文本和图片消息 |
| 1 | 原生Markdown | 需要富文本格式 |
| 3 | 旧图文模板 | 复杂图文混排 |
| 4 | 纯文模板 | 多段文本消息 |
| 5 | 自定义处理 | 完全自定义逻辑 |
#### 支持的事件类型
QQ机器人适配器通过统一的webhook地址接收以下事件类型:
| 事件类型 | 说明 | 处理函数 |
|---------|------|---------|
|
GROUP_AT_MESSAGE_CREATE | 群聊@机器人消息 | onGroupMsg |
| C2C_MESSAGE_CREATE | C2C私聊消息 | onFriendMsg |
| GUILD_MESSAGE_CREATE | 频道消息 | onChannelMsg |
| DIRECT_MESSAGE_CREATE | 频道私信 | onDirectMsg |所有这些事件都通过同一个回调地址
/qqbot/webhook 接收,适配器内部会根据事件类型自动分发到对应的处理函数。使用说明
$3
#### 1. Webhook 方式
- 优点:配置简单,不需要额外的中转服务
- 缺点:需要有公网IP或域名
- 适用场景:有固定服务器或云服务器的用户
配置完成后,需要在 QQ 开放平台配置 Webhook 回调地址。
#### 2. WebSocket 方式
- 优点:适合内网环境,通过中转服务连接
- 缺点:需要额外部署中转服务
- 适用场景:没有公网IP的本地开发环境
$3
#### 模式 0:直接发送(推荐)
最简单的模式,直接发送纯文本和图片消息。
#### 模式 1:原生 Markdown
使用 QQ 官方的原生 Markdown 格式发送消息。
#### 模式 3:旧图文模板 Markdown
使用旧版图文混排模板,适合需要复杂排版的场景。
#### 模式 4:纯文模板 Markdown
使用纯文本模板,支持多个文本字段。
#### 模式 5:自定义处理
完全自定义消息处理逻辑。
开发指南
$3
- Node.js >= 16
- TypeScript >= 5.0
- Karin 框架
$3
1. 克隆仓库
`bash
git clone https://github.com/KarinJS/karin-plugin-adapter-qqbot.git
cd karin-plugin-adapter-qqbot
`2. 安装依赖
`bash
npm install
`3. 开发模式运行
`bash
npm run dev
`$3
项目使用
tsup 进行打包,同时会运行 tsc 进行类型检查。`bash
npm run build
`构建产物会输出到
dist 目录。$3
`bash
npm run lint
`$3
`bash
发布正式版
npm run pub发布测试版
npm run pub-beta
`项目结构
`
karin-plugin-adapter-qqbot/
├── src/
│ ├── connection/ # 连接层(WebSocket、Webhook、路由)
│ ├── core/ # 核心功能(适配器、事件处理、API)
│ ├── types/ # TypeScript 类型定义
│ └── utils/ # 工具函数
├── dist/ # 构建产物
├── config/ # 配置文件目录
├── package.json
├── tsconfig.json # TypeScript 配置
└── tsup.config.ts # 打包配置
`API 使用示例
$3
`typescript
import type { AdapterQQBot } from '@karinjs/adapter-qqbot'// 在你的插件中使用
export class MyPlugin extends plugin {
async handleGroupMessage(e: KarinMessage) {
const bot = e.bot as AdapterQQBot
// 发送消息
await bot.SendMessage(e.contact, [
{ type: 'text', text: 'Hello, World!' }
])
}
}
`$3
`typescript
await bot.recallMsg(e.contact, messageId)
`常见问题
$3
#### 1. 检查配置文件
确保配置文件格式正确:
`bash
查看配置文件
cat @karinjs/@karinjs-adapter-qqbot/config/config.json
`#### 2. 启动服务
`bash
启动 Karin 服务
npm start
或者
node app.js
`#### 3. 查看日志
检查日志文件,确认机器人连接成功:
`bash
查看最新日志
tail -f logs/error/*.log
`正常情况下应该看到类似信息:
-
QQBot [AppID] 连接成功
- Webhook服务已启动,端口: 3000#### 4. 测试机器人
1. 将机器人邀请到测试群
2. 发送消息测试机器人响应
3. 检查日志确认消息接收正常
$3
#### 问题1:Webhook接收不到消息
检查清单:
- [ ] QQ开放平台回调地址配置正确
- [ ] 服务器防火墙开放对应端口
- [ ] Nginx反向代理配置正确
- [ ] 域名解析正确指向服务器IP
排查命令:
`bash
检查端口是否监听
netstat -tlnp | grep :3000检查防火墙状态
sudo ufw status测试本地接口
curl -X POST http://localhost:3000/qqbot/webhook
`#### 问题2:签名验证失败
可能原因:
- Secret配置错误
- 反向代理修改了请求体
- 时间戳差异过大
解决方案:
`nginx
Nginx配置中添加
proxy_buffering off;
proxy_request_buffering off;
`#### 问题3:消息发送失败
检查清单:
- [ ] AppID和Secret正确
- [ ] 机器人有发送消息权限
- [ ] API地址配置正确
- [ ] 网络连接正常
#### 问题4:频道消息收不到
可能原因:
- 频道机器人权限不足
- guildEnable配置为false
- 私域机器人未正确配置
解决方案:
`json
{
"guildEnable": true,
"guildMode": 1 // 私域机器人使用1
}
`$3
#### 多机器人配置
`json
[
{
"appId": "机器人1的AppID",
"secret": "机器人1的Secret",
"event": { "type": 1 }
},
{
"appId": "机器人2的AppID",
"secret": "机器人2的Secret",
"event": { "type": 1 }
}
]
`#### 环境分离配置
开发环境使用沙盒:
`json
{
"sandbox": true,
"sandboxApi": "https://sandbox.api.sgroup.qq.com"
}
`生产环境使用正式API:
`json
{
"sandbox": false,
"prodApi": "https://api.sgroup.qq.com"
}
`#### 消息过滤配置
`json
{
"exclude": [
"https://example.com",
"https://trusted-site.com"
],
"regex": [
{
"reg": "^/",
"rep": "#"
},
{
"reg": "\\[图片\\]",
"rep": ""
}
]
}
``查看 CHANGELOG.md 了解版本更新历史。
欢迎提交 Issue 和 Pull Request!
本项目基于 [项目许可证] 开源。
- Karin 框架
- QQ 机器人开放平台
- QQ 机器人开发文档
如有问题,请通过以下方式获取帮助:
- 提交 GitHub Issue
- 加入 Karin 开发者社群