# Spotify Tracker A rock-solid Rust implementation for retrieving the current playing song from Spotify. This replaces the unreliable custom API approach with a direct integration to the official Spotify Web API. ## Features 🎵 **Real-time Track Information** - Current playing track details (song, artist, album) - Playback progress and duration - Playing/paused status - Album artwork URLs 🔄 **Robust & Reliable** - Automatic token refresh - Rate limiting handling with exponential backoff - Comprehensive error handling - Retry logic for failed requests ⚙️ **Flexible Usage** - One-time track lookup - Continuous monitoring mode - Multiple output formats (JSON, plain text, formatted) - Configurable polling intervals 🛠️ **Easy Setup** - Simple CLI interface - Automatic configuration management - Secure token storage 🎮 **PhantomBot Integration** - HTTP server mode for bot integration - Multiple endpoints for different use cases - Compatible with existing bot APIs ## Prerequisites 1. **Spotify Developer Account**: Create one at [developer.spotify.com](https://developer.spotify.com/) 2. **Spotify App**: Create a new app in your Spotify Developer Dashboard 3. **Rust**: Install from [rustup.rs](https://rustup.rs/) ## Installation ```bash git clone cd spotify-tracker cargo build --release ``` ## Quick Start ### 1. Set up Spotify App 1. Go to [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/) 2. Create a new app 3. Note your **Client ID** and **Client Secret** 4. Add `http://localhost:8888/callback` to your app's Redirect URIs ### 2. Authenticate ```bash # Run the authentication setup cargo run -- auth # Or provide credentials directly cargo run -- auth --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET ``` Follow the prompts to complete OAuth2 authentication. ### 3. Get Current Track ```bash # Get current track once cargo run -- current # Monitor continuously (updates every second) cargo run -- monitor # Monitor with custom interval cargo run -- monitor --interval 5 ``` ## Usage ### Commands #### `auth` Set up Spotify authentication ```bash cargo run -- auth --client-id YOUR_ID --client-secret YOUR_SECRET ``` #### `current` Get the currently playing track once ```bash cargo run -- current cargo run -- current --format json ``` #### `monitor` Continuously monitor the current track ```bash cargo run -- monitor --interval 2 ``` #### `config` Show current configuration ```bash cargo run -- config ``` #### `logout` Reset authentication (remove saved tokens) ```bash cargo run -- logout ``` #### `auth-url` Get the authorization URL for manual setup ```bash cargo run -- auth-url ``` #### `server` Start HTTP server for PhantomBot integration ```bash cargo run -- server --port 8888 ``` ### Output Formats #### Formatted (Default) ``` ▶️ Bohemian Rhapsody - Queen (A Night at the Opera) 2:34 / 5:55 ``` #### JSON ```json { "track_name": "Bohemian Rhapsody", "artist_name": "Queen", "album_name": "A Night at the Opera", "is_playing": true, "progress_ms": 154000, "duration_ms": 355000, "external_url": "https://open.spotify.com/track/...", "image_url": "https://i.scdn.co/image/...", "timestamp": "2024-01-15T10:30:00Z" } ``` #### Plain ``` Bohemian Rhapsody - Queen - A Night at the Opera ``` ### CLI Options - `-v, --verbose`: Enable verbose logging - `-i, --interval `: Override polling interval - `-f, --format `: Output format (json, plain, formatted) ## Configuration Configuration is automatically managed in: - **macOS**: `~/Library/Application Support/spotify-tracker/` - **Linux**: `~/.config/spotify-tracker/` - **Windows**: `%APPDATA%\\spotify-tracker\\` Files: - `config.toml`: Application configuration - `token.json`: OAuth2 tokens (automatically managed) ### Example config.toml ```toml [spotify] client_id = "your_client_id" client_secret = "your_client_secret" redirect_uri = "http://localhost:8888/callback" scopes = ["user-read-currently-playing", "user-read-playback-state"] output_format = "formatted" polling_interval = 1 max_retries = 3 ``` ## Error Handling The application handles various error scenarios: - **Token Expiration**: Automatically refreshes using refresh token - **Rate Limiting**: Implements exponential backoff - **Network Issues**: Retry logic with configurable attempts - **API Errors**: Comprehensive error reporting - **No Current Track**: Graceful handling when nothing is playing ## Development ### Project Structure ``` src/ ├── main.rs # CLI application entry point ├── lib.rs # Library exports ├── auth.rs # OAuth2 authentication ├── client.rs # Spotify API client ├── models.rs # Data structures ├── config.rs # Configuration management └── error.rs # Error types ``` ### Running Tests ```bash cargo test ``` ### Building Release Binary ```bash cargo build --release ./target/release/spotify-tracker --help ``` ## Comparison with Previous Implementation | Feature | Old API | New Rust Implementation | |---------|---------|------------------------| | **Reliability** | Unreliable custom API | Direct Spotify Web API | | **Authentication** | Manual code passing | Full OAuth2 flow with refresh | | **Error Handling** | Basic | Comprehensive with retries | | **Rate Limiting** | None | Exponential backoff | | **Token Management** | Manual | Automatic refresh | | **Output Formats** | Limited | JSON, Plain, Formatted | | **Configuration** | None | Persistent config management | | **Monitoring** | Single requests | Continuous monitoring mode | ## PhantomBot Integration Perfect for streamers using PhantomBot! The server mode provides HTTP endpoints that your bot can call. ### Starting the Server ```bash # Start server on default port (8888) cargo run -- server # Start on custom port cargo run -- server --port 9000 ``` ### Available Endpoints #### `/current` - JSON Response ```json { "playing": true, "track": "Bohemian Rhapsody", "artist": "Queen", "album": "A Night at the Opera", "url": "https://open.spotify.com/track/...", "image": "https://i.scdn.co/image/...", "progress_ms": 154000, "duration_ms": 355000, "is_playing": true, "timestamp": "2024-01-15T10:30:00Z" } ``` #### `/phantombot` - Plain Text Response ``` 🎵 Bohemian Rhapsody - Queen (A Night at the Opera) ``` #### `/health` - Health Check ```json { "status": "healthy", "service": "spotify-tracker", "timestamp": "2024-01-15T10:30:00Z" } ``` ### PhantomBot Usage Replace your existing custom API call: ```javascript // Old unreliable API // https://pizzabot.t1nc4n.tech/sptf-cur-track?code=... // New rock-solid API http://localhost:8888/phantombot ``` ### Example PhantomBot Commands ```javascript // In your PhantomBot command $.customAPI.get("http://localhost:8888/phantombot").content ``` For JSON data: ```javascript var response = JSON.parse($.customAPI.get("http://localhost:8888/current").content); if (response.playing) { $.say("Now playing: " + response.track + " by " + response.artist); } else { $.say("No music currently playing"); } ``` ## Troubleshooting ### Authentication Issues ```bash # Clear saved tokens and re-authenticate cargo run -- logout cargo run -- auth ``` ### Rate Limiting The application automatically handles rate limiting, but you can increase polling interval: ```bash cargo run -- monitor --interval 5 # Poll every 5 seconds instead of 1 ``` ### Verbose Logging ```bash cargo run -- current --verbose ``` ## License [Add your license here] ## Contributing [Add contribution guidelines here]