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 }