I’ve been thinking about adding last.fm integration to my site for a while now, but I’ve never been able to fit it with the style. It’s really just not a great thing for my website, because most of my online “personality” is on bsky,1 so I decided to put it on my bsky profile.

In the first iteration, I polled the last.fm API every 90 seconds with pylast, and updated the bio with the data I got from that. This solution was fine but something about it grossed me out2. It’s by far the least optimal way this could’ve been implemented and I simply could not let it stand.

In the next (and current) iteration, I decided to replace the last.fm monitoring with a simple webhook that would trigger from my phone whenever the song I was playing changed. To implement this, I decided to write a tiny flask server that would accept a post request with an API key (because I have this webhook exposed to the internet), artist name and track title.

@app.route('/now_playing', methods=['POST'])
def lastfm_endpoint():
    provided_api_key = request.args.get('api_key')
    
    if provided_api_key == api_key:
        artist = request.args.get('artist')
        track = request.args.get('track')
        update_track(artist, track)
        return "Success", 200
    else:
        return "Unauthorized", 401

That flask server calls the update_track function, which passes formats the data into “{artist} - {track}” and updates my bio with it using the atproto python library.

I have the whole thing sitting on my server, running at about 231 MiB RAM usage, so you could run this just about anywhere for cheap/free (or rewrite it in a more performant language).

To actually get the data from my phone to the webhook, I use MacroDroid. I looked in to Tasker and Automate, but they were too complex for what I needed. I have a simple macro that, when my media changes, checks if it’s from one of the apps that I scrobble from with Pano Scrobbler, and if so sends the track to my webhook.

You can see it in action here, and the source here.

  1. See dame’s account for a really good example 

  2. Not just me 

back to home page