Please consider leaving a donation if you appreciate this information. Lightning network now available
I’ve become interested in expanding my music appreciation lately and as a result, I’m listening to a lot of things that I haven’t had any exposure to previously. A great deal of my music listening happens while I’m working and that work can often require very intense focus. Task switching is a productivity killer. Moving completely out of the context of my workspace to “like” a song just isn’t going to happen. But if I don’t, it may be gone forever.
I wanted a way to quickly mark a groovy track for later exploration and more listening. I wasn’t able to find any out-of-the-box solution that met my needs. I should have stopped there.
I decided to try to hack something together. Spotify has a quite nice web API. The Spotify Web API equivalent of ‘liking’ a song is called Save Tracks for Current User. I also found a node wrapper for the Spotify API and so at first glance, it looked easy enough to just generate my access token on the Spotify developer ‘try it out’ page and hard code that into a few lines of JavaScript and be done with it. And that worked! For awhile 🙁
So it turns out, the access token is only valid for an hour. The access token can be refreshed so long as it is still valid. Refreshing the token requires that a refresh token is issued in addition to an access token. I definitely should have stopped there.
The access token needs to be refreshed before it expires and if I can’t be bothered to switch to an app to press a button, I certainly can’t be bothered to run a series of commands every 45 minutes or so, 24 hours a day.
The solution I finally cobbled together is a two part solution edit: I changed this up a bit. see comments. Part one is tasked with keeping the access token fresh:
- Some JavaScript resides on a server somewhere. It’s on a cron schedule to run every 30 minutes.
- That script refreshes the access token and writes the new access token to a file.
- It also reads that same file for its own access token. The code looks something like this:
Part two does the actual job of ‘liking’ a song.
- Takes some input in the form of a spotify song URI, e.g.: spotify:track:4675yUu8AUbE72T94BkLCD
- strips the
spotify:track:
bit off of that - Uses scp (via node scp) to fetch token.txt from the remote server and writes that locally.
- Reads the token file and sets that to the access token.
- Does this: ❤️ to a song.
That bit looks like this:
Just a side note, the Spotify track URI is fetched via shpotify.
And here’s how it all works
And, of course I have a voice command so now, all I need to do is say “heart song” and the magic happens in the background.
That’s where I stopped.
Please consider leaving a donation if you appreciate this information. Lightning network now available
Will says
Ok, that isn't where I stopped. There was no good reason to be transporting the token so I moved the song liker script to the remote server and just call it up over ssh passing the song id as the sole argument. It’s faster now and the only thing I pass over the network is an already publicly known piece of data 🙂
Will says
Also
Will says
And…I didn’t stop there either. Turns out Spotify provides an endpoint to Get the User’s Currently Playing Track as well so I don’t have to pass that value. Unfortunately, the node wrapper I found hasn’t got support for that end point (looks like it’s beta [and it acts a bit strange]) I just removed that from my project and used node-XMLHttpRequest instead, just building my headers/query params myself.