Spotify Integration Setup Guide
This document explains how to set up and use the Spotify "What Was I Listening To?" integration.
Overview
The Spotify integration allows users to:
- Connect their Spotify account
- Automatically track their listening history
- Attach the track they were listening to when creating journal entries
- View track information (title, artist, album art) on entry detail pages
Prerequisites
-
Spotify Developer Account
- Go to https://developer.spotify.com/dashboard
- Create a new app
- Note your Client ID and Client Secret
- Add redirect URI:
http://localhost:3000/auth/spotify/callback(development) and your production URL
-
Environment Variables
Add to
apps/backend/.env:SPOTIFY_CLIENT_ID=your_client_id_here SPOTIFY_CLIENT_SECRET=your_client_secret_here SPOTIFY_REDIRECT_URI=http://localhost:3000/auth/spotify/callbackFor production, also set:
SPOTIFY_REDIRECT_URI=https://yourdomain.com/auth/spotify/callbackOptional (for background sync):
ENABLE_SPOTIFY_BACKGROUND_SYNC=true SPOTIFY_SYNC_INTERVAL_MS=900000 # 15 minutes in milliseconds SPOTIFY_SYNC_CRON_SECRET=your_secret_token_here # For /api/spotify/sync-all endpoint
Database Setup
Run the migration to create the necessary tables:
# In Supabase SQL Editor, run:
supabase/migrations/014_add_spotify_integration.sql
This creates:
spotify_accounts- Stores OAuth tokens per userspotify_tracks- Cached track metadataspotify_plays- Historical play events- Adds
spotify_track_idcolumn tojournal_entries
How It Works
1. User Connection Flow
- User goes to Settings → Spotify Integration
- Clicks "Connect Spotify"
- Redirected to Spotify OAuth (with PKCE)
- User authorizes the app
- Callback stores tokens in
spotify_accountstable
2. Listening History Sync
Option A: Background Sync (Recommended)
- Set
ENABLE_SPOTIFY_BACKGROUND_SYNC=truein backend.env - Server automatically syncs every 15 minutes (configurable)
- Syncs listening history for all connected users
Option B: Manual Sync
- Users can click "Sync Now" in Settings
- Calls
/api/spotify/syncendpoint
Option C: External Cron
- Set up a cron job to call
/api/spotify/sync-all - Include header:
X-Cron-Secret: your_secret_token - Example cron job (every 15 minutes):
*/15 * * * * curl -X POST https://your-backend.railway.app/api/spotify/sync-all \ -H "X-Cron-Secret: your_secret_token"
3. Journal Entry Linking
When a user creates a journal entry:
- System looks up the most recent Spotify play before the entry timestamp
- If found, links the track to the entry via
spotify_track_id - Track information is displayed on the entry detail page
4. Display
On the entry detail page:
- Shows album artwork (if available)
- Track name
- Artist names
- Album name
- "Open in Spotify" button
API Endpoints
GET /api/spotify/auth/initiate
Initiates OAuth flow. Returns authUrl, codeVerifier, and state.
POST /api/spotify/auth/callback
Handles OAuth callback. Requires code, codeVerifier, and state.
GET /api/spotify/status
Returns connection status for the current user.
POST /api/spotify/sync
Manually sync listening history for the current user.
POST /api/spotify/sync-all
Syncs all connected users (requires X-Cron-Secret header).
DELETE /api/spotify/disconnect
Disconnects Spotify for the current user.
Frontend Components
Settings Page
apps/frontend/src/app/dashboard/settings/page.tsx- Shows connection status
- Connect/Disconnect buttons
- Manual sync button
OAuth Callback
apps/frontend/src/app/auth/spotify/callback/page.tsx- Handles OAuth redirect
- Exchanges code for tokens
Entry Detail Page
apps/frontend/src/app/dashboard/entries/[id]/page.tsx- Displays Spotify track information
Troubleshooting
"Spotify client ID not configured"
- Ensure
SPOTIFY_CLIENT_IDis set inapps/backend/.env
"Failed to exchange code for tokens"
- Check that
SPOTIFY_CLIENT_SECRETis correct - Verify redirect URI matches exactly in Spotify dashboard
"No valid access token"
- Token may have expired
- System should auto-refresh, but user may need to reconnect
Tracks not appearing on entries
- Ensure listening history is being synced
- Check that user has played music recently
- Verify
spotify_playstable has data for the user
Background sync not working
- Check
ENABLE_SPOTIFY_BACKGROUND_SYNC=truein.env - Verify server logs for sync errors
- Consider using external cron job instead
Security Notes
- OAuth uses PKCE (Proof Key for Code Exchange) for security
- Tokens are stored encrypted in the database
- Access tokens are automatically refreshed when expired
- Cron endpoint requires secret token to prevent unauthorized access
Limitations
- Spotify API only provides recently played tracks (last 50)
- Tracks older than ~24 hours may not be available
- Requires active Spotify Premium or Free account
- Rate limits: 10,000 requests per hour per app
Future Enhancements
- Real-time sync via webhooks (if Spotify adds support)
- Playlist integration
- Listening statistics/insights
- Multiple account support