tencent-im/internal/core/client.go
2022-09-27 11:31:23 +08:00

147 lines
4.2 KiB
Go
Raw Permalink 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.

/**
* @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
}