go-cqhttp 全面解析:基于 Golang 的 OneBot-v11 实现、接口兼容与扩展能力指南
2026/9/24 13:58:15 网站建设 项目流程
  • 后端
  • 即时通讯
  • API网关

【免费下载链接】go-cqhttp

cqhttp的golang实现,轻量、原生跨平台.

项目地址:https://gitcode.com/gh_mirrors/go/go-cqhttp
点击查看免费下载

本篇技术指南以 go-cqhttp 开源仓库为主体,系统讲解其项目定位、OneBot-v11 兼容性、四大通信接口、拓展 CQ 码 / API / 事件体系,以及基于config.ymldevice.json的完整配置与部署方式,并结合仓库源码说明各功能模块的底层实现原理。读者读完可完整掌握 go-cqhttp 的能力边界、配置方法、命令行参数与消息 / 事件模型,具备基于其搭建 QQ 机器人与上层应用的实际能力。

项目定位与技术背景

go-cqhttp 是一个基于 Mirai),项目描述为"cqhttp 的 golang 实现,轻量、原生跨平台"。其核心价值在于:将 QQ 客户端协议能力封装为标准的 OneBot 接口,使上层 Bot 应用可以通过统一的 HTTP / WebSocket 协议收发消息,而无需关心底层协议实现。

从源码结构看,整个项目分为以下几大模块,与文章后续章节一一对应:

  • coolq/:核心业务层,负责 CQ 码编解码、消息转换与全部 API 的具体实现(cqcode.go、api.go);
  • server/modules/servers/:通信服务层,实现 HTTP、正向 / 反向 WebSocket、pprof 等服务器的注册与启动(http.go、websocket.go、servers.go);
  • modules/config/:配置文件解析与默认配置生成(config.go、default_config.yml);
  • db/:消息数据库实现,支持 LevelDB、SQLite3、MongoDB 三种后端;
  • cmd/gocq/:程序入口,负责参数解析、登录流程、重连与签名服务器逻辑(main.go)。

需要特别说明的是,README 在"重要信息"一节明确提示:由于 QQ 官方不断更新加密方案,该项目的协议维护已停止,README 建议 Bot 开发者迁移至无头 NTQQ 方案。因此,本文内容以当前仓库实际能力为准,读者在选型时应结合这一背景做出判断。

兼容性与通信接口

go-cqhttp 兼容 OneBot-v11):

接口类型说明
HTTP API由 Bot 应用主动调用 go-cqhttp 暴露的 HTTP 接口(默认监听0.0.0.0:5700
反向 HTTP POSTgo-cqhttp 将事件主动 POST 到应用配置的地址(支持多点上报)
正向 WebSocket应用作为客户端主动连接 go-cqhttp 的 WebSocket 服务(默认监听0.0.0.0:6700
反向 WebSocketgo-cqhttp 作为客户端连接应用提供的 WebSocket 服务(支持 Universal / API / Event 三通道)

源码层的服务注册机制

这四类服务在启动时由统一的注册机制加载。在 servers.go 中,servers包维护两个注册表:svr(需要配置节点的服务)与nocfgsvr(无需配置的服务),并提供RegisterRegisterCustom两个注册函数:

func Register(name string, proc func(*coolq.CQBot, yaml.Node)) { ... svr[name] = proc } func Run(bot *coolq.CQBot) { for _, l := range base.Servers { for name, conf := range l { if fn, ok := svr[name]; ok { go fn(bot, conf) } } } ... }

也就是说,config.ymlservers列表里出现的每个服务名,都会在登录成功后(见 cmd/gocq/main.go 中servers.Run(coolq.NewQQBot(cli))调用)以 goroutine 形式并发启动,这也是 go-cqhttp 支持"同一连接方式可添加多个"的底层原因。HTTP 服务、反向 HTTP 多点上报、WebSocket 服务的具体监听与转发逻辑位于 server/http.go 与 server/websocket.go。

拓展支持一览

在 OneBot-v11 标准之上,go-cqhttp 增加了以下能力(完整说明见 docs/cqhttp.md):

  • HTTP POST 多点上报:servershttp.post列表可配置多个上报地址;
  • 反向 WS 多点连接:ws-reverse支持同时配置多个地址;
  • 修改群名(/set_group_name);
  • 消息撤回事件(群消息撤回group_recall、好友消息撤回friend_recall);
  • 解析 / 发送回复消息([CQ:reply]);
  • 解析 / 发送合并转发([CQ:forward][CQ:node]);
  • 使用代理请求网络图片(message.proxy-rewrite配置项)。

已实现的 CQ 码体系

CQ 码是 OneBot 协议中描述消息内容的核心语法,形如[CQ:face,id=178]。go-cqhttp 既完整实现了 OneBot 标准的 CQ 码,也扩展了标准之外的类型。

符合 OneBot 标准的 CQ 码

CQ 码功能
[CQ:face]QQ 表情
[CQ:record]语音
[CQ:video]短视频
[CQ:at]@某人
[CQ:share]链接分享
[CQ:music]音乐分享 / 音乐自定义分享
[CQ:reply]回复
[CQ:forward]合并转发
[CQ:node]合并转发节点
[CQ:xml]XML 消息
[CQ:json]JSON 消息

拓展 CQ 码及与标准略有差异的 CQ 码

拓展 CQ 码功能
[CQ:image]图片(支持 flash 闪照、show 秀图)
[CQ:redbag]红包(仅接收)
[CQ:poke]戳一戳(仅群聊发送)
[CQ:node]合并转发消息节点
[CQ:cardimage]一种 xml 的图片消息(装逼大图)
[CQ:tts]文本转语音(仅群聊,音源与登录账号性别有关)

其中[CQ:image]是使用最频繁的拓展码,详细参数(见 docs/cqhttp.md)包括:file(文件名,支持本地路径、HTTP URL、base64://前缀)、typeflash闪照 /show秀图)、subType(群聊图片子类型,0~13 分别表示正常图片、表情包、热图、斗图、贴图、自拍、热搜图等)、urlcache(是否使用缓存)、id(秀图特效 ID,默认 40000)与c(下载线程数)。秀图特效 ID 对应关系为:40000 普通、40001 幻影、40002 抖动、40003 生日、40004 爱你、40005 征友。示例:[CQ:image,file=http://baidu.com/1.jpg,type=show,id=40004]

注意:图片总大小不能超过 30MB,gif 总帧数不能超过 300 帧。

源码中的 CQ 码转换链路

CQ 码的编解码核心在 coolq/cqcode.go。上行方向(应用 → QQ),ConvertElement将解析出的msg.Element转换为 MiraiGo 消息元素,例如:

  • image类型:依据file前缀(http/file/base64/base16384/ 缓存文件)分别走网络下载、本地读取、解码流等路径,makeImageOrVideoElem中通过md5.Sum([]byte(f))生成缓存文件名,并限制图片 30MB、视频 100MB 的上限(常量maxImageSizemaxVideoSize定义于文件头部);
  • reply类型:reply()函数支持两种用法,id存在时从数据库查询原消息构造ReplyElement,否则使用text/qq/time/seq字段构造自定义回复;
  • music类型:qq(QQ 音乐)与163(网易云音乐)走各自平台的歌曲信息接口,custom类型则拼接 XML 卡片;
  • tts类型:调用bot.Client.GetTts()获取语音数据并ResampleSilk重采样。

下行方向(QQ → 应用),toElements函数将 MiraiGo 元素数组转换为 OneBot 消息元素,群图、好友图、频道图分别映射为image类型,并自动附加type=flashtype=show字段。

已实现的 API 体系

go-cqhttp 实现了 OneBot 标准的绝大部分 API,并额外提供了大量拓展 API。标准 API 与拓展 API 的完整定义分别见 README.md 与 docs/cqhttp.md。

符合 OneBot 标准的 API

涵盖消息、群管理、好友管理、信息查询四大类,主要包括:

  • 消息类:/send_private_msg/send_group_msg/send_msg/delete_msg(撤回信息);
  • 群管理类:/set_group_kick(群组踢人)、/set_group_ban(单人禁言)、/set_group_whole_ban(全员禁言)、/set_group_admin(设置管理员)、/set_group_card(设置群名片)、/set_group_name(设置群名)、/set_group_leave(退出群组)、/set_group_special_title(设置专属头衔);
  • 请求处理类:/set_friend_add_request(处理加好友请求)、/set_group_add_request(处理加群请求/邀请);
  • 信息查询类:/get_login_info/get_stranger_info/get_friend_list/get_group_info/get_group_list/get_group_member_info/get_group_member_list/get_group_honor_info/can_send_image/can_send_record/get_version_info
  • 运维类:/set_restart(重启 go-cqhttp)、/.handle_quick_operation(对事件执行快速操作)。

拓展 API 及与标准略有差异的 API

拓展 API功能
/set_group_portrait设置群头像
/get_image获取图片信息(sizefilenameurl
/get_msg获取消息(message_idreal_idsendertimemessage
/get_forward_msg获取合并转发内容
/send_group_forward_msg发送合并转发(群)
/.get_word_slices获取中文分词
/.ocr_image图片 OCR(仅支持已接收的图片)
/get_group_system_msg获取群系统消息(邀请 / 进群请求列表)
/get_group_file_system_info获取群文件系统信息
/get_group_root_files获取群根目录文件列表
/get_group_files_by_folder获取群子目录文件列表
/get_group_file_url获取群文件资源链接
/get_status获取状态(运行统计)

此外,docs/cqhttp.md 还记录了更丰富的拓展 API,包括:/get_group_at_all_remain(@全体成员剩余次数)、/download_file(下载文件到缓存目录,返回绝对路径,可配合 CQ 码直接发送)、/get_group_msg_history(群消息历史)、/get_online_clients(在线客户端列表)、/check_url_safely(链接安全性检查,1 安全 / 2 未知 / 3 危险)、/_get_vip_info(用户 VIP 信息)、/_send_group_notice//_get_group_notice//_del_group_notice(群公告管理)、/set_essence_msg//delete_essence_msg//get_essence_msg_list(精华消息管理)、/upload_group_file//upload_private_file(上传文件,仅支持本地路径,HTTP 文件需先经/download_file下载)、/set_qq_profile(设置个人资料)、/get_unidirectional_friend_list//delete_unidirectional_friend//delete_friend/qidian_get_account_info(企点协议专用)、/mark_msg_as_read/reload_event_filter(重载事件过滤器)等。

/get_status为例,其响应中的stat统计对象包含packet_receivedpacket_sentpacket_lostmessage_receivedmessage_sentdisconnect_timeslost_times等字段,所有统计信息在重启后重置,可用于监控 Bot 运行健康度。

已实现的事件体系

go-cqhttp 的事件上报同样分为 OneBot 标准事件与拓展事件两类。

符合 OneBot 标准的事件

  • 消息事件:私聊信息、群消息;
  • 通知事件:群文件上传、群管理员变动、群成员减少、群成员增加、群禁言、好友添加、群消息撤回、好友消息撤回、群内戳一戳、群红包运气王、群成员荣誉变更;
  • 请求事件:加好友请求、加群请求/邀请。

拓展事件

事件类型拓展 Event
通知事件好友戳一戳
通知事件群内戳一戳
通知事件群成员名片更新
通知事件接收到离线文件

详细的字段定义见 docs/cqhttp.md 的事件章节,例如:

  • 群消息撤回post_type=noticenotice_type=group_recall,携带group_iduser_id(消息发送者)、operator_id(操作者)、message_id
  • 群内戳一戳notice_type=notifysub_type=poke,携带group_iduser_idtarget_id。注意此事件无法在平板和手表协议上触发;
  • 群成员名片更新notice_type=group_card,携带card_newcard_old(名片为空时为空字符串而非昵称),不保证时效性,仅在收到消息时校验;
  • 群成员头衔更新事件notice_type=notify,携带user_idtitle
  • 接收到离线文件notice_type=offline_filefile对象含namesizeurl
  • 其他客户端在线状态变更notice_type=client_status,携带client(Device 对象)与online
  • 精华消息notice_type=essencesub_typeadd/delete,携带sender_idoperator_idmessage_id

事件过滤器机制可参考 docs/EventFilter.md 与 modules/filter/,通过在default-middlewares.filter配置过滤器文件路径,可按条件筛选需要上报的事件,并通过/reload_event_filterAPI 热重载。

配置体系:config.yml 与 device.json

go-cqhttp 运行时依赖config.yml(运行配置)与device.json(虚拟设备信息)两个文件。配置文件使用 YAML 语法,首次启动时若未找到配置文件,程序会自动生成config.yml(默认内容来自 default_config.yml,通过//go:embed嵌入二进制,见 config.go),并交互式询问需要启用的通信方式,生成完成后退出等待用户修改。

账号配置(account)

account: # 账号相关 uin: 1233456 # QQ账号 password: '' # 密码为空时使用扫码登录 encrypt: false # 是否开启密码加密 status: 0 # 在线状态 relogin: # 重连设置 delay: 3 # 首次重连延迟, 单位秒 interval: 3 # 重连间隔 max-times: 0 # 最大重连次数, 0为无限制 use-sso-address: true # 是否使用服务器下发的新地址进行重连 allow-temp-session: false # 是否允许发送临时会话消息
  • encrypt: true时,程序每次启动要求输入解密密钥;密钥错误会导致登录时提示密码错误。解密后的密码哈希存储于内存中用于自动重连,因此该加密并不能防止内存读取(见 docs/config.md 注 1)。实现上,密码哈希经 PBKDF2(迭代 114514 次)+ AES 加密后写入password.encrypt文件,相关函数PasswordHashEncrypt/PasswordHashDecrypt位于 cmd/gocq/main.go;
  • status在线状态取值 0~21,分别对应在线、离开、隐身、忙、听歌中、星座运势、今日天气、遇见春天、Timi 中、吃鸡中、恋爱中、汪汪汪、干饭中、学习中、熬夜中、打球中、信号弱、在线学习、游戏中、度假中、追剧中、健身中。源码中allowStatus数组(cmd/gocq/main.go)对应了这些状态,且登录时会做越界保护(if uint(base.Account.Status) >= uint(len(allowStatus)) { base.Account.Status = 0 });
  • relogin重连逻辑:断开后首先等待delay秒,随后按interval间隔重试,max-times为最大重连次数,0 表示无限制;relogin.disabled: true可关闭自动重连(对应源码中if base.Reconnect.Disabled { os.Exit(1) })。

签名服务器配置(sign-servers)

这是 go-cqhttp 后期版本的核心配置块,用于规避登录 45 错误码与发送消息风控:

sign-servers: - url: '-' # 主签名服务器地址, 必填 key: '114514' # 签名服务器所需要的apikey(版本 1.1.0 及以下此项无效) authorization: '-' # authorization 内容, 依服务端设置,如 'Bearer xxxx' - url: '-' # 备用 key: '114514' authorization: '-' rule-change-sign-server: 1 # 判断签名服务不可用的额外规则 max-check-count: 0 # 连续寻找可用签名服务器最大尝试次数 sign-server-timeout: 60 # 签名服务请求超时时间(s) is-below-110: false # 签名服务器版本 <= 1.1.0 时设为 true auto-register: false # 是否在实例丢失时自动重新注册 auto-refresh-token: false # token 过期后是否立即自动刷新 refresh-interval: 40 # 定时刷新 token 间隔(分钟),建议 30~40,不可超过 60

rule-change-sign-server取值:0 不设置(仅在请求无返回时判定不可用);1 在获取到的 sign 为空时切换(建议配合关闭auto-register);2 在 sign 或 token 为空时切换(建议配合关闭auto-refresh-token)。签名服务器的处理逻辑位于 cmd/gocq/main.go 的getAvaliableSignServer与定时刷新逻辑signStartRefreshToken。若未配置可用签名服务器,程序会输出警告"未配置签名服务器或签名服务器不可用, 这可能会导致登录 45 错误码或发送消息被风控"。

消息与上报配置(message)

message: post-format: string # 上报数据类型: string,array ignore-invalid-cqcode: false # 是否忽略无效的CQ码, 为假将原样发送 force-fragment: false # 是否强制分片发送消息 fix-url: false # 是否将url分片发送 proxy-rewrite: '' # 下载图片等请求网络代理 report-self-message: false # 是否上报自身消息 remove-reply-at: false # 移除服务端的Reply附带的At extra-reply-data: false # 为Reply附加更多信息 skip-mime-scan: false # 跳过 Mime 扫描, 忽略错误数据 convert-webp-image: false # 是否自动转换 WebP 图片 http-timeout: 15 # download 超时时间(s)
  • post-format决定上报消息体是字符串形式(string,含 CQ 码)还是数组形式(array,分段元素);源码在 base/flag.go 的Init()中对非法的post-format值会警告并回退为string
  • force-fragment为原酷 Q 发送长消息的老方案,分片发送速度更优、兼容性更好,但在有发言频率限制的群里可能无法发送;关闭后优先使用新方案,能发送更长消息但速度更慢,部分老客户端无法解析(docs/config.md 注 3);
  • fix-url对应源码中SplitURL,在ConvertElementtext分支中通过param.SplitURL将 URL 拆分发送;
  • remove-reply-at/extra-reply-data对应toElements中对ReplyElement的处理:前者移除 reply 后紧跟的 @ 元素,后者为 reply 附加seqqqtimetext字段。

日志与数据库配置(output / database)

output: log-level: warn # trace,debug,info,warn,error log-aging: 15 # 日志时效 单位天, 0 为永久保留 log-force-new: true # 是否每次启动强制创建全新日志文件 log-colorful: true # 是否启用日志颜色 debug: false # 开启调试模式 database: leveldb: enable: true # 启用内置leveldb数据库 sqlite3: enable: false cachettl: 3600000000000 # 1h
  • 日志按天轮转,写入logs/%Y-%m-%d.log,轮转与清理逻辑见 cmd/gocq/main.go 的PrepareData()(使用file-rotatelogs);
  • 数据库启用 leveldb 会增加 10~20MB 内存占用;关闭后将无法使用撤回、回复、get_msg等上下文相关功能。数据库抽象层位于 db/database.go 与 db/multidb.go,LevelDB / SQLite3 / MongoDB 实现分别在 db/leveldb/、db/sqlite3/、db/mongodb/。

中间件与连接服务(default-middlewares / servers)

default-middlewares: &default access-token: '' # 访问密钥, 强烈推荐在公网的服务器设置 filter: '' # 事件过滤器文件目录 rate-limit: # API限速设置(令牌桶算法, 全局生效) enabled: false frequency: 1 # 令牌回复频率, 单位秒 bucket: 1 # 令牌桶大小 servers: - http: address: 0.0.0.0:5700 timeout: 5 # 反向HTTP超时时间, 最小值为5 middlewares: <<: *default post: # 反向HTTP POST地址列表 #- url: '' # 地址 # secret: '' # 密钥 - ws: address: 0.0.0.0:6700 middlewares: <<: *default - ws-reverse: universal: ws://your_websocket_universal.server # api: ws://your_websocket_api.server # event: ws://your_websocket_event.server reconnect-interval: 3000 middlewares: <<: *default - pprof: host: 127.0.0.1 port: 7700
  • HTTP / WS 地址支持tcp4://前缀指定 IPv4 监听(address: tcp4://0.0.0.0:5700,IPv6 同理);
  • ws-reverse中设置universal后,apievent将被忽略;同时配置多个反向 WS 地址可实现多点连接;
  • pprof性能分析服务器不支持中间件、不支持鉴权,请勿开放到公网
  • 对于不需要的通信方式,可以注释停用(推荐),或添加配置disabled: true关闭。

环境变量占位符

配置文件支持${VAR}占位符读取环境变量(实现于 config.go 的expand函数,使用正则\${([a-zA-Z_]+[a-zA-Z0-9_:/.]*)}匹配):

account: uin: ${CQ_UIN} # 读取环境变量 CQ_UIN password: ${CQ_PWD:123456} # 当 CQ_PWD 为空时使用默认值 123456

设备信息(device.json)与协议

device.json保存虚拟设备信息,首次启动自动生成随机设备。关键字段为protocol

| 值 | 类型 | 限制 | | -- | ---- | ---- | | 0 | iPad | 无 | | 1 | Android Phone | 无 | | 2 | Android Watch | 无法接收notify事件、无法接收口令红包、无法接收撤回消息 | | 3 | MacOS | 无 | | 4 | 企点 | 只能登录企点账号或企点子账号 |

协议不同对各类消息有所限制;扫码登录(password为空)仅部分协议支持,源码中isQRCodeLogin && cli.Device().Protocol != 2时会提示"当前协议不支持二维码登录"。另外可创建address.txt文件(位于工作目录,每行IP:PORT)自定义服务器 IP,用于解决海外服务器的链路问题,该逻辑见 cmd/gocq/main.go 的newClient()c.SetCustomServer(addr))。

命令行参数与启动流程

通过-h可查看全部命令行参数,源码定义于 internal/base/flag.go:

参数说明
-c <filename>指定配置文件路径,默认config.yml
-d以 daemon(守护进程)方式运行
-h打印帮助
-w <dir>覆盖工作目录
-D开启 debug 模式
-faststart跳过启动等待 5 秒的流程
-update-protocol启动时更新协议版本

启动流程(见 cmd/gocq/main.go)分为四个阶段:

  1. InitBase():解析参数、处理双击运行 /-h/-d,读取配置;
  2. PrepareData():初始化日志(rotatelogs 按天轮转)、创建图片 / 语音 / 视频缓存目录、打开数据库;
  3. LoginInteract():处理密码加密、加载 / 生成device.json、获取签名服务器、选择扫码 / 密码 / token 登录(登录成功后会保存session.token以便快速重连)、加载好友与群列表、设置在线状态、启动各通信服务;
  4. WaitSignal():后台检查更新与网络诊断,等待退出信号。

登录后程序会在断开时自动重连(DisconnectedEvent.Subscribe回调),优先使用session.token快速恢复会话,失败后回退为普通登录;若relogin.disabled则直接退出。

性能参考

README 中给出的官方性能数据为:在关闭数据库的情况下,加载 25 个好友、128 个群运行 24 小时后,内存使用约 15MB;开启数据库后内存使用将根据消息量增加 10~20MB。如果系统内存小于 128M,建议关闭数据库使用。该数据为项目自述,实际占用会随好友数、群数、消息量与协议版本变化。

云函数部署与跨平台运行

go-cqhttp 支持通过云函数(CustomRuntime)部署,scripts/bootstrap已给出 bootstrap 文件。部署步骤为:在本地完成登录,将config.ymldevice.jsonbootstrapgo-cqhttp二进制一起打包;在触发器中创建 API 网关触发器并启用集成响应,即可通过 API 网关访问 go-cqhttp(建议配置 AccessToken)。注意scripts/bootstrap中使用的工作路径为/tmp,该目录最大容量约 500M,如需长期使用应挂载文件存储(CFS)。详细说明见 docs/config.md。

其他周边文档还包括:快速开始、CQ 码与 API 详解、配置文件详解、事件过滤器、频道(guild)支持、滑动验证码处理、MIME 文件识别、管理 API(adminApi) 以及 常见问题(QA),可作为深入使用的参考。

总结

go-cqhttp 以 Go 原生实现、跨平台、轻量著称,通过完整兼容 OneBot-v11 标准并在此基础上扩展大量 CQ 码、API 与事件,为 QQ 机器人开发提供了统一、清晰的协议入口。本文从接口兼容、消息模型、事件体系、配置与启动流程、底层源码实现五个维度对其进行了系统梳理——理解coolq/的 CQ 码转换链路、modules/config/的配置解析机制、modules/servers/的服务注册机制,以及cmd/gocq/的登录与签名流程,是深入掌握 go-cqhttp 并进行二次开发的关键。需要注意的是,项目 README 已声明协议维护停止,生产环境选型时应关注其维护状态与替代方案。

  • 后端
  • 即时通讯
  • API网关

【免费下载链接】go-cqhttp

cqhttp的golang实现,轻量、原生跨平台.

项目地址:https://gitcode.com/gh_mirrors/go/go-cqhttp
点击查看免费下载
上一篇:Chrome 串口 API 实战:用 Chrome App 与 Arduino 控制舵机(Servo Serial Sample 全解析)
下一篇:【亲测免费】 SHADERed:轻量级跨平台着色器集成开发环境

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询