Files
snowluma/README.md

7.4 KiB
Raw Blame History

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] 泛型)裸调,因此能力差异不会卡住迁移。