QQ channel fails with 401 "Authorization参数格式错误" — root cause in botgo v0.2.1 + resty >= v2.17
Environment
- Device: Orange Pi 3B (RK3566, aarch64)
- picoclaw: nightly build (
--versionreports0.3.1), modulegithub.com/sipeed/picoclaw - botgo:
github.com/tencent-connect/botgo v0.2.1(latest available) - resty:
github.com/go-resty/resty/v2 v2.17.1(indirect dependency)
Symptom
The QQ channel fails to start. The gateway log shows:
failed to get websocket info: HTTP 401
code:11241 err_code:40011005
message: "请求头Authorization参数格式错误"The credentials are valid — calling POST https://bots.qq.com/app/getAppAccessToken with the same appId/clientSecret returns a valid access_token.
What is actually sent (MITM capture)
Intercepting the real TLS traffic from picoclaw to api.sgroup.qq.com:
GET /gateway/bot HTTP/1.1
User-Agent: BotGoSDK/v0.0.2
Authorization: Bearer VEf7J-... <-- WRONG, must be "QQBot"
X-Union-Appid: 1903802227Cross-check on the same machine/token:
| Authorization header | Result |
|---|---|
QQBot <token> |
200, gateway returned |
Bearer <token> |
401 / 11241 / 40011005 |
| empty | 401 / 11241 / 40011005 |
Root cause (upstream, in botgo)
This is not a bug in picoclaw's own code — picoclaw is a victim of an incompatibility between botgo v0.2.1 and resty v2.17.1.
botgo's token source sets the correct type:
TokenType: TypeQQBot("QQBot").botgo
openapi/v1/openapi.gosetupClient()sets the auth scheme inside anOnBeforeRequesthook on the resty Client, and discards the*resty.Requestargument:OnBeforeRequest(func(c *resty.Client, _ *resty.Request) error { tk, err := o.tokenSource.Token() ... c.SetAuthScheme(tk.TokenType) // Client-level, set AFTER R() ran c.SetAuthToken(tk.AccessToken) })resty >= v2.17 snapshots
AuthScheme: c.AuthScheme(default"Bearer") into the Request atClient.R()time, and itsaddCredentials()now reads only the request-level scheme. The old client-level fallback (else if !IsStringEmpty(c.AuthScheme)) was removed. So the request that was already built keeps"Bearer"regardless of the laterc.SetAuthScheme(...).
Full source-level analysis (with the exact resty v2.11.0 vs v2.17.1 diffs) is available if needed.
Impact
Every project that combines botgo v0.2.1 (the only/latest release) with resty >= v2.17.0 has a completely broken QQ channel.
Suggested fixes (for picoclaw maintainers)
Pin the indirect dependency to a resty version that still has the client-level
AuthSchemefallback (e.g.v2.16.x) — please verify the fallback branch exists in the chosen version — ORreplacebotgo with a fork that sets the scheme on the*resty.Request:OnBeforeRequest(func(_ *resty.Client, req *resty.Request) error { tk, err := o.tokenSource.Token() ... req.SetAuthScheme(tk.TokenType) // request-level req.SetAuthToken(tk.AccessToken) })This is correct on both old and new resty (request-level
SetAuthSchemeoverrides the client-level one).
I'm also submitting a PR with the 3-line fix to tencent-connect/botgo.
Note: the QQ channel (pkg/channels/qq/) only exists on main/nightly, not in the v0.3.1 tag — worth keeping in mind if anyone tries to reproduce on the tagged release.
Source: sipeed/picoclaw