104 lines
3.3 KiB
Markdown
104 lines
3.3 KiB
Markdown
# Spotify
|
|
|
|
The Spotify skill adds a local helper for Spotify Web API playlist work from OpenClaw.
|
|
|
|
## Scope
|
|
|
|
- search Spotify tracks
|
|
- list the current user's playlists
|
|
- create private or public playlists
|
|
- add and remove track URIs
|
|
- search and add tracks
|
|
- import tracks from text lists, M3U/M3U8 playlists, and local folders
|
|
|
|
The skill uses OAuth2 Authorization Code with PKCE. It does not need a Spotify client secret and does not use browser automation for Spotify operations.
|
|
|
|
## Setup
|
|
|
|
Create the local credential directory:
|
|
|
|
```bash
|
|
mkdir -p ~/.openclaw/workspace/.clawdbot/credentials/spotify
|
|
chmod 700 ~/.openclaw/workspace/.clawdbot/credentials/spotify
|
|
$EDITOR ~/.openclaw/workspace/.clawdbot/credentials/spotify/config.json
|
|
```
|
|
|
|
Example `config.json`:
|
|
|
|
```json
|
|
{
|
|
"clientId": "your-spotify-client-id",
|
|
"redirectUri": "http://127.0.0.1:8888/callback"
|
|
}
|
|
```
|
|
|
|
Run auth from the active OpenClaw skill copy:
|
|
|
|
```bash
|
|
cd ~/.openclaw/workspace/skills/spotify
|
|
scripts/setup.sh
|
|
```
|
|
|
|
Or run only the OAuth login after dependencies are installed:
|
|
|
|
```bash
|
|
scripts/spotify auth
|
|
scripts/spotify status --json
|
|
```
|
|
|
|
Tokens are written to the local credentials directory as `token.json` with owner-only file mode when the filesystem supports it. Do not print token files.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
scripts/spotify status --json
|
|
scripts/spotify search "Radiohead Karma Police" --limit 3 --json
|
|
scripts/spotify list-playlists --limit 10 --json
|
|
scripts/spotify create-playlist "OpenClaw Mix" --description "Created by OpenClaw" --json
|
|
scripts/spotify add-to-playlist "<playlistId>" "spotify:track:..." --json
|
|
scripts/spotify remove-from-playlist "<playlistId>" "spotify:track:..." --json
|
|
scripts/spotify search-and-add "<playlistId>" "Radiohead Karma Police" --json
|
|
scripts/spotify import "/path/to/tracks.txt" --playlist "Imported Mix" --json
|
|
scripts/spotify import "/path/to/playlist.m3u8" --playlist-id "<playlistId>" --json
|
|
scripts/spotify import "/path/to/music-folder" --playlist "Folder Import" --json
|
|
```
|
|
|
|
`--playlist NAME` always creates a new playlist, private by default unless `--public` is provided. Spotify allows duplicate playlist names, so use `--playlist-id ID` when updating an existing playlist.
|
|
|
|
## Import Behavior
|
|
|
|
Text imports ignore blank lines and comment lines starting with `#` or `//`.
|
|
|
|
M3U/M3U8 imports use `#EXTINF` metadata when present and fall back to the filename otherwise.
|
|
|
|
Folder imports recursively scan supported audio filenames and ignore non-audio files.
|
|
|
|
The importer searches Spotify once per parsed candidate, adds the first match, reports misses, and skips duplicate Spotify URI matches.
|
|
|
|
## Endpoint Notes
|
|
|
|
This skill uses the current Spotify playlist endpoints:
|
|
|
|
```text
|
|
GET /v1/me
|
|
GET /v1/search?type=track&q=<query>&limit=<1-10>
|
|
GET /v1/me/playlists?limit=<n>&offset=<n>
|
|
POST /v1/me/playlists
|
|
POST /v1/playlists/{id}/items
|
|
DELETE /v1/playlists/{id}/items
|
|
POST https://accounts.spotify.com/api/token
|
|
```
|
|
|
|
Do not use the removed 2026 endpoints:
|
|
|
|
```text
|
|
POST /v1/users/{user_id}/playlists
|
|
GET /v1/users/{id}/playlists
|
|
POST /v1/playlists/{id}/tracks
|
|
DELETE /v1/playlists/{id}/tracks
|
|
```
|
|
|
|
## Live Smoke Caution
|
|
|
|
Spotify does not offer a normal delete-playlist Web API operation. Any live smoke that creates a playlist must be explicitly approved because the playlist can only be manually cleaned up later.
|