123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package spotify
-
- import (
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "golang.org/x/oauth2/clientcredentials"
- spotifyAuth "golang.org/x/oauth2/spotify"
- "io"
- "net/http"
- "net/url"
- "strings"
- )
-
- type SpotifyClient struct {
- clientID string
- clientSecret string
- bearerAuth string
- baseURL *url.URL
- httpClient *http.Client
- }
-
- type TrackInfo struct {
- Album AlbumInfo `json:"album"`
- Artists []ArtistInfo `json:"artists"`
- DiskNumber int `json:"disc_number"`
- DurationMS int `json:"duration_ms"`
- Explicit bool `json:"explicit"`
- ExternalIds ExternalIds `json:"external_ids"`
- ExternalUrls ExternalUrls `json:"external_urls"`
- Href string `json:"href"`
- ID string `json:"id"`
- IsPlayable bool `json:"is_playable"`
- Name string `json:"name"`
- Popularity int `json:"popularity"`
- PreviewUrl string `json:"preview_url"`
- TrackNumber int `json:"track_number"`
- Type string `json:"type"`
- Uri string `json:"uri"`
- }
-
- type AlbumInfo struct {
- AlbumType string `json:"album_type"`
- Artists []ArtistInfo `json:"artists"`
- ExternalUrls ExternalUrls `json:"external_urls"`
- Href string `json:"href"`
- ID string `json:"id"`
- Images []ImageInfo `json:"images"`
- Name string `json:"name"`
- Type string `json:"type"`
- Uri string `json:"uri"`
- }
-
- type ArtistInfo struct {
- ExternalUrls ExternalUrls `json:"external_urls"`
- Href string `json:"href"`
- ID string `json:"id"`
- Name string `json:"name"`
- Type string `json:"type"`
- Uri string `json:"uri"`
- }
-
- type ImageInfo struct {
- Height int `json:"height"`
- URL string `json:url`
- Width int `json:"width"`
- }
-
- type ExternalIds struct {
- ISRC string `json:"isrc"`
- }
- type ExternalUrls struct {
- Spotify string `json:"spotify"`
- }
-
- type TokenInfo struct {
- AccessToken string `json:"access_token"`
- TokenType string `json:"token_type"`
- ExpiresIn int `json:"expires_in"`
- }
-
- type AuthErrorResponse struct {
- Error string `json:"error"`
- ErrorDescription string `json:"error_description"`
- }
-
- type ErrorResponse struct {
- Error ErrorInfo `json:"error"`
- }
-
- type ErrorInfo struct {
- Status int `json:"status"`
- Message string `json:"message"`
- }
-
- func NewClient(username, secret string) *SpotifyClient {
- baseURL, _ := url.Parse("https://api.spotify.com")
- httpClient := &http.Client{}
- return &SpotifyClient{
- clientID: username,
- clientSecret: secret,
- baseURL: baseURL,
- httpClient: httpClient,
- }
- }
-
- func (s *SpotifyClient) Authenticate() error {
- config := &clientcredentials.Config{
- ClientID: s.clientID,
- ClientSecret: s.clientSecret,
- TokenURL: spotifyAuth.Endpoint.TokenURL,
- }
- token, err := config.Token(context.Background())
- if err != nil {
- fmt.Println(err)
- return err
- }
- s.bearerAuth = token.AccessToken
- return nil
- }
-
- func (s *SpotifyClient) GetTrack(trackId string) (*TrackInfo, error) {
- var trackInfo TrackInfo
- url := s.urlFromBase(fmt.Sprintf("/v1/tracks/%s", trackId))
- err := s.doRequest("GET", url, &trackInfo, nil)
- if err != nil {
- return nil, err
- } else {
- return &trackInfo, nil
- }
- }
-
- func (s *SpotifyClient) urlFromBase(path string) *url.URL {
- endpoint := &url.URL{Path: path}
- return s.baseURL.ResolveReference(endpoint)
- }
-
- func (s *SpotifyClient) doRequest(method string, url *url.URL, object interface{}, values *url.Values) error {
- var bodyReader io.Reader
- if values != nil {
- s := values.Encode()
- bodyReader = strings.NewReader(s)
- }
-
- req, err := http.NewRequest(method, url.String(), bodyReader)
- if err != nil {
- return err
- }
- req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", s.bearerAuth))
-
- if values != nil {
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- }
-
- req.Header.Set("Accept", "application/json")
- req.Header.Set("User-Agent", "github.com/lamperi/e4bot/spotify")
-
- resp, err := s.httpClient.Do(req)
- if err != nil {
- return err
- }
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- var errorResp ErrorResponse
- err = json.NewDecoder(resp.Body).Decode(&errorResp)
- return errors.New(fmt.Sprintf("Spotify API returned: %d: %s", resp.StatusCode, errorResp.Error.Message))
- }
-
- err = json.NewDecoder(resp.Body).Decode(object)
- if err != nil {
- return err
- }
- return nil
-
- }
|