83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
const axios = require("axios");
|
|
const logger = require("./logging");
|
|
const fs = require("fs/promises");
|
|
const Song = require("../../models/song");
|
|
|
|
class SpotifyTracker {
|
|
constructor(config, token) {
|
|
this._token = token;
|
|
this._cache = null;
|
|
this._config = config;
|
|
this._auth = new Buffer.from(config.client_id + ':' + config.client_secret).toString('base64');
|
|
}
|
|
|
|
async poll(useCache = false) {
|
|
if (token == null)
|
|
return null;
|
|
if (useCache)
|
|
return cache;
|
|
|
|
if (token.expires_at < Date.now() + 300)
|
|
await this.#refreshTokenIfNeeded();
|
|
|
|
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 = null;
|
|
return null;
|
|
}
|
|
|
|
cache = [this.#transform(response.data)];
|
|
return cache;
|
|
} catch (ex) {
|
|
logger.error(ex, "Failed to get currently playing data from Spotify.");
|
|
return [];
|
|
}
|
|
}
|
|
|
|
#transform(data) {
|
|
const item = data.item;
|
|
const artists = item.artists.map(a => a.name);
|
|
const year = null;
|
|
const state = data.is_playing ? "playing" : "paused";
|
|
return new Song(item.id, item.name, item.album.name, artists, year, item.duration_ms, data.progress_ms, "spotify", state, "spotify");
|
|
}
|
|
|
|
async #refreshTokenIfNeeded() {
|
|
if (!this._token || this._token.expires_at && this._token.expires_at - Date.now() > 900)
|
|
return false;
|
|
|
|
const response = await axios.post("https://accounts.spotify.com/api/token",
|
|
{
|
|
client_id: this._config.client_id,
|
|
refresh_token: this._token.refresh_token,
|
|
grant_type: "refresh_token"
|
|
},
|
|
{
|
|
headers: {
|
|
"Authorization": "Basic " + this._auth,
|
|
"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"] = this._token.refresh_token;
|
|
|
|
this._token = data;
|
|
await fs.writeFile("credentials.spotify.json", JSON.stringify(data));
|
|
logger.debug("Updated access token for Spotify.");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
module.exports = SpotifyTracker; |