UNPKG

react-native-spotify-web-api

Version:
1,143 lines (1,049 loc) 61.3 kB
'use strict'; var AuthenticationRequest = require('./authentication-request'), WebApiRequest = require('./webapi-request'), HttpManager = require('./http-manager'); function SpotifyWebApi(credentials) { this._credentials = credentials || {}; } SpotifyWebApi.prototype = { setCredentials: function(credentials) { for (var 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) { return; } else { return this._credentials[credentialKey]; } }, _resetCredential: function(credentialKey) { if (!this._credentials) { return; } 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) { // In case someone is using a version where options parameter did not exist. var actualCallback, actualOptions; if (typeof options === 'function' && !callback) { actualCallback = options; actualOptions = {}; } else { actualCallback = callback; actualOptions = options; } return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/tracks/' + trackId) .withQueryParameters(actualOptions) .build() .execute(HttpManager.get, actualCallback); }, /** * 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) { // In case someone is using a version where options parameter did not exist. var actualCallback, actualOptions; if (typeof options === 'function' && !callback) { actualCallback = options; actualOptions = {}; } else { actualCallback = callback; actualOptions = options; } return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/tracks') .withQueryParameters({ 'ids' : trackIds.join(',') }, actualOptions) .build() .execute(HttpManager.get, actualCallback); }, /** * 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) { // In case someone is using a version where options parameter did not exist. var actualCallback, actualOptions; if (typeof options === 'function' && !callback) { actualCallback = options; actualOptions = {}; } else { actualCallback = callback; actualOptions = options; } return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/albums/' + albumId) .withQueryParameters(actualOptions) .build() .execute(HttpManager.get, actualCallback); }, /** * 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) { // In case someone is using a version where options parameter did not exist. var actualCallback, actualOptions; if (typeof options === 'function' && !callback) { actualCallback = options; actualOptions = {}; } else { actualCallback = callback; actualOptions = options; } return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/albums') .withQueryParameters({ 'ids' : albumIds.join(',') }, actualOptions) .build() .execute(HttpManager.get, actualCallback); }, /** * 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', and 'track'. * @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' : 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) { var path; if (typeof userId === 'string') { path = '/v1/users/' + encodeURIComponent(userId) + '/playlists'; } else { path = '/v1/me/playlists'; } return WebApiRequest.builder(this.getAccessToken()) .withPath(path) .withQueryParameters(options) .build() .execute(HttpManager.get, callback); }, /** * Get a playlist. * @param {string} userId The playlist's owner's user ID. * @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('thelinmichael', '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(userId, playlistId, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId) .withQueryParameters(options) .build() .execute(HttpManager.get, callback); }, /** * Get tracks in a playlist. * @param {string} userId THe playlist's owner's user ID. * @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('thelinmichael', '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(userId, playlistId, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/tracks') .withQueryParameters(options) .build() .execute(HttpManager.get, callback); }, /** * Create a playlist. * @param {string} userId The playlist's owner's user ID. * @param {string} playlistName The name of the playlist. * @param {Object} [options] The possible options, currently only public. * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example createPlaylist('thelinmichael', 'My cool playlist!', { public : false }).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(userId, playlistName, options, callback) { // In case someone is using a version where options parameter did not exist. var actualCallback; if (typeof options === 'function' && !callback) { actualCallback = options; } else { actualCallback = callback; } var actualOptions = { 'name' : playlistName }; if (typeof options === 'object') { Object.keys(options).forEach(function(key) { actualOptions[key] = options[key]; }); } return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters(actualOptions) .build() .execute(HttpManager.post, actualCallback); }, /** * Follow a playlist. * @param {string} userId The playlist's owner's user ID * @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(userId, playlistId, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/followers') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters(options) .build() .execute(HttpManager.put, callback); }, /** * Unfollow a playlist. * @param {string} userId The playlist's owner's user ID * @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. */ unfollowPlaylist: function(userId, playlistId, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/followers') .withHeaders({ 'Content-Type' : 'application/json' }) .build() .execute(HttpManager.del, callback); }, /** * Change playlist details. * @param {string} userId The playlist's owner's user ID * @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('thelinmichael', '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(userId, playlistId, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId) .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters(options) .build() .execute(HttpManager.put, callback); }, /** * Add tracks to a playlist. * @param {string} userId The playlist's owner's user ID * @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('thelinmichael', '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(userId, playlistId, tracks, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/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} userId The playlist's owner's user ID * @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 * a 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(userId, playlistId, tracks, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/tracks') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters({ 'tracks': tracks }, options) .build() .execute(HttpManager.del, callback); }, /** * Remove tracks from a playlist by position instead of specifying the tracks' URIs. * @param {string} userId The playlist's owner's user ID * @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(userId, playlistId, positions, snapshotId, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/tracks') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters({ 'positions': positions, 'snapshot_id' : snapshotId }) .build() .execute(HttpManager.del, callback); }, /** * Replace tracks in a playlist. * @param {string} userId The playlist's owner's user ID * @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(userId, playlistId, uris, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/playlists/' + playlistId + '/tracks') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters({ 'uris': uris }) .build() .execute(HttpManager.put, callback); }, /** * Reorder tracks in a playlist. * @param {string} userId The playlist's owner's user ID * @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(userId, playlistId, rangeStart, insertBefore, options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/users/' + encodeURIComponent(userId) + '/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) { var _opts = {}; var optionsOfTypeArray = ['seed_artists', 'seed_genres', 'seed_tracks']; for (var 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 a URL where the user can give the application permissions. * @param {string[]} scopes The scopes corresponding to the permissions the application needs. * @param {string} state A parameter that you can use to maintain a value between the request and the callback to redirect_uri.It is useful to prevent CSRF exploits. * @param {boolean} showDialog A parameter that you can use to force the user to approve the app on each login rather than being automatically redirected. * @returns {string} The URL where the user can give application permissions. */ createAuthorizeURL: function(scopes, state, showDialog) { return AuthenticationRequest.builder() .withPath('/authorize') .withQueryParameters({ 'client_id' : this.getClientId(), 'response_type' : 'code', 'redirect_uri' : this.getRedirectURI(), 'scope' : scopes.join('%20'), 'state' : state, 'show_dialog': showDialog && !!showDialog }) .build() .getURL(); }, /** * 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 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, 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(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(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 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, 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 tracks, * otherwise an error. Not returned if a callback is given. */ getMyRecentlyPlayedTracks: function(options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/recently-played') .withQueryParameters(options) .build() .execute(HttpManager.get, callback); }, /** * Get the Current User's Connect Devices * @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. */ 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 the Current User's Current Playback State * @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. */ 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 {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. */ transferMyPlayback: function(options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters({ 'device_ids': options.deviceIds, 'play': !!options.play }) .build() .execute(HttpManager.put, callback); }, /** * Starts o Resumes the Current User's Playback * @param {Object} [options] Options, being context_uri, offset, uris. * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackResume({context_uri: 'spotify:album:5ht7ItJgpBH7W6vJ5BqpPr'}).then(...) * @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. */ play: function(options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/play') .withHeaders({ 'Content-Type' : 'application/json' }) .withBodyParameters(options) .build() .execute(HttpManager.put, callback); }, /** * Pauses the Current User's Playback * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackPause().then(...) * @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. */ pause: function(callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/pause') .withHeaders({ 'Content-Type' : 'application/json' }) .build() .execute(HttpManager.put, callback); }, /** * Skip the Current User's Playback To Previous Track * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackPrevious().then(...) * @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. */ skipToPrevious: function(callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/previous') .withHeaders({ 'Content-Type' : 'application/json' }) .build() .execute(HttpManager.post, callback); }, /** * Skip the Current User's Playback To Next Track * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackNext().then(...) * @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. */ skipToNext: function(callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/next') .withHeaders({ 'Content-Type' : 'application/json' }) .build() .execute(HttpManager.post, callback); }, /** * Set Repeat Mode On The Current User's Playback * @param {Object} [options] Options, being state (track, context, off). * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackRepeat({state: 'context'}).then(...) * @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. */ setRepeat: function(options, callback) { return WebApiRequest.builder(this.getAccessToken()) .withPath('/v1/me/player/repeat') .withQueryParameters({ 'state': options.state || 'off' }) .build() .execute(HttpManager.put, callback); }, /** * Set Shuffle Mode On The Current User's Playback * @param {Object} [options] Options, being state (true, false). * @param {requestCallback} [callback] Optional callback method to be called instead of the promise. * @example playbackShuffle({state: 'false'}).then(...) * @returns {Promise|undefined} A pro