Detecting and Encouraging a Fan’s Affinity using Spotify’s Top Recent Streamed Tracks
How much Faith do you have in Hurts?

Attempting to understand a fan’s loyalty to an artist and then rank that fan among others is one of those core problems I’ve been asked about over the years. Lots of artists want to gamify fan devotion to encourage more streaming, awareness, and sales. While there are many products which have come and gone (and still exist) which attempt to fill this gap, I ventured to build something simple using publicly available Spotify data for Hurts and their aptly named new record, Faith. All that is required of the user is that they login with their Spotify account. We then detect their affinity for a particular artist based on their top recently streamed tracks and encourage further streaming to affect the score. Fans then have the ability to submit their score to a leaderboard to see if they are among the most faithful.
Detect your faith in Hurts by visiting the web app and read on to find out how it was developed.
Get a User’s Top Tracks

As part of their Web API, Spotify provides an endpoint for getting a user’s top artist and tracks. As Spotify states, affinity is measured by user behavior, including play history, but does not include actions made while in incognito mode. The endpoint is able to provide up to 50 tracks and artists for three different timeframes:
- Long term — Several years of data, including all new data as it becomes available
- Medium term — Approximately last 6 months
- Short term — Approximately last 4 weeks
According to Spotify, this data is updated once each day for each user. For our project, we were most interested in the short term time range because users could directly affect these tracks every 24 hours.
curl -X GET "https://api.spotify.com/v1/me/top/tracks?time_range=short_term&limit=50" -H "Authorization: Bearer {your access token}"
Algorithm
An easy way to turn the 50 top tracks into a score, would be to simply count how many of those tracks were from Hurts. For example, if 25 of the 50 tracks were from Hurts, that would be a 50% faithfulness. However, I wanted to create a slightly more dynamic score so I also took position of track into consideration. If we were to say the top track is worth 50 points and the last track is worth 1 point, the total amount of points possible would be 1275. Here’s an equation for detecting total points:
let total = (tracks.length * (tracks.length + 1)) / 2
From here, we can loop through all of the tracks and increment a running points total based on the track’s position (if it is a track from Hurts.)
let points = 0tracks.forEach((track, i) => {
if (track.artist == "Hurts") {
points += tracks.length - i
}
})return Math.round(points / total * 100)
This provides us with a much more dynamic score and awards those users who not only stream Hurts but stream them most often.
Leaderboard
I’m not a huge fan of adding databases to my projects since they are usually short lived but I could certainly understand the client’s wish to have a leaderboard included with this project. The leaderboard takes an otherwise private score and gives a fan the ability to share it publicly. This visibility in turn encourages friendly competition between fans. When building databases these days, I just put together a simple Serverless stack with a DynamoDB and that is what I have done here. Since the user has logged in with Spotify, we can use their user id to make sure their database record is unique and also give them the opportunity to update it every day.
Component Design and Development

I am a notoriously simple designer and my embrace for component based design principles has only deepened that approach. Using the wireframe and provided aesthetics as a guide, I begin by creating a basic design system in Figma. This mostly involves turning print album packaging into a responsive system of required colors, typography, buttons, and components. All of these elements are then used to turn the wireframes into designed screens.

In order to keep the client focused on what core design is necessary, I only send through mobile screens which show the limited amount of screen real estate we have available. Only once we’re all on board with these simple screens do I begin tackling larger screens or sprinkling on any delighters. When developing special components, I almost always start on CodePen.IO and then migrate the code into my project. Let’s take a look at two of these.
Faith Loader
Even though we can calculate a user’s faithfulness in a second or two, once Spotify sends through the data, I thought it would be nice to add a little loader which shows off more of the album packaging. This is done in Vue.js by preloading and randomly flashing through images.
Faith Progress
One of the most important moments of the experience is when the user’s faithfulness is finally displayed. In order to make this interesting, I turned the Faith logo into a progress bar which is animated using anime.js. This is really just two images absolutely positioned on top of each other with a mask div to adjust the height of the top logo.
Check out these components and others in the companion CodePen collection I’ve made available. Very special thanks to CodePen for adding the Vue pen starter which makes these sort of experiments very easy to put together.
Thanks

Very special thanks to Hannah Celnikier and her team at The Orchard along with Ben Frith and his team at Seven 7 Management for bringing this project to me. Everything really fell into place nicely from concept and design to execution and launch. I look forward to working with both parties again. Thanks to Hurts for allowing me to build this experience for their fanbase and congratulations for releasing Faith which can be streamed today. I look forward to increasing my faith.