使用webhook方式搭建QQ群机器人
最近突然想开发一个 QQ 群机器人,于是就去找了相关资料,发现有 websocket
和 webhook
两种方式,但是 websocket
方式将慢慢弃用转向 webhook
方式
既然都弃用了,那肯定要选新的方式了,于是就尝试使用 webhook
方式来搭建一个 QQ 群机器人
这篇文章用于记录机器人的开发环境搭建
创建机器人
首先根据文档的描述,注册一个账号,然后在QQ开放平台创建一个机器人
机器人创建好之后,找一个自己是群主或者管理员的少于20个人的群,在沙箱配置中设置该群,然后在 QQ 群中将机器人加入群聊

创建机器人之后,在开发管理中查看机器人的 AppID
和 Token
,并生成 AppSecret
,记好备用

准备环境
为了搭建官方 QQ 群机器人,需要一个经过 ICP 备案的域名,并将这个域名指向一台国内的服务器
域名指向服务器后,需要申请 SSL 证书,如果是国内的提供商,一般有免费的 SSL 证书可以直接申请,也可以使用 acme 申请证书
申请 SSL 证书后,将证书上传到服务器以备后续使用
开发环境搭建
机器人框架我使用的是 NoneBot,需要 Python3.9 以上的版本,Ubuntu 可以直接安装
1
| sudo apt install python3.9 python3.9-venv python3.9-dev
|
然后创建一个虚拟环境
1 2 3 4 5 6 7
| mkdir QQ_BOT cd QQ_BOT python3.9 -m venv .venv
source .venv/bin/activate pip install pipx pipx install nb-cli
|
按照文档安装 nonebot2 以及驱动器,为了使用 webhook 方式,需要安装 fastapi 和 httpx 这两个驱动器
1 2
| nb driver install nonebot2[fastapi] nb driver install nonebot2[httpx]
|
再安装适配器,这里使用的官方 QQ 的适配器
1
| nb adapter install nonebot-adapter-qq
|
配置反向代理
官方 QQ 群机器人必须使用 HTTPS
,所以需要安装 nginx 来配置反向代理
创建配置文件 /etc/nginx/sites-available/域名.conf
,并编辑如下配置,其中的域名请替换为自己的域名,自定义端口可以随意设置,只要与后面的机器人配置的端口一致即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| server { listen 80; server_name 域名; return 301 https://$host$request_uri; # 强制HTTP跳转到HTTPS }
server { listen 443 ssl http2; server_name 域名;
# SSL证书路径 ssl_certificate /path/to/your/domain.crt; ssl_certificate_key /path/to/your/domain.key;
# SSL协议和加密套件 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; ssl_prefer_server_ciphers on;
# 反向代理配置 location /qq/webhook { proxy_pass http://127.0.0.1:自定义端口/qq/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_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
|
保存并退出后,使用命令链接配置文件
1
| sudo ln -sf /etc/nginx/sites-available/域名.conf /etc/nginx/sites-enabled/
|
测试配置文件是否正确,并重载 nginx 服务
1 2
| sudo nginx -t sudo systemctl reload nginx
|
配置机器人
在 QQ_BOT
目录下创建一个 .env
文件,并编辑如下内容,其中的 id
, token
, secret
分别为前面开发管理中获取到的AppID
和 Token
,和生成的 AppSecret
1 2 3 4 5 6 7 8 9 10 11 12
| HOST=0.0.0.0 PORT=自定义端口,与nginx配置文件中的端口一致 COMMAND_START=["/", ""] COMMAND_SEP=[".", " "] DRIVER=~fastapi+~httpx LOG_LEVEL=DEBUG API_TIMEOUT=10.0 NICKNAME=["机器人昵称1", "机器人昵称2"] SESSION_EXPIRE_TIMEOUT=00:02:00 QQ_IS_SANDBOX=true
QQ_BOTS=[{"id":"xxx","token":"xxx","secret":"xxx","intent":{"c2c_group_at_messages":true},"use_websocket":false}]
|
测试机器人
写一个简单的小功能测试机器人是否搭建完成
在 QQ_BOT
下创建机器人主文件 bot.py
,内容如下
1 2 3 4 5 6 7 8 9 10 11 12
| import nonebot from nonebot.adapters.qq import Adapter as QQAdapter
nonebot.init()
driver = nonebot.get_driver() driver.register_adapter(QQAdapter)
nonebot.load_plugins("my_bot/plugins")
if __name__ == "__main__": nonebot.run()
|
在 QQ_BOT
下创建一个目录,并再在其下创建一个 plugins
目录,在 plugins
目录下创建一个 repeater.py
文件,内容如下
1 2 3 4 5 6 7 8 9 10
| from nonebot import on_message from nonebot.adapters.qq import MessageEvent, MessageSegment
repeater = on_message()
@repeater.handle() async def repeat(event: MessageEvent): msg = event.get_plaintext() await repeater.send(MessageSegment.text(msg))
|
目录结构如下
1 2 3 4 5 6
| QQ_BOT/ ├── bot.py ├── .env ├── my_bot/ │ └── plugins/ │ │ └── repeater.py
|
这段代码可以使机器人重复发送所有收到的消息,使用如下命令启动机器人
1 2
| source .venv/bin/activate python bot.py
|
启动之后,在 QQ 开放平台的机器人页面中,回调配置地址设置为 https://your_domain/qq/webhook/
在沙箱群中,测试机器人是否正常运行

突然奇想想开发一个机器人,小时候用过一键脚本搭建过机器人,那时候还什么技术都不懂,只知道这样很好玩,现在长大了,学了很多技术了,可以尝试自己实现一个想要的功能了(★O∀O*)◇+。