javascriptnode.jsdiscord.jsspotifyspotify-app

Nodejs - Spotify API Refresh Token


First off. I have not worked with APIs before.

The problem I have is to refresh the token. The code that's returned as a query parameter to the redirect URI seems to be needed to be put in manually each time. When I get that authentication code, the code below gets me the new access token, as well as the refresh token.

The package I use is spotify-web-api-node and the code below is a result of following their readme. I have also tried spotify-oauth-refresher but I'm too new to coding to figure it out how to use it.

I've tried following the guide on Spotify's own website as well. But I don't seem to be able to get this right by myself.

Would love some guidance. Thanks. Hope things are clear.

 var scopes = ['user-read-private', 'user-read-email', 'playlist-read-private', 'playlist-modify-private'],
      redirectUri = '<redirect uri>',
      clientId = '<client id>',
      clientSecret = '<client secret>',
      state = '<random string>';
    
    var spotifyApi = new SpotifyWebApi({
      redirectUri: redirectUri,
      clientId: clientId,
      clientSecret: clientSecret
    });
    
    // Create the authorization URL
    var authorizeURL = spotifyApi.createAuthorizeURL(scopes, state);
    
    console.log(authorizeURL);
    
    var credentials = {
      clientId: '<client id>',
      clientSecret: '<client secret>',
      redirectUri: '<redirect uri>'
    };
    
    var spotifyApi = new SpotifyWebApi(credentials);
    
    // The code that's returned as a query parameter to the redirect URI
    var code = 'I HAVE TO MANUALLY PUT THIS IN WHEN THE DURATION RUNS OUT';
    
    // Retrieve an access token and a refresh token
    spotifyApi.authorizationCodeGrant(code).then(
      function(data) {
        console.log('The token expires in ' + data.body['expires_in']);
        console.log('The access token is ' + data.body['access_token']);
        console.log('The refresh token is ' + data.body['refresh_token']);
    
        // Set the access token on the API object to use it in later calls
        spotifyApi.setAccessToken(data.body['access_token']);
        spotifyApi.setRefreshToken(data.body['refresh_token']);
      },
      function(err) {
        console.log('Something went wrong!', err);
      }
    );
    
    // clientId, clientSecret and refreshToken has been set on the api object previous to this call.
    spotifyApi.refreshAccessToken().then(
      function(data) {
        console.log('The access token has been refreshed!');
    
        // Save the access token so that it's used in future calls
        spotifyApi.setAccessToken(data.body['access_token']);
      },
      function(err) {
        console.log('Could not refresh access token', err);
      }
    );

EDIT: I’ve created a working solution and will submit my code when I get time. Hopefully today.


Solution

  • The way I managed to get this to work was by the code below:

    const express = require('express');
    const SpotifyWebApi = require('spotify-web-api-node');
    
    var generateRandomString = function(length) {
        var text = '';
        var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    
        for (var i = 0; i < length; i++) {
            text += possible.charAt(Math.floor(Math.random() * possible.length));
        }
    
        return text;
    };
    
    var scopes = ['user-read-private', 'user-read-email', 'playlist-read-private', 'playlist-modify-private'],
        redirectUri = '<redirect uri>',
        clientId = '<client id>',
        clientSecret = '<client secret>',
        state = generateRandomString(16);
    
    // Setting credentials can be done in the wrapper's constructor, or using the API object's setters.
    var spotifyApi = new SpotifyWebApi({
        redirectUri: redirectUri,
        clientId: clientId,
        clientSecret: clientSecret
    });
    
    // Create the authorization URL
    var authorizeURL = spotifyApi.createAuthorizeURL(scopes, state);
    
    // https://accounts.spotify.com:443/authorize?client_id=5fe01282e44241328a84e7c5cc169165&response_type=code&redirect_uri=https://example.com/callback&scope=user-read-private%20user-read-email&state=some-state-of-my-choice
    console.log(authorizeURL);
    
    // --------------------------------
    
    var credentials = {
        clientId: '<client id>',
        clientSecret: '<client secret>',
        redirectUri: '<redirect uri>'
    };
    
    var spotifyApi = new SpotifyWebApi(credentials);
    
    var app = express();
    
    app.get('/login', function(req, res) {
        res.redirect(authorizeURL);
    });
    
    // The code that's returned as a query parameter to the redirect URI
    var code = '<authorization code>'; // this does not need to be updated
    
    // Retrieve an access token and a refresh token
    spotifyApi.authorizationCodeGrant(code).then(
        function(data) {
            console.log('The token expires in ' + data.body['expires_in']);
            console.log('The access token is ' + data.body['access_token']);
            console.log('The refresh token is ' + data.body['refresh_token']);
    
            // Set the access token on the API object to use it in later calls
            spotifyApi.setAccessToken(data.body['access_token']);
            spotifyApi.setRefreshToken(data.body['refresh_token']);
        },
        function(err) {
            console.log('Something went wrong!', err);
        }
    );
    // --------------------------------------------------
    // clientId, clientSecret and refreshToken has been set on the api object previous to this call.
    function refreshSpotifyToken() {
        spotifyApi.refreshAccessToken().then(
            function(data) {
                console.log('The access token has been refreshed!');
    
                // Save the access token so that it's used in future calls
                spotifyApi.setAccessToken(data.body['access_token']);
                console.log('The access token is ' + data.body['access_token']);
                console.log('The token expires in ' + data.body['expires_in']);
            },
            function(err) {
                console.log('Could not refresh access token', err);
            });
    };
    client.on('ready', () => {
        refreshSpotifyToken();
        setInterval(refreshSpotifyToken, 1000 * 59 * 59);
    })