api

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultBaseURL = "https://api.sports-tracker.com/apiserver/v1/"
View Source
const TimelineBaseURL = "https://247.sports-tracker.com/"

TimelineBaseURL hosts the 24/7 wellness streams (sleep, activity, recovery, sleepstages). It uses STTAuthorization just like the ASKO base URL, but a different response shape (gzipped NDJSON, no AskoResponse envelope).

Variables

This section is empty.

Functions

func DecodeAsko

func DecodeAsko[T any](body []byte) (T, error)

DecodeAsko parses body into an AskoResponse[T] and surfaces server errors as *Error.

func DecodeAskoWithMeta added in v0.2.0

func DecodeAskoWithMeta[T any](body []byte) (T, json.RawMessage, error)

DecodeAskoWithMeta parses the envelope and returns payload + raw metadata. The raw metadata can be further unmarshalled by the caller (e.g. to extract pagination cursors). If parsing fails a *Error is returned; metadata may be nil even on success when the server omits it.

func JSONBody added in v0.3.0

func JSONBody(v any) (io.Reader, map[string]string, error)

JSONBody marshals v as JSON and returns a reader + the matching Content-Type header (always "application/json;charset=UTF-8" — the format Suunto uses). Errors are returned as-is (callers wrap into *Error if they want exit codes).

func TextBody added in v0.3.0

func TextBody(s string) (io.Reader, map[string]string)

TextBody wraps a plain-text body. Used by /v1/workouts/comment/{key}.

func WorkoutMultipart added in v0.3.0

func WorkoutMultipart(smlPath, extensionsPath string) (io.ReadCloser, map[string]string, error)

WorkoutMultipart builds a streaming multipart/form-data body for POST /v1/workout. smlPath points to a .sml file on disk (required). extensionsPath is optional; pass "" to omit. The returned reader pipes parts through io.Pipe — closing the reader cancels the goroutine. The returned headers contain the Content-Type with the auto-generated boundary; merge with any auth headers the caller needs (e.g. STTAuthorization is added by Client.Do).

Caller MUST eventually consume or Close the reader to release the goroutine.

Types

type AskoError

type AskoError struct {
	Code        int    `json:"code"`
	Description string `json:"description"`
}

type AskoResponse

type AskoResponse[T any] struct {
	Error    *AskoError      `json:"error"`
	Metadata json.RawMessage `json:"metadata"`
	Payload  T               `json:"payload"`
}

AskoResponse is the standard envelope returned by /apiserver/* endpoints. `error == nil` means success.

type Client

type Client struct {
	BaseURL    string
	HTTP       *http.Client
	SessionKey string // empty for unauthenticated calls
}

Client is a thin HTTP client that injects STTAuthorization and maps HTTP status codes to typed errors. Construct via NewClient.

func NewClient

func NewClient(baseURL, sessionKey string, timeout time.Duration) *Client

func NewTimelineClient added in v0.2.0

func NewTimelineClient(sessionKey string, timeout time.Duration) *Client

NewTimelineClient is a convenience wrapper for endpoints on TimelineBaseURL.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, body io.Reader, headers map[string]string) ([]byte, error)

Do executes the request, applies common headers, and maps HTTP errors to *Error. On 2xx it returns the raw body. Envelope decoding is the caller's responsibility (DecodeAsko for ASKO endpoints).

func (*Client) DoStream added in v0.2.0

func (c *Client) DoStream(ctx context.Context, method, path string, body io.Reader, headers map[string]string) (io.ReadCloser, error)

DoStream executes the request and returns a streaming ReadCloser for 2xx responses. The caller MUST close the returned ReadCloser.

Transparent gzip decompression:

  • If the response carries Content-Encoding: gzip, the body is gunzipped via that header.
  • Otherwise the first two bytes are peeked; if they are the gzip magic (0x1f 0x8b), the body is still gunzipped (Suunto's 247 service gzips unconditionally without setting the header).
  • Otherwise the raw body is returned.

Non-2xx responses are mapped to *Error exactly as Do does.

type Error

type Error struct {
	Code    string // stable token: AUTH_EXPIRED, FORBIDDEN, NOT_FOUND, SERVER, NETWORK, BAD_ENVELOPE
	Message string
	Hint    string
	HTTP    int // 0 if not HTTP-derived
	Exit    int // process exit code (cmd.Exit*)
}

Error is a typed API error with an exit code, used by cmd/ to set os.Exit.

func (*Error) Error

func (e *Error) Error() string

func (*Error) ExitCode

func (e *Error) ExitCode() int

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL