spotify.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import config from "config";
  2. import async from "async";
  3. import oauth from "oauth";
  4. import CoreClass from "../core";
  5. const { OAuth2 } = oauth;
  6. let apiResults = {
  7. access_token: "",
  8. token_type: "",
  9. expires_in: 0,
  10. expires_at: 0,
  11. scope: ""
  12. };
  13. let SpotifyModule;
  14. let CacheModule;
  15. let UtilsModule;
  16. class _SpotifyModule extends CoreClass {
  17. // eslint-disable-next-line require-jsdoc
  18. constructor() {
  19. super("spotify");
  20. SpotifyModule = this;
  21. }
  22. /**
  23. * Initialises the spotify module
  24. *
  25. * @returns {Promise} - returns promise (reject, resolve)
  26. */
  27. initialize() {
  28. return new Promise((resolve, reject) => {
  29. CacheModule = this.moduleManager.modules.cache;
  30. UtilsModule = this.moduleManager.modules.utils;
  31. const client = config.get("apis.spotify.client");
  32. const secret = config.get("apis.spotify.secret");
  33. this.SpotifyOauth = new OAuth2(client, secret, "https://accounts.spotify.com/", null, "api/token", null);
  34. async.waterfall(
  35. [
  36. next => {
  37. this.setStage(2);
  38. CacheModule.runJob("HGET", { table: "api", key: "spotify" })
  39. .then(data => {
  40. next(null, data);
  41. })
  42. .catch(next);
  43. },
  44. (data, next) => {
  45. this.setStage(3);
  46. if (data) apiResults = data;
  47. next();
  48. }
  49. ],
  50. async err => {
  51. if (err) {
  52. err = await UtilsModule.runJob("GET_ERROR", {
  53. error: err
  54. });
  55. reject(new Error(err));
  56. } else {
  57. resolve();
  58. }
  59. }
  60. );
  61. });
  62. }
  63. /**
  64. * Returns the request token for the Spotify api if one exists, otherwise creates a new one
  65. *
  66. * @returns {Promise} - returns a promise (resolve, reject)
  67. */
  68. GET_TOKEN() {
  69. return new Promise(resolve => {
  70. if (Date.now() > apiResults.expires_at) {
  71. SpotifyModule.runJob("REQUEST_TOKEN", null, this).then(() => {
  72. resolve(apiResults.access_token);
  73. });
  74. } else resolve(apiResults.access_token);
  75. });
  76. }
  77. /**
  78. * Creates a request token for the Spotify api
  79. *
  80. * @returns {Promise} - returns a promise (resolve, reject)
  81. */
  82. REQUEST_TOKEN() {
  83. return new Promise(resolve => {
  84. async.waterfall(
  85. [
  86. next => {
  87. SpotifyModule.log("INFO", "SPOTIFY_REQUEST_TOKEN", "Requesting new Spotify token.");
  88. SpotifyModule.SpotifyOauth.getOAuthAccessToken("", { grant_type: "client_credentials" }, next);
  89. },
  90. (accessToken, refreshToken, results, next) => {
  91. apiResults = results;
  92. apiResults.expires_at = Date.now() + results.expires_in * 1000;
  93. CacheModule.runJob(
  94. "HSET",
  95. {
  96. table: "api",
  97. key: "spotify",
  98. value: apiResults,
  99. stringifyJson: true
  100. },
  101. this
  102. ).finally(() => next());
  103. }
  104. ],
  105. () => resolve()
  106. );
  107. });
  108. }
  109. }
  110. export default new _SpotifyModule();