4.8 - Recommendations

Introduction

screenshot

How it works

When a user search for something the application does a request for both tracks and artists. The recommendations are based on some of the audio features the track has. First we have to do another request to get the audio features. Currently the code only supports recommendations based on one track. This is because if we were be doing the recommendations on all the tracks the application would make too many request in a short time period for the Spotify API to handle and it will be prompted with an too many request error.

const searchResults = await getDataFromSpotfy(
  `https://api.spotify.com/v1/search?q=${req.query.query}&type=track%2Cartist&limit=10&offset=0`,
  options
);
const audioIdList = searchResults.tracks.items.map((track) => track.id);
const formattedIdList = audioIdList.toString().replace(/,/g, '%2C');

Request audio features

const audioFeatures = await getDataFromSpotfy(
  `https://api.spotify.com/v1/audio-features?ids=${formattedIdList}`,
  options
);

Mood

When we have the audio features we run the songs through the mood assignment code. This will return a mood. Every mood has a min and max value for the danceability, energy and valence endpoints. Based on these values we can request recommendations by putting them inside the URL: &min_feature=, &max_feature=

const featuresWithMood = audioFeatures.audio_features.map((track) => {
  return moodFilter.addMood(track);
});

const recommended = await getDataFromSpotfy(
  `https://api.spotify.com/v1/recommendations?limit=${10}&market=US&min_energy=${
    featuresWithMood[0].values.energyValues.min
  }&max_energy=${featuresWithMood[0].values.energyValues.max}&min_valence=${
    featuresWithMood[0].values.valenceValues.min
  }&max_valence=${
    featuresWithMood[0].values.valenceValues.max
  }&min_danceability=${
    featuresWithMood[0].values.danceabilityValues.min
  }&max_danceability=${
    featuresWithMood[0].values.danceabilityValues.max
  }&seed_tracks=${featuresWithMood[0].id}`,
  options
);

Render

These recommendations will be rendered on the page.

res.render(__dirname + '/view/components/result-list.ejs', {
  trackData: searchResults.tracks.items,
  token: access_token,
  recommendations: recommended.tracks,
});

Last updated

Was this helpful?