package client import ( "bytes" "encoding/json" "errors" "gitea.siteworxpro.com/golang-packages/email-api-client/redis" "net/http" "time" ) type Token struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` ExpiresIn uint16 `json:"expires_in"` } type AccessTokenRequest struct { GrantType string `json:"grant_type"` ClientId string `json:"client_id"` ClientSecret string `json:"client_secret"` } func NewToken(config *Configuration) *Token { return &Token{} } func getToken(configuration *Configuration) (*Token, error) { token := FromCache() if token != nil && token.AccessToken != "" { return token, nil } request := accessTokenRequest{ GrantType: "client_credentials", ClientId: configuration.ClientId, ClientSecret: configuration.ClientSecret, } body, _ := json.Marshal(request) resp, err := http.Post(configuration.Endpoint+"/access_token", "application/json", bytes.NewBuffer(body)) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, errors.New("Failed to retrieve access token: " + resp.Status) } token, err = readResponseBody[Token](resp) if err != nil { return nil, err } saveCache(token) return token, nil } func FromCache() *Token { rdb, err := redis.NewRedis() // Check if Redis connection was successful if rdb == nil || err != nil { return nil } token := Token{} result, err := rdb.Get("api.access_token").Result() if err != nil { return &token } err = json.Unmarshal([]byte(result), &token) if err != nil { return &token } return &token } func saveCache(token *Token) { rdb, err := redis.NewRedis() // no cache available if rdb == nil || err != nil { return } tokenJson, _ := json.Marshal(token) const nanosPerSecond = int64(time.Second) expiresIn := time.Duration(int64(token.ExpiresIn) * nanosPerSecond) cmd := rdb.Set("api.access_token", tokenJson, expiresIn) _, _ = cmd.Result() }