Hipster cred! I have it, you want it. No way to build it up faster than to be into something before it becomes popular. You may have been wondering how you might be able to pull a random list of fifteen infrequently listened to bands and document the fact that you knew of them before it became all about the money. Well lucky for you PowerShell has what you need.
Note: if you see a band in this list and object to their placement, you are functioning at a higher hipster level than this blog accounts for and can add that feather to your fedora.
Setting up the Spotify API
Before this script will be able to run at all we will need to set up an API (Application Program Interface) using this link. This will give us the client ID and let us set a redirect URI (Uniform Resource Identifier) for after we authenticate. Seen below is what this screen looks like after I use cutting edge blurring technology to hide my actual IDs.
With this created, you can now generate an access request. The request has to contain the following:
Client ID: Identification number generated by Spotify
Redirect URI: URI that the browser will go to after you authenticate.
Response Type: How you want the Spotify servers to respond to the request
Scope: Permissions you are requesting
Opening your Spotify hipster playlist
Here is how our URI request looks. $clientID should be replaced with your client ID after you register your application with Spotify
$clientid = <Your Client ID Here> $AuthUri = "https://accounts.spotify.com/en/authorize?" + "client_id=$clientid" + #Put the client ID from your web application here here "&redirect_uri=//www.pdq.com/aa/img/jonathan-lindgren-hipster-220x247-lossy30.gif" + #Thanks to Jonathan Lindgren (www.jonathanlindgren.com) for use of that awesome gif "&scope=playlist-modify-public playlist-modify-private playlist-read-private playlist-read-collaborative" + "&response_type=token"
If you copy the above URL into a web browser it will respond with your access token inside the address bar. We could manually copy that over like we are animals, or we can use PowerShell to build our own browser on the fly that will have the token we need in an object. Let’s check in with Kris for a product demo to see how he might perform such a task.
Add-Type -AssemblyName System.Windows.Forms $FormProperties = @{ Size = New-Object System.Drawing.Size(850, 675) StartPosition = "CenterScreen" } $Form = New-Object System.Windows.Forms.Form -Property $FormProperties $BrowserProperties = @{ Dock = "Fill" } $Browser = New-Object System.Windows.Forms.WebBrowser -Property $BrowserProperties $Form.Controls.Add($Browser) $Browser.Navigate($AuthUri) $Form.Add_Shown({$Form.Activate()}) $Form.ShowDialog()
Compelling stuff Kris, thanks for stopping by.
Running this will bring you to a login screen for Spotify. Once your credentials are in it will take you to some fantastic artwork by Jonathan Lindgren.
Feel free to bask in its glory, but to move forward with the script you will eventually have to close this browser.
Once you close that browser, your access token will be in $Browser.Url.Fragment. It will take a little work to clean up that data to make it usable. First, you need to use regular expressions to strip everything but the token value. Then, you need to specify the token type and create a header variable.
If ($Browser.url.Fragment -match "access_token=(.*)&token") {$AccessToken = $Matches[1]} $BearerToken = "Bearer $AccessToken" $HeaderValue = @{Authorization = $BearerToken}
That is it. Just use different variations of that command and it will let you grab your account, build a playlist, grab every genre, and get the three least listened to bands for each one.
Now that we have all the steps lets take a look at the completed script.
### Create uri for generating access request ### $AuthUri = "https://accounts.spotify.com/en/authorize?" + "client_id=$clientid" + #Put the client ID from your web application here here "&redirect_uri=//www.pdq.com/aa/img/jonathan-lindgren-hipster-220x247-lossy30.gif" + #Thanks to Jonathan Lindgren (www.jonathanlindgren.com) for use of that awesome gif "&scope=playlist-modify-public playlist-modify-private playlist-read-private playlist-read-collaborative" + "&response_type=token"
### Build Browser and request authentication ### Add-Type -AssemblyName System.Windows.Forms $FormProperties = @{ Size = New-Object System.Drawing.Size(850, 675) StartPosition = "CenterScreen" } $Form = New-Object System.Windows.Forms.Form -Property $FormProperties $BrowserProperties = @{ Dock = "Fill" } $Browser = New-Object System.Windows.Forms.WebBrowser -Property $BrowserProperties $Form.Controls.Add($Browser) $Browser.Navigate($AuthUri) $Form.Add_Shown({$Form.Activate()}) $Form.ShowDialog()
### Create access token variable and grab your user account information ### If ($Browser.url.Fragment -match "access_token=(.*)&token") {$AccessToken = $Matches[1]} $UserUri = "https://api.spotify.com/v1/me" $BearerToken = "Bearer $AccessToken" $HeaderValue = @{Authorization = $BearerToken} $UserAccount = (Invoke-RestMethod -Uri $UserUri -Method Get -ContentType application\json -Headers $HeaderValue).href
### Build Playlist and get ID ### $PlaylistUri = $UserAccount + "/playlists" $NewPlaylist = @{ name = "Before they are Popular" public = "true" } | ConvertTo-Json $PlaylistID = Invoke-RestMethod -Uri $PlaylistUri -Method Post -ContentType application/json -Headers $HeaderValue -Body $NewplayList
### Grab all genres seeds and select 5 random ones that have more than 10 bands associated with it #### $GenreSeedUri = "https://api.spotify.com/v1/recommendations/available-genre-seeds" $Genres = Invoke-RestMethod -Uri $GenreSeedUri -Headers $HeaderValue | Select-Object -ExpandProperty genres $GenreList = @() foreach($Genre in $Genres){ $GenreUri = "https://api.spotify.com/v1/search?q=genre:$Genre&type=artist&limit=5&market=us" $BandCount = (Invoke-RestMethod -Uri $GenreUri -ContentType Application/json -Headers $HeaderValue).artists.total if($BandCount -gt 10){ $GenreList += $Genre } Write-Output "Generating list for: $Genre" Start-Sleep -Milliseconds 100 } $FinalList = Get-Random -InputObject $GenreList -Count 5
### Grab 3 least popular band per genre ### $Bands = @() foreach($Item in $FinalList){ $BandUri = "https://api.spotify.com/v1/search?q=genre:$($Item)&type=artist&type=artist&limit=5&market=us" $BandCount = [System.Math]::Round(((Invoke-RestMethod -Uri $BandUri -ContentType Application/json).artists.total - 3), 0) $OffsetUri = "https://api.spotify.com/v1/search?q=genre:$($Item)&type=artist&offset=$($BandCount)&limit=3&market=us" $LastThreeBands = (Invoke-RestMethod -Uri $OffsetUri -ContentType Application/json).artists.items | Select-Object name, id $Bands += $LastThreeBands }
### Add top track from bands to playlist ### Foreach($Band in $Bands){ $TopTrackUri = "https://api.spotify.com/v1/artists/$($Band.id)/top-tracks?country=us" $TopTrack = (Invoke-RestMethod -Uri $TopTrackUri -ContentType Application/json).tracks | Select-Object uri if($TopTrack -ne $null){ $CombinedTopTrack = $TopTrack.uri -join ',' $AddTrackUri = $UserAccount + "/playlists/" + $PlaylistID.id + "/tracks?position=0&uris=$CombinedTopTrack" Invoke-RestMethod -Uri $AddTrackUri -Method Post -ContentType application/json -Headers $HeaderValue } }
### List the 5 Genres used ### Write-Host "You have created a playlist from the following genres: $FinalList"
Final note, should you want to do something useful with these commands the format would be the same. Just know that I used these commands before they were cool.
Discover the many uses of PowerShell (such as tracking 401K growth and securing passwords) in PDQ's blog.