Skip to content

peterhartree/records

Repository files navigation

Records of the day

A daily homepage of album suggestions, seeded from your Spotify playlists.

Every day, a cron job picks a handful of artists you already follow (via a configured playlist) and features one random album from each on the homepage. Click through to open in Spotify. Not feeling it? Hit the trash icon on any card to permanently dismiss that artist — none of their albums will be suggested again.

Originally extracted from hartreeworks.org; see the backstory at wow.pjh.is/journal/vibe-spotify.

How it works

  1. Weekly: a cron sweeps your configured Spotify playlist(s) and adds any new artists to spotify_artists.
  2. Daily: a cron picks ~9 random non-dismissed artists, fetches a random album from each, and writes rows to spotify_featured_albums for that date.
  3. Homepage reads the featured albums for today (falling back to the most recent day if today is empty) and renders them as a grid.
  4. Dismiss writes dismissed_at on the artist row; future runs skip them.

Stack

  • Next.js 15 (App Router) on Vercel
  • Supabase (Postgres + RLS)
  • Spotify Web API (refresh-token auth)

Setup

1. Spotify app

  1. Create an app at https://developer.spotify.com/dashboard.
  2. Under Redirect URIs, add https://YOUR-DOMAIN/api/spotify-auth (and http://localhost:3000/api/spotify-auth for local use).
  3. Note the Client ID and Client Secret.

2. Supabase project

  1. Create a project at https://supabase.com.
  2. In the SQL editor, run supabase/schema.sql.
  3. From Project Settings → API, copy:
    • Project URL → NEXT_PUBLIC_SUPABASE_URL
    • anon public key → NEXT_PUBLIC_SUPABASE_ANON_KEY
    • service_role key → SUPABASE_SERVICE_ROLE_KEY

3. Environment variables

Copy .env.example to .env.local (or set them in Vercel). Fill in the Supabase and Spotify credentials, then generate secrets:

# Shared secret for cron requests
openssl rand -hex 32   # → CRON_SECRET

# One-time gate for the OAuth setup route
openssl rand -hex 32   # → SETUP_SECRET

Set SPOTIFY_PLAYLIST_ID to a single playlist, or SPOTIFY_PLAYLIST_IDS to a comma-separated list. The playlist must be owned by the Spotify account you authenticate as.

4. Get a Spotify refresh token

With SETUP_SECRET set, visit:

https://YOUR-DOMAIN/api/spotify-auth?secret=YOUR_SETUP_SECRET

(Or http://localhost:3000/api/spotify-auth?secret=... locally.) You'll be redirected to Spotify to authorise, then back to a JSON page containing your refresh_token.

  1. Copy the refresh_token into SPOTIFY_REFRESH_TOKEN.
  2. Redeploy (or restart yarn dev).
  3. Unset SETUP_SECRET — the setup route will then return 403 and stay disabled.

5. Seed the data

Trigger the two cron endpoints manually once:

curl -H "Authorization: Bearer $CRON_SECRET" \
     https://YOUR-DOMAIN/api/cron/spotify-sync-artists

curl -H "Authorization: Bearer $CRON_SECRET" \
     https://YOUR-DOMAIN/api/cron/spotify-feature-albums

The first populates spotify_artists from your playlist(s); the second picks today's featured albums. Open / and you should see them.

6. Scheduled runs

vercel.json already schedules:

  • /api/cron/spotify-sync-artists — weekly, Sundays 02:00 UTC
  • /api/cron/spotify-feature-albums — daily at 03:00 UTC

Vercel automatically attaches the Authorization: Bearer $CRON_SECRET header on scheduled calls.

Local development

yarn install
yarn dev

Open http://localhost:3000.

In dev, the spotify-feature-albums endpoint doesn't require the bearer token, so you can just open http://localhost:3000/api/cron/spotify-feature-albums in a browser to regenerate today's picks.

Structure

app/
  page.tsx                              # "Today's records" homepage
  RecordsGrid.tsx                       # Client grid + dismiss dialog
  api/
    records/dismiss/route.ts            # POST — mark an artist dismissed
    spotify-auth/route.ts               # One-time OAuth setup (SETUP_SECRET gated)
    cron/
      spotify-sync-artists/route.ts     # Weekly — pull artists from playlists
      spotify-feature-albums/route.ts   # Daily — pick random albums
components/ui/                           # shadcn/ui primitives
lib/
  spotify-auth.ts                       # Spotify token exchange + authed fetch
  supabase/{server,service}.ts          # Supabase clients
supabase/schema.sql                     # Database schema

Tuning

Two env vars adjust the daily selection:

  • MAX_ALBUMS_PER_DAY (default 9) — how many albums to feature per day
  • MAX_CLASSICAL_PER_DAY (default 1) — cap on classical artists per day (classical = matched by genre keywords: orchestra, symphony, baroque, opera, etc.)

Licence

MIT. See LICENSE.

About

A daily homepage of album suggestions, seeded from your Spotify playlists. Extracted from hartreeworks.org.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors