package playlist import ( "encoding/base64" "encoding/json" "fmt" "io" "net/http" "net/url" "strings" ) const spotifyAPIBase = "https://api.spotify.com/v1" type SpotifyTokenResponse struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` ExpiresIn int `json:"expires_in"` } type SpotifyPlaylist struct { Name string `json:"name"` Description string `json:"description"` Public bool `json:"public"` Images []struct { Url string `json:"url"` Height int `json:"height"` Width int `json:"width"` } `json:"images"` Items struct { Limit int `json:"limit"` Offset int `json:"offset"` Total int `json:"total"` Items []struct { Item SpotifyTrack `json:"item"` } `json:"items"` } `json:"items"` ExternalURLs struct { Spotify string `json:"spotify"` } `json:"external_urls"` } type SpotifyTrack struct { ID string `json:"id"` Name string `json:"name"` Artists []struct { Name string `json:"name"` } `json:"artists"` ExternalIDs struct { Isrc string `json:"isrc"` } `json:"external_ids"` } func GetSpotifyAccessToken(clientID, clientSecret string) (string, error) { creds := base64.StdEncoding.EncodeToString([]byte(clientID + ":" + clientSecret)) data := url.Values{} data.Set("grant_type", "client_credentials") req, err := http.NewRequest("POST", "https://accounts.spotify.com/api/token", strings.NewReader(data.Encode())) if err != nil { return "", err } req.Header.Set("Authorization", "Basic "+creds) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil { return "", err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("auth failed (%d): %s", resp.StatusCode, body) } var token SpotifyTokenResponse if err := json.Unmarshal(body, &token); err != nil { return "", err } return token.AccessToken, nil } func GetPlaylist(token, playlistID string) (*SpotifyPlaylist, error) { // TODO: handle rate limit // TODO: handle request limits reqURL := fmt.Sprintf("%s/playlists/%s", spotifyAPIBase, playlistID) req, err := http.NewRequest("GET", reqURL, nil) if err != nil { return nil, err } req.Header.Set("Authorization", "Bearer "+token) resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("API error (%d): %s", resp.StatusCode, body) } var playlist SpotifyPlaylist if err := json.Unmarshal(body, &playlist); err != nil { return nil, err } return &playlist, nil }