3.0.1 • Published 3 months ago

spoteasy v3.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

spoteasy

An easy-to-use zero-dependencies node.js wrapper for the Spotify API.

All versions are written in node.js v18.17.0 and have no dependencies.

Some of the most notable capabilities:

  • Fetching a Spotify Token in each one of the four ways specified in the Spotify API documentation;
  • Simple & documented methods to request anything from the api;
  • Access token auto-refreshing

 

How to use

Note free accounts can only be used for browsing and current playback status. Only premium accounts can be controlled (pause, play, next, etc.).

Importing & Initialization

const SpotifyAPI = require("spoteasy");

To fetch the Spotify API, you must first create a token. The purpose of this library is to make that as easy as possible. There are four ways to create one, as described in the Spotify API documentation, and each one has its advantages and disadvantages.

Note that each method requires a Spotify Client ID (and sometimes a Spotify Client Secret). You can get both of them by creating an app in the Spotify Dashboard and accessing the app credentials.

I've made two examples that use the Client Credentials Flow and the Authorization Code PKCE Flow

 

Client Credentials Flow

let spoteasy = new SpotifyAPI()
spoteasy.clientCredentialsFlow("<Client ID>", "<Client Secret>")

Adds a "token" property to the "spoteasy" object. The "token" property contains an object with various useful properties, beyond the actual access token.

For security reasons, do not hardcode the client ID and Secret in your code. Consider using environment variables or configuration files.

Now let's try to fetch an album from the Spotify API.

// Same as spoteasy.getAlbum("6PFPjumGRpZnBzqnDci6qJ")
// Also, if you are in an async function, you can, of course, "await" the Promise.
spoteasy.getAlbum("https://open.spotify.com/album/6PFPjumGRpZnBzqnDci6qJ")
  .then(res => {
    let tracklist = res.tracks.items
    console.log(tracklist.map(track => track.name))
  })

/*
  [
    'Papercut',
    'One Step Closer',
    'With You',
    'Points of Authority',
    'Crawling',
    'Runaway',
    'By Myself',
    'In the End',
    'A Place for My Head',
    'Forgotten',
    'Cure for the Itch',
    'Pushing Me Away'
  ]
*/

 

Authorization Code PKCE Flow

Now let's create a playlist in a logged user's account. To do this, we have to make the user log in into his spotify account. The next examples will use the express.js library to do that. (Note: they are very barebones implementations, useful only for explanation purposes.)

As you can see (and can also be seen from the JSDOC documentation), it's stated that to do that we need two authorization scopes: "playlist-modify-public" and "playlist-modify-private". We can pass them as arguments in the authorization code PKCE method, like any other token creation method (except for client credentials).

const SpotifyAPI = require("spoteasy")
let spoteasy = new SpotifyAPI()

app.get("/auth", async (req, res) => {

  let url = spoteasy.authorizationCodePKCEFlow(
    "<Client ID>",
    "<Redirect URL>", //WARNING! you must whitelist this URL in the redirect URI section of the spotify app settings
    {
      scope: ["playlist-modify-public", "playlist-modify-private"]
    }
  )

  //This will redirect the user to the Spotify login page, where they can log in
  res.redirect(200, url)
})

Once the user has logged in, they will be redirected again to the specified "Redirect URL" parameter with a code in the url query, which needs to be passed as an argument to the "resolveToken" method.

Finally, (as you will see in the next piece of code) calling the "resolveToken" method with the URL query as argument will create an access token in the "spoteasy" object, enabling us to easily create a playlist.

app.get("/login", async (req, res) => {
  // Checking if the auth code is in the URL query & if token is waiting to be resolved
  if ("code" in req.query && "resolve" in spoteasy.token) {

    // Resolve the authentication code in the URL query to get the access token
    await spoteasy.resolveToken(req.query)

    // Successful Login
    res.status(200).send({ info: "Login completed" })

    // The ID of the current user can be obtained via the Get Current User's Profile endpoint
    let currentUser = await spoteasy.getCurrentUserProfile()

    let response = await spoteasy.createPlaylist(currentUser.id, {
      name: "Hello World",
      public_playlist: false,
      description: "Your coolest playlist"
    })

    // Print out the url of the just created playlist
    console.log( response.external_urls.spotify )
  }
  // If user rejected the authentication request
  else if ("error" in req.query) {
    res.status(401).send({ error: "Login rejected" })
  }
})

 

SpotifyAPI Constructor Options

OptionDescription
autoRefreshTokenWhether to set the token to auto-refresh when expired on its creation.
precautionSecondsSeconds to tick off of token.expires_in to try refresh the token in advance before it expires. Recommended 2 to 5.
awaitTokenIf true, and a token creation is in progress, makes any request wait for the token to be created before continuing.
responseParserThe response parser to apply to any API response.
defaultMarketThe default country market to apply to requests options.

 

SpotifyAPI Object Main Methods

*Note that the methods and parameters are fully documented in the JSDOC methods comments

MethodDescription
new SpotifyAPI()Creates a SpotifyAPI object with some optional settings passed as argument, such as "autoRefreshToken".
authorizationCodeFlowUses the Authorization code flow method to get an authorization token.
authorizationCodePKCEFlowUses the Authorization code PKCE flow method to get an authorization token.
clientCredentialsFlowUses the Client credentials flow method to get an authorization token.
implicitGrantFlowUses the Implicit grant flow method to get an authorization token.
resolveTokenThis method has to be called after using a Grant Flow that gives you an authentication code in the URL query.
setTokenSets the token with the provided properties.
refreshTokenTries to refresh the authorization token.
requestMake an API request to the spotify API with the given options.
(static) tracksParserThe "request" method default parser. Adds a "parsed_tracks" property to the response which is an array of EVERY track found in it, even episodes.
(static) parseURLExtractes important information out of a Spotify URL (like type and id).
(static) isValidURLReturns true if a given string is a valid Spotify URL.
...other...getArtistTopTracks, followPlaylist, getPlaybackState... There is a method for every SpotifyAPI endpoint, fully documented in JSDOC.
searchTrackShorthand for fetching a "search for item" request with limit 1 and type track, then returning the first item.
getMagicReturns an API response based on the argument (either a search query or a Spotify URL).

 

SpotifyAPI "token" properties

These are the properties that the token object might have during or after its creation with one of the 4 methods

PropertyDescription
access_tokenThe actual access token
token_typeThe token type (e.g. "Bearer")
expires_inThe amount of seconds that the token can be used for before it expires, starting from its creation
expires_in_msThe amount of milliseconds that the token can be used for before it expires, starting from its creation
expire_timeThe Date.now() milliseconds on which the token will expire
scopeAn array of the allowed authorization scopes
refresh_timeoutThe Timeout object of the auto refresh
expires_now_in(Getter) The amount of milliseconds that the token can be used for before it expires, starting from now
is_expired(Getter) Whether the token is expired
auto_refresh(Getter/Setter) Whether the token is going to automatically refresh when expired
promiseWhen creating or refreshing token, this will be the fetch request Promise

 

Changelog & Breaking Changes

Watch out for this section if you wish to migrate to a different version.

  • v1.1.0: - Added "searchTrack" method - Added declaration file. - Removed minified version.

  • v1.2.0: - Added "tracksParser" parser, and placed it as the default parser of the "request" method.

  • v1.3.0: - Added "precautionSeconds" option on constructor. - Added "refresh_timeout", "expires_now_in" and "auto_refresh" token properties.

    • v1.3.1: - Fixed bug where the "searchTrack" method wouldn't parse its track.

  • v1.4.0 - Added "isValidURL" method. - Fixed trackParser bug regarding episodes.

  • v1.5.0: - Added a shorthand for every SpotifyAPI endpoint as of this version upload date. - Added a "defaultMarket" option on constructor. - Fixed a bug where an empty response would throw an Exception.

  • v1.6.0: - Added URL "id", "ids" and "uris" parsing for every SpotifyAPI endpoint shorthand.

    • v1.6.1: - Fixed bug where the "public_playlist" property won't work.
    • v1.6.2: - Updated spoteasy declaration file.

  • v1.7.0: - Added "getMagic" method. - Added "responseParser" option on constructor. - Added "promise" token property. - Fixed declaration file link in package.json.

    • v1.7.1: - Fixed wrong JSDOC parameter types. - Fixed "startOrResumePlayback" method that won't parse URIs.

  • v1.8.0: - Added "awaitToken" option on constructor. - Fixed broken JSDOC optional parameters types, caused by patch v1.7.1

  • v2.0.0: - Removed "parser" option from "request" method. You can choose the response parser by setting the "responseParser" property either in the constructor or whenever you need it in the SpotifyAPI class object. - Made "scope" property in the token obect an Array of scopes, instead of a string of scopes separated by a space " ". - Made "image" parameter an optional one in the method "addCustomPlaylistCover". - Made "searchTrack" method return the actual response, not only the parsed track (This will also affect the "getMagic" method). - Fixed bug where a track object with no external url would crash "trackParser".

  • v2.1.0: - Updated shorthands so that they use body instead of query when possible to send requests (to avoid exceeding the maximum length of the request URI). - Fixed bugs where a lot of Playlists related shorthands used body instead of query to send requests or viceversa, making them unusable. - Fixed bugs where some shorthands wouldn't parse given URLs/URIs

  • v2.2.0: - Added "trackParser" support for getting several albums. This might also generally fix some bugs with the parser, as the previously used method was changed to a more flexible one.

 

Found a bug and/or need help?

Please open an issue on Github to request a change, report a bug or ask for help about something and i will gladly look into it.

If you like this library, consider giving it a star on Github. It means a lot :)

3.0.1

3 months ago

3.0.0

3 months ago

2.2.0

9 months ago

2.1.0

9 months ago

2.0.0

9 months ago

1.8.0

9 months ago

1.7.1

9 months ago

1.7.0

9 months ago

1.6.2

9 months ago

1.6.1

9 months ago

1.6.0

9 months ago

1.5.0

9 months ago

1.4.0

9 months ago

1.3.1

9 months ago

1.3.0

9 months ago

1.2.0

9 months ago

1.1.0

9 months ago

1.0.0

9 months ago