Spotify-tracker/README.md
RTSDA bcfa2ba1c2 Initial Spotify Tracker with PhantomBot integration
- Rock-solid Rust implementation replacing unreliable custom API
- OAuth2 authentication with automatic token refresh
- HTTP server with multiple endpoints (/current, /phantombot, /health)
- Comprehensive error handling and retry logic
- PhantomBot integration examples and documentation
- CLI tool with monitoring and configuration management
2025-08-18 17:56:58 -04:00

7.5 KiB

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
  2. Spotify App: Create a new app in your Spotify Developer Dashboard
  3. Rust: Install from rustup.rs

Installation

git clone <repository-url>
cd spotify-tracker
cargo build --release

Quick Start

1. Set up Spotify App

  1. Go to Spotify Developer 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

# 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

# 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

cargo run -- auth --client-id YOUR_ID --client-secret YOUR_SECRET

current

Get the currently playing track once

cargo run -- current
cargo run -- current --format json

monitor

Continuously monitor the current track

cargo run -- monitor --interval 2

config

Show current configuration

cargo run -- config

logout

Reset authentication (remove saved tokens)

cargo run -- logout

auth-url

Get the authorization URL for manual setup

cargo run -- auth-url

server

Start HTTP server for PhantomBot integration

cargo run -- server --port 8888

Output Formats

Formatted (Default)

▶️ Bohemian Rhapsody - Queen (A Night at the Opera)
   2:34 / 5:55

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 <SECONDS>: Override polling interval
  • -f, --format <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

[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

cargo test

Building Release Binary

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

# Start server on default port (8888)
cargo run -- server

# Start on custom port
cargo run -- server --port 9000

Available Endpoints

/current - JSON Response

{
  "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

{
  "status": "healthy",
  "service": "spotify-tracker",
  "timestamp": "2024-01-15T10:30:00Z"
}

PhantomBot Usage

Replace your existing custom API call:

// Old unreliable API
// https://pizzabot.t1nc4n.tech/sptf-cur-track?code=...

// New rock-solid API
http://localhost:8888/phantombot

Example PhantomBot Commands

// In your PhantomBot command
$.customAPI.get("http://localhost:8888/phantombot").content

For JSON data:

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

# 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:

cargo run -- monitor --interval 5  # Poll every 5 seconds instead of 1

Verbose Logging

cargo run -- current --verbose

License

[Add your license here]

Contributing

[Add contribution guidelines here]