Files
Cyrene_v2/plugins/channels/qq_obv11/ws_client.go
T
AskaEth 9253fef92a
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
feat(qq_obv11): OneBot v11 四端齐备(裁决 1.4 / 12.4.1)
- 四端=ws×client / ws×server(原有,补语义注释)+ **http×client**(新增 http_client.go:
  调 OneBot HTTP API、请求-响应、retcode 判成败、token 只走 Authorization 头)+
  **http×server**(新增 http_server.go:监听 listen_addr 收上报、fail-closed 鉴权、10MiB 体上限)
- 配置面:适配器新增 transport / api_base_url / report_path(json tag 沿用既有口径);
  env 兜底 CHANNEL_QQ_OBV11_{TRANSPORT,API_BASE_URL,REPORT_PATH};**默认值=现状**(ws+server)
- 出站分流:session.go 发送路径按 transport 走 WS 写帧或 HTTP POST(不改它则 HTTP 端无法出站)
- 端口豁免边界:http+server 沿用 AGENTS §9 已登记的同一豁免(design/13 §0 原文即含 HTTP server),
  且 listen_addr 为空时报错、**绝不开端口**(与 ws 侧同名校验成对)
- 关键取舍(已上报):OneBot 的 HTTP 是「动作 + 上报」两半,mode 决定**哪一半必需**、
  另一半给齐字段就一并启用 ⇒ 单个适配器即可「收上报 + 回消息」,四端仍各自可独立选择与测试
- 复核:build/vet 绿 + qq_obv11/cmd 包测试绿 + `-race` 干净;10 条新用例(HTTP 两端全部用本地
  httptest 假 OneBot,未连真实 QQ);变异 3 条(伪造 retcode 成功 / 去掉上报鉴权门 / 默认值翻 http)已还原
- 未接:get_group_list(后续)、无 token 时放行(与既有 ws_server 一致,如需 fail-closed 请裁决)
2026-10-04 13:58:18 +08:00

44 lines
1.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package qq_obv11
// 本文件实现四个端里的 **ws + client**(裁决 1.4):连接由 Cyrene 发起
// (Cyrene→OneBot),主动拨号 OneBot 实现的「正向 WS」端点(remote_url),建立后
// 收发都走这条长连接。access_token 同时以 Authorization: Bearer 头与
// ?access_token= 查询参数发送,兼容只认其中一种的 OneBot 实现。
import (
"context"
"errors"
"fmt"
"net/url"
"strings"
)
// connectClient dials the configured OneBot WebSocket endpoint and installs the
// resulting connection as the active session.
func (a *Adapter) connectClient(ctx context.Context) error {
if a.cfg.RemoteURL == "" {
return errors.New("qq-obv11: client mode requires remoteURL")
}
target := appendQueryToken(a.cfg.RemoteURL, a.cfg.AccessToken)
conn, err := dialWS(ctx, a.cfg.DialContext, target, a.cfg.AccessToken)
if err != nil {
return fmt.Errorf("qq-obv11: dial onebot ws %s: %w", a.cfg.RemoteURL, err)
}
a.setConn(conn)
a.log.Info("connected to onebot ws (client mode)", "url", a.cfg.RemoteURL)
return nil
}
// appendQueryToken adds an access_token query parameter to a URL, preserving any
// existing query string.
func appendQueryToken(rawURL, token string) string {
if token == "" {
return rawURL
}
sep := "?"
if strings.Contains(rawURL, "?") {
sep = "&"
}
return rawURL + sep + "access_token=" + url.QueryEscape(token)
}