package dingtalk import ( "ai_scheduler/internal/config" 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 { config *config.Config cli *oauth2.Client redisCli *redis.Client } func NewOauth2Client(config *config.Config, rds *utils.Rdb) (*Oauth2Client, error) { cfg := &openapi.Config{ AccessKeyId: tea.String(config.Tools.DingTalkBot.APIKey), AccessKeySecret: tea.String(config.Tools.DingTalkBot.APISecret), Protocol: tea.String("https"), RegionId: tea.String("central"), } c, err := oauth2.NewClient(cfg) if err != nil { return nil, err } return &Oauth2Client{config: config, cli: c, redisCli: rds.Rdb}, nil } type AppKey struct { AppKey string `json:"appKey"` AppSecret string `json:"appSecret"` } // GetAccessToken 获取access token func (c *Oauth2Client) GetAccessToken(req AppKey) (string, error) { // 取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 }