Powershell – Spotify API
To get the a Spotify Token you must create create an App to authorize and get an access token. You can do this on:
https://developer.spotify.com/dashboard/applications
As redirect URI you can enter: http://localhost
This example Powershell Function will return the access token. Also this script checks if there was already an access token (C:\Misc\SpotifyRefreshToken.txt) present and if it will return you a new valid refresh token that will be writen to the SpotifyRefreshToken.txt. This is needed if you don’t run the script on a regulary time (e.g. 60 min). In this case you read the last token and you will get a new refresh token.
Note: On first run you must copy the provided URL to an browser and login with your Spotify credentials. After the login you will get an empty page, but in the URL bar you will find your access token. This token you must copy and enter in the Powershell script prompt.
Function Get-SpotifyToken {
$RefreshTokenPath = "C:\Misc\SpotifyRefreshToken.txt"
$RefreshToken = Get-Content $RefreshTokenPath -ErrorAction SilentlyContinue
Set-Variable -Name SpotifyRefreshToken -Value $RefreshToken -Scope Global
# Application IDs
$ClientId = "Your Client ID"
$ClientSecret = "Your App Secret"
# Encode to Base64
$ClientIdBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($ClientId))
# I'dont know why but this works ;-)
$ClientIdBase64 = $ClientIdBase64.replace("=","6")
$ClientSecretBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($ClientSecret))
$ClientAppBase64 = $ClientIdBase64 + $ClientSecretBase64
# Header/Body (Read Only)
$HeaderGetToken = @{'Authorization' = 'Basic ' + $ClientAppBase64}
# If a Refresh Token is saved get new access token
$Result = Invoke-RestMethod -Uri "https://accounts.spotify.com/api/token" -Method POST -Headers $HeaderGetToken -Body @{grant_type="refresh_token";refresh_token="$SpotifyRefreshToken"} -ErrorAction SilentlyContinue
If ($Result)
{
Set-Variable -Name SpotifyAccessToken -Value $Result.access_token -Scope Global
Set-Variable -Name SpotifyAccessTokenDateExpires -Value (Get-Date).AddSeconds(3540) -Scope Global
}
if (-Not $SpotifyAccessToken) {
$URLAuthenticate = "https://accounts.spotify.com/en/authorize"
$ResponseType = "code"
$RedirectURI = "http://localhost"
# Scope - App Permissions
$Scope = "playlist-modify-private playlist-modify-public"
$URI = $URLAuthenticate + "?client_id=" + $ClientId + "&response_type=" + $ResponseType + "&redirect_uri=" + $RedirectURI + "&scope=" + $Scope
Write-Host ""
Write-Host $URI -ForegroundColor Yellow
Write-Host ""
$CodeUser = Read-Host "Please enter the URL in a Browser and copy the code from the url bar here"
$Body = @{'grant_type' = "authorization_code"; 'code' = $CodeUser; 'redirect_uri' = "http://localhost"}
$Result = Invoke-RestMethod -Uri "https://accounts.spotify.com/api/token" -Method POST -Headers $HeaderGetToken -Body $Body
Set-Variable -Name SpotifyAccessToken -Value $Result.access_token -Scope Global
Set-Variable -Name SpotifyRefreshToken -Value $Result.refresh_token -Scope Global
Set-Content -Path $RefreshTokenPath -Value $SpotifyRefreshToken -Force
Set-Variable -Name SpotifyAccessTokenDateExpires -Value (Get-Date).AddSeconds(3540) -Scope Global
}
If ((Get-Date) -gt $SpotifyAccessTokenDateExpires)
{
$Result = Invoke-RestMethod -Uri "https://accounts.spotify.com/api/token" -Method POST -Headers $HeaderGetToken -Body @{grant_type="refresh_token";refresh_token="$SpotifyRefreshToken"}
If ($Result)
{
Set-Variable -Name SpotifyAccessToken -Value $Result.access_token -Scope Global
Set-Variable -Name SpotifyAccessTokenDateExpires -Value (Get-Date).AddSeconds(3540) -Scope Global
}
}
return $SpotifyAccessToken
}
Now it’s time for an example what you can do. First of all save the above script to some locatain. E.g. C:\SpotifyAPI\Get-SpotifyToken.ps1
As you can see we import the Get-SpotifyToken.ps1 so we can call the function Get-SpotifyToken.
At the bottom you see the Function Script. Lets call it Get-Spotify-Functions.ps1 This is also an Module that you can import in the final script.
# Load the Spotify API Function
. C:\SpotifyAPI\Get-SpotifyToken.ps1
# Start the function to get a access token (The access token will be set in the current Powershell Console as a global variable -> See: Get-SpotifyToken.ps1)
Get-SpotifyToken
$Header = @{'Authorization' = 'Bearer ' + $SpotifyAccessToken}
# Create a new Spotify Playlist
function New-Spotify-Playlist() {
Param(
[string]$Name,
[switch]$Public
)
# Create Playlist
if ($Public) {
$Body = @{'name' = $Name; 'public' = 'true' }
} else {
$Body = @{'name' = $Name; 'public' = 'false' }
}
try {
$Playlist = Invoke-RestMethod -Uri "https://api.spotify.com/v1/users/benedikt.winder/playlists" -Method Post -Headers $Header -Body ($Body | ConvertTo-JSON)
}
catch {
$LogError = $_.Exception.Message
}
$PlaylistID = $Playlist.id
return $PlaylistID
}
# Search the Spotify Library
function Search-Spotify-Library() {
Param(
[string]$Artist,
[string]$Title
)
# Create Search Filter
[uri]$URI = "https://api.spotify.com/v1/search?q=artist:"+$Artist+"+track:"+$Title+"&type=track&limit=1"
$Tracks = Invoke-RestMethod -Uri $URI -Method Get -Headers $Header
# Get First Track
try {
[array]$TrackID = $Tracks.tracks.items.uri
}
catch {
$LogError = $_.Exception.Message
}
return $TrackID
}
# Add a track to a playlist.
function Add-Spotify-Track {
param (
[array]$TrackID,
[string]$PlaylistID
)
[uri]$URI = "https://api.spotify.com/v1/playlists/"+$PlaylistID+"/tracks"
$Body = @{'uris' = $TrackID}
try {
Invoke-RestMethod -Uri $URI -Method Post -Headers $Header -Body ($Body | ConvertTo-JSON)
}
catch {
$LogError = $_.Exception.Message
}
}
And now the final script.
# Load Functions
. C:\SpotifyAPI\Get-SpotifyToken.ps1
. C:\SpotifyAPI\Get-Spotify-Functions.ps1
# Create a new playlist
$PlaylistName = "Some cool playlist"
$PlaylistID = New-Spotify-Playlist -Name $PlaylistName -Public
# Search for a song / artist and the TrackID
$Atrist = "Machine Head"
$Track = "Locust"
[array]$TrackID = Search-Spotify-Library -Artist $Artist -Title $Title
# If an TrackID is returnen add it to a playlist / For multiple results you must create a foreach loop
if ($TrackID) {
Add-Spotify-Track -TrackID $TrackID -PlaylistID $PlaylistID
}
1 Comment
Mike · September 2, 2021 at 14:31
Hi!
Should this
# Encode to Base64
$ClientIdBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($ClientId))
# I’dont know why but this works 😉
$ClientIdBase64 = $ClientIdBase64.replace(“=”,”6″)
$ClientSecretBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($ClientSecret))
$ClientAppBase64 = $ClientIdBase64 + $ClientSecretBase64
… not rather be this?
# Encode to Base64
$ClientAppBase64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($ClientId + “:” + $ClientSecret))
Works fine in my tests.
Cheers,
Mike