const axios = require("axios")
const _ = require("lodash")
const changes = {}
const oldPlaylistState = this.$checkpoint || {}
newPlaylistState = await getCurrentPlaylistState(steps.get_saved_playlists.playlists)
if (_.isEmpty(oldPlaylistState)) {
this.$checkpoint = newPlaylistState
$end("Saved initial playlist data. Will check for changes on next run.")
}
if (!_.isEmpty(oldPlaylistState)) {
const playlistsThatChanged = steps.get_saved_playlists.playlists.filter(playlist => {
if (!oldPlaylistState[playlist.id]) {
return false
}
return oldPlaylistState[playlist.id].snapshot_id !== playlist.snapshot_id
})
if (!playlistsThatChanged.length) {
this.$checkpoint = newPlaylistState
$end("No playlists changed")
}
for (const playlist of playlistsThatChanged) {
const { id, images, name, external_urls } = playlist
const oldTracks = _.sortBy(oldPlaylistState[id].tracks, 'track.id')
const newTracks = _.sortBy(newPlaylistState[id].tracks, 'track.id')
const trackDiff = _.differenceBy(newTracks, oldTracks, 'track.id')
if (!trackDiff.length) {
continue
}
changes[id] = {
images,
link: external_urls.spotify,
name,
trackDiff,
}
}
if (_.isEmpty(changes)) {
this.$checkpoint = newPlaylistState
$end("No new tracks")
}
formatAndSendEmail(changes)
}
this.$checkpoint = newPlaylistState
async function getCurrentPlaylistState(playlists) {
const currentPlaylistState = {}
for (const playlist of playlists) {
const { id, external_urls, images, name, snapshot_id } = playlist
let tracks = []
let url = `https://api.spotify.com/v1/playlists/${id}/tracks?limit=100`
do {
const { items, next } = (await axios({
method: "GET",
url,
params: {
fields: "items(track(id,name,artists))"
},
headers: {
Authorization: `Bearer ${auths.spotify.oauth_access_token}`,
},
})).data
tracks = tracks.concat(items)
url = next
} while (url)
currentPlaylistState[id] = {
link: external_urls.spotify,
images,
name,
snapshot_id,
tracks,
}
}
return currentPlaylistState
}
function formatAndSendEmail(changes) {
let html = ''
for (let [id, playlist] of Object.entries(changes)) {
const { link, images, name, trackDiff } = playlist
html += `<strong>New tracks on <a href="${link}">${name}</a></strong><br><br>
<img width="200px" alt="${name}" src="${images[0].url}"><br><br>
${trackDiff.map(t => {
const { name, artists } = t.track
const artistString = artists.map(a => a.name).join(', ')
return `${name} by ${artistString}`
}).join('<br>')}
<br><br>`
}
$send.email({
subject: "Updates to Spotify playlists you follow",
html,
})
}