feat(channels): QQ 账号 get_status 主动探活(复用既有 action 通道 / 状态变化才记日志 / AccountStatus 与 WS 连通分开)
This commit is contained in:
1 parent
f44114301e
commit
a79fe9684e
6 files changed
+577
-18
No files matched your search
@@ -96,7 +96,8 @@ func (c *obHTTPClient) Close() {
|
||||
// send 把一条已构造好的 action 请求(payload 已含 action/params/echo)POST 给 OneBot
|
||||
// 并等待结果。它替代 WS 端的「写一帧就返回」:HTTP 有明确响应,成败以 retcode 为准。
|
||||
func (c *obHTTPClient) send(ctx context.Context, payload []byte) error {
|
||||
return c.post(ctx, payload)
|
||||
_, err := c.post(ctx, payload)
|
||||
return err
|
||||
}
|
||||
|
||||
// probe 用最轻量的标准 action `get_login_info` 探活 OneBot 实现,供 HealthCheck 使用。
|
||||
@@ -106,20 +107,32 @@ func (c *obHTTPClient) probe(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = c.post(ctx, payload)
|
||||
return err
|
||||
}
|
||||
|
||||
// call 编码一条通用 action 请求并取回**响应信封**(含 data)。get_status 之类需要读
|
||||
// 返回值的主动 action 走它——它复用与 send_msg 完全相同的出站客户端与校验路径,绝不
|
||||
// 新建第二条请求通道。
|
||||
func (c *obHTTPClient) call(ctx context.Context, action string, params any) (*obAPIResponse, error) {
|
||||
payload, err := buildActionReq(action, params, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.post(ctx, payload)
|
||||
}
|
||||
|
||||
// post 发送一条 action 请求并解析响应。任何失败都返回带上下文(action、retcode)的
|
||||
// wrapped error;错误信息与日志都不含 token。
|
||||
func (c *obHTTPClient) post(ctx context.Context, payload []byte) error {
|
||||
func (c *obHTTPClient) post(ctx context.Context, payload []byte) (*obAPIResponse, error) {
|
||||
if c == nil {
|
||||
return errors.New("qq-obv11: http api client not configured")
|
||||
return nil, errors.New("qq-obv11: http api client not configured")
|
||||
}
|
||||
action := actionOf(payload)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/"+action, bytes.NewReader(payload))
|
||||
if err != nil {
|
||||
return fmt.Errorf("qq-obv11: build http %s request: %w", action, err)
|
||||
return nil, fmt.Errorf("qq-obv11: build http %s request: %w", action, err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if c.token != "" {
|
||||
@@ -129,26 +142,26 @@ func (c *obHTTPClient) post(ctx context.Context, payload []byte) error {
|
||||
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("qq-obv11: http %s request: %w", action, err)
|
||||
return nil, fmt.Errorf("qq-obv11: http %s request: %w", action, err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(resp.Body, maxHTTPRespBytes))
|
||||
if err != nil {
|
||||
return fmt.Errorf("qq-obv11: read http %s response: %w", action, err)
|
||||
return nil, fmt.Errorf("qq-obv11: read http %s response: %w", action, err)
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("qq-obv11: http %s status %d", action, resp.StatusCode)
|
||||
return nil, fmt.Errorf("qq-obv11: http %s status %d", action, resp.StatusCode)
|
||||
}
|
||||
var env obAPIResponse
|
||||
if err := json.Unmarshal(body, &env); err != nil {
|
||||
return fmt.Errorf("qq-obv11: decode http %s response: %w", action, err)
|
||||
return nil, fmt.Errorf("qq-obv11: decode http %s response: %w", action, err)
|
||||
}
|
||||
if env.RetCode != 0 || (env.Status != "" && !strings.EqualFold(env.Status, "ok")) {
|
||||
return fmt.Errorf("qq-obv11: http %s failed: retcode=%d status=%q msg=%q",
|
||||
return nil, fmt.Errorf("qq-obv11: http %s failed: retcode=%d status=%q msg=%q",
|
||||
action, env.RetCode, env.Status, env.Msg)
|
||||
}
|
||||
return nil
|
||||
return &env, nil
|
||||
}
|
||||
|
||||
// actionOf 从已编码的 action 请求里取出 action 名,仅用于日志与错误上下文。
|
||||
|
||||
Reference in new issue
Block a user