Last active
June 12, 2024 13:33
-
-
Save coreequip/d4862da50efe3d848c513f231db357d4 to your computer and use it in GitHub Desktop.
Google Apps Script - Energy Hamburg - Last 14 days playlist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const CACHE_TOKEN = 'NRJ14D_TOKEN' | |
const SPOTIFY_CLIENT_ID = PropertiesService.getScriptProperties().getProperty('CLIENT_ID') | |
const SPOTIFY_CLIENT_SECRET = PropertiesService.getScriptProperties().getProperty('CLIENT_SECRET') | |
const REFRESH_TOKEN = PropertiesService.getScriptProperties().getProperty('REFRESH_TOKEN') | |
const PLAYLIST_ID = PropertiesService.getScriptProperties().getProperty('PLAYLIST_ID') | |
const ENERGY_HAMBURG_API_URL = 'https://api.nrjnet.de/webradio/playlist/energy/hamburg?day=0&hour=-1'; | |
// fetch a new Spotify access token | |
function getSpotifyAccessToken() { | |
let token = CacheService.getScriptCache().get(CACHE_TOKEN); | |
if (!token) { | |
const res = JSON.parse(UrlFetchApp.fetch('https://accounts.spotify.com/api/token', { | |
method: 'post', | |
contentType: 'application/x-www-form-urlencoded', | |
headers: {'Authorization': 'Basic ' + Utilities.base64Encode(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`)}, | |
payload: { | |
'grant_type': 'refresh_token', | |
'refresh_token': REFRESH_TOKEN | |
} | |
}).getContentText()); | |
token = res.access_token | |
CacheService.getScriptCache().put(CACHE_TOKEN, token, 3500) | |
Logger.log('Fresh token fetched.') | |
} | |
return token | |
} | |
// search for a track on Spotify | |
function searchSpotifyTrack(artist, title) { | |
const query = encodeURIComponent(`${artist} ${title}`); | |
const searchUrl = `https://api.spotify.com/v1/search?q=${query}&type=track&limit=1`; | |
const response = UrlFetchApp.fetch(searchUrl, { | |
method: 'get', | |
headers: { | |
'Authorization': 'Bearer ' + getSpotifyAccessToken() | |
} | |
}); | |
const data = JSON.parse(response.getContentText()); | |
const tracks = data.tracks.items; | |
return tracks.length > 0 ? tracks[0].id : null; | |
} | |
// check if a track is already in the playlist | |
function isTrackInPlaylist(trackId) { | |
let url = `https://api.spotify.com/v1/playlists/${PLAYLIST_ID}/tracks?fields=items(track(id)),next&limit=100`; | |
let trackFound = false; | |
while (url && !trackFound) { | |
const response = UrlFetchApp.fetch(url, { | |
method: 'get', | |
headers: { | |
'Authorization': 'Bearer ' + getSpotifyAccessToken() | |
} | |
}); | |
const data = JSON.parse(response.getContentText()); | |
trackFound = data.items.some(item => item.track.id === trackId); | |
url = data.next; | |
} | |
return trackFound; | |
} | |
// add a track to the playlist | |
function addTrackToPlaylist(trackId) { | |
const url = `https://api.spotify.com/v1/playlists/${PLAYLIST_ID}/tracks?uris=spotify:track:${trackId}`; | |
Logger.log('[addTrackToPlaylist] Adding track ' + trackId) | |
UrlFetchApp.fetch(url, { | |
method: 'post', | |
headers: { | |
'Authorization': 'Bearer ' + getSpotifyAccessToken(), | |
'Content-Type': 'application/json' | |
} | |
}); | |
} | |
// remove tracks from playlist that are older than two weeks | |
function removeOldTracksFromPlaylist() { | |
const url = `https://api.spotify.com/v1/playlists/${PLAYLIST_ID}/tracks`; | |
const response = UrlFetchApp.fetch(url, { | |
method: 'get', | |
headers: { | |
'Authorization': 'Bearer ' + getSpotifyAccessToken() | |
} | |
}); | |
const data = JSON.parse(response.getContentText()); | |
const twoWeeksAgo = new Date(); | |
twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14); | |
const tracksToRemove = data.items.filter(item => { | |
const addedAt = new Date(item.added_at); | |
return addedAt < twoWeeksAgo; | |
}).map(item => ({ uri: item.track.uri })); | |
if (tracksToRemove.length > 0) { | |
const removePayload = { | |
tracks: tracksToRemove | |
}; | |
UrlFetchApp.fetch(url, { | |
method: 'delete', | |
headers: { | |
'Authorization': 'Bearer ' + getSpotifyAccessToken(), | |
'Content-Type': 'application/json' | |
}, | |
payload: JSON.stringify(removePayload) | |
}); | |
} | |
} | |
// main function | |
function updateSpotifyPlaylist() { | |
removeOldTracksFromPlaylist(); | |
const response = UrlFetchApp.fetch(ENERGY_HAMBURG_API_URL); | |
const data = JSON.parse(response.getContentText()); | |
if (!data.playlist || !data.playlist.songs) { | |
Logger.log("Keine Songs gefunden"); | |
return; | |
} | |
const songs = data.playlist.songs; | |
songs.forEach(song => { | |
const trackId = searchSpotifyTrack(song.artist, song.title); | |
if (trackId) { | |
Logger.log('Found trackId %s for song "%s - %s"', trackId, song.artist, song.title) | |
if (!isTrackInPlaylist(trackId)) { | |
addTrackToPlaylist(trackId); | |
} | |
} | |
}); | |
} | |
function checkToken() { | |
CacheService.getScriptCache().remove(CACHE_TOKEN) | |
Logger.log("Token: %s", getSpotifyAccessToken()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment