
- 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
339 lines
7.5 KiB
Markdown
339 lines
7.5 KiB
Markdown
# 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 <repository-url>
|
|
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 <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
|
|
```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] |