const coreClass = require("../core"); const config = require('config'), async = require('async'); let apiResults = { access_token: "", token_type: "", expires_in: 0, expires_at: 0, scope: "", }; module.exports = class extends coreClass { constructor(name, moduleManager) { super(name, moduleManager); this.dependsOn = ["cache"]; } initialize() { return new Promise((resolve, reject) => { this.setStage(1); this.cache = this.moduleManager.modules["cache"]; this.utils = this.moduleManager.modules["utils"]; const client = config.get("apis.spotify.client"); const secret = config.get("apis.spotify.secret"); const OAuth2 = require('oauth').OAuth2; this.SpotifyOauth = new OAuth2( client, secret, 'https://accounts.spotify.com/', null, 'api/token', null); async.waterfall([ (next) => { this.setStage(2); this.cache.hget("api", "spotify", next, true); }, (data, next) => { this.setStage(3); if (data) apiResults = data; next(); } ], async (err) => { if (err) { err = await this.utils.getError(err); reject(err); } else { resolve(); } }); }); } async getToken() { try { await this._validateHook(); } catch { return; } return new Promise((resolve, reject) => { if (Date.now() > apiResults.expires_at) { this.requestToken(() => { resolve(apiResults.access_token); }); } else resolve(apiResults.access_token); }); } async requestToken(cb) { try { await this._validateHook(); } catch { return; } async.waterfall([ (next) => { this.logger.info("SPOTIFY_REQUEST_TOKEN", "Requesting new Spotify token."); this.SpotifyOauth.getOAuthAccessToken( '', { 'grant_type': 'client_credentials' }, next ); }, (access_token, refresh_token, results, next) => { apiResults = results; apiResults.expires_at = Date.now() + (results.expires_in * 1000); this.cache.hset("api", "spotify", apiResults, next, true); } ], () => { cb(); }); } }