Spotify Playlist Backup
Project to create a web app that displays a user's Spotify playlist track details so they can be downloaded as a csv file.
https://spotify-playlist-backup.herokuapp.com (using Heroku's free sandbox account that sleeps inactive applications, so the application will take time to start if it's been inactive for 30mins)
The app will allow users to:
- log in
- display their playlists (and search for a particular playlist)
- display the details (name, album, artist(s)) of the tracks in that playlist
- download a copy of the track details as a csv file
Navigate to https://spotify-playlist-backup.herokuapp.com. You'll be asked to log in, authorise the connection of the app to your Spotify account, and then the page will display a list of all your playlists. Clicking on a playlist will display the tracks and the option to download the list to a csv file.
The project is hosted on Heroku but can also be run locally.
- node (version 8.9.1)
- npm (version 5.6.0)
- Spotify accounts (a normal user account and a developer account)
- Heroku account and CLI (if deploying to Heroku)
An overview of Spotify Web API setup: https://developer.spotify.com/web-api/ and deploying to Heroku: https://devcenter.heroku.com/articles/deploying-nodejs/
Setup your Spotify Developer account and in the Dashboard create an App. Edit the settings so the
Redirect URIs section includes
http://localhost:8888/callback/. You will need to (later) add additional entries if deploying to Heroku (e.g. in my case
Clone the repository.
Install node and npm.
Using the Authorization Code Flow to access Spotify, the following configuration variables must be set as environment variables in a
.env file in the project root directory (if running locally) and/or as config variables if deploying to Heroku. If running locally, the
dotenv module will load the file into
REDIRECT_URI will have a different address in Heroku. In the
.env file include:
CLIENT_ID=<value in your Spotify app account> CLIENT_SECRET=<value in your Spotify app account> REDIRECT_URI=http://localhost:8888/callback/
To install the required packages (see package.json), run:
$ npm install
Start the server locally:
$ npm start
Then open the browser and go to http://localhost:8888/
To rebuild (after any file changes), run:
$ npm run build
Or to watch for and rebuild automatically after any changes (
webpack) AND automatically re-start the server if there are changes there as well (
$ npm run watch
Deploying to Heroku requires some additional setup such as installing Heroku and creating an app and setting config variables (see https://devcenter.heroku.com/articles/deploying-nodejs) however the settings in
package.json are already done.
Project file structure
server.js public/ |- index.html |- bundle.js |- style.css
bundle.js file is built using webpack from the files in
working_js/ |- authentication.js |- helpers.js |- playlist.js |- tracks.js
The project is complete. Further tweaks and modifications may be made if anything comes up:
- Possible further research into Spotify's authorisation workflows and addition of refresh tokens
This project came about because due to Spotify's UI update a while ago, I could no longer copy the details of the tracks on my Spotify playlists anymore (and I'd really really like a list of my tracks for when I forget). Also it was a great way to learn about fetching data from external sources where authorisation was required and building something that I'd actually use.
My first step was to investigate how to connect to Spotify, how their Web API and authentication worked and other resources that would assist in fetching data (e.g. I used https://github.com/jmperez/spotify-web-api-js). In order to access user data in Spotify, users need to log in and then authorize the application.
I picked the
Authentication Code Flow for authentication, as it allowed me to access user data and had the greatest options. The
Implicit Grant workflow could work as I currently do not use refresh tokens (something I plan to add in the future). Using the
Authentication Code Flow would be a good opportunity to build on the server-side as well and use
The server and authentication code was based on the code in https://github.com/spotify/web-api-auth-examples, which I modified so only the parts I needed remained and which I spent some time reviewing to understand what it did.
There is no way to log out from spotify's web api and redirect to the app, the
/logout endpoint they provide does not allow redirection so the workaround is to direct users to the authorisation page where they can select
(Not you?) to log out of the app. This seems to be the most common work around.
Retrieving Data from Spotify
Rather than using callbacks (and resulting in very ugly code), I decided to implement "function ordering" using Promises. I'm still grappling with using them, but a lot of searching and experimenting got me able to make my functions run in order and wait for loops to completely finish before moving on. These loops were required as Spotify has limits on the amount of data returned and multiple calls were often required to retrieve chunks of data, which then needed to be pieced together.
Downloading to a Local File
One new item I had never touched on was downloading/saving information from a website to a local file, which I needed as I wanted to be able to save track information to a csv file. This turned out to be pretty easy to implement once I worked out how to download using the anchor
I also included the
Design-wise, working out how the data would display, particularly in mobile view required a fair amount of testing to determine appropriate spacing and to make sure data did not overrun. I ended up displaying the track information in a table as this was both appropriate and meant I could literally copy and paste the data, if I wanted to, into excel as well. I added some spinning animations to show data was loading/retrieved and further animations to fade in the playlist. Displaying the playlists themselves went through a few iterations.
Initially the playlist data was displayed in a 'table-like' form (playlist owner, name, number of tracks), however I have since changed it to a more modern display that displays the information over two lines and uses font size, weight and colour to differentiate the information. The Spotify Developer website has information on spotify colours. Something I hadn't thought about was favicons! I downloaded one from a free-favicon website.
The background image is from Bruno Cervera on Unsplash. Once I added this image I changed the design to make the playlist more transparent and managed to find a css trick so the playlist scrolls in its own area and the header/search bar stays up the top. That was simple but very cool.
The project has essentially finished (barring some ongoing feature/design tweaks/refactoring) and was pretty fun, a great learning experience and resulted in something I will use.