Files
DeemixFix/spotify-web-api-node/src/spotify-web-api.js

1662 lines
70 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict'
const AuthenticationRequest = require('./authentication-request')
const WebApiRequest = require('./webapi-request')
const HttpManager = require('./http-manager')
function SpotifyWebApi (credentials) {
this._credentials = credentials || {}
}
SpotifyWebApi.prototype = {
setCredentials: function (credentials) {
for (const key in credentials) {
if (credentials.hasOwnProperty(key)) {
this._credentials[key] = credentials[key]
}
}
},
getCredentials: function () {
return this._credentials
},
resetCredentials: function () {
this._credentials = null
},
setClientId: function (clientId) {
this._setCredential('clientId', clientId)
},
setClientSecret: function (clientSecret) {
this._setCredential('clientSecret', clientSecret)
},
setAccessToken: function (accessToken) {
this._setCredential('accessToken', accessToken)
},
setRefreshToken: function (refreshToken) {
this._setCredential('refreshToken', refreshToken)
},
setRedirectURI: function (redirectUri) {
this._setCredential('redirectUri', redirectUri)
},
getRedirectURI: function () {
return this._getCredential('redirectUri')
},
getClientId: function () {
return this._getCredential('clientId')
},
getClientSecret: function () {
return this._getCredential('clientSecret')
},
getAccessToken: function () {
return this._getCredential('accessToken')
},
getRefreshToken: function () {
return this._getCredential('refreshToken')
},
resetClientId: function () {
this._resetCredential('clientId')
},
resetClientSecret: function () {
this._resetCredential('clientSecret')
},
resetAccessToken: function () {
this._resetCredential('accessToken')
},
resetRefreshToken: function () {
this._resetCredential('refreshToken')
},
resetRedirectURI: function () {
this._resetCredential('redirectUri')
},
_setCredential: function (credentialKey, value) {
this._credentials = this._credentials || {}
this._credentials[credentialKey] = value
},
_getCredential: function (credentialKey) {
if (!this._credentials) {
} else {
return this._credentials[credentialKey]
}
},
_resetCredential: function (credentialKey) {
if (!this._credentials) {
} else {
this._credentials[credentialKey] = null
}
},
/**
* Look up a track.
* @param {string} trackId The track's ID.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getTrack('3Qm86XLflmIXVm1wcwkgDK').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the track. Not returned if a callback is given.
*/
getTrack: function (trackId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/tracks/' + trackId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up several tracks.
* @param {string[]} trackIds The IDs of the artists.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getArtists(['0oSGxfWSnnOXhD2fKuz2Gy', '3dBVyJ7JuOMt4GE9607Qin']).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the artists. Not returned if a callback is given.
*/
getTracks: function (trackIds, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/tracks')
.withQueryParameters(
{
ids: trackIds.join(',')
},
options
)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up an album.
* @param {string} albumId The album's ID.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAlbum('0sNOF9WDwhWunNAHPD3Baj').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the album. Not returned if a callback is given.
*/
getAlbum: function (albumId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/albums/' + albumId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up several albums.
* @param {string[]} albumIds The IDs of the albums.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAlbums(['0oSGxfWSnnOXhD2fKuz2Gy', '3dBVyJ7JuOMt4GE9607Qin']).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the albums. Not returned if a callback is given.
*/
getAlbums: function (albumIds, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/albums')
.withQueryParameters(
{
ids: albumIds.join(',')
},
options
)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up an artist.
* @param {string} artistId The artist's ID.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example api.getArtist('1u7kkVrr14iBvrpYnZILJR').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the artist. Not returned if a callback is given.
*/
getArtist: function (artistId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/artists/' + artistId)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up several artists.
* @param {string[]} artistIds The IDs of the artists.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getArtists(['0oSGxfWSnnOXhD2fKuz2Gy', '3dBVyJ7JuOMt4GE9607Qin']).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the artists. Not returned if a callback is given.
*/
getArtists: function (artistIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/artists')
.withQueryParameters({
ids: artistIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Search for music entities of certain types.
* @param {string} query The search query.
* @param {string[]} types An array of item types to search across.
* Valid types are: 'album', 'artist', 'playlist', 'track', 'show', and 'episode'.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example search('Abba', ['track', 'playlist'], { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
search: function (query, types, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/search/')
.withQueryParameters(
{
type: types.join(','),
q: query
},
options
)
.build()
.execute(HttpManager.get, callback)
},
/**
* Search for an album.
* @param {string} query The search query.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchAlbums('Space Oddity', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchAlbums: function (query, options, callback) {
return this.search(query, ['album'], options, callback)
},
/**
* Search for an artist.
* @param {string} query The search query.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchArtists('David Bowie', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchArtists: function (query, options, callback) {
return this.search(query, ['artist'], options, callback)
},
/**
* Search for a track.
* @param {string} query The search query.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchTracks('Mr. Brightside', { limit : 3, offset : 2 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchTracks: function (query, options, callback) {
return this.search(query, ['track'], options, callback)
},
/**
* Search for playlists.
* @param {string} query The search query.
* @param {Object} options The possible options.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchPlaylists('workout', { limit : 1, offset : 0 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchPlaylists: function (query, options, callback) {
return this.search(query, ['playlist'], options, callback)
},
/**
* Get an artist's albums.
* @param {string} artistId The artist's ID.
* @options {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getArtistAlbums('0oSGxfWSnnOXhD2fKuz2Gy', { album_type : 'album', country : 'GB', limit : 2, offset : 5 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the albums
* for the given artist. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
getArtistAlbums: function (artistId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/artists/' + artistId + '/albums')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the tracks of an album.
* @param albumId the album's ID.
* @options {Object} [options] The possible options, e.g. limit.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAlbumTracks('41MnTivkwTO3UUJ8DrqEJJ', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* tracks in the album. The result is paginated. If the promise is rejected.
* it contains an error object. Not returned if a callback is given.
*/
getAlbumTracks: function (albumId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/albums/' + albumId + '/tracks')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get an artist's top tracks.
* @param {string} artistId The artist's ID.
* @param {string} country The country/territory where the tracks are most popular. (format: ISO 3166-1 alpha-2)
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getArtistTopTracks('0oSGxfWSnnOXhD2fKuz2Gy', 'GB').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* artist's top tracks in the given country. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
getArtistTopTracks: function (artistId, country, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/artists/' + artistId + '/top-tracks')
.withQueryParameters({
country
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Get related artists.
* @param {string} artistId The artist's ID.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getArtistRelatedArtists('0oSGxfWSnnOXhD2fKuz2Gy').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* related artists. If the promise is rejected, it contains an error object. Not returned if a callback is given.
*/
getArtistRelatedArtists: function (artistId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/artists/' + artistId + '/related-artists')
.build()
.execute(HttpManager.get, callback)
},
/**
* Get information about a user.
* @param userId The user ID.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getUser('thelinmichael').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object
* containing information about the user. If the promise is
* rejected, it contains an error object. Not returned if a callback is given.
*/
getUser: function (userId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/users/' + encodeURIComponent(userId))
.build()
.execute(HttpManager.get, callback)
},
/**
* Get information about the user that has signed in (the current user).
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getMe().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object
* containing information about the user. The amount of information
* depends on the permissions given by the user. If the promise is
* rejected, it contains an error object. Not returned if a callback is given.
*/
getMe: function (callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me')
.build()
.execute(HttpManager.get, callback)
},
/**
* Get a user's playlists.
* @param {string} userId An optional id of the user. If you know the Spotify URI it is easy
* to find the id (e.g. spotify:user:<here_is_the_id>). If not provided, the id of the user that granted
* the permissions will be used.
* @param {Object} [options] The options supplied to this request.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getUserPlaylists('thelinmichael').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing
* a list of playlists. If rejected, it contains an error object. Not returned if a callback is given.
*/
getUserPlaylists: function (userId, options, callback) {
let path
if (typeof userId === 'string') {
path = '/v1/users/' + encodeURIComponent(userId) + '/playlists'
} else if (typeof userId === 'object') {
callback = options
options = userId
path = '/v1/me/playlists'
} /* undefined */ else {
path = '/v1/me/playlists'
}
return WebApiRequest.builder(this.getAccessToken())
.withPath(path)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get a playlist.
* @param {string} playlistId The playlist's ID.
* @param {Object} [options] The options supplied to this request.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getPlaylist('3EsfV6XzCHU8SPNdbnFogK').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing
* the playlist. If rejected, it contains an error object. Not returned if a callback is given.
*/
getPlaylist: function (playlistId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get tracks in a playlist.
* @param {string} playlistId The playlist's ID.
* @param {Object} [options] Optional options, such as fields.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getPlaylistTracks('3ktAYNcRHpazJ9qecm3ptn').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object that containing
* the tracks in the playlist. If rejected, it contains an error object. Not returned if a callback is given.
*/
getPlaylistTracks: function (playlistId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Create a playlist.
* @param {string} [name] The name of the playlist.
* @param {Object} [options] The possible options, being description, collaborative and public.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example createPlaylist('My playlist', {''description': 'My description', 'collaborative' : false, 'public': true}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing information about the
* created playlist. If rejected, it contains an error object. Not returned if a callback is given.
*/
createPlaylist: function (name, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/playlists')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters({
name
}, options)
.build()
.execute(HttpManager.post, callback)
},
/**
* Follow a playlist.
* @param {string} playlistId The playlist's ID
* @param {Object} [options] The possible options, currently only public.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
followPlaylist: function (playlistId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/followers')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(options)
.build()
.execute(HttpManager.put, callback)
},
/**
* Unfollow a playlist.
* @param {string} playlistId The playlist's ID
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
unfollowPlaylist: function (playlistId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/followers')
.build()
.execute(HttpManager.del, callback)
},
/**
* Change playlist details.
* @param {string} playlistId The playlist's ID
* @param {Object} [options] The possible options, e.g. name, public.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example changePlaylistDetails('3EsfV6XzCHU8SPNdbnFogK', {name: 'New name', public: true}).then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
changePlaylistDetails: function (playlistId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId)
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(options)
.build()
.execute(HttpManager.put, callback)
},
/**
* Replace the image used to represent a specific playlist.
* @param {string} playlistId The playlist's ID
* @param {string} base64URI Base64 encoded JPEG image data, maximum payload size is 256 KB
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example uploadCustomPlaylistCoverImage('3EsfV6XzCHU8SPNdbnFogK', 'longbase64uri').then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
uploadCustomPlaylistCoverImage: function (playlistId, base64URI, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/images')
.withHeaders({ 'Content-Type': 'image/jpeg' })
.withBodyParameters(base64URI)
.build()
.execute(HttpManager.put, callback)
},
/**
* Add tracks to a playlist.
* @param {string} playlistId The playlist's ID
* @param {string[]} tracks URIs of the tracks to add to the playlist.
* @param {Object} [options] Options, position being the only one.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example addTracksToPlaylist('3EsfV6XzCHU8SPNdbnFogK',
'["spotify:track:4iV5W9uYEdYUVa79Axb7Rh", "spotify:track:1301WleyT98MSxVHPZCA6M"]').then(...)
* @returns {Promise|undefined} A promise that if successful returns an object containing a snapshot_id. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
addTracksToPlaylist: function (playlistId, tracks, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withQueryParameters(options)
.withBodyParameters({
uris: tracks
})
.build()
.execute(HttpManager.post, callback)
},
/**
* Remove tracks from a playlist.
* @param {string} playlistId The playlist's ID
* @param {Object[]} tracks An array of objects containing a property called uri with the track URI (String), and
* an optional property called positions (int[]), e.g. { uri : "spotify:track:491rM2JN8KvmV6p0oDDuJT", positions : [0, 15] }
* @param {Object} options Options, snapshot_id being the only one.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns an object containing a snapshot_id. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
removeTracksFromPlaylist: function (playlistId, tracks, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(
{
tracks
},
options
)
.build()
.execute(HttpManager.del, callback)
},
/**
* Remove tracks from a playlist by position instead of specifying the tracks' URIs.
* @param {string} playlistId The playlist's ID
* @param {int[]} positions The positions of the tracks in the playlist that should be removed
* @param {string} snapshot_id The snapshot ID, or version, of the playlist. Required
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns an object containing a snapshot_id. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
removeTracksFromPlaylistByPosition: function (
playlistId,
positions,
snapshotId,
callback
) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters({
positions,
snapshot_id: snapshotId
})
.build()
.execute(HttpManager.del, callback)
},
/**
* Replace tracks in a playlist.
* @param {string} playlistId The playlist's ID
* @param {Object[]} uris An array of track URIs (strings)
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
replaceTracksInPlaylist: function (playlistId, uris, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters({
uris
})
.build()
.execute(HttpManager.put, callback)
},
/**
* Reorder tracks in a playlist.
* @param {string} playlistId The playlist's ID
* @param {int} rangeStart The position of the first track to be reordered.
* @param {int} insertBefore The position where the tracks should be inserted.
* @param {Object} options Optional parameters, i.e. range_length and snapshot_id.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns an object containing a snapshot_id. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
reorderTracksInPlaylist: function (
playlistId,
rangeStart,
insertBefore,
options,
callback
) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/playlists/' + playlistId + '/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(
{
range_start: rangeStart,
insert_before: insertBefore
},
options
)
.build()
.execute(HttpManager.put, callback)
},
/**
* Get audio features for a single track identified by its unique Spotify ID.
* @param {string} trackId The track ID
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAudioFeaturesForTrack('38P3Q4QcdjQALGF2Z92BmR').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object
* containing information about the audio features. If the promise is
* rejected, it contains an error object. Not returned if a callback is given.
*/
getAudioFeaturesForTrack: function (trackId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/audio-features/' + trackId)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get audio analysis for a single track identified by its unique Spotify ID.
* @param {string} trackId The track ID
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAudioAnalysisForTrack('38P3Q4QcdjQALGF2Z92BmR').then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object
* containing information about the audio analysis. If the promise is
* rejected, it contains an error object. Not returned if a callback is given.
*/
getAudioAnalysisForTrack: function (trackId, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/audio-analysis/' + trackId)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get audio features for multiple tracks identified by their unique Spotify ID.
* @param {string[]} trackIds The track IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAudioFeaturesForTracks(['38P3Q4QcdjQALGF2Z92BmR', '2HO2bnoMrpnZUbUqiilLHi']).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object
* containing information about the audio features for the tracks. If the promise is
* rejected, it contains an error object. Not returned if a callback is given.
*/
getAudioFeaturesForTracks: function (trackIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/audio-features')
.withQueryParameters({
ids: trackIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Create a playlist-style listening experience based on seed artists, tracks and genres.
* @param {Object} [options] The options supplied to this request.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getRecommendations({ min_energy: 0.4, seed_artists: ['6mfK6Q2tzLMEchAr0e9Uzu', '4DYFVNKZ1uixa6SQTvzQwJ'], min_popularity: 50 }).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing
* a list of tracks and a list of seeds. If rejected, it contains an error object. Not returned if a callback is given.
*/
getRecommendations: function (options, callback) {
const _opts = {}
const optionsOfTypeArray = ['seed_artists', 'seed_genres', 'seed_tracks']
for (const option in options) {
if (options.hasOwnProperty(option)) {
if (
optionsOfTypeArray.indexOf(option) !== -1 &&
Object.prototype.toString.call(options[option]) === '[object Array]'
) {
_opts[option] = options[option].join(',')
} else {
_opts[option] = options[option]
}
}
}
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/recommendations')
.withQueryParameters(_opts)
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve a list of available genres seed parameter values for recommendations.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getAvailableGenreSeeds().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing
* a list of available genres to be used as seeds for recommendations.
* If rejected, it contains an error object. Not returned if a callback is given.
*/
getAvailableGenreSeeds: function (callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/recommendations/available-genre-seeds')
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve the tracks that are saved to the authenticated users Your Music library.
* @param {Object} [options] Options, being market, limit, and/or offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which in turn contains
* playlist track objects. Not returned if a callback is given.
*/
getMySavedTracks: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/tracks')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Check if one or more tracks is already saved in the current Spotify users “Your Music” library.
* @param {string[]} trackIds The track IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an array of booleans. The order
* of the returned array's elements correspond to the track ID in the request.
* The boolean value of true indicates that the track is part of the user's library, otherwise false.
* Not returned if a callback is given.
*/
containsMySavedTracks: function (trackIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/tracks/contains')
.withQueryParameters({
ids: trackIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Remove a track from the authenticated user's Your Music library.
* @param {string[]} trackIds The track IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error.
* Not returned if a callback is given.
*/
removeFromMySavedTracks: function (trackIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters({ ids: trackIds })
.build()
.execute(HttpManager.del, callback)
},
/**
* Add a track from the authenticated user's Your Music library.
* @param {string[]} trackIds The track IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error. Not returned if a callback is given.
*/
addToMySavedTracks: function (trackIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/tracks')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters({ ids: trackIds })
.build()
.execute(HttpManager.put, callback)
},
/**
* Remove an album from the authenticated user's Your Music library.
* @param {string[]} albumIds The album IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error.
* Not returned if a callback is given.
*/
removeFromMySavedAlbums: function (albumIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(albumIds)
.build()
.execute(HttpManager.del, callback)
},
/**
* Add an album from the authenticated user's Your Music library.
* @param {string[]} albumIds The track IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error. Not returned if a callback is given.
*/
addToMySavedAlbums: function (albumIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(albumIds)
.build()
.execute(HttpManager.put, callback)
},
/**
* Retrieve the albums that are saved to the authenticated users Your Music library.
* @param {Object} [options] Options, being market, limit, and/or offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which in turn contains
* playlist album objects. Not returned if a callback is given.
*/
getMySavedAlbums: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Check if one or more albums is already saved in the current Spotify users “Your Music” library.
* @param {string[]} albumIds The album IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an array of booleans. The order
* of the returned array's elements correspond to the album ID in the request.
* The boolean value of true indicates that the album is part of the user's library, otherwise false.
* Not returned if a callback is given.
*/
containsMySavedAlbums: function (albumIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums/contains')
.withQueryParameters({
ids: albumIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the current user's top artists based on calculated affinity.
* @param {Object} [options] Options, being time_range, limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of artists,
* otherwise an error. Not returned if a callback is given.
*/
getMyTopArtists: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/top/artists')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the current user's top tracks based on calculated affinity.
* @param {Object} [options] Options, being time_range, limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
getMyTopTracks: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/top/tracks')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the Current User's Recently Played Tracks
* @param {Object} [options] Options, being type, after, limit, before.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of play history objects,
* otherwise an error. Not returned if a callback is given. Note that the response will be empty
* in case the user has enabled private session.
*/
getMyRecentlyPlayedTracks: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/recently-played')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Add track or episode to device queue
* @param {string} [uri] uri of the track or episode to add
* @param {Object} [options] Options, being device_id.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
addToQueue: function (uri, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/queue')
.withQueryParameters(
{
uri
},
options
)
.build()
.execute(HttpManager.post, callback)
},
/**
* Get the Current User's Available Devices
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an array of device objects,
* otherwise an error. Not returned if a callback is given.
*/
getMyDevices: function (callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/devices')
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the Current User's Currently Playing Track.
* @param {Object} [options] Options, being market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
getMyCurrentPlayingTrack: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/currently-playing')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get Information About The User's Current Playback State
* @param {Object} [options] Options, being market and additional_types.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into a paging object of tracks,
* otherwise an error. Not returned if a callback is given.
*/
getMyCurrentPlaybackState: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Transfer a User's Playback
* @param {string[]} [deviceIds] An _array_ containing a device ID on which playback should be started/transferred.
* (NOTE: The API is currently only supporting a single device ID.)
* @param {Object} [options] Options, the only one being 'play'.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
transferMyPlayback: function (deviceIds, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(
{
device_ids: deviceIds
},
options
)
.build()
.execute(HttpManager.put, callback)
},
/**
* Starts o Resumes the Current User's Playback
* @param {Object} [options] Options, being device_id, context_uri, offset, uris, position_ms.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example play({context_uri: 'spotify:album:5ht7ItJgpBH7W6vJ5BqpPr'}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
play: function (options, callback) {
/* jshint camelcase: false */
const _options = options || {}
const queryParams = _options.device_id
? { device_id: _options.device_id }
: null
const postData = {};
['context_uri', 'uris', 'offset', 'position_ms'].forEach(function (field) {
if (field in _options) {
postData[field] = _options[field]
}
})
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/play')
.withQueryParameters(queryParams)
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(postData)
.build()
.execute(HttpManager.put, callback)
},
/**
* Pauses the Current User's Playback
* @param {Object} [options] Options, being device_id. If left empty will target the user's currently active device.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example pause().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
pause: function (options, callback) {
return (
WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/pause')
/* jshint camelcase: false */
.withQueryParameters(
options && options.device_id ? { device_id: options.device_id } : null
)
.withHeaders({ 'Content-Type': 'application/json' })
.build()
.execute(HttpManager.put, callback)
)
},
/**
* Skip the Current User's Playback To Previous Track
* @param {Object} [options] Options, being device_id. If left empty will target the user's currently active device.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example skipToPrevious().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
skipToPrevious: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/previous')
.withQueryParameters(
options && options.device_id ? { device_id: options.device_id } : null
)
.build()
.execute(HttpManager.post, callback)
},
/**
* Skip the Current User's Playback To Next Track
* @param {Object} [options] Options, being device_id. If left empty will target the user's currently active device.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example skipToNext().then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
skipToNext: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/next')
.withQueryParameters(
options && options.device_id ? { device_id: options.device_id } : null
)
.build()
.execute(HttpManager.post, callback)
},
/**
* Seeks to the given position in the users currently playing track.
*
* @param {number} positionMs The position in milliseconds to seek to. Must be a positive number.
* @param {Object} options Options, being device_id. If left empty will target the user's currently active device.
* @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first
* one is the error object (null if no error), and the second is the value if the request succeeded.
* @return {Object} Null if a callback is provided, a `Promise` object otherwise
*/
seek: function (positionMs, options, callback) {
const params = {
/* jshint camelcase: false */
position_ms: positionMs
}
if (options && 'device_id' in options) {
/* jshint camelcase: false */
params.device_id = options.device_id
}
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/seek')
.withQueryParameters(params)
.build()
.execute(HttpManager.put, callback)
},
/**
* Set Repeat Mode On The Current User's Playback
* @param {string} [state] State (track, context, or off)
* @param {Object} [options] Options, being device_id. If left empty will target the user's currently active device.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example setRepeat('context', {}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
setRepeat: function (state, options, callback) {
const params = {
state
}
if (options && 'device_id' in options) {
/* jshint camelcase: false */
params.device_id = options.device_id
}
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/repeat')
.withQueryParameters(params)
.build()
.execute(HttpManager.put, callback)
},
/**
* Set Shuffle Mode On The Current User's Playback
* @param {boolean} [state] State
* @param {Object} [options] Options, being device_id. If left empty will target the user's currently active device.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example setShuffle({state: 'false'}).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an empty response,
* otherwise an error. Not returned if a callback is given.
*/
setShuffle: function (state, options, callback) {
const params = {
state
}
if (options && 'device_id' in options) {
/* jshint camelcase: false */
params.device_id = options.device_id
}
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/shuffle')
.withQueryParameters(params)
.build()
.execute(HttpManager.put, callback)
},
/**
* Set the volume for the users current playback device.
* @param {number} volumePercent The volume to set. Must be a value from 0 to 100.
* @param {Object} options Options, being device_id. If left empty will target the user's currently active device.
* @param {function(Object,Object)} callback An optional callback that receives 2 parameters. The first
* one is the error object (null if no error), and the second is the value if the request succeeded.
* @return {Object} Null if a callback is provided, a `Promise` object otherwise
*/
setVolume: function (volumePercent, options, callback) {
const params = {
/* jshint camelcase: false */
volume_percent: volumePercent
}
if (options && 'device_id' in options) {
/* jshint camelcase: false */
params.device_id = options.device_id
}
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/player/volume')
.withQueryParameters(params)
.build()
.execute(HttpManager.put, callback)
},
/**
* Add the current user as a follower of one or more other Spotify users.
* @param {string[]} userIds The IDs of the users to be followed.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example followUsers(['thelinmichael', 'wizzler']).then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
followUsers: function (userIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following')
.withQueryParameters({
ids: userIds.join(','),
type: 'user'
})
.build()
.execute(HttpManager.put, callback)
},
/**
* Add the current user as a follower of one or more artists.
* @param {string[]} artistIds The IDs of the artists to be followed.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example followArtists(['0LcJLqbBmaGUft1e9Mm8HV', '3gqv1kgivAc92KnUm4elKv']).then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
followArtists: function (artistIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following')
.withQueryParameters({
ids: artistIds.join(','),
type: 'artist'
})
.build()
.execute(HttpManager.put, callback)
},
/**
* Remove the current user as a follower of one or more other Spotify users.
* @param {string[]} userIds The IDs of the users to be unfollowed.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example unfollowUsers(['thelinmichael', 'wizzler']).then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
unfollowUsers: function (userIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following')
.withQueryParameters({
ids: userIds.join(','),
type: 'user'
})
.build()
.execute(HttpManager.del, callback)
},
/**
* Remove the current user as a follower of one or more artists.
* @param {string[]} artistIds The IDs of the artists to be unfollowed.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example unfollowArtists(['0LcJLqbBmaGUft1e9Mm8HV', '3gqv1kgivAc92KnUm4elKv']).then(...)
* @returns {Promise|undefined} A promise that if successful, simply resolves to an empty object. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
unfollowArtists: function (artistIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following')
.withQueryParameters({
ids: artistIds.join(','),
type: 'artist'
})
.build()
.execute(HttpManager.del, callback)
},
/**
* Check to see if the current user is following one or more other Spotify users.
* @param {string[]} userIds The IDs of the users to check if are followed by the current user.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example isFollowingUsers(['thelinmichael', 'wizzler']).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an array of booleans. The order
* of the returned array's elements correspond to the users IDs in the request.
* The boolean value of true indicates that the user is following that user, otherwise is not.
* Not returned if a callback is given.
*/
isFollowingUsers: function (userIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following/contains')
.withQueryParameters({
ids: userIds.join(','),
type: 'user'
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the current user's followed artists.
* @param {Object} [options] Options, being after and limit.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which contains
* album objects. Not returned if a callback is given.
*/
getFollowedArtists: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following')
.withQueryParameters(
{
type: 'artist'
},
options
)
.build()
.execute(HttpManager.get, callback)
},
/**
* Check if users are following a playlist.
* @param {string} userId The playlist's owner's user ID
* @param {string} playlistId The playlist's ID
* @param {String[]} User IDs of the following users
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns an array of booleans. If rejected,
* it contains an error object. Not returned if a callback is given.
*/
areFollowingPlaylist: function (userId, playlistId, followerIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath(
'/v1/users/' +
encodeURIComponent(userId) +
'/playlists/' +
playlistId +
'/followers/contains'
)
.withQueryParameters({
ids: followerIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Check to see if the current user is following one or more artists.
* @param {string[]} artistIds The IDs of the artists to check if are followed by the current user.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example isFollowingArtists(['0LcJLqbBmaGUft1e9Mm8HV', '3gqv1kgivAc92KnUm4elKv']).then(...)
* @returns {Promise|undefined} A promise that if successful, resolves into an array of booleans. The order
* of the returned array's elements correspond to the artists IDs in the request.
* The boolean value of true indicates that the user is following that artist, otherwise is not.
* Not returned if a callback is given.
*/
isFollowingArtists: function (artistIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/following/contains')
.withQueryParameters({
ids: artistIds.join(','),
type: 'artist'
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve new releases
* @param {Object} [options] Options, being country, limit and/or offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which contains
* album objects. Not returned if a callback is given.
*/
getNewReleases: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/browse/new-releases')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve featured playlists
* @param {Object} [options] Options, being country, locale, timestamp, limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which contains
* featured playlists. Not returned if a callback is given.
*/
getFeaturedPlaylists: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/browse/featured-playlists')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve a list of categories used to tag items in Spotify (e.g. in the 'Browse' tab)
* @param {Object} [options] Options, being country, locale, limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object of categories.
* Not returned if a callback is given.
*/
getCategories: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/browse/categories')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve a category.
* @param {string} categoryId The id of the category to retrieve.
* @param {Object} [options] Options, being country, locale.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a category object.
* Not returned if a callback is given.
*/
getCategory: function (categoryId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/browse/categories/' + categoryId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Retrieve playlists for a category.
* @param {string} categoryId The id of the category to retrieve playlists for.
* @param {Object} [options] Options, being country, limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to a paging object containing simple playlists.
* Not returned if a callback is given.
*/
getPlaylistsForCategory: function (categoryId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/browse/categories/' + categoryId + '/playlists')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get a show.
* @param {string} showId The show's ID.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getShow('3Qm86XLflmIXVm1wcwkgDK').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the show. Not returned if a callback is given.
*/
getShow: function (showId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/shows/' + showId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up several shows.
* @param {string[]} showIds The IDs of the shows.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getShows(['0oSGxfWSnnOXhD2fKuz2Gy', '3dBVyJ7JuOMt4GE9607Qin']).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the shows. Not returned if a callback is given.
*/
getShows: function (showIds, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/shows')
.withQueryParameters(
{
ids: showIds.join(',')
},
options
)
.build()
.execute(HttpManager.get, callback)
},
/**
* Check if one or more shows is already saved in the current Spotify users “Your Music” library.
* @param {string[]} showIds The show IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an array of booleans. The order
* of the returned array's elements correspond to the show ID in the request.
* The boolean value of true indicates that the show is part of the user's library, otherwise false.
* Not returned if a callback is given.
*/
containsMySavedShows: function (showIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/shows/contains')
.withQueryParameters({
ids: showIds.join(',')
})
.build()
.execute(HttpManager.get, callback)
},
/**
* Remove an show from the authenticated user's Your Music library.
* @param {string[]} showIds The show IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error.
* Not returned if a callback is given.
*/
removeFromMySavedShows: function (showIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/shows')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(showIds)
.build()
.execute(HttpManager.del, callback)
},
/**
* Add a show from the authenticated user's Your Music library.
* @param {string[]} showIds The show IDs
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful returns null, otherwise an error. Not returned if a callback is given.
*/
addToMySavedShows: function (showIds, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/shows')
.withHeaders({ 'Content-Type': 'application/json' })
.withBodyParameters(showIds)
.build()
.execute(HttpManager.put, callback)
},
/**
* Retrieve the shows that are saved to the authenticated users Your Music library.
* @param {Object} [options] Options, being market, limit, and/or offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves to an object containing a paging object which in turn contains
* playlist show objects. Not returned if a callback is given.
*/
getMySavedShows: function (options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/shows')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Get the episodes of an show.
* @param showId the show's ID.
* @options {Object} [options] The possible options, being limit, offset, and market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getShowEpisodes('41MnTivkwTO3UUJ8DrqEJJ', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* episodes in the album. The result is paginated. If the promise is rejected.
* it contains an error object. Not returned if a callback is given.
*/
getShowEpisodes: function (showId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/shows/' + showId + '/episodes')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Search for a show.
* @param {string} query The search query.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchShows('Space Oddity', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchShows: function (query, options, callback) {
return this.search(query, ['show'], options, callback)
},
/**
* Search for an episode.
* @param {string} query The search query.
* @param {Object} [options] The possible options, e.g. limit, offset.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example searchEpisodes('Space Oddity', { limit : 5, offset : 1 }).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing the
* search results. The result is paginated. If the promise is rejected,
* it contains an error object. Not returned if a callback is given.
*/
searchEpisodes: function (query, options, callback) {
return this.search(query, ['episode'], options, callback)
},
/**
* Look up an episode.
* @param {string} episodeId The episode's ID.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getEpisode('3Qm86XLflmIXVm1wcwkgDK').then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the episode. Not returned if a callback is given.
*/
getEpisode: function (episodeId, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/episodes/' + episodeId)
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback)
},
/**
* Look up several episodes.
* @param {string[]} episodeIds The IDs of the episodes.
* @param {Object} [options] The possible options, currently only market.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @example getEpisodes(['0oSGxfWSnnOXhD2fKuz2Gy', '3dBVyJ7JuOMt4GE9607Qin']).then(...)
* @returns {Promise|undefined} A promise that if successful, returns an object containing information
* about the episodes. Not returned if a callback is given.
*/
getEpisodes: function (episodeIds, options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/episodes')
.withQueryParameters(
{
ids: episodeIds.join(',')
},
options
)
.build()
.execute(HttpManager.get, callback)
}
}
SpotifyWebApi._addMethods = function (methods) {
for (const i in methods) {
if (methods.hasOwnProperty(i)) {
this.prototype[i] = methods[i]
}
}
}
module.exports = SpotifyWebApi