diff --git a/internal/apis/strava/activities.go b/internal/apis/strava/activities.go index 894ed4b..9500cd3 100644 --- a/internal/apis/strava/activities.go +++ b/internal/apis/strava/activities.go @@ -1,10 +1,7 @@ package strava import ( - "encoding/json" "fmt" - "io" - "net/http" "net/url" "time" @@ -68,32 +65,13 @@ type activity struct { } func fetchActivities(minioClient minio.Client, tokens tokens) ([]activity, error) { - req, err := http.NewRequest("GET", "https://www.strava.com/api/v3/athlete/activities", nil) - if err != nil { - lumber.Error(err, "creating request failed") - return nil, err - } - req.Header.Set("Authorization", "Bearer "+tokens.Access) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - lumber.Error(err, "sending request for Strava activities failed") - return nil, err - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - lumber.Error(err, "reading response body failed") - return nil, err - } - - var stravaActivities []stravaActivity - err = json.Unmarshal(body, &stravaActivities) + stravaActivities, err := sendStravaAPIRequest[[]stravaActivity]( + "api/v3/athlete/activities", + tokens, + ) if err != nil { - lumber.Error(err, "failed to parse json") - lumber.Debug(string(body)) - return nil, err + lumber.Error(err, "failed to send request to Strava API to get activities") + return []activity{}, err } var activities []activity @@ -148,85 +126,26 @@ func fetchHeartrate(id uint64, tokens tokens) []int { "keys": {"heartrate"}, "resolution": {"low"}, } - req, err := http.NewRequest( - "GET", - fmt.Sprintf("https://www.strava.com/api/v3/activities/%d/streams?"+params.Encode(), id), - nil, + stream, err := sendStravaAPIRequest[struct{ Heartrate activityStream }]( + fmt.Sprintf("api/v3/activities/%d/streams?%s", id, params.Encode()), + tokens, ) if err != nil { - lumber.Error(err, "creating request failed") - return nil - } - req.Header.Set("Authorization", "Bearer "+tokens.Access) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - lumber.Error(err, "Failed to send request for HR data for", id) - return nil - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - lumber.Error(err, "reading response body failed") - return nil - } - - if resp.StatusCode != http.StatusOK { - lumber.ErrorMsg("status code of", resp.StatusCode) - lumber.Debug(string(body)) - return nil - } - - var stream struct{ Heartrate activityStream } - err = json.Unmarshal(body, &stream) - if err != nil { - lumber.Error(err, "failed to parse json") - lumber.Debug(string(body)) - return nil + lumber.Error(err, "failed to send request for HR data from activity with ID of", id) } return stream.Heartrate.Data } func fetchActivityDetails(id uint64, tokens tokens) (detailedStravaActivity, error) { - req, err := http.NewRequest( - "GET", - fmt.Sprintf("https://www.strava.com/api/v3/activities/%d", id), - nil, + details, err := sendStravaAPIRequest[detailedStravaActivity]( + fmt.Sprintf("api/v3/activities/%d", id), + tokens, ) if err != nil { - lumber.Error(err, "creating request failed") + lumber.Error(err, "failed to request detailed activity data for", id) return detailedStravaActivity{}, err } - req.Header.Set("Authorization", "Bearer "+tokens.Access) - - resp, err := http.DefaultClient.Do(req) - if err != nil { - lumber.Error(err, "Failed to send request for activity details with an ID of", id) - return detailedStravaActivity{}, err - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - lumber.Error(err, "reading response body failed") - return detailedStravaActivity{}, err - } - - if resp.StatusCode != http.StatusOK { - lumber.ErrorMsg("status code of", resp.StatusCode) - lumber.Debug(string(body)) - return detailedStravaActivity{}, nil - } - - var details detailedStravaActivity - err = json.Unmarshal(body, &details) - if err != nil { - lumber.Error(err, "failed to parse json") - lumber.Debug(string(body)) - return detailedStravaActivity{}, nil - } return details, nil } diff --git a/internal/apis/strava/api.go b/internal/apis/strava/api.go new file mode 100644 index 0000000..0ebd44a --- /dev/null +++ b/internal/apis/strava/api.go @@ -0,0 +1,32 @@ +package strava + +import ( + "net/http" + "net/url" + + "github.com/gleich/lcp-v2/internal/apis" + "github.com/gleich/lumber/v3" +) + +func sendStravaAPIRequest[T any](path string, tokens tokens) (T, error) { + var zeroValue T + u, err := url.JoinPath("https://www.strava.com/", path) + if err != nil { + lumber.Error(err, "failed to join URL") + return zeroValue, err + } + + req, err := http.NewRequest("GET", u, nil) + if err != nil { + lumber.Error(err, "failed to create request") + return zeroValue, err + } + req.Header.Set("Authorization", "Bearer "+tokens.Access) + + resp, err := apis.SendRequest[T](req) + if err != nil { + lumber.Error(err, "failed to make strava API request") + return zeroValue, err + } + return resp, nil +} diff --git a/internal/apis/strava/tokens.go b/internal/apis/strava/tokens.go index 4e39303..7802e17 100644 --- a/internal/apis/strava/tokens.go +++ b/internal/apis/strava/tokens.go @@ -1,12 +1,11 @@ package strava import ( - "encoding/json" - "io" "net/http" "net/url" "time" + "github.com/gleich/lcp-v2/internal/apis" "github.com/gleich/lcp-v2/internal/secrets" "github.com/gleich/lumber/v3" ) @@ -43,28 +42,10 @@ func (t *tokens) refreshIfNeeded() { lumber.Error(err, "creating request for new token failed") return } - resp, err := http.DefaultClient.Do(req) - if err != nil { - lumber.Error(err, "sending request for new data token failed") - return - } - defer resp.Body.Close() - - body, err := io.ReadAll(resp.Body) - if err != nil { - lumber.Error(err, "reading response body failed") - return - } - if resp.StatusCode != http.StatusOK { - lumber.ErrorMsg(resp.StatusCode, "when trying to get new token data:", string(body)) - return - } - var tokens tokens - err = json.Unmarshal(body, &tokens) + tokens, err := apis.SendRequest[tokens](req) if err != nil { - lumber.Error(err, "failed to parse json") - lumber.Debug("body:", string(body)) + lumber.Error(err, "failed to refresh tokens") return }