package wx import ( "context" "sorbet/pkg/env" "sync" "time" ) var lastAccessToken *AccessTokenResult var lock sync.Mutex type AccessTokenResult struct { AccessToken string `json:"access_token"` // 获取到的凭证 ExpiresIn int `json:"expires_in"` // 凭证有效时间,单位:秒。目前是7200秒之内的值 GetTime time.Time `json:"-"` // 获取凭证的时间 } func (a *AccessTokenResult) IsExpired() bool { return time.Since(lastAccessToken.GetTime) >= time.Duration(lastAccessToken.ExpiresIn)*time.Second-time.Minute } // GetAccessToken 获取接口调用凭据 // https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getAccessToken.html func GetAccessToken(ctx context.Context) (*AccessTokenResult, error) { lock.Lock() defer lock.Lock() if lastAccessToken != nil && !lastAccessToken.IsExpired() { return lastAccessToken, nil } result, err := httpGet[AccessTokenResult](ctx, "https://api.weixin.qq.com/cgi-bin/token", map[string]string{ "appid": env.String("WECHAT_APPID"), "secret": env.String("WECHAT_SECRET"), "grant_type": "client_credential", }) if err != nil { return nil, err } result.GetTime = time.Now() lastAccessToken = result return result, nil }