# QTransfer Spotify -> Qobuz playlist transfer tool in Go. ## Features - Spotify OAuth login via Authorization Code + PKCE (client secret not required). - Manual Spotify callback code entry (paste callback URL/code) enabled by default. - Session cache for Spotify/Qobuz credentials and tokens (so you do not need to re-enter each run). - Fetches all Spotify playlists and liked songs. - Playlist URL mode (`--playlist-url`) for direct targeted transfers. - Monitor mode to detect playlist updates (`--monitor`) with optional auto-transfer (`--monitor-transfer`). - Interactive selection prompt (or non-interactive flags). - Creates Qobuz playlists and fills them with best-effort track matches. - Transfers liked songs into a dedicated playlist (not favorites). - Writes a JSON transfer report with unmatched tracks and errors. ## Requirements - Go 1.22+ - Spotify app client ID with redirect URI configured (default: `http://127.0.0.1:8888/callback`) - Qobuz account username/password ## Build ```bash go build ./cmd/qtransfer ``` ## Usage ```bash ./qtransfer login ``` `qtransfer login` runs an interactive setup and stores Spotify/Qobuz credentials/tokens in the session file. After login, run transfers without re-entering credentials: ```bash ./qtransfer ``` For first-time non-interactive usage (without `login`), you can still pass flags: ```bash ./qtransfer \ --spotify-client-id "" \ --qobuz-username "" \ --qobuz-password "" ``` Credentials/tokens are cached in `~/.config/qtransfer/session.json` by default. ### Useful flags - `--all`: transfer all Spotify playlists - `--liked`: include liked songs as a generated Qobuz playlist - `--playlist "Name"` (repeatable): transfer specific playlists by exact name - `--playlist-url "..."` (repeatable): transfer specific Spotify playlists by URL/URI/ID - `--spotify-manual-code=true|false`: paste callback URL/code manually or use local callback server - `--remember-creds=true|false`: persist/reuse tokens and credentials in session file - `--session-file path`: custom session file path (default `~/.config/qtransfer/session.json`) - `--monitor`: monitor selected playlists for updates - `--monitor-interval 5m`: monitor polling interval - `--monitor-once`: run one monitor check and exit - `--monitor-transfer`: in monitor mode, transfer only changed playlists - `--qobuz-self-test`: run Qobuz login/verify/search checks and exit (skips Spotify) - `--qobuz-self-test-write`: when self-test is enabled, also create a test playlist and add one track - `--qobuz-self-test-query "..."`: search query used during self-test - `--non-interactive`: fail instead of prompting when no explicit selection is given - `--dry-run`: resolve matches only, do not create playlists or add tracks - `--report transfer-report.json`: report output path - `--public-playlists`: create public Qobuz playlists Quick auth check without waiting for Spotify: ```bash ./qtransfer \ --qobuz-self-test \ --qobuz-username "" \ --qobuz-password "" ``` Transfer from direct Spotify playlist URLs: ```bash ./qtransfer \ --spotify-client-id "" \ --qobuz-username "" \ --qobuz-password "" \ --playlist-url "https://open.spotify.com/playlist/37i9dQZF1DX0XUsuxWHRQd" \ --playlist-url "spotify:playlist:37i9dQZF1DWY4xHQp97fN6" ``` Monitor selected playlists for changes: ```bash ./qtransfer \ --spotify-client-id "" \ --playlist-url "https://open.spotify.com/playlist/37i9dQZF1DX0XUsuxWHRQd" \ --monitor --monitor-interval 2m ``` Login command: ```bash ./qtransfer login ``` Logout command (removes cached session): ```bash ./qtransfer logout ``` ### Environment variables - `SPOTIFY_CLIENT_ID` - `SPOTIFY_REDIRECT_URI` (optional) - `SPOTIFY_SCOPES` (optional) - `QTRANSFER_SPOTIFY_MANUAL_CODE` (optional, defaults to true) - `QTRANSFER_SESSION_FILE` (optional) - `QTRANSFER_REMEMBER_CREDS` (optional, defaults to true) - `QTRANSFER_MONITOR` (optional) - `QTRANSFER_MONITOR_ONCE` (optional) - `QTRANSFER_MONITOR_TRANSFER` (optional) - `QTRANSFER_MONITOR_INTERVAL` (optional) - `QTRANSFER_QOBUZ_SELF_TEST` (optional) - `QTRANSFER_QOBUZ_SELF_TEST_WRITE` (optional) - `QTRANSFER_QOBUZ_SELF_TEST_QUERY` (optional) - `QOBUZ_USERNAME` - `QOBUZ_PASSWORD` - `QOBUZ_APP_ID` (optional, defaults to reverse-engineered app id) - `QOBUZ_APP_SECRET` (optional, defaults to reverse-engineered app secret)