apollo/services/spotify.js

98 lines
2.6 KiB
JavaScript

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
}