Yordi Verkroost

Show Your Recently Played Song using Netlify Functions and Last.fm

Netlify Functions (serverless functions) allow you to write simple JavaScript functions that Netlify turns into API endpoints. This is a handy service, especially for the use case I had in mind.

I wanted to show the last song I listened to on my website. The Spotify API has an endpoint that provides you with this information, but it requires a browser-based OAuth flow. Since I needed a server-to-server solution, I turned to the Last.fm API, which has a similar endpoint to retrieve your recent tracks and allows you to call this endpoint with an API key.

If you're new to Netlify Functions, they provide this excellent tutorial that guides you through setting up your first Functions project. If you're more advanced or want to figure things out for yourself, you can start by cloning this example Hello World project in combination with this more bare-bones documentation.

The Code

To retrieve my recent tracks from the Last.fm API, I wrote the following function:

import fetch from 'node-fetch'

export const handler = async () => {
    const LASTFM_API = 'https://ws.audioscrobbler.com'
    const API_KEY = process.env.LASTFM_API_KEY
    const USER = process.env.LASTFM_USER
    const ENDPOINT = `${LASTFM_API}/2.0/?method=user.getrecenttracks&user=${USER}&api_key=${API_KEY}&format=json&limit=1`

    const response = await fetch(ENDPOINT)
    const data = await response.json()

    const track = data.recenttracks.track[0]

    const result = {
        artist: track.artist['#text'],
        title: track.name,
        url: track.url

    return {
        statusCode: 200,
        headers: {"Access-Control-Allow-Origin": process.env.CORS_ORIGIN},
        body: JSON.stringify(result)

The first few lines define endpoint information, such as the root API URL, the endpoint path, and the API key required to retrieve the data. I stored this API key in an environment variable, which can be created in the settings of a Netlify Functions project.

Next, I call the Functions endpoint, extract the data I need, and reformat it into a new JSON object.

Then, on my website, I added a placeholder in HTML to hold the API response:

🎧 <span id="last-played" class="blurred">Last played: the song will show here when it's loaded.</span>

The span ID is necessary to find this element via JavaScript and replace the placeholder data.

There's also some CSS involved to blur this placeholder text initially until the Function data is collected:

.blurred {
    filter: blur(5px);

Finally, the following small script calls my Function and replaces the placeholder data:

  .then(res => res.json())
  .then((track) => {
    let lastPlayed = document.querySelector('#last-played');
    lastPlayed.innerHTML = `Last played: <a href='${track.url}' target='_blank'>${track.title} (${track.artist})</a>`;

This code calls the Function endpoint and uses the result to populate the previously mentioned span element with new data, which is textual information about the song's name and artist, plus a link to the song on Last.fm.

Final Result

At the moment of writing, you can view the final result at the bottom of my website homepage. The displayed song looks like this:

🎧 Last played: the song will show here when it's loaded.

#Development #Music