go-cqhttp,基于 Mirai 以及 MiraiGo 的 OneBot Golang 原生实现,只需简单的配置, 就可以基于 go-cqhttp 使用框架开发,具有轻量, 原生, 高并发, 低占用, 跨平台等特点。
1 go-cqhttp 官网及可执行文件下载链接
- go-cqhttp 官网:https://go-cqhttp.org/
- 开发文档:https://docs.go-cqhttp.org/
- 下载页连接:https://github.com/Mrs4s/go-cqhttp/releases,目前版本为1.2.0,在下载页的底部 Assets 的位置,您可以根据需要选择对应的版本,docker 的 alpine 系统下安装,我选 linux_amd64.tar.gz 压缩版本 。
下载后解压缩,里面包含了 3 个文件,其中最关键的文件为: go-cqhttp 执行文件:
2 go-cqhttp 模块目录结构
- copy_into_volume/1.2.0 目录
此目录下面的内容为刚才从 go-cqhttp 官网下载解压后的 3 个文件,此文件会通过 Dockerfile 的编排,打包到镜像里,以后就不用再下载了 - volumes/bs-cqhttp 目录
此目录为容器运行时的映射目录,初始是空的,当容器生成时,会将目录 copy_into_volume/1.2.0 下面的 3 个文件拷到容器的工作目录里(容器工作目录为 /app/bs-cqhttp ,且此工作。目录映射到了宿主机的 volumes/bs-cqhttp 目录) - Dockerfile 文件和 sh 执行脚本文件
此部分文件和前面模块里讲到的文件功能相似,只是内容略有变化。
3 关于 bs-cqhttp 的镜像配置
此模块镜像的功能相对简单,主要是实现模块功能的配置,没有什么业务逻辑,所以模块并不需要安装 python 环境。
代码说明:
- 下面的文件里加入了时区,这样系统的时间就和我国的时间相同了,其他模块课参照此功能添加时区处理。
- go-cqhttp 执行文件先拷贝到镜像的 /opt/app/bs-cqhttp/copy_into_volume/ 目录下,以备在生成容器时,将此几个文件拷到工作目录 /app/bs-cqhttp 下
COPY ./copy_into_volume /opt/app/bs-cqhttp/copy_into_volume/
Dockerfile 完整代码如下:
# 引用官方的轻量级基础镜像
FROM alpine:3.10
# 定义作者信息
LABEL MAINTAINER="tanbushi@qq.com"
# 设置国内源更新系统、安装 bash
RUN echo "https://mirrors.ustc.edu.cn/alpine/v3.13/main" > /etc/apk/repositories && \
echo "https://mirrors.ustc.edu.cn/alpine/v3.13/community" >> /etc/apk/repositories && \
apk update && apk upgrade && \
apk add tzdata bash && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone
# 设置环境变量
ENV WORK_DIR /app/bs-cqhttp
# 设置工作目录
WORKDIR $WORK_DIR
# 拷贝运行时文件(go-cqhttp v1.2.0 内核文件)
COPY ./copy_into_volume /opt/app/bs-cqhttp/copy_into_volume/
# entrypoint.sh 文件为容器启动时自执行文件,拷贝到镜像工作目录下备调用
COPY entrypoint.sh /root/bs-cqhttp/entrypoint.sh
# 镜像启动时调用 entrypoint.sh 文件
ENTRYPOINT [ "/bin/bash", "-c", "/root/bs-cqhttp/entrypoint.sh" ]
4 配置文件 config.sh
此配置文件内容如下,和前述模块的配置文件类似,不做解释:
#!/bin/bash
# 基本参数
appName="bs-cqhttp" # 应用名称
appVersion="0.0.1" # 应用版本号
imageName="$appName:$appVersion" # 镜像名称
containerName="$appName" # 容器名称
# 下面的路径用到了 pwd 命令,默认要求当前脚本文件和 volumes 目录同在项目目录下(本例项目目录为 bs-cahttp 目录)
volumes=("`pwd`/volumes/bs-cqhttp:/app/bs-cqhttp")
# 标记是否已经配置过
configured=true # 标记变量——此脚本已经被执行过
5 运行 build.sh 生成 Docker 镜像
脚本 build.sh 内容为:
#!/bin/bash
set -e # 遇到错误时退出脚本
# 判断是否运行过配置文件 config.sh,如果未运行过,则运行配置文件
if [ -z "$configured" ]; then
. ./config.sh
# configured=true # 设置一个标志,表示已经运行过配置文件
fi
# 检查Docker命令是否可用
if ! command -v docker &> /dev/null; then
echo "Docker 命令不可用,请确保已经安装并启动了Docker。"
exit 1
fi
# 检查 Docker 是否在运行
if ! docker info > /dev/null 2>&1; then
echo "Docker 没用运行。请启动 Docker 再试!"
exit 2
fi
# 判断 Dockerfile 文件是否存在
if [ ! -f "Dockerfile" ]; then
echo "Dockerfile 文件不存在。请检查!"
exit 3
fi
# 构建镜像,注意此处用到了
docker build -t $imageName .
echo ""
echo "*********************************************************"
echo "成功生成 Docker 镜像:【 $imageName 】!"
echo "*********************************************************"
echo ""
6 运行 run.sh 创建容器
脚本 run.sh 的内容为:
#!/bin/bash
# 运行初始化脚本
. ../../shell-scripts/run_init.sh
# 创建并执行临时文件——实现 docker run 命令(临时文件不是在容器里哦!)
. ../../shell-scripts/run_in_tmp.sh
echo ""
echo "*********************************************************"
echo "成功创建容器:【 $containerName 】!"
echo "*********************************************************"
echo ""
此处调用的 run_init.sh 和 run_in_tmp.sh 是公共脚本,内容可参照:《docker安装并跑通QQ机器人实践(2)-签名服务器bs-qsign搭建》里的对应代码。
7 一次性构建脚本和创建容器脚本 all.sh
脚本 all.sh 内容为:
#!/bin/bash
# 构建镜像
. ./build.sh
# 运行容器
. ./run.sh
8 运行模块
8.1 先运行 bs-qsign
cd bs-qsign
./run.sh
8.2 再运行 bs-nonebot
cd bs-nonebt
./all.sh
启动后,进入 bs-nonebot 容器,运行 bot.py
模块,最后再运行 bs-cqhttp 模块。
用终端,cd 到 bs-cqhttp 目录下,运行下面的命令:
8.3 最后运行 bs-cqhttp
cd bs-cqhttp
./all.sh
即可生成镜像、启动容器。
bs-cqhttp 容器启动后,会立即执行 entrypoint.sh 文件,代码如下:
#!/bin/bash
if [ -d "/opt/app/bs-cqhttp/copy_into_volume/1.2.0" ]; then
cp -u -r /opt/app/bs-cqhttp/copy_into_volume/1.2.0/. /app/bs-cqhttp/
rm -fr /opt/app/bs-cqhttp/copy_into_volume/1.2.0
fi
echo "haha..."
# tail -f /dev/null
# 死循环
while [ ! -f "./willbreak" ]; do
echo "目前在循环等待状态,如果需要退出循环,启动 cqhttp,请创建 /root/bs-cqhttp/willbreak 文件"
sleep 5
if [ -f "./willbreak" ]; then
break
fi
done
echo "开始执行 ./go-cqhttp"
./go-cqhttp
9 配置 bs-cqhttp
9.1 查看初始执行文件
检查宿主机的映射目录:volumes/bs-cqhttp,里面只有三个初始目录,见下图:
9.2 执行 go-cqhttp 文件
选择反向代理,生成 config.yml 文件
9.3 修改 config.yml 文件
1)填写 QQ 账号、密码
因为手表协议功能有限,所以采用账号密码登录(不用手表协议2),部分 QQ 能通过,但部分 QQ 始终通不过,可能和 QQ 号是否长期未使用有关,我在慢慢挂(“洗”)小号,不知是否有效。建议不要使用重要的 QQ 号,怕万一被封造成损失。
2)配置签名服务器
主机不要写“localhost”、“127.0.0.1”,因为在 bs-cqhttp 容器内部是没办法通过此种主机名找到签名服务器 bs-qsign 的,主机名请写死“host.docker.internal”,端口根据前面服务器容器映射的端口:18080。
3)配置反向代理服务器
连接到 bs-nonebot 容器的映射端口 15703,主机名也同样为:“host.docker.internal”,注意最后有个
/ws
config.yml配置完毕,需要再运行一次 ./go-cqhttp,这次要创建 device.json 配置文件。
上图信息:
- 生成了新的 device.json 文件
- 连接前面服务器成功
- QQ 登录成功
- 连接反向 websocker 服务器成功
启动 QQ 给机器人发指令 /echo,测试自动回复功能:
自动回复成功,说明 bs-nonebot 运行正常!
9.4 修改 device.json 文件
- “protocol” 默认为6,保持原值,不要修改
图12 设备协议 protocol - 修改 device.json 里的 android_id
在 bs-nonebot 模块的 config.sh 文件里,设置了 ANDROID 环境变量
图13 ANDROID_ID 配置
device.json 文件里并没有进行相应修改,他们目前是不一致的,但没有影响 QQ 消息收发,至于是否需要一致,我也不清楚。为了避免有什么影响,建议还是将二者改为一致。修改后:
图14 device.json 里的 android_id 配置
9.5 启动 go-cqhttp 的自动运行
bs-cqhttp 容器启动后,先执行 entrypoint.sh 文件,此文件中有这样的一段代码:
# 死循环
while [ ! -f "./willbreak" ]; do
echo "目前在循环等待状态,如果需要退出循环,启动 cqhttp,请创建 /root/bs-cqhttp/willbreak 文件"
sleep 5
if [ -f "./willbreak" ]; then
break
fi
done
echo 开始执行 ./go-cqhttp"
./go-cqhttp
启动后会进入死循环,无法执行 ./go-cqhttp。此死循环的循环条件是:当在当前目录下找不到 willbreak 文件时(可以是空文件),就一直循环,当找到 willbreak 文件时,就退出循环,所以在 go-cqhttp 所在的工作目录下创建一个 willbreak 文件即可。
在 Docker 管理器的 Exec 页面,Ctrl+C停止go-cqhttp的运行,使用touch 命令创建文件 willbreak
center>图15 停止entryoint.sh 里的死循环
以后 bs-cqhttp 容器启动时,go-cqhttp 就可以正常运行了。当下次重启容器时,不让go-cqhttp运行,删掉这个 willbreak 文件即可。
至此,基于 Docker 的 QQ 机器人框架就搭建完成了(注意,测试代码bot.py并没有自动加载运行,请自行完善,避免测试时“入坑”)。
下一步的工作就是玩转 nonebot 就可以了,通过开发或使用第三方 nonebot 插件实现 QQ 机器人的智能,也就是对接大模型或自建的知识库以后,就可以让 QQ 机器人上线了。
上一篇:docker安装并跑通QQ机器人实践(3)-bs-nonebot搭建
下一篇:没有了