7.4 KiB
snowluma
对接 SnowLuma(OneBot v11 协议)的 Go 软件包,零第三方依赖(仅 gorilla/websocket)。
本包与 gitea.doicat.com/bot/napcat 的公开 API 保持一致:方法名、消息段构造函数、事件结构、Client/Context 用法完全相同。现有的 napcat 机器人项目,只需改一行导入即可切到 SnowLuma。
bot := snowluma.New().SetToken("xxx").SetForwardWS("ws://127.0.0.1:3001")
bot.OnGroupMessage(func(c *snowluma.Context) {
if c.HasAtMe() {
c.ReplyText("hi")
}
})
bot.Run(ctx)
从 napcat 迁移(drop-in)
napcat 用法:
import "gitea.doicat.com/bot/napcat"
// ... napcat.New() / napcat.Text(...) / *napcat.Context ...
改成:
import napcat "gitea.doicat.com/bot/snowluma"
// ... 其余代码一字不改,napcat.New() / napcat.Text(...) / *napcat.Context 全部照常编译
导入别名 napcat 覆盖了包的声明名,因此所有 napcat.XXX 引用保持不变。差异只在协议/能力覆盖上(见下文「与 napcat 的差异」)。
特性
- 一个对象搞定:
New()创建与 SnowLuma 交互的客户端对象,配置、事件、API 全在对象上 - 四种通信方式,链式配置、可任意叠加:
- 正向 WebSocket(自动重连 + 指数退避)
- 反向 WebSocket(支持多 bot 实例同时连入)
- HTTP API
- HTTP POST 上报(自动支持 OneBot 快速操作)
- 事件模型:message / message_sent / notice / request / meta_event 全量结构化,notice 未知字段不丢失(收进
Extra) - 消息段:全类型构造函数;收到的 CQ 码字符串与段数组统一解码
- API 覆盖:OneBot 11 标准 + go-cqhttp/NapCat 兼容 + SnowLuma 扩展(闪传、Ark 卡片、群待办、群相册、QQ 空间、系统表情、流式接口等);未收录的扩展可用
Call裸调 - echo 路由:WS 上的 action 请求/响应按 echo 精确配对,支持并发调用
- 连接级路由:事件处理函数里的 API 调用自动走产生该事件的连接,多 bot 互不串线
- 内置文本命令路由、请求 Approve/Reject、心跳记录、panic 隔离
目录结构
snowluma/
├── doc.go 包文档(pkg.go.dev 首页)
├── client.go Client:配置方法、连接汇聚、事件分发、Handler 注册
├── context.go Context:处理函数上下文(Reply/Approve/快速操作)
├── api.go API:OneBot 11 / go-cqhttp / NapCat 兼容的类型化方法
├── api_ext.go API:SnowLuma 扩展动作(闪传/Ark/待办/相册/空间/表情/流式)
├── caller.go Caller 接口 + WS echo 路由 + CallAPI 泛型
├── connect_ws.go 正向/反向 WebSocket 连接器 + Session
├── connect_http.go HTTP 上报(快速操作)+ HTTP API 连接器
├── event.go 事件结构(message/notice/request/meta)
├── segment.go 消息段构造与解码
├── cqcode.go CQ 码解析/编码
├── types.go 响应信封与实体类型
├── example_test.go 用法示例(godoc Example)
└── snowluma_test.go 单元测试(CQ 码回环、事件解码、消息段解码)
安装
go get gitea.doicat.com/bot/snowluma
使用指定版本:
go get gitea.doicat.com/bot/snowluma@v1.0.0
私有仓库使用者:如果仓库设为私有,除了给 Git 配置 Gitea 凭据外,还需设置:
set GOPRIVATE=gitea.doicat.com
快速开始
1. SnowLuma 侧配置
在 SnowLuma 的 OneBot 网络配置里按需启用一项(或多项):
| 配置方法 | SnowLuma 侧配置 |
|---|---|
SetForwardWS("ws://127.0.0.1:3001") |
启用「正向 WebSocket」,端口 3001 |
SetReverseWS(":8080") |
启用「反向 WebSocket」,URL 填 ws://<本机IP>:8080/ |
SetHTTPAPI("http://127.0.0.1:3000") |
启用「HTTP」,端口 3000 |
SetHTTPReport(":8081") |
启用「HTTP POST 上报」,地址填 http://<本机IP>:8081/ |
若配置了 token,SetToken 填同一个值即可,框架会在 WS 握手(query + Authorization 头)和 HTTP 调用(Authorization 头)中自动携带;HTTP 上报场景若配了 secret,SetSecret 会自动校验 X-Signature(HMAC-SHA1)。
2. 完整示例
见 example_test.go 的 Example 函数。
配置方法一览
| 方法 | 说明 |
|---|---|
SetToken(t) |
OneBot access_token,所有连接自动携带 |
SetSecret(s) |
HTTP 上报 X-Signature 校验密钥 |
SetLogger(l) |
自定义 *slog.Logger |
SetForwardWS(urls...) |
正向 WS 目标,可多个,重复调用替换 |
SetReverseWS(addrs...) |
反向 WS 监听地址,可多个,重复调用替换 |
SetHTTPAPI(baseURL) |
HTTP API 地址 |
SetHTTPReport(addrs...) |
HTTP 上报监听地址,可多个,重复调用替换 |
Use(conn...) |
注册自定义 Connector(高级扩展点) |
以上方法均返回 *Client,支持链式调用。请勿在 Run 之后修改配置。
事件处理
bot.OnEvent(fn) // 所有事件
bot.OnMessage(fn) // 私聊 + 群聊消息(含 message_sent)
bot.OnPrivateMessage(fn) // 私聊消息
bot.OnGroupMessage(fn) // 群聊消息
bot.OnNotice(fn) // 全部通知
bot.OnNoticeType(t, fn) // 指定 notice_type
bot.OnRequest(fn) // 好友/群请求
bot.OnMeta(fn) // 心跳/生命周期
bot.OnCommand(name, fn) // 文本命令,args 为空白切分的参数
同一会话的事件串行分发(保序);handler 里的 panic 会被隔离并记录日志。
Context 常用方法
| 方法 | 说明 |
|---|---|
Reply(msg...) / ReplyText(s) |
回复当前消息(群聊/私聊自动判断) |
Recall() |
撤回当前消息 |
Approve() / Reject(reason) |
同意/拒绝当前的请求事件 |
HasAtMe() / PlainText() / Segments() |
消息内容判断 |
IsGroup() / IsPrivate() / IsSelfMessage() |
事件类型判断 |
SendGroupMsg(nil, gid, ...) 等 |
直接调用任意 API(ctx 传 nil 用默认 30s 超时) |
Call(nil, action, params, &out) |
裸调未收录的扩展 API |
消息段
snowluma.Text("hello")
snowluma.At(12345) // snowluma.AtAll()
snowluma.Image("C:/a.jpg") // 支持本地路径 / http(s) URL / base64://
snowluma.Reply(678).With("text", "引用")
snowluma.CustomNode(10001, "某人", []snowluma.Segment{snowluma.Text("...")})
测试
go test ./...
与 napcat 的差异
两包面向不同运行时(SnowLuma vs NapCatQQ),但都是 OneBot v11 + NapCat 兼容协议。协议层完全一致,方法名一一对应;能力覆盖上的差异体现在:
- SnowLuma 独有:闪传(flash)、Ark 卡片分享、群待办、群分类标签、群相册、QQ 空间、系统表情、流式文件上传/下载等扩展动作;本包在
api_ext.go中提供类型化封装。 - napcat 有而 SnowLuma 可能未实现/改名:个别 NapCat 私有动作(如
ArkShareGroup这类大小写混合名)在 SnowLuma 中改用了标准名(send_group_ark_share),本包对这些动作做了别名适配,保证同名方法仍可用。
未收录到类型化方法里的动作,一律可通过 Client.Call / Context.Call(或 CallAPI[T] 泛型)裸调,因此能力差异不会卡住迁移。