Public/Add-SpotifyPlaylistTracks.ps1
|
<# .SYNOPSIS Adds tracks to a Spotify playlist .DESCRIPTION Adds one or more tracks to an existing Spotify playlist. Accepts SpotifyTrack objects via -Tracks (or the pipeline) and prints "Artist - Title successfully added" for each track. Also accepts raw Spotify URIs via -TrackUris when track metadata is not needed. Batches requests automatically (Spotify allows max 100 URIs per call). .PARAMETER PlaylistId The Spotify playlist ID (e.g. the 'id' from New-SpotifyPlaylist output). .PARAMETER Tracks One or more SpotifyTrack objects as returned by Search-SpotifyTrack, Get-SpotifyTracks, or Get-SpotifyPlaylists. Accepts pipeline input. .PARAMETER TrackUris One or more Spotify track URIs in the format spotify:track:<id>. .PARAMETER ClientId Optional. The ClientId of the app you registered in the Spotify developer portal. .PARAMETER RedirectURI Optional. The redirect URI used for OAuth authentication. .PARAMETER ConfigFile Optional. The path to a JSON configuration file containing 'ClientId' and 'RedirectURI' properties. .EXAMPLE $track = Search-SpotifyTrack -Artist "Radiohead" -Title "Creep" Add-SpotifyPlaylistTracks -PlaylistId "3cEYpjA9oz9GiPac4AsH4n" -Tracks $track .EXAMPLE $songs | Add-SpotifyPlaylistTracks -PlaylistId "3cEYpjA9oz9GiPac4AsH4n" .EXAMPLE Add-SpotifyPlaylistTracks -PlaylistId "3cEYpjA9oz9GiPac4AsH4n" -TrackUris "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" #> function Add-SpotifyPlaylistTracks { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string] $PlaylistId, [Parameter(Mandatory=$false, ValueFromPipeline=$true)] [object[]] $Tracks, [Parameter(Mandatory=$false)] [string[]] $TrackUris, [Parameter(Mandatory=$false)] [string] $ClientId, [Parameter(Mandatory=$false)] [string] $RedirectURI, [ValidateScript({Test-Path $_})] [Parameter(Mandatory=$false)] [string] $ConfigFile ) begin { Set-StrictMode -Version 1.0 $ErrorActionPreference = 'Stop' $collectedTracks = [System.Collections.ArrayList]::new() } process { if ($Tracks) { foreach ($t in $Tracks) { $collectedTracks.Add($t) | Out-Null } } } end { $uris = [System.Collections.ArrayList]::new() $labels = [System.Collections.ArrayList]::new() foreach ($t in $collectedTracks) { $uris.Add($t.uri) | Out-Null $labels.Add("$($t.artists[0]) - $($t.name)") | Out-Null } if ($PSBoundParameters.ContainsKey('TrackUris')) { $uris.AddRange($TrackUris) } if ($uris.Count -eq 0) { throw "Either 'Tracks' or 'TrackUris' is required" } $TokenParams = @{ Scopes = @('playlist-modify-public', 'playlist-modify-private') } foreach ($param in @('ClientId', 'RedirectURI', 'ConfigFile')) { if ($PSBoundParameters.ContainsKey($param)) { $TokenParams.Add($param, $PSBoundParameters[$param]) } } $token = Get-SpotifyToken @TokenParams $headers = @{ Authorization = "Bearer $token" } for ($i = 0; $i -lt $uris.Count; $i += 100) { [System.Threading.Thread]::Sleep($script:API_DELAY) $chunk = [array] $uris[$i .. [math]::Min($i + 99, $uris.Count - 1)] $body = @{ uris = $chunk } | ConvertTo-Json Invoke-SpotifyRequest ` -Uri "$script:BASE_URI/playlists/$PlaylistId/items" ` -Method Post ` -ContentType 'application/json' ` -Body $body ` -Headers $headers | Out-Null } if ($labels.Count -gt 0) { foreach ($label in $labels) { Write-Host "${script:GREEN}${label} successfully added${script:RESETANSI}" } } else { Write-Host "${script:GREEN}Successfully added $($uris.Count) track(s) to playlist${script:RESETANSI}" } } } |