ICM Week 4 – Simple Spotify App

Final project here
– Share a song with other users currently logged on by pasting a spotify url
See the code here

I began my exploration for the assignment by playing around with recursion and the dom library… But I decided soon that I wanted to try and create some kind of application. One idea I was toying around with was a simple web app that lets you search for songs, select one, and post them to a wall. So I started going through Shiffman’s node.js tutorial.

Ok I wanted to really simplify this idea. So basically a user enters a url for a song, I break that url down to be able to search for it with the spotify api, I give an error to the user if something goes wrong, or if it works, add the song to the wall.

Here’s a really rough sketch of that.

In reality, my “wall” is going to be a lot simpler of an interface. probably just a list of links or something of the like. But I’m not really worrying about that yet.

And my basic psuedo code:

- draw the canvas : search bar, enter button (html / css)
- user submits data, parse it in javascript

- send data to server
- server fetches info from spotify
- sends back data (the wall)

or

- send data to spotify from the client
- parse back result
- either show error or send data to server
- server updates walls of all users

overall limitations:
no database! only tracks stuff when users are connected.

I started by setting up my basic html page with divs that I’d insert the elements into with p5. That seemed to work alright

Then I started figuring out how to check the input

And from there, went about grabbing the track ID using the split function. I started defining how I’d pass my data from the client, eventually to spotify. This was my first area of unknown; I’d have to handle this spotify request from within javascript, passing in an authorization token (this is static for the application and the PIA I wasn’t sure how to handle). My goal wasn’t to do this in the most proper form but to just get it done. I also wanted to avoid a library, but the auth stuff is annoying and even broke an example they provide… But after some fiddling around, I figured out how to set up a http request to spotify including an auth token. I also ran through their example app so I could generate auth tokens using my app’s keys. From there, I started experimenting with how to actually make the request in my node script. I couldn’t use ‘loadJson’ since that was a p5 function, so I read up on fetch. After some failures, I finally got it to work!

function spotifyTrackQuery(trackID){
var access_token = XXXXXXXXX ;
let getRequestURL = ("https://api.spotify.com/v1/tracks/" + trackID + "?access_token=" + access_token) ;
console.log(getRequestURL);
fetch(getRequestURL)
.then(function(response){
return response.json();
})
.then(function(json){
console.log(json);
});
}

from there I could log more of the data I’d be interested in broadcasting back to the clients:

console.log(json.name); // track name
console.log(json.external_urls.spotify) //url
console.log(json.artists[0].name) // artist name

Now I finalized my server to send data to all connected users, set up my client to handle the incoming data, and cleaned up some code.

So I had a few options of where to go from here…
1. Visual improvements (much needed!)
2. Additional features (perhaps a database?)
3. Actually hosting this.

Ok visual improvements first… I started setting up my basic css:

body{
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
margin-bottom: 0px;
}

#nav-bar{
margin: 20px;
width: 100%;
}

#nav-bar input{
min-width: 250px;
height: 30px;
font-size: 18px;
}
#nav-bar button{
background: green;
color:white;
border:none;
margin-left:10px;
}

But I ran into another problem – my stupid spotify access tokens keep expiring! Time to dig… I tried copying some code from the spotify examples but had no luck… I moved on to the styling.


After cleaning things up a bit, I went back to correcting my auth token issue. After much wrestling and help from Leon, I was able to sort the issue out – although it is very hackish. I added a try& catch around my initial spotify request and then created the following function to fetch the token. It triggers a GET request to my own server, which then triggers a POST request to spotify. The Spotify request then updates my auth token. I don’t understand why it works but basically the only thing I was able to do successfully.

function getNewToken(trackID){
request.get('http://localhost:'+ process.env.PORT + '/refresh_token', function (error, response, body) {
spotifyTrackQuery(trackID);

});
}

app.get('/refresh_token', function(req, res) {

// requesting access token from refresh token
// var refresh_token = req.query.refresh_token;
// console.log("refresh_token", refresh_token);
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};

request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
access_token = body.access_token;
console.log(access_token);

res.send({
});
}
});
});

From there, it was time to get it deployed. I struggled some more, but after swapping in some environment variables for the port numbers and replacing localhost references with the heroku url, all worked! If I were to keep working on this, I’d add some new functionality like seeing how many users are on, creating an upvote/downvote system, and possibly tying it in to a playlist generator or some way of actually having everyone tuned into the list of songs simultaneously.

Posted in ICM

One thought on “ICM Week 4 – Simple Spotify App

Leave a Reply

Your email address will not be published. Required fields are marked *