github.com/fumiama/NanoBot@v0.0.0-20231122134259-c22d8183efca/openapi_wss.go (about) 1 package nano 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "strconv" 7 8 "github.com/pkg/errors" 9 ) 10 11 var ( 12 ErrEmptyToken = errors.New("empty token") 13 ErrInvalidExpire = errors.New("invalid expire") 14 ) 15 16 // GetGeneralWSSGatewayNoContext 获取通用 WSS 接入点 17 // 18 // https://bot.q.qq.com/wiki/develop/api/openapi/wss/url_get.html 19 func (bot *Bot) GetGeneralWSSGatewayNoContext() (string, error) { 20 resp := struct { 21 CodeMessageBase 22 U string `json:"url"` 23 }{} 24 err := bot.GetOpenAPI("/gateway", "", &resp) 25 return resp.U, err 26 } 27 28 // ShardWSSGateway 带分片 WSS 接入点响应数据 29 // 30 // https://bot.q.qq.com/wiki/develop/api/openapi/wss/shard_url_get.html#%E8%BF%94%E5%9B%9E 31 type ShardWSSGateway struct { 32 URL string `json:"url"` 33 Shards int `json:"shards"` 34 SessionStartLimit struct { 35 Total int `json:"total"` 36 Remaining int `json:"remaining"` 37 ResetAfter int `json:"reset_after"` 38 MaxConcurrency int `json:"max_concurrency"` 39 } `json:"session_start_limit"` 40 } 41 42 // GetShardWSSGatewayNoContext 获取带分片 WSS 接入点 43 // 44 // https://bot.q.qq.com/wiki/develop/api/openapi/wss/shard_url_get.html 45 func (bot *Bot) GetShardWSSGatewayNoContext() (*ShardWSSGateway, error) { 46 return bot.getOpenAPIofShardWSSGateway("/gateway/bot") 47 } 48 49 // GetAppAccessTokenNoContext 获取接口凭证并保存到 bot.Token 50 // 51 // https://bot.q.qq.com/wiki/develop/api-231017/dev-prepare/interface-framework/api-use.html#%E8%8E%B7%E5%8F%96%E6%8E%A5%E5%8F%A3%E5%87%AD%E8%AF%81 52 func (bot *Bot) GetAppAccessTokenNoContext() error { 53 req, err := newHTTPEndpointRequestWithAuth("POST", "", AccessTokenAPI, "", "", WriteBodyFromJSON(&struct { 54 A string `json:"appId"` 55 S string `json:"clientSecret"` 56 }{bot.AppID, bot.Secret})) 57 if err != nil { 58 return err 59 } 60 resp, err := bot.client.Do(req) 61 if err != nil { 62 return errors.Wrap(err, getThisFuncName()) 63 } 64 defer resp.Body.Close() 65 if resp.StatusCode != http.StatusOK { 66 return errors.Wrap(errors.New("http status code: "+strconv.Itoa(resp.StatusCode)), getThisFuncName()) 67 } 68 body := struct { 69 C int `json:"code"` 70 M string `json:"message"` 71 T string `json:"access_token"` 72 E string `json:"expires_in"` 73 }{} 74 err = json.NewDecoder(resp.Body).Decode(&body) 75 if err != nil { 76 return errors.Wrap(err, getThisFuncName()) 77 } 78 if body.C != 0 { 79 return errors.Wrap(errors.New("code: "+strconv.Itoa(body.C)+", msg: "+body.M), getThisFuncName()) 80 } 81 if body.T == "" { 82 return errors.Wrap(ErrEmptyToken, getThisFuncName()) 83 } 84 if body.E == "" { 85 return errors.Wrap(ErrInvalidExpire, getThisFuncName()) 86 } 87 bot.token = body.T 88 bot.expiresec, err = strconv.ParseInt(body.E, 10, 64) 89 if err != nil { 90 return errors.Wrap(err, getThisFuncName()) 91 } 92 if bot.expiresec <= 0 { 93 return errors.Wrap(ErrInvalidExpire, getThisFuncName()) 94 } 95 return nil 96 }