Skip to content

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

License

Notifications You must be signed in to change notification settings

zWolfrost/spoteasy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

 

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'
  ]
*/

 

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 example will use the express.js library to do that. (Note: it's a very barebones implementation, useful only for explanation purposes.)

Spotify Create Playlist Docs - Authorization Scopes

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". These tell spotify what we are about to do with the user's account. We can pass them as arguments in the authorization code PKCE method.

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

app.get("/auth", async (req, res) => {
  // If the URL query is empty (thus user hasn't logged in yet).
  if (Object.keys(req.query).length === 0) {
    // Create the Spotify authentication URL, using the authorization code PKCE flow.
    let url = spoteasy.authorizationCodePKCEFlow(
      // Your Spotify Client ID.
      "<Client ID>",
      // Redirect back to this URL after the user logs in.
      // WARNING! you must whitelist this URL in the redirect URI section of the spotify app settings.
      "https://whatever.webpage.com/auth",
      {
        // The scopes that the user will be asked to authorize.
        scope: ["playlist-modify-public", "playlist-modify-private"]
      }
    )

    // Redirect the user to the Spotify authentication page.
    res.status(100).redirect(url)
  }
  // If the auth code is in the URL query (thus user was redirected back from the spotify auth page).
  // & if the token is waiting to be resolved.
  else if ("code" in req.query && "resolve" in spoteasy.token) {
    // Resolve the authentication code in the URL query to finally create the access token.
    await spoteasy.resolveToken(req.query)

    // We are now logged in. Let's create a playlist.
    // The ID of the current user can be obtained via the Get Current User's Profile endpoint
    let currentUser = await spoteasy.getCurrentUserProfile()

    // Create a playlist in the user's account.
    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 )

    // Do whatever after the user logs in.
    res.status(202).redirect("https://whatever.webpage.com/")
  }
  // If user rejected the authentication request.
  else {
    // Do whatever after the user rejects the authentication request.
    res.status(401).redirect("https://whatever.webpage.com/")
  }
})

 

SpotifyAPI Constructor Options

Option Description
autoRefreshToken Whether to set the token to auto-refresh when expired on its creation.
precautionSeconds Seconds to tick off of token.expires_in to try refresh the token in advance before it expires. Recommended 2 to 5.
awaitToken If true, and a token creation is in progress, makes any request wait for the token to be created before continuing.
responseParser The response parser to apply to any API response.
defaultMarket The 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

Method Description
new SpotifyAPI() Creates a SpotifyAPI object with some optional settings passed as argument, such as "autoRefreshToken".
authorizationCodeFlow Uses the Authorization code flow method to get an authorization token.
authorizationCodePKCEFlow Uses the Authorization code PKCE flow method to get an authorization token.
clientCredentialsFlow Uses the Client credentials flow method to get an authorization token.
implicitGrantFlow Uses the Implicit grant flow method to get an authorization token.
resolveToken This method has to be called after using a Grant Flow that gives you an authentication code in the URL query.
setToken Sets the token with the provided properties.
refreshToken Tries to refresh the authorization token.
request Make an API request to the spotify API with the given options.
(static) tracksParser The "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) parseURL Extractes important information out of a Spotify URL (like type and id).
(static) isValidURL Returns 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.
searchTrack Shorthand for fetching a "search for item" request with limit 1 and type track, then returning the first item.
getMagic Returns 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

Property Description
access_token The actual access token
token_type The token type (e.g. "Bearer")
expires_in The amount of seconds that the token can be used for before it expires, starting from its creation
expires_in_ms The amount of milliseconds that the token can be used for before it expires, starting from its creation
expire_time The Date.now() milliseconds on which the token will expire
scope An array of the allowed authorization scopes
refresh_timeout The 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
promise When 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.

  • v3.0.0:
    - Completely migrated to TypeScript.
    - Updated parameters to the ones accepted by current Spotify API.
    - Made "name" parameter in the "createPlaylist" method mandatory, and moved it out of the "options" object.
    - Made "seed_artists", "seed_genres" and "seed_tracks" parameters in the "getRecommendations" method optional, and moved them in the "options" object.
    - Fixed wrong parameter types & a few bugs.

 

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 :)

About

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

Topics

Resources

License

Stars

Watchers

Forks