reverted to spotify-web-api-node (local) and applied Buffer fix.

This commit is contained in:
deeplydrumming
2024-07-31 09:15:50 +01:00
parent b36388ddad
commit b01bda5848
32 changed files with 893 additions and 391 deletions

View File

@@ -0,0 +1,5 @@
language: node_js
node_js:
- 14
after_success:
- npm run travis

View File

@@ -0,0 +1,213 @@
## Change log
#### 5.0.2 (Jan 2021)
* Fix: Make `transferMyPlayback` not require the `options` object, since it should be optional. Thanks for the heads-up [@Simber1](https://github.com/Simber1)!
#### 5.0.1 (Jan 2021)
* Fix error handling in the HTTP client. Thanks [@yamadapc](https://github.com/yamadapc)!
* This package can currently not be built on **Node 15 on Linux**, due to a dependency not being available yet. Issue can be followed on the [node-canvas](https://github.com/Automattic/node-canvas/issues/1688) issue tracker. In the mean time, Travis CI will run on earlier versions of Node.
#### 5.0.0 (Oct 2020)
* **BREAKING CHANGES**.
* Arguments for some API methods have changed, causing incorrect behaviour using argument order from version 4.x. See the `README.md` for examples of how the methods can be used.
* Create Playlist (`createPlaylist`) method no longer accepts a `userId` string as its first argument.
* Transfer A User's Playback (`transferMyPlayback`) method takes a `deviceIds` array as its first argument.
* Skip to Previous (`skipToPrevious`) method takes an `options` object as its first argument.
* Skip to Next (`skipToNext`) method takes an `options` object as its first argument.
* Set Repeat Mode on the Current User's Playback (`setRepeat`) method takes a `state` string as its first argument.
* Set Shuffle Mode on the Current User's Playback (`setShuffle`) method takes a `state` string as its first argument.
Cheers [@marinacrachi](https://github.com/marinacrachi) for the createPlaylist update.
* Removed legacy support for not passing an `options` object while providing a callback method. This was only supported on a few of the older endpoints, and could lead to tricky bugs. The affected endpoints are `getTrack`, `getTracks`, `getAlbum`, `getAlbums`, and `createPlaylist`. Again, check the `README.md` for examples on how these methods can be used if needed.
* Removed `options` argument for retrieving an access token using the Client Credentials flow, `clientCredentialsGrant`.
* API errors come in five different flavours.
* WebapiRegularError - For errors returned by most API endpoints.
* WebapiPlayerError - For errors returned by the Player API. These contain a bit more information.
* WebapiAuthenticationError - For errors related to authentication.
* WebapiError - For errors that come from the Web API that didn't fit into one of the above.
* TimeoutError - For network timeout errors.
More importantly, errors now contain the response body, headers, and status code. One side-effect of this is that rate limited requests can be handled by checking the `Retry-After` header. Thanks for the PRs [@kauffecup](https://github.com/kauffecup), [@lantelyes](https://github.com/lantelyes), [@dkliemsch](https://github.com/dkliemsch), and [@erezny](https://github.com/erezny).
Much appreciated [@konstantinjdobler](https://github.com/konstantinjdobler) for updates to the Player API errors.
* Added support for [Implicit Grant flow](https://developer.spotify.com/documentation/general/guides/authorization-guide/#implicit-grant-flow) - Thanks [@gaganza](https://github.com/gaganza), [@reblws](https://github.com/reblws) and [@noahp78](https://github.com/noahp78)!
* Starts or Resumes the Current User's Playback (`play`) method now supports the `position_ms` option. Thanks [@alqubo](https://github.com/alqubo), [@koflin](https://github.com/koflin), [@DoctorFishy](https://github.com/DoctorFishy). Thanks [@carmilso](https://github.com/carmilso) for general improvements to the Player API methods.
* Binding for [Add an Item to the User's Playback Queue](https://developer.spotify.com/documentation/web-api/reference/player/add-to-queue/) endpoint added. Thanks [@thattomperson](https://github.com/thattomperson) and [@AriciducaZagaria](https://github.com/AriciducaZagaria)!
* Binding for all [Shows and Episodes endpoints](https://developer.spotify.com/console/shows/). Thanks a _lot_ [@andyruwruw](https://github.com/andyruwruw)!
* Documentation updates to keep up to date with ES6, thanks [@dandv](https://github.com/dandv)! Other documentation improvements by [@terensu-desu](https://github.com/terensu-desu), and examples by [@dersimn](https://github.com/dersimn). Thanks!
* Bumped dependencies to resolve critical security issues.
* Finally, hat off to [@dersimn](https://github.com/dersimn). Thanks for collecting all of the lingering PRs and merging them into a working and up-to-date fork. You really stepped up.
Likely more changes coming before release to npm, which will happen shortly.
#### 4.0.0 (14 Sep 2018)
* Modified functions that operate on playlists to drop the user id parameter. This is a breaking change. [PR](https://github.com/thelinmichael/spotify-web-api-node/pull/243)
* Updated superagent to fix a security warning [PR](https://github.com/thelinmichael/spotify-web-api-node/pull/211)
* Fixed a bug by which an empty user was not handled properly in getUserPlaylists(). [PR](https://github.com/thelinmichael/spotify-web-api-node/pull/244)
#### 3.1.1 (29 Apr 2018)
* Modernized stack for a better developer experience. Integrated [prettier](https://github.com/thelinmichael/spotify-web-api-node/pull/205) and [jest](https://github.com/thelinmichael/spotify-web-api-node/pull/206). This simplifies the amount of dev dependencies.
* Improved calls to save and remove saved tracks by adding a key as specified in the Spotify docs (See [PR](https://github.com/thelinmichael/spotify-web-api-node/pull/207)). Thanks to [@yanniz0r](https://github.com/yanniz0r) and [@adcar](https://github.com/adcar) for bringing it up.
#### 3.1.0 (26 Apr 2018)
* Added support for seeking and setting volume. Thanks to [@isokar](https://github.com/isokar), [@jamesemwallis](https://github.com/jamesemwallis), [@ashthespy](https://github.com/ashthespy), and [@vanderlin](https://github.com/vanderlin) for your PRs.
#### 3.0.0 (8 Mar 2018)
* @DalerAsrorov added support for uploading a custom image to a playlist in [this PR](https://github.com/thelinmichael/spotify-web-api-node/pull/169).
* You can now pass a `device_id` when playing and pausing playback. @pfftdammitchris started [a PR to add device_id to the play() method](https://github.com/thelinmichael/spotify-web-api-node/pull/185). The changes served to another PR where we included the functionality. Thanks!
* Added documentation in the README for `getMyCurrentPlaybackState()`. Thanks @PanMan for [your PR](https://github.com/thelinmichael/spotify-web-api-node/pull/160)!
* @brodin realized we there was a lot of duplicated code and refactored it in a [great PR](https://github.com/thelinmichael/spotify-web-api-node/pull/123).
#### 2.5.0 (4 Sep 2017)
* Change README to reflect new authorization. Thanks [@arirawr](https://github.com/arirawr) for the [PR](https://github.com/thelinmichael/spotify-web-api-node/pull/146).
* Add support for 'show_dialog' parameter when creating authorization url. Thanks [@ajhaupt7](https://github.com/ajhaupt7) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/101).
* Add support for playback control (play, pause, prev, next), shuffle and repeat. Thanks [@JoseMCO](https://github.com/JoseMCO) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/150).
* Add support for currently playing. Thanks [@dustinblackman](https://github.com/dustinblackman) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/145).
* Fix to remove unnecessary deviceIds parameter from request to transfer playback. Thanks [@philnash](https://github.com/philnash) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/154).
#### 2.4.0 (2 May 2017)
* Change `addTracksToPlaylist` to pass the data in the body, preventing an issue with a long URL when passing many tracks. Thanks [@dolcalmi](https://github.com/dolcalmi) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/117)
* Add support for fetching [recently played tracks](https://developer.spotify.com/web-api/console/get-recently-played/). Thanks [@jeremyboles](https://github.com/jeremyboles) for [the PR](https://github.com/thelinmichael/spotify-web-api-node/pull/111).
#### 2.3.6 (15 October 2016)
* Add language bindings for the **[Get Audio Analysis for a Track](https://developer.spotify.com/web-api/get-audio-analysis/)** endpoint.
#### 2.3.5 (20 July 2016)
* Use `encodeURIComponent` instead of `encodeURI` to encode the user's id. 'encodeURI' wasn't encoding characters like `/` or `#` that were generating an invalid endpoint url. Thanks [@jgranstrom](https://github.com/jgranstrom) for the PR.
#### 2.3.4 (18 July 2016)
* Fixed a bug in `clientCredentialsGrant()`.
#### 2.3.3 (18 July 2016)
* Migrated to the `superagent` request library to support Node.JS and browsers. Thanks [@SomeoneWeird](https://github.com/SomeoneWeird) for the PR to add it, and [@erezny](https://github.com/erezny) for reporting bugs.
#### 2.3.2 (10 July 2016)
* Add language bindings for **[Get a List of Current User's Playlists](https://developer.spotify.com/web-api/get-a-list-of-current-users-playlists/)**. Thanks [@JMPerez](https://github.com/JMPerez) and [@vinialbano](https://github.com/vinialbano).
#### 2.3.1 (3 July 2016)
* Fix for `getRecomendations` method causing client error response from the API when making the request. Thanks [@kyv](https://github.com/kyv) for reporting, and [@Boberober](https://github.com/Boberober) and [@JMPerez](https://github.com/JMPerez) for providing fixes.
#### 2.3.0 (2 April 2016)
* Add language bindings for **[Get Recommendations Based on Seeds](https://developer.spotify.com/web-api/get-recommendations/)**, **[Get a User's Top Artists and Tracks](https://developer.spotify.com/web-api/get-users-top-artists-and-tracks/)**, **[Get Audio Features for a Track](https://developer.spotify.com/web-api/get-audio-features/)**, and **[Get Audio Features for Several Tracks](https://developer.spotify.com/web-api/get-several-audio-features/)**. Read more about the endpoints in the links above or in this [blog post](https://developer.spotify.com/news-stories/2016/03/29/api-improvements-update/).
* Add generic search method enabling searches for several types at once, e.g. search for both tracks and albums in a single request, instead of one request for track results and one request for album results.
#### 2.2.0 (23 November 2015)
* Add language bindings for **[Get User's Saved Albums](https://developer.spotify.com/web-api/get-users-saved-albums/)** and other endpoints related to the user's saved albums.
#### 2.1.1 (23 November 2015)
* Username encoding bugfix.
#### 2.1.0 (16 July 2015)
* Add language binding for **[Get Followed Artists](https://developer.spotify.com/web-api/get-followed-artists/)**
#### 2.0.2 (11 May 2015)
* Bugfix for retrieving an access token through the Client Credentials flow. (Thanks [Nate Wilkins](https://github.com/Nate-Wilkins)!)
* Add test coverage and Travis CI.
#### 2.0.1 (2 Mar 2015)
* Return WebApiError objects if error occurs during authentication.
#### 2.0.0 (27 Feb 2015)
* **Breaking change**: Response object changed. Add headers and status code to all responses to enable users to implement caching.
#### 1.3.13 (26 Feb 2015)
* Add language binding for **[Reorder tracks in a Playlist](https://developer.spotify.com/web-api/reorder-playlists-tracks/)**
#### 1.3.12 (22 Feb 2015)
* Add language binding for **[Remove tracks in a Playlist by Position](https://developer.spotify.com/web-api/remove-tracks-playlist/)**
#### 1.3.11
* Add **[Search for Playlists](https://developer.spotify.com/web-api/search-item/)** endpoint.
#### 1.3.10
* Add market parameter to endpoints supporting **[Track Relinking](https://developer.spotify.com/web-api/track-relinking-guide/)**.
* Improve SEO by adding keywords to the package.json file. ;-)
#### 1.3.8
* Add **[Get a List of Categories](https://developer.spotify.com/web-api/get-list-categories/)**, **[Get a Category](https://developer.spotify.com/web-api/get-category/)**, and **[Get A Category's Playlists](https://developer.spotify.com/web-api/get-categorys-playlists/)** endpoints.
#### 1.3.7
* Add **[Check if Users are Following Playlist](https://developer.spotify.com/web-api/check-user-following-playlist/)** endpoint.
#### 1.3.5
* Add missing options parameter in createPlaylist (issue #19). Thanks for raising this [allinallin](https://github.com/allinallin).
#### 1.3.4
* Add **[Follow Playlist](https://developer.spotify.com/web-api/follow-playlist/)** and **[Unfollow Playlist](https://developer.spotify.com/web-api/unfollow-playlist/)** endpoints.
#### 1.3.3
* [Fix](https://github.com/thelinmichael/spotify-web-api-node/pull/18) error format. Thanks [extrakt](https://github.com/extrakt).
#### 1.3.2
* Add ability to use callback methods instead of promise.
#### 1.2.2
* Bugfix. api.addTracksToPlaylist tracks parameter can be a string or an array. Thanks [ofagbemi](https://github.com/ofagbemi)!
#### 1.2.1
* Add **[Follow endpoints](https://developer.spotify.com/web-api/web-api-follow-endpoints/)**. Great work [JMPerez](https://github.com/JMPerez).
#### 1.1.0
* Add **[Browse endpoints](https://developer.spotify.com/web-api/browse-endpoints/)**. Thanks [fsahin](https://github.com/fsahin).
#### 1.0.2
* Specify module's git repository. Thanks [vincentorback](https://github.com/vincentorback).
#### 1.0.1
* Allow options to be set when retrieving a user's playlists. Thanks [EaterOfCode](https://github.com/EaterOfCode).
#### 1.0.0
* Add **[Replace tracks in a Playlist](https://developer.spotify.com/web-api/replace-playlists-tracks/)** endpoint
* Add **[Remove tracks in a Playlist](https://developer.spotify.com/web-api/remove-tracks-playlist/)** endpoint
* Return errors as Error objects instead of unparsed JSON. Thanks [niftylettuce](https://github.com/niftylettuce).
#### 0.0.11
* Add **[Change Playlist details](https://developer.spotify.com/web-api/change-playlist-details/)** endpoint (change published status and name). Gracias [JMPerez](https://github.com/JMPerez).
#### 0.0.10
* Add Your Music Endpoints (**[Add tracks](https://developer.spotify.com/web-api/save-tracks-user/)**, **[Remove tracks](https://developer.spotify.com/web-api/remove-tracks-user/)**, **[Contains tracks](https://developer.spotify.com/web-api/check-users-saved-tracks/)**, **[Get tracks](https://developer.spotify.com/web-api/get-users-saved-tracks/)**).
* Documentation updates (change scope name of playlist-modify to playlist-modify-public, and a fix to a parameter type). Thanks [JMPerez](https://github.com/JMPerez) and [matiassingers](https://github.com/matiassingers).
#### 0.0.9
* Add **[Related artists](https://developer.spotify.com/web-api/get-related-artists/)** endpoint

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014-2021 Michael Thelin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
const SpotifyWebApi = require('../');
/**
* This example refreshes an access token. Refreshing access tokens is only possible access tokens received using the
* Authorization Code flow, documented here: https://developer.spotify.com/spotify-web-api/authorization-guide/#authorization_code_flow
*/
/* Retrieve an authorization code as documented here:
* https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
* or in the Authorization section of the README.
*
* Codes are given for a set of scopes. For this example, the scopes are user-read-private and user-read-email.
* Scopes are documented here:
* https://developer.spotify.com/documentation/general/guides/scopes/
*/
const authorizationCode =
'<insert authorization code with user-read-private and user-read-email scopes>';
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
// When our access token will expire
let tokenExpirationEpoch;
// First retrieve an access token
spotifyApi.authorizationCodeGrant(authorizationCode).then(
function(data) {
// Set the access token and refresh token
spotifyApi.setAccessToken(data.body['access_token']);
spotifyApi.setRefreshToken(data.body['refresh_token']);
// Save the amount of seconds until the access token expired
tokenExpirationEpoch =
new Date().getTime() / 1000 + data.body['expires_in'];
console.log(
'Retrieved token. It expires in ' +
Math.floor(tokenExpirationEpoch - new Date().getTime() / 1000) +
' seconds!'
);
},
function(err) {
console.log(
'Something went wrong when retrieving the access token!',
err.message
);
}
);
// Continually print out the time left until the token expires..
let numberOfTimesUpdated = 0;
setInterval(function() {
console.log(
'Time left: ' +
Math.floor(tokenExpirationEpoch - new Date().getTime() / 1000) +
' seconds left!'
);
// OK, we need to refresh the token. Stop printing and refresh.
if (++numberOfTimesUpdated > 5) {
clearInterval(this);
// Refresh token and print the new time to expiration.
spotifyApi.refreshAccessToken().then(
function(data) {
tokenExpirationEpoch =
new Date().getTime() / 1000 + data.body['expires_in'];
console.log(
'Refreshed token. It now expires in ' +
Math.floor(tokenExpirationEpoch - new Date().getTime() / 1000) +
' seconds!'
);
},
function(err) {
console.log('Could not refresh the token!', err.message);
}
);
}
}, 1000);

View File

@@ -0,0 +1,32 @@
const SpotifyWebApi = require('../');
/**
* This example retrieves an access token using the Client Credentials Flow, documented at:
* https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow
*/
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>'
});
// Retrieve an access token
spotifyApi.clientCredentialsGrant().then(
function(data) {
console.log('The access token expires in ' + data.body['expires_in']);
console.log('The access token is ' + data.body['access_token']);
// Save the access token so that it's used in future calls
spotifyApi.setAccessToken(data.body['access_token']);
},
function(err) {
console.log(
'Something went wrong when retrieving an access token',
err.message
);
}
);

View File

@@ -0,0 +1,84 @@
const SpotifyWebApi = require('../');
/**
* This example demonstrates adding tracks, removing tracks, and replacing tracks in a playlist. At the time of writing this
* documentation, this is the available playlist track modification feature in the Spotify Web API.
*
* Since authorization is required, this example retrieves an access token using the Authorization Code Grant flow,
* documented here: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
*
* Codes are given for a set of scopes. For this example, the scopes are playlist-modify-public.
* Scopes are documented here:
* https://developer.spotify.com/documentation/general/guides/scopes/
*/
/* Obtain the `authorizationCode` below as described in the Authorization section of the README.
*/
const authorizationCode =
'<insert authorization code with playlist-modify-public scope>';
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
let playlistId;
// First retrieve an access token
spotifyApi
.authorizationCodeGrant(authorizationCode)
.then(function(data) {
// Save the access token so that it's used in future requests
spotifyApi.setAccessToken(data['access_token']);
// Create a playlist
return spotifyApi.createPlaylist(
'thelinmichael',
'My New Awesome Playlist'
);
})
.then(function(data) {
console.log('Ok. Playlist created!');
playlistId = data.body['id'];
// Add tracks to the playlist
return spotifyApi.addTracksToPlaylist(playlistId, [
'spotify:track:4iV5W9uYEdYUVa79Axb7Rh',
'spotify:track:6tcfwoGcDjxnSc6etAkDRR',
'spotify:track:4iV5W9uYEdYUVa79Axb7Rh'
]);
})
.then(function(data) {
console.log('Ok. Tracks added!');
// Woops! Made a duplicate. Remove one of the duplicates from the playlist
return spotifyApi.removeTracksFromPlaylist('thelinmichael', playlistId, [
{
uri: 'spotify:track:4iV5W9uYEdYUVa79Axb7Rh',
positions: [0]
}
]);
})
.then(function(data) {
console.log('Ok. Tracks removed!');
// Actually, lets just replace all tracks in the playlist with something completely different
return spotifyApi.replaceTracksInPlaylist('thelinmichael', playlistId, [
'spotify:track:5Wd2bfQ7wc6GgSa32OmQU3',
'spotify:track:4r8lRYnoOGdEi6YyI5OC1o',
'spotify:track:4TZZvblv2yzLIBk2JwJ6Un',
'spotify:track:2IA4WEsWAYpV9eKkwR2UYv',
'spotify:track:6hDH3YWFdcUNQjubYztIsG'
]);
})
.then(function(data) {
console.log('Ok. Tracks replaced!');
})
.catch(function(err) {
console.log('Something went wrong:', err.message);
});

View File

@@ -0,0 +1,49 @@
const SpotifyWebApi = require('../');
/**
* This example demonstrates adding tracks to a specified position in a playlist.
*
* Since authorization is required, this example retrieves an access token using the Authorization Code Grant flow,
* documented here: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
*
* Codes are given for a set of scopes. For this example, the scopes are playlist-modify-public.
* Scopes are documented here:
* https://developer.spotify.com/documentation/general/guides/scopes/
*/
/* Obtain the `authorizationCode` below as described in the Authorization section of the README.
*/
const authorizationCode = '<insert authorization code>';
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
// First retrieve an access token
spotifyApi
.authorizationCodeGrant(authorizationCode)
.then(function(data) {
spotifyApi.setAccessToken(data.body['access_token']);
return spotifyApi.addTracksToPlaylist(
'5ieJqeLJjjI8iJWaxeBLuK',
[
'spotify:track:4iV5W9uYEdYUVa79Axb7Rh',
'spotify:track:1301WleyT98MSxVHPZCA6M'
],
{
position: 10
}
);
})
.then(function(data) {
console.log('Added tracks to the playlist!');
})
.catch(function(err) {
console.log('Something went wrong:', err.message);
});

View File

@@ -0,0 +1,26 @@
const { util } = require('prettier');
var SpotifyWebApi = require('../');
/**
* This example uses the Client Credentials authorization flow.
*/
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<Client ID>',
clientSecret: '<Client Secret>'
});
// Retrieve an access token using your credentials
spotifyApi.clientCredentialsGrant().
then(function(result) {
console.log('It worked! Your access token is: ' + result.body.access_token);
}).catch(function(err) {
console.log('If this is printed, it probably means that you used invalid ' +
'clientId and clientSecret values. Please check!');
console.log('Hint: ');
console.log(err);
});

View File

@@ -0,0 +1,54 @@
const SpotifyWebApi = require('../');
/**
* This example retrieves information about the 'current' user. The current user is the user that has
* authorized the application to access its data.
*/
/* Retrieve a code as documented here:
* https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
*
* Codes are given for a set of scopes. For this example, the scopes are user-read-private and user-read-email.
* Scopes are documented here:
* https://developer.spotify.com/documentation/general/guides/scopes/
*/
const authorizationCode =
'<insert authorization code with user-read-private and user-read-email scopes>';
/* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
// First retrieve an access token
spotifyApi
.authorizationCodeGrant(authorizationCode)
.then(function(data) {
console.log('Retrieved access token', data.body['access_token']);
// Set the access token
spotifyApi.setAccessToken(data.body['access_token']);
// Use the access token to retrieve information about the user connected to it
return spotifyApi.getMe();
})
.then(function(data) {
// "Retrieved data for Faruk Sahin"
console.log('Retrieved data for ' + data.body['display_name']);
// "Email is farukemresahin@gmail.com"
console.log('Email is ' + data.body.email);
// "Image URL is http://media.giphy.com/media/Aab07O5PYOmQ/giphy.gif"
console.log('Image URL is ' + data.body.images[0].url);
// "This user has a premium account"
console.log('This user has a ' + data.body.product + ' account');
})
.catch(function(err) {
console.log('Something went wrong:', err.message);
});

View File

@@ -0,0 +1,49 @@
var SpotifyWebApi = require('../');
/*
* This example shows how to get artists related to another artists. The endpoint is documented here:
* https://developer.spotify.com/web-api/get-related-artists/
* Please note that authorization is now required and so this example retrieves an access token using the Authorization Code Flow,
* documented here: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
*/
var authorizationCode =
'AQAgjS78s64u1axMCBCRA0cViW_ZDDU0pbgENJ_-WpZr3cEO7V5O-JELcEPU6pGLPp08SfO3dnHmu6XJikKqrU8LX9W6J11NyoaetrXtZFW-Y58UGeV69tuyybcNUS2u6eyup1EgzbTEx4LqrP_eCHsc9xHJ0JUzEhi7xcqzQG70roE4WKM_YrlDZO-e7GDRMqunS9RMoSwF_ov-gOMpvy9OMb7O58nZoc3LSEdEwoZPCLU4N4TTJ-IF6YsQRhQkEOJK';
/* Set the credentials given on Spotify's My Applications page.
* https://developer.spotify.com/my-applications
*/
var spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
var artistId = '0qeei9KQnptjwb8MgkqEoy';
spotifyApi
.authorizationCodeGrant(authorizationCode)
.then(function(data) {
console.log('Retrieved access token', data.body['access_token']);
// Set the access token
spotifyApi.setAccessToken(data.body['access_token']);
// Use the access token to retrieve information about the user connected to it
return spotifyApi.getArtistRelatedArtists(artistId);
})
.then(function(data) {
if (data.body.artists.length) {
// Print the number of similar artists
console.log('I got ' + data.body.artists.length + ' similar artists!');
console.log('The most similar one is ' + data.body.artists[0].name);
} else {
console.log("I didn't find any similar artists.. Sorry.");
}
},
function(err) {
console.log('Something went wrong:', err.message);
}
);

View File

@@ -0,0 +1,56 @@
const SpotifyWebApi = require('../');
/**
* This example retrieves the top tracks for an artist.
* https://developer.spotify.com/documentation/web-api/reference/artists/get-artists-top-tracks/
*/
/**
* This endpoint doesn't require an access token, but it's beneficial to use one as it
* gives the application a higher rate limit.
*
* Since it's not necessary to get an access token connected to a specific user, this example
* uses the Client Credentials flow. This flow uses only the client ID and the client secret.
* https://developer.spotify.com/documentation/general/guides/authorization-guide/#client-credentials-flow
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>'
});
// Retrieve an access token
spotifyApi
.clientCredentialsGrant()
.then(function(data) {
// Set the access token on the API object so that it's used in all future requests
spotifyApi.setAccessToken(data.body['access_token']);
// Get the most popular tracks by David Bowie in Great Britain
return spotifyApi.getArtistTopTracks('0oSGxfWSnnOXhD2fKuz2Gy', 'GB');
})
.then(function(data) {
console.log('The most popular tracks for David Bowie is..');
console.log('Drum roll..');
console.log('...');
/*
* 1. Space Oddity - 2009 Digital Remaster (popularity is 51)
* 2. Heroes - 1999 Digital Remaster (popularity is 33)
* 3. Let's Dance - 1999 Digital Remaster (popularity is 20)
* 4. ...
*/
data.body.tracks.forEach(function(track, index) {
console.log(
index +
1 +
'. ' +
track.name +
' (popularity is ' +
track.popularity +
')'
);
});
})
.catch(function(err) {
console.log('Unfortunately, something has gone wrong.', err.message);
});

View File

@@ -0,0 +1,55 @@
const SpotifyWebApi = require('../');
/*
* This example shows how to search for a track. The endpoint is documented here:
* https://developer.spotify.com/documentation/web-api/reference/search/
* Since authorization is now required, this example retrieves an access token using the Authorization Code Grant flow,
* documented here: https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
*
* Obtain the `authorizationCode` below as described in the Authorization section of the README.
*/
const authorizationCode = '<insert authorization code>';
/**
* Get the credentials from Spotify's Dashboard page.
* https://developer.spotify.com/dashboard/applications
*/
const spotifyApi = new SpotifyWebApi({
clientId: '<insert client id>',
clientSecret: '<insert client secret>',
redirectUri: '<insert redirect URI>'
});
spotifyApi
.authorizationCodeGrant(authorizationCode)
.then(function(data) {
console.log('Retrieved access token', data.body['access_token']);
// Set the access token
spotifyApi.setAccessToken(data.body['access_token']);
// Use the access token to retrieve information about the user connected to it
return spotifyApi.searchTracks('Love');
})
.then(function(data) {
// Print some information about the results
console.log('I got ' + data.body.tracks.total + ' results!');
// Go through the first page of results
var firstPage = data.body.tracks.items;
console.log('The tracks in the first page are (popularity in parentheses):');
/*
* 0: All of Me (97)
* 1: My Love (91)
* 2: I Love This Life (78)
* ...
*/
firstPage.forEach(function(track, index) {
console.log(index + ': ' + track.name + ' (' + track.popularity + ')');
});
}).catch(function(err) {
console.log('Something went wrong:', err.message);
});

View File

@@ -0,0 +1,101 @@
/**
* This example is using the Authorization Code flow.
*
* In root directory run
*
* npm install express
*
* then run with the followinng command. If you don't have a client_id and client_secret yet,
* create an application on Create an application here: https://developer.spotify.com/my-applications to get them.
* Make sure you whitelist the correct redirectUri in line 26.
*
* node access-token-server.js "<Client ID>" "<Client Secret>"
*
* and visit <http://localhost:8888/login> in your Browser.
*/
const SpotifyWebApi = require('../../');
const express = require('../../node_modules/express');
const scopes = [
'ugc-image-upload',
'user-read-playback-state',
'user-modify-playback-state',
'user-read-currently-playing',
'streaming',
'app-remote-control',
'user-read-email',
'user-read-private',
'playlist-read-collaborative',
'playlist-modify-public',
'playlist-read-private',
'playlist-modify-private',
'user-library-modify',
'user-library-read',
'user-top-read',
'user-read-playback-position',
'user-read-recently-played',
'user-follow-read',
'user-follow-modify'
];
const spotifyApi = new SpotifyWebApi({
redirectUri: 'http://localhost:8888/callback',
clientId: process.argv.slice(2)[0],
clientSecret: process.argv.slice(2)[1]
});
const app = express();
app.get('/login', (req, res) => {
res.redirect(spotifyApi.createAuthorizeURL(scopes));
});
app.get('/callback', (req, res) => {
const error = req.query.error;
const code = req.query.code;
const state = req.query.state;
if (error) {
console.error('Callback Error:', error);
res.send(`Callback Error: ${error}`);
return;
}
spotifyApi
.authorizationCodeGrant(code)
.then(data => {
const access_token = data.body['access_token'];
const refresh_token = data.body['refresh_token'];
const expires_in = data.body['expires_in'];
spotifyApi.setAccessToken(access_token);
spotifyApi.setRefreshToken(refresh_token);
console.log('access_token:', access_token);
console.log('refresh_token:', refresh_token);
console.log(
`Sucessfully retreived access token. Expires in ${expires_in} s.`
);
res.send('Success! You can now close the window.');
setInterval(async () => {
const data = await spotifyApi.refreshAccessToken();
const access_token = data.body['access_token'];
console.log('The access token has been refreshed!');
console.log('access_token:', access_token);
spotifyApi.setAccessToken(access_token);
}, expires_in / 2 * 1000);
})
.catch(error => {
console.error('Error getting Tokens:', error);
res.send(`Error getting Tokens: ${error}`);
});
});
app.listen(8888, () =>
console.log(
'HTTP Server up. Now go to http://localhost:8888/login in your browser.'
)
);

View File

@@ -0,0 +1,11 @@
const SpotifyWebApi = require('../../../');
const spotifyApi = new SpotifyWebApi();
spotifyApi.setAccessToken(process.env.SPOTIFY_ACCESS_TOKEN);
(async () => {
const me = await spotifyApi.getMe();
console.log(me);
})().catch(e => {
console.error(e);
});

View File

@@ -0,0 +1,17 @@
Execute all commands from the root folder of this repository.
Start with
git clone <this repo url>
cd spotify-web-api-node
npm install
npm install express
node examples/tutorial/00-get-access-token.js "<Client ID>" "<Client Secret>"
and visit <http://localhost:8888/login> in your browser to get an `access_token`.
If you don't have a `client_id` and `client_secret` yet, create an application here: <https://developer.spotify.com/my-applications> to get them. Make sure you whitelist the correct redirectUri when creating your application, which is `http://localhost:8888/callback`.
After you got the `access_token`, call all other examples with this token in ENV variable `SPOTIFY_ACCESS_TOKEN`. The easiest way is to call:
export SPOTIFY_ACCESS_TOKEN="<Token content here>"
node examples/tutorial/01-basics/01-get-info-about-current-user.js

View File

@@ -0,0 +1,69 @@
{
"name": "spotify-web-api-node",
"version": "5.0.3",
"homepage": "https://github.com/thelinmichael/spotify-web-api-node",
"description": "A Node.js wrapper for Spotify's Web API",
"main": "./src/server.js",
"author": "Michael Thelin",
"contributors": [
{
"name": "José M. Perez",
"url": "https://github.com/JMPerez"
},
{
"name": "Deeplydrumming",
"url": "https://gitlab.com/deeplydrumming"
}
],
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/thelinmichael/spotify-web-api-node.git"
},
"scripts": {
"test": "jest",
"travis": "npm test -- --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
"precommit": "lint-staged"
},
"jest": {
"verbose": true,
"testURL": "http://localhost/"
},
"lint-staged": {
"*.{js,json,css,md}": [
"prettier --single-quote --write",
"git add"
]
},
"dependencies": {
"superagent": "^6.1.0"
},
"devDependencies": {
"coveralls": "^3.1.0",
"husky": "^4.3.0",
"jest": "^26.6.3",
"lint-staged": "^10.4.0",
"prettier": "^2.1.2",
"sinon": "^9.0.3",
"canvas": "^2.6.1",
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2",
"jest-resolve": "^26.6.2",
"minimist": "^1.2.5",
"set-value": ">=2.0.1",
"mixin-deep": ">=1.3.2",
"ini": ">=1.3.6"
},
"keywords": [
"spotify",
"echonest",
"music",
"api",
"wrapper",
"client",
"web api"
],
"browser": {
"./src/server.js": "./src/client.js"
}
}

View File

@@ -0,0 +1,14 @@
'use strict'
const Request = require('./base-request')
const DEFAULT_HOST = 'accounts.spotify.com'
const DEFAULT_PORT = 443
const DEFAULT_SCHEME = 'https'
module.exports.builder = function () {
return Request.builder()
.withHost(DEFAULT_HOST)
.withPort(DEFAULT_PORT)
.withScheme(DEFAULT_SCHEME)
}

View File

@@ -0,0 +1,165 @@
'use strict'
const Request = function (builder) {
if (!builder) {
throw new Error('No builder supplied to constructor')
}
this.host = builder.host
this.port = builder.port
this.scheme = builder.scheme
this.queryParameters = builder.queryParameters
this.bodyParameters = builder.bodyParameters
this.headers = builder.headers
this.path = builder.path
}
Request.prototype._getter = function (key) {
return function () {
return this[key]
}
}
Request.prototype.getHost = Request.prototype._getter('host')
Request.prototype.getPort = Request.prototype._getter('port')
Request.prototype.getScheme = Request.prototype._getter('scheme')
Request.prototype.getPath = Request.prototype._getter('path')
Request.prototype.getQueryParameters = Request.prototype._getter(
'queryParameters'
)
Request.prototype.getBodyParameters = Request.prototype._getter(
'bodyParameters'
)
Request.prototype.getHeaders = Request.prototype._getter('headers')
Request.prototype.getURI = function () {
if (!this.scheme || !this.host || !this.port) {
throw new Error('Missing components necessary to construct URI')
}
let uri = this.scheme + '://' + this.host
if (
(this.scheme === 'http' && this.port !== 80) ||
(this.scheme === 'https' && this.port !== 443)
) {
uri += ':' + this.port
}
if (this.path) {
uri += this.path
}
return uri
}
Request.prototype.getURL = function () {
const uri = this.getURI()
if (this.getQueryParameters()) {
return uri + this.getQueryParameterString(this.getQueryParameters())
} else {
return uri
}
}
Request.prototype.getQueryParameterString = function () {
const queryParameters = this.getQueryParameters()
if (queryParameters) {
return (
'?' +
Object.keys(queryParameters)
.filter(function (key) {
return queryParameters[key] !== undefined
})
.map(function (key) {
return key + '=' + queryParameters[key]
})
.join('&')
)
}
}
Request.prototype.execute = function (method, callback) {
if (callback) {
method(this, callback)
return
}
const _self = this
return new Promise(function (resolve, reject) {
method(_self, function (error, result) {
if (error) {
reject(error)
} else {
resolve(result)
}
})
})
}
const Builder = function () {}
Builder.prototype._setter = function (key) {
return function (value) {
this[key] = value
return this
}
}
Builder.prototype.withHost = Builder.prototype._setter('host')
Builder.prototype.withPort = Builder.prototype._setter('port')
Builder.prototype.withScheme = Builder.prototype._setter('scheme')
Builder.prototype.withPath = Builder.prototype._setter('path')
Builder.prototype._assigner = function (key) {
return function () {
for (let i = 0; i < arguments.length; i++) {
this[key] = this._assign(this[key], arguments[i])
}
return this
}
}
Builder.prototype.withQueryParameters = Builder.prototype._assigner(
'queryParameters'
)
Builder.prototype.withBodyParameters = Builder.prototype._assigner(
'bodyParameters'
)
Builder.prototype.withHeaders = Builder.prototype._assigner('headers')
Builder.prototype.withAuth = function (accessToken) {
if (accessToken) {
this.withHeaders({ Authorization: 'Bearer ' + accessToken })
}
return this
}
Builder.prototype._assign = function (src, obj) {
if (obj && Array.isArray(obj)) {
return obj
}
if (obj && typeof obj === 'string') {
return obj
}
if (obj && Object.keys(obj).length > 0) {
return Object.assign(src || {}, obj)
}
return src
}
Builder.prototype.build = function () {
return new Request(this)
}
module.exports.builder = function () {
return new Builder()
}

View File

@@ -0,0 +1 @@
module.exports = require('./spotify-web-api')

View File

@@ -0,0 +1,134 @@
'use strict'
const superagent = require('superagent')
const {
TimeoutError,
WebapiError,
WebapiRegularError,
WebapiAuthenticationError,
WebapiPlayerError
} = require('./response-error')
const HttpManager = {}
/* Create superagent options from the base request */
const _getParametersFromRequest = function (request) {
const options = {}
if (request.getQueryParameters()) {
options.query = request.getQueryParameters()
}
if (request.getHeaders() && request.getHeaders()['Content-Type'] === 'application/json') {
options.data = JSON.stringify(request.getBodyParameters())
} else if (request.getBodyParameters()) {
options.data = request.getBodyParameters()
}
if (request.getHeaders()) {
options.headers = request.getHeaders()
}
return options
}
const _toError = function (response) {
if (typeof response.body === 'object' && response.body.error && typeof response.body.error === 'object' && response.body.error.reason) {
return new WebapiPlayerError(response.body, response.headers, response.statusCode)
}
if (typeof response.body === 'object' && response.body.error && typeof response.body.error === 'object') {
return new WebapiRegularError(response.body, response.headers, response.statusCode)
}
if (typeof response.body === 'object' && response.body.error && typeof response.body.error === 'string') {
return new WebapiAuthenticationError(response.body, response.headers, response.statusCode)
}
/* Other type of error, or unhandled Web API error format */
return new WebapiError(response.body, response.headers, response.statusCode, response.body)
}
/* Make the request to the Web API */
HttpManager._makeRequest = function (method, options, uri, callback) {
const req = method.bind(superagent)(uri)
if (options.query) {
req.query(options.query)
}
if (options.headers) {
req.set(options.headers)
}
if (options.data) {
req.send(options.data)
}
req.end(function (err, response) {
if (err) {
if (err.timeout) {
return callback(new TimeoutError())
} else if (err.response) {
return callback(_toError(err.response))
} else {
return callback(err)
}
}
return callback(null, {
body: response.body,
headers: response.headers,
statusCode: response.statusCode
})
})
}
/**
* Make a HTTP GET request.
* @param {BaseRequest} The request.
* @param {Function} The callback function.
*/
HttpManager.get = function (request, callback) {
const options = _getParametersFromRequest(request)
const method = superagent.get
HttpManager._makeRequest(method, options, request.getURI(), callback)
}
/**
* Make a HTTP POST request.
* @param {BaseRequest} The request.
* @param {Function} The callback function.
*/
HttpManager.post = function (request, callback) {
const options = _getParametersFromRequest(request)
const method = superagent.post
HttpManager._makeRequest(method, options, request.getURI(), callback)
}
/**
* Make a HTTP DELETE request.
* @param {BaseRequest} The request.
* @param {Function} The callback function.
*/
HttpManager.del = function (request, callback) {
const options = _getParametersFromRequest(request)
const method = superagent.del
HttpManager._makeRequest(method, options, request.getURI(), callback)
}
/**
* Make a HTTP PUT request.
* @param {BaseRequest} The request.
* @param {Function} The callback function.
*/
HttpManager.put = function (request, callback) {
const options = _getParametersFromRequest(request)
const method = superagent.put
HttpManager._makeRequest(method, options, request.getURI(), callback)
}
module.exports = HttpManager

View File

@@ -0,0 +1,64 @@
/* Timeout */
class NamedError extends Error {
get name () {
return this.constructor.name
}
}
class TimeoutError extends NamedError {
constructor () {
const message = 'A timeout occurred while communicating with Spotify\'s Web API.'
super(message)
}
}
/* Web API Parent and fallback error */
class WebapiError extends NamedError {
constructor (body, headers, statusCode, message) {
super(message)
this.body = body
this.headers = headers
this.statusCode = statusCode
}
}
/**
* Regular Error
* { status : <integer>, message : <string> }
*/
class WebapiRegularError extends WebapiError {
constructor (body, headers, statusCode) {
const message = 'An error occurred while communicating with Spotify\'s Web API.\n' +
'Details: ' + body.error.message + '.'
super(body, headers, statusCode, message)
}
}
/**
* Authentication Error
* { error : <string>, error_description : <string> }
*/
class WebapiAuthenticationError extends WebapiError {
constructor (body, headers, statusCode) {
const message = 'An authentication error occurred while communicating with Spotify\'s Web API.\n' +
'Details: ' + body.error + (body.error_description ? ' ' + body.error_description + '.' : '.')
super(body, headers, statusCode, message)
}
}
/**
* Player Error
* { status : <integer>, message : <string>, reason : <string> }
*/
class WebapiPlayerError extends WebapiError {
constructor (body, headers, statusCode) {
const message = 'An error occurred while communicating with Spotify\'s Web API.\n' +
'Details: ' + body.error.message + (body.error.reason ? ' ' + body.error.reason + '.' : '.')
super(body, headers, statusCode, message)
}
}
module.exports = { WebapiError, TimeoutError, WebapiRegularError, WebapiAuthenticationError, WebapiPlayerError }

View File

@@ -0,0 +1,106 @@
'use strict'
const AuthenticationRequest = require('./authentication-request')
const HttpManager = require('./http-manager')
module.exports = {
/**
* 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.
* @param {string} responseType An optional parameter that you can use to specify the code response based on the authentication type - can be set to 'code' or 'token'. Default 'code' to ensure backwards compatability.
* @returns {string} The URL where the user can give application permissions.
*/
createAuthorizeURL: function (scopes, state, showDialog, responseType = 'code') {
return AuthenticationRequest.builder()
.withPath('/authorize')
.withQueryParameters({
client_id: this.getClientId(),
response_type: responseType,
redirect_uri: this.getRedirectURI(),
scope: scopes.join('%20'),
state,
show_dialog: showDialog && !!showDialog
})
.build()
.getURL()
},
/**
* Request an access token using the Client Credentials flow.
* Requires that client ID and client secret has been set previous to the call.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an object containing the access token,
* token type and time to expiration. If rejected, it contains an error object. Not returned if a callback is given.
*/
clientCredentialsGrant: function (callback) {
return AuthenticationRequest.builder()
.withPath('/api/token')
.withBodyParameters({
grant_type: 'client_credentials'
})
.withHeaders({
Authorization:
'Basic ' +
Buffer.from(
this.getClientId() + ':' + this.getClientSecret()
).toString('base64'),
'Content-Type': 'application/x-www-form-urlencoded'
})
.build()
.execute(HttpManager.post, callback)
},
/**
* Request an access token using the Authorization Code flow.
* Requires that client ID, client secret, and redirect URI has been set previous to the call.
* @param {string} code The authorization code returned in the callback in the Authorization Code flow.
* @param {requestCallback} [callback] Optional callback method to be called instead of the promise.
* @returns {Promise|undefined} A promise that if successful, resolves into an object containing the access token,
* refresh token, token type and time to expiration. If rejected, it contains an error object.
* Not returned if a callback is given.
*/
authorizationCodeGrant: function (code, callback) {
return AuthenticationRequest.builder()
.withPath('/api/token')
.withBodyParameters({
grant_type: 'authorization_code',
redirect_uri: this.getRedirectURI(),
code,
client_id: this.getClientId(),
client_secret: this.getClientSecret()
})
.withHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' })
.build()
.execute(HttpManager.post, callback)
},
/**
* Refresh the access token given that it hasn't expired.
* Requires that client ID, client secret and refresh token has been set previous to the call.
* @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 the
* access token, time to expiration and token type. If rejected, it contains an error object.
* Not returned if a callback is given.
*/
refreshAccessToken: function (callback) {
return AuthenticationRequest.builder()
.withPath('/api/token')
.withBodyParameters({
grant_type: 'refresh_token',
refresh_token: this.getRefreshToken()
})
.withHeaders({
Authorization:
'Basic ' +
Buffer.from(
this.getClientId() + ':' + this.getClientSecret()
).toString('base64'),
'Content-Type': 'application/x-www-form-urlencoded'
})
.build()
.execute(HttpManager.post, callback)
}
}

View File

@@ -0,0 +1,4 @@
const SpotifyWebApi = require('./spotify-web-api')
const ServerMethods = require('./server-methods')
SpotifyWebApi._addMethods(ServerMethods)
module.exports = SpotifyWebApi

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
'use strict'
const Request = require('./base-request')
const DEFAULT_HOST = 'api.spotify.com'
const DEFAULT_PORT = 443
const DEFAULT_SCHEME = 'https'
module.exports.builder = function (accessToken) {
return Request.builder()
.withHost(DEFAULT_HOST)
.withPort(DEFAULT_PORT)
.withScheme(DEFAULT_SCHEME)
.withAuth(accessToken)
}