ai_scheduler/internal/pkg/dingtalk/oauth2_client.go

75 lines
1.8 KiB
Go

package dingtalk
import (
errorcode "ai_scheduler/internal/data/error"
"ai_scheduler/utils"
"context"
"fmt"
"time"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
oauth2 "github.com/alibabacloud-go/dingtalk/oauth2_1_0"
"github.com/alibabacloud-go/tea/tea"
"github.com/redis/go-redis/v9"
)
type Oauth2Client struct {
cli *oauth2.Client
redisCli *redis.Client
}
func NewOauth2Client(rds *utils.Rdb) (*Oauth2Client, error) {
cfg := &openapi.Config{
Protocol: tea.String("https"),
RegionId: tea.String("central"),
}
c, err := oauth2.NewClient(cfg)
if err != nil {
return nil, err
}
return &Oauth2Client{cli: c, redisCli: rds.Rdb}, nil
}
type AppKey struct {
AppKey string `json:"appKey"`
AppSecret string `json:"appSecret"`
AccessToken string `json:"accessToken"`
}
// GetAccessToken 获取access token
func (c *Oauth2Client) GetAccessToken(req AppKey) (string, error) {
// 兼容直接传入 access token 场景
if req.AccessToken != "" {
return req.AccessToken, nil
}
// 取cache
ctx := context.Background()
accessToken, err := c.redisCli.Get(ctx, fmt.Sprintf("dingtalk:oauth2:%s:access_token", req.AppKey)).Result()
if err == nil {
fmt.Println("get access token from cache:", accessToken)
return accessToken, nil
}
if err != redis.Nil {
return "", err
}
// 调用API
resp, err := c.cli.GetAccessToken(&oauth2.GetAccessTokenRequest{
AppKey: tea.String(req.AppKey),
AppSecret: tea.String(req.AppSecret),
})
if err != nil {
return "", err
}
if resp.Body == nil {
return "", errorcode.ParamErrf("empty response body")
}
// 缓存token
c.redisCli.Set(ctx, fmt.Sprintf("dingtalk:oauth2:%s:access_token", req.AppKey), *resp.Body.AccessToken, time.Duration(*resp.Body.ExpireIn)*time.Second)
return *resp.Body.AccessToken, nil
}