const axios = require("axios"); const config = require("../config/configuration") const logger = require("./logging"); const fs = require("fs/promises"); const fss = require("fs"); let token = null; let cache = {} async function refreshTokenIfNeeded() { if (!token || token["expires_at"] && token["expires_at"] - Date.now() > 900) { return false; } try { const response = await axios.post("https://accounts.spotify.com/api/token", { client_id: config.spotify.client_id, refresh_token: token["refresh_token"], grant_type: "refresh_token" }, { headers: { "Authorization": "Basic " + new Buffer.from(config.spotify.client_id + ':' + config.spotify.client_secret).toString('base64'), "Content-Type": "application/x-www-form-urlencoded" } } ); const data = response.data; data["expires_at"] = Date.now() + data["expires_in"] * 1000; if (!data["refresh_token"]) { data["refresh_token"] = token["refresh_token"]; } await fs.writeFile("credentials.spotify.json", JSON.stringify(data)); token = data; logger.debug("Updated access token for Spotify."); return true; } catch (ex) { logger.error(ex, "Failed to get Spotify oauth."); return false; } } async function loadCredentials() { if (!fss.existsSync("credentials.spotify.json")) { logger.info("No Spotify credentials found."); return; } const content = await fs.readFile("credentials.spotify.json", "utf-8"); token = JSON.parse(content); } async function getCurrentlyPlaying(cached = false) { if (cached) { return cache['spotify'] } try { const response = await axios.get("https://api.spotify.com/v1/me/player/currently-playing", { headers: { "Authorization": "Bearer " + token["access_token"] } } ); if (!response.data) { cache['spotify'] = null; return null; } const media = response.data.item; cache['spotify'] = { "track": media.name, "album": media.album.name, "artist": media.artists.map(a => a.name).join(', '), "year": media.parentYear, "duration": media.duration_ms, "playtime": response.data.progress_ms, "mediaKey": media.id, "sessionKey": "spotify", "state": response.data.is_playing ? "playing" : "paused", "source": "spotify" }; return cache['spotify']; } catch (ex) { logger.error(ex, "Failed to get currently playing data from Spotify."); return null; } } module.exports = { refreshTokenIfNeeded, loadCredentials, getCurrentlyPlaying }