Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions playlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,44 @@ func (c *Client) AddTracksToPlaylist(ctx context.Context, playlistID ID, trackID
return result.SnapshotID, nil
}

// AddItemsToPlaylist adds one or more items to a user's playlist.
// This call requires ScopePlaylistModifyPublic or ScopePlaylistModifyPrivate.
// A maximum of 100 items can be added per call. It returns a snapshot ID that
// can be used to identify this version (the new version) of the playlist in
// future requests.
// The position to insert the items, a zero-based index. For example, to insert
// the items in the first position: `position=0` ; to insert the items in the
// third position: `position=2`. If omitted, the items will be appended to the
// playlist. Items are added in the order they appear in the uris array.
func (c *Client) AddItemsToPlaylist(ctx context.Context, playlistID ID, position int, items ...URI) (snapshotID string, err error) {
m := make(map[string]interface{})
m["uris"] = items
m["position"] = position
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes it impossible for users to fall back to the behaviour of appending items to the playlist when the position value is not provided - we should make this a functional option.


spotifyURL := fmt.Sprintf("%splaylists/%s/tracks",
c.baseURL, string(playlistID))
body, err := json.Marshal(m)
if err != nil {
return "", err
}
req, err := http.NewRequestWithContext(ctx, "POST", spotifyURL, bytes.NewReader(body))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")

result := struct {
SnapshotID string `json:"snapshot_id"`
}{}

err = c.execute(req, &result, http.StatusCreated)
if err != nil {
return "", err
}

return result.SnapshotID, nil
}

// RemoveTracksFromPlaylist removes one or more tracks from a user's playlist.
// This call requrles that the user has authorized the ScopePlaylistModifyPublic
// or ScopePlaylistModifyPrivate scopes.
Expand Down
13 changes: 13 additions & 0 deletions playlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,19 @@ func TestAddTracksToPlaylist(t *testing.T) {
}
}

func TestAddItemsToPlaylist(t *testing.T) {
client, server := testClientString(http.StatusCreated, `{ "snapshot_id" : "JbtmHBDBAYu3/bt8BOXKjzKx3i0b6LCa/wVjyl6qQ2Yf6nFXkbmzuEa+ZI/U1yF+" }`)
defer server.Close()

snapshot, err := client.AddItemsToPlaylist(context.Background(), ID("playlist_id"), 0, URI("spotify:track:111"), URI("spotify:track:222"), URI("spotify:episode:111"))
if err != nil {
t.Error(err)
}
if snapshot != "JbtmHBDBAYu3/bt8BOXKjzKx3i0b6LCa/wVjyl6qQ2Yf6nFXkbmzuEa+ZI/U1yF+" {
t.Error("Didn't get expected snapshot ID")
}
}

func TestRemoveTracksFromPlaylist(t *testing.T) {
client, server := testClientString(http.StatusOK, `{ "snapshot_id" : "JbtmHBDBAYu3/bt8BOXKjzKx3i0b6LCa/wVjyl6qQ2Yf6nFXkbmzuEa+ZI/U1yF+" }`, func(req *http.Request) {
requestBody, err := ioutil.ReadAll(req.Body)
Expand Down