协议端 go-cqhttp 安装

使用 mirai 以及 MiraiGo 开发的 cqhttp golang 原生实现,并在 cqhttp 原版 的基础上做了部分修改和拓展。

测试版下载地址:https://github.com/Mrs4s/go-cqhttp/releases

正式版下载地址:https://github.com/Mrs4s/go-cqhttp/releases

例如:宝塔 centos 系统服务器 Linux 版本

go-cqhttp_linux_amd64.tar.gz	4.8 MB	Jun 27

window 版本 zip 解压

docker 比宝塔方便吗 docker和宝塔的区别_docker 比宝塔方便吗


go-cqhttp 接口

在 PowerShell 窗口进行运行:shift + 右击 进入 PowerShell 窗口运行

Windows 标准启动方法
双击 go-cqhttp_*.exe,根据提示生成运行脚本
双击运行脚本
PS C:\Users\Administrator\Desktop\go-cqhttp_windows_amd64> .\go-cqhttp.exe
未找到配置文件,正在为您生成配置文件中!
请选择你需要的通信方式:
> 0: HTTP通信
> 1: 云函数服务
> 2: 正向 Websocket 通信
> 3: 反向 Websocket 通信
请输入你需要的编号(0-9),可输入多个,同一编号也可输入多个(如: 233)
您的选择是: 3
默认配置文件已生成,请修改 config.yml 后重新启动!

在当前目录生成 config.yml 配置文件

go-cqhttp 性能

在关闭数据库的情况下, 加载 25 个好友 128 个群运行 24 小时后内存使用为 10MB 左右. 开启数据库后内存使用将根据消息量增加 10-20MB , 如果系统内存小于 128M 建议关闭数据库使用。

go-cqhttp 交互

在 go-cqhttp 成功运行之后, 你就可以通过自己写的程序, 使用 HTTP 或者 WebSocket 与 go-cqhttp 进行通讯, 实现 QQ 机器人. 在这个过程中, 你的程序只需要把一些数据发送给 go-cqhttp, 关于 QQ 的通信协议, go-cqhttp 会帮你解决.

你也可以将 go-cqhttp 部署在你的服务器上, 并加上验证, 这样, 你就可以在各个地方使用自己的程序连接到远程的 go-cqhttp.

想要与 go-cqhttp 进行通信, 你可以使用专门为 go-cqhttp 开发的开源 SDK, 这是最好的选择. 不过你也可以直接使用实现 OneBot 协议的开源 SDK, 只是他们可能并不包含 go-cqhttp 中的某些 API 或者消息类型, 这或许会影响你的使用体验。

跳过启动 5s 延时

使用命令行参数 faststart即可跳过启动的五秒钟延时,例如

# Windows
.\go-cqhttp.exe -faststart

go-cqhttp config.yml 配置文件

CQ Code CQ 码

CQ 码是指 CQ 中特殊消息类型的文本格式, 这是它的基本语法:

CQ 码文档地址:https://docs.go-cqhttp.org/cqcode

[CQ:类型,参数=值,参数=值]

在 QQ 中, 一个消息由多个部分构成, 例如一段文本, 一个图片, at 某人的一个部分. CQ 中定义了与这些消息相符的 CQ 码, 以方便用户使用。

QSign 签名服务器

对于qq机器人来说,最难过的就是因为腾讯风控,导致消息发不出去、qq小号被冻结。所以才有了签名服务,虽然可以解决部分账号的风控。但该冻结还是冻结!!!

最新很不幸的消息:由于腾狗的脑瘫行为,QSign 已经被请喝茶了!!!

Docker QSign 容器

安装 Docker 版 go-cqhttp 的签名服务器容器

docker run -d --restart=always --name qsign -p 5709:8080 -e ANDROID_ID={android_id} xzhouqd/qsign:8.9.63

案例例如:

docker run -d --restart=always --name qsign -p 5709:8080 -e ANDROID_ID=ebefad01e3964c11 xzhouqd/qsign:8.9.63

android_id 这只需要在 go-cqhttp 的 device.json 里面

docker 比宝塔方便吗 docker和宝塔的区别_docker 比宝塔方便吗_02

C:\Users\Administrator>docker run -d --restart=always --name qsign -p 5709:8080 -e ANDROID_ID=ebefad01e3964c11 xzhouqd/qsign:8.9.63
Unable to find image 'xzhouqd/qsign:8.9.63' locally
8.9.63: Pulling from xzhouqd/qsign

本机对接配置

sign-server:'http://127.0.0.1:5709'

云服务器对接配置

sign-server:'http://服务器ipv4ip:5709'

最后确认你的 docker 在运行 打开浏览器:网页显示 IAA

http://localhost:【你的本地端口号】/

ffmpeg 安装

如果想要在liunx端进行发送任意格式的视频或者音频,那么就需要借助ffmpeg音视频转换工具,在linux安装比在windows端安装过程要复杂,接下来就详细的介绍下。

官网下载:http://ffmpeg.org/download.html

docker 比宝塔方便吗 docker和宝塔的区别_环境变量_03


下载之后上传至Linux任意的文件夹(一般是home下)准备安装,首先解压安装包

tar -xjvf ffmpeg-snapshot.tar.bz2

执行上述的命令,会在压缩包的同级目录下,生成解压后的文件夹。

如果现在执行configure配置的话,可能会报如下的错误:

docker 比宝塔方便吗 docker和宝塔的区别_python_04


错误的意思是 yasm/nasm 包不存在或者很旧,可以使用–disable-yasm禁用这个选项编译,yasm是一款汇编器,并且是完全重写了nasm的汇编环境,接收nasm和gas语法,支持x86和amd64指令集,所以这里安装一下yasm即可。

安装yasm过程介绍如下所示:

官网下载:http://yasm.tortall.net/Download.html

下载之后上传至Linux准备安装,首先解压安装包,然后依次进行如下的操作:

tar -xvzf yasm-1.3.0.tar.gz
cd yasm-1.3.0/
./configure
make
make install

编译参数都是默认的,直接安装到系统中即可。

继续安装ffmpeg,接下来就是编译安装,配置环境变量操作

安装成功之后继续回到ffmpeg解压后的目录,执行下面命令编译并安装

./configure --enable-shared --prefix=/usr/local/ffmpeg
make
make install

--prefix=[安装地址],make编译过程有点长,耐心等待。

make install会把ffmpeg相关执行程序、头文件、lib库安装在/usr/local/ffmpeg/下 耐心等待完成之后执行。

耐心等待完成之后执行:

cd /usr/local/ffmpeg/

进入安装目录,查看一下发现有bin, include, lib, share这4个目录

bin是ffmpeg主程序二进制目录
include是C/C++头文件目录
lib是编译好的库文件目录
share是文档目录

接下来cd 到 bin 目录:执行./ffmpeg -version,正常情况出现如下报错:原因是lib目录未加载到链接到系统库中。

docker 比宝塔方便吗 docker和宝塔的区别_机器人_05


系统ld目录列表在/etc/ld.so.conf中,打开文件,在底部插入/usr/local/ffmpeg/lib,之后保存并退出,然后执行 ldconfig 使配置生效,现在再次执行 ./ffmpeg -version 显示就正常了。第二种方式:系统ld目录列表在/etc/ld.so.conf中,打开文件会发现,里面引用了/etc/ld.so.conf.d/下面所有的.conf文件,比如mysql-x86_64.conf,创建一个文件并写入lib路径即可,执行命令: vim /etc/ld.so.conf.d/ffmpeg.conf,然后添加一行内容: /usr/local/ffmpeg/lib,然后执行 ldconfig 使配置生效,现在再次执行 ./ffmpeg -version 显示就正常了。

docker 比宝塔方便吗 docker和宝塔的区别_docker 比宝塔方便吗_06


执行结果如下所示:

docker 比宝塔方便吗 docker和宝塔的区别_python_07


ffmpeg相关的库主要是以下7个

libavutil:用于多媒体编程,主要包含安全合适的字符串操作函数、数学运算函数、随机数字生产器、数据结构、多媒体处理的相关函数(如对像素和采样格式的计数)等,但它不是libavcodec和libavformat所需的库代码;

libavcodec、libavformat:有些视频文件格式(如AVI)没有指出应该使用哪种编码(如h.264)来解析音频和视频数据,它们只是按视频格式封装音视频数据,所以经常碰到打开视频文件只能听到声音而没有画面,则用libavformat来解析视频文件并将编码流分离出来,libavcodec对流进行解码;

libavdevice:为一些常见的多媒体输入或输出设备提供了抓取和渲染的通用架构,并且很多输入和输出设备,如Video4Linux2, VfW, DShow, and ALSA;

libavfilter:提供了一个通用规定音视频过滤架构,包括一些过滤器、源、汇(什么是源、汇,我也没搞清楚,待研究)

libswscale:执行高度优化的图像缩放、色彩、像素格式转换操作

libswresample:执行高度优化的音频重采样、重换算、样本格式转换操作

在环境变量中添加ffmpeg

为了在任何目录在都能使用ffmpeg,则需要在环境变量中添加,打开/etc/profile文件,添加新的环境变量,展示如下:

docker 比宝塔方便吗 docker和宝塔的区别_环境变量_08


为了让服务器不重启就生效修改后的profile配置文件,执行source /etc/profile

测试ffmpeg,转换视频格式,比如:将mp4格式转换成avi格式

ffmpeg -i /home/apple.mp4 -acodec copy -vcodec copy /home/apple2.avi

安装 nonebot 环境

NoneBot2 是一个现代、跨平台、可扩展的 Python 聊天机器人框架(下称 NoneBot),它基于 Python 的类型注解和异步优先特性(兼容同步),能够为你的需求实现提供便捷灵活的支持。同时,NoneBot 拥有大量的开发者为其开发插件,用户无需编写任何代码,仅需完成环境配置及插件安装,就可以正常使用 NoneBot。

docker 比宝塔方便吗 docker和宝塔的区别_环境变量_09

脚手架安装(官方推荐)

pip install nb-cli

NoneBot 基于 Python asyncio 编写,并在异步机制的基础上进行了一定程度的同步函数兼容。

插件系统

插件系统是 NoneBot 的核心,通过它可以实现机器人的模块化以及功能扩展,便于维护和管理。

nonebot 撤回消息

在 NoneBot 中,你可以使用 bot.finish() 方法来撤回发送的消息。该方法可以用在任何消息处理函数中。以下是一个示例代码:

from nonebot import on_command, CommandSession, get_bot

@on_command('撤回', aliases=['recall'])
async def recall_message(session: CommandSession):
    # 获取 bot 对象
    bot = get_bot()

    # 获取原始消息
    message = session.ctx['message']

    # 撤回消息
    await bot.delete_msg(message['message_id'])

在上述代码中,我们定义了一个名为 recall_message 的命令处理函数,并将其绑定到了 撤回 和 recall 这两个命令别名。当用户发送这两个命令时,NoneBot 将会调用这个处理函数。

在函数中,我们通过 get_bot() 方法获取了 bot 对象,在这个对象上调用 delete_msg() 方法来撤回消息。message['message_id'] 是原始消息的消息 ID,通过这个 ID 来指定要撤回的消息。

需要注意的是,撤回消息的功能需要满足一些条件,比如消息必须是机器人自己发送的,并且距离发送时间不能超过一定的时限。具体的限制条件可以参考对应的聊天机器人平台文档。

APScheduler 定时任务

APScheduler (Advanced Python Scheduler) 是一个 Python 第三方库,其强大的定时任务功能被广泛应用于各个场景。在 NoneBot 中,定时任务作为一个额外功能,依赖于基于 APScheduler 开发的 nonebot-plugin-apscheduler 插件进行支持。

安装插件

nb plugin install nonebot-plugin-apscheduler

使用插件

nonebot-plugin-apscheduler 本质上是对 APScheduler 进行了封装以适用于 NoneBot 开发,因此其使用方式与 APScheduler 本身并无显著区别。

调度器

由于 nonebot_plugin_apscheduler 作为插件,因此需要在使用前对其进行加载并导入其中的 scheduler 调度器来创建定时任务。

from nonebot import require

require("nonebot_plugin_apscheduler")

from nonebot_plugin_apscheduler import scheduler

@scheduler.scheduled_job("cron", hour=18, minute=35, second=40)
async def timer_task():
    # 获取 bot 信息
    (bot, ) = nonebot.get_bots().values()
    msg = f"测试消息"
    await bot.send_group_msg(group_id=642122283, message=msg)

读取 env 环境变量

nonebot 项目目录有 .env 文件配置环境变量

ENVIRONMENT=dev
APSCHEDULER_AUTOSTART=true
APSCHEDULER_CONFIG={"apscheduler.timezone": "Asia/Shanghai"}

加载环境变量

import os
from dotenv import load_dotenv
load_dotenv()
os.getenv("APSCHEDULER_AUTOSTART")

读取 sender 群昵称

通过 event 事件对象进行读取 sender 发送者信息

@chat.handle()
async def listen_chat(bot: Bot, event: GroupMessageEvent, state: T_State):
    sender = event.sender
    print(sender.nickname)
    await bot.call_api("send_group_message", group_id=642122283, message="测试信息")

sender:user_id=1620444902 nickname=‘唤醒手腕’ sex=‘unknown’ age=0 card=‘’ area=‘’ level=‘’ role=‘member’ title=‘’

发送 tts 语音消息

from nonebot import on_command
from nonebot.adapters.onebot.v11 import Bot, PrivateMessageEvent, Message
from nonebot.typing import T_State

msg = on_command(cmd="img")

@msg.handle()
async def chat_listener(bot: Bot, event: PrivateMessageEvent, state: T_State):
    tts = "[CQ:tts,text=这是一条测试消息]"
    await bot.send(event, Message(tts))

测试效果

docker 比宝塔方便吗 docker和宝塔的区别_docker 比宝塔方便吗_10

发送 img 图片资源

MessageSegment 发送图片

@msg.handle()
async def chat_listener(bot: Bot, event: PrivateMessageEvent, state: T_State):
    print("img")
    await bot.call_api("send_private_msg", user_id=1620444902, message="hello")
    await bot.send(event, MessageSegment.image("https://q4.qlogo.cn/headimg_dl?dst_uin=1620444902&spec=640"))

解析 CQ 码 发送图片

@msg.handle()
async def chat_listener(bot: Bot, event: PrivateMessageEvent, state: T_State):
    print("img")
    await bot.call_api("send_private_msg", user_id=1620444902, message="hello")
    image = "[CQ:image,file=https://q4.qlogo.cn/headimg_dl?dst_uin=1620444902&spec=640,type=show,id=40004]"
    await bot.send(event, Message(image))

会话控制 询问操作

msg = on_command(cmd="test")

@msg.handle()
async def chat_listener(bot: Bot, event: PrivateMessageEvent, state: T_State):
    tts = "[CQ:tts,text=这是一条测试消息]"
    await bot.send(event, Message(tts))


@msg.got(key="name", prompt="请告诉我你的名字?")
async def got_listener(name: str = ArgPlainText()):
    await msg.send(f"你的名字是{name}")

在上面的代码中,我们使用 got 事件响应器操作来向用户发送 prompt 消息,并等待用户的回复。用户的回复消息将会被作为 location 参数存储于事件响应器状态中。

docker 比宝塔方便吗 docker和宝塔的区别_机器人_11

会话轮询操作

msg = on_command(cmd="test")

@msg.handle()
async def chat_listener(bot: Bot, event: PrivateMessageEvent, state: T_State):
    tts = "[CQ:tts,text=考考你的智商水平]"
    await bot.send(event, Message(tts))


@msg.got(key="name", prompt="请猜猜我的名字?")
async def got_listener(name: str = ArgPlainText()):
    if name == "边缘骇客":
        await msg.send(f"恭喜你回答正确!!!")
    else:
        await msg.reject("请重新继续猜猜?")

docker 比宝塔方便吗 docker和宝塔的区别_机器人_12