Now Playing
2023
·
Apple Music listening data on my site — without the Apple Developer account.
The short version
This repo (injoon5/data) is the backend for the “now listening” widget on this site. It fetches what I’m playing from Last.fm and writes a JSON file that the frontend reads directly from GitHub.
I wrote the full story in How I made the “Now Listening” section on my website — Apple Music API age limits, why I refused to switch to Spotify, Sleeve for scrobbling, and the CORS trick with raw.githubusercontent.com.
The script
now-playing.py hits Last.fm’s user.getrecenttracks endpoint with my username and API key from env, then writes the response to now-playing.json. It trims the track list to the 20 most recent entries before saving (the blog post originally said 4 — I bumped it at some point).
response['recenttracks']['track'] = response['recenttracks']['track'][:20]Last.fm marks the currently playing track with @attr: { nowplaying: "true" } on the first item — the homepage widget checks for that.
GitHub Actions
The workflow (.github/workflows/update.yml) runs every 5 minutes on a cron, and also on pushes to main. Each run:
- Rebases from remote (
git pullwith rebase) to avoid push conflicts - Runs
photos.py(separate widget — recent photos JSON) - Runs
now-playing.pywithLAST_FM_PUBLIC_API_KEYfrom secrets - Commits as
github-actions[bot]if anything changed - Pushes via
ad-m/github-push-actionusing aREPO_SECRETtoken
Keeping all this in a separate repo is the trick that makes it cheap: the bot commits fresh JSON on its own schedule, and the website never has to redeploy to pick up new data.
How the site reads it
The homepage does a client-side fetch on mount:
https://raw.githubusercontent.com/injoon5/data/main/now-playing.jsonRaw GitHub files have no CORS restrictions, so no backend proxy needed. If the fetch fails, the widget shows an error state instead of breaking the page.
No server. No cost. No $99/year developer account. Not bad for a workaround.