147 lines
4.2 KiB
Go
147 lines
4.2 KiB
Go
/**
|
||
* @Author: Echo
|
||
* @Email:1711788888@qq.com
|
||
* @Date: 2021/8/27 11:31 上午
|
||
* @Desc: TODO
|
||
*/
|
||
|
||
package core
|
||
|
||
import (
|
||
"fmt"
|
||
"math/rand"
|
||
"time"
|
||
|
||
"git.echol.cn/loser/http"
|
||
|
||
"git.echol.cn/loser/tencent-im/internal/enum"
|
||
"git.echol.cn/loser/tencent-im/internal/sign"
|
||
"git.echol.cn/loser/tencent-im/internal/types"
|
||
)
|
||
|
||
const (
|
||
defaultBaseUrl = "https://console.tim.qq.com"
|
||
defaultVersion = "v4"
|
||
defaultContentType = "json"
|
||
defaultExpiration = 3600
|
||
)
|
||
|
||
var invalidResponse = NewError(enum.InvalidResponseCode, "invalid response")
|
||
|
||
type Client interface {
|
||
// Get GET请求
|
||
Get(serviceName string, command string, data interface{}, resp interface{}) error
|
||
// Post POST请求
|
||
Post(serviceName string, command string, data interface{}, resp interface{}) error
|
||
// Put PUT请求
|
||
Put(serviceName string, command string, data interface{}, resp interface{}) error
|
||
// Patch PATCH请求
|
||
Patch(serviceName string, command string, data interface{}, resp interface{}) error
|
||
// Delete DELETE请求
|
||
Delete(serviceName string, command string, data interface{}, resp interface{}) error
|
||
}
|
||
|
||
type client struct {
|
||
client *http.Client
|
||
opt *Options
|
||
userSig string
|
||
userSigExpireAt int64
|
||
}
|
||
|
||
type Options struct {
|
||
AppId int // 应用SDKAppID,可在即时通信 IM 控制台 的应用卡片中获取。
|
||
AppSecret string // 密钥信息,可在即时通信 IM 控制台 的应用详情页面中获取,具体操作请参见 获取密钥
|
||
UserId string // 用户ID
|
||
Expiration int // UserSig过期时间
|
||
}
|
||
|
||
func NewClient(opt *Options) Client {
|
||
rand.Seed(time.Now().UnixNano())
|
||
c := new(client)
|
||
c.opt = opt
|
||
c.client = http.NewClient()
|
||
c.client.SetContentType(http.ContentTypeJson)
|
||
c.client.SetBaseUrl(defaultBaseUrl)
|
||
|
||
return c
|
||
}
|
||
|
||
// Get GET请求
|
||
func (c *client) Get(serviceName string, command string, data interface{}, resp interface{}) error {
|
||
return c.request(http.MethodGet, serviceName, command, data, resp)
|
||
}
|
||
|
||
// Post POST请求
|
||
func (c *client) Post(serviceName string, command string, data interface{}, resp interface{}) error {
|
||
return c.request(http.MethodPost, serviceName, command, data, resp)
|
||
}
|
||
|
||
// Put PUT请求
|
||
func (c *client) Put(serviceName string, command string, data interface{}, resp interface{}) error {
|
||
return c.request(http.MethodPut, serviceName, command, data, resp)
|
||
}
|
||
|
||
// Patch PATCH请求
|
||
func (c *client) Patch(serviceName string, command string, data interface{}, resp interface{}) error {
|
||
return c.request(http.MethodPatch, serviceName, command, data, resp)
|
||
}
|
||
|
||
// Delete DELETE请求
|
||
func (c *client) Delete(serviceName string, command string, data interface{}, resp interface{}) error {
|
||
return c.request(http.MethodDelete, serviceName, command, data, resp)
|
||
}
|
||
|
||
// request Request请求
|
||
func (c *client) request(method, serviceName, command string, data, resp interface{}) error {
|
||
res, err := c.client.Request(method, c.buildUrl(serviceName, command), data)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if err = res.Scan(resp); err != nil {
|
||
return err
|
||
}
|
||
|
||
if r, ok := resp.(types.ActionBaseRespInterface); ok {
|
||
if r.GetActionStatus() == enum.FailActionStatus {
|
||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||
}
|
||
|
||
if r.GetErrorCode() != enum.SuccessCode {
|
||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||
}
|
||
} else if r, ok := resp.(types.BaseRespInterface); ok {
|
||
if r.GetErrorCode() != enum.SuccessCode {
|
||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||
}
|
||
} else {
|
||
return invalidResponse
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// buildUrl 构建一个请求URL
|
||
func (c *client) buildUrl(serviceName string, command string) string {
|
||
format := "/%s/%s/%s?sdkappid=%d&identifier=%s&usersig=%s&random=%d&contenttype=%s"
|
||
random := rand.Int31()
|
||
userSig := c.getUserSig()
|
||
return fmt.Sprintf(format, defaultVersion, serviceName, command, c.opt.AppId, c.opt.UserId, userSig, random, defaultContentType)
|
||
}
|
||
|
||
// getUserSig 获取签名
|
||
func (c *client) getUserSig() string {
|
||
now, expiration := time.Now(), c.opt.Expiration
|
||
|
||
if expiration <= 0 {
|
||
expiration = defaultExpiration
|
||
}
|
||
|
||
if c.userSig == "" || c.userSigExpireAt <= now.Unix() {
|
||
c.userSig, _ = sign.GenUserSig(c.opt.AppId, c.opt.AppSecret, c.opt.UserId, expiration)
|
||
c.userSigExpireAt = now.Add(time.Duration(expiration) * time.Second).Unix()
|
||
}
|
||
|
||
return c.userSig
|
||
}
|