Limerio/spotify-backup

โ˜… 0Forks 0TypeScriptGitHub โ†—Compare

README

Spotify Backup

A TypeScript application using Effect-TS to backup your Spotify playlists and tracks to the local filesystem. Features secure OAuth 2.0 authentication with PKCE (Proof Key for Code Exchange).

Features

  • ๐Ÿ” Secure OAuth 2.0 authentication with PKCE flow
  • ๐ŸŽต Fetches all user playlists from Spotify
  • ๐Ÿ“ฅ Downloads all tracks from each playlist
  • ๐Ÿ’พ Saves playlists as folders and tracks as JSON files
  • ๐Ÿ“„ Automatic pagination handling
  • ๐Ÿ›ก๏ธ Robust error handling with typed errors
  • โฑ๏ธ Rate limit handling with exponential backoff retries
  • ๐ŸŒ Automatic browser-based authorization

Prerequisites

  • Bun runtime
  • Spotify account
  • Spotify Developer application

Installation

bun install

Setup

1. Create a Spotify Application

  1. Go to Spotify Developer Dashboard
  2. Click "Create app"
  3. Fill in the application details:
    • App name: Choose any name (e.g., "Spotify Backup")
    • App description: Optional
    • Redirect URI: http://localhost:4202/callback
  4. Check the "Web API" option
  5. Click "Save"
  6. Copy your Client ID from the application settings

2. Run the Application

Set your Spotify Client ID as an environment variable and run:

export SPOTIFY_CLIENT_ID="your_client_id_here"
bun run start

Or run directly:

SPOTIFY_CLIENT_ID="your_client_id_here" bun run src/index.ts

The application will:

  1. Start a local server on port 4202
  2. Open your default browser for Spotify authorization
  3. Prompt you to log in and grant permissions
  4. Automatically begin backing up your playlists after authorization

Output Structure

The backup creates the following structure in your current directory:

playlists/
โ”œโ”€โ”€ Playlist Name 1/
โ”‚   โ”œโ”€โ”€ _playlist.json          # Playlist metadata
โ”‚   โ”œโ”€โ”€ Track Name_trackId.json # Track details
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€โ”€ Playlist Name 2/
โ”‚   โ”œโ”€โ”€ _playlist.json
โ”‚   โ””โ”€โ”€ ...
โ””โ”€โ”€ ...

Playlist Metadata (_playlist.json)

Contains playlist information including:

  • ID, name, description, URI
  • Owner details (ID, display name)
  • Public/collaborative status
  • Snapshot ID and total tracks count
  • Images and external URLs

Track Files ({track_name}_{track_id}.json)

Contains comprehensive track information including:

  • Track details: ID, name, URI, duration, popularity
  • Flags: explicit content, local file status
  • Track numbers: disc number, track number
  • Album information:
    • ID, name, album type
    • Release date, total tracks
    • Album artists and images
  • Artists: ID, name, URI for all track artists
  • Metadata:
    • Added date (added_at)
    • Who added the track (added_by)
    • Preview URL (if available)
    • External URLs and IDs (ISRC, etc.)

How It Works

OAuth 2.0 with PKCE Flow

The application implements the secure OAuth 2.0 Authorization Code flow with PKCE:

  1. Generates a random code verifier and challenge
  2. Starts a local HTTP server to receive the OAuth callback
  3. Opens Spotify's authorization page in your browser
  4. After you authorize, Spotify redirects to localhost:4202/callback
  5. Exchanges the authorization code for an access token
  6. Begins backing up your playlists

Data Fetching

  • Uses Effect-TS for functional, composable data pipelines
  • Automatically handles pagination for large playlists
  • Implements exponential backoff retry for rate limits
  • Supports up to 50 playlists per page and 100 tracks per page

Required Scopes

The application requests the following Spotify API scopes:

  • playlist-read-private - Read private playlists
  • playlist-read-collaborative - Read collaborative playlists

Development

Type check:

bun run typecheck

Tech Stack

Error Handling

The application includes comprehensive typed error handling:

  • SpotifyAuthError - Authentication failures (401/403)
  • SpotifyRateLimitError - Rate limit exceeded (429) with automatic retry
  • SpotifyNotFoundError - Resource not found (404)
  • SpotifyDecodeError - Invalid API response format
  • SpotifyNetworkError - Network connectivity issues
  • OAuthError - OAuth flow errors

Contributors

Limerio

Issues