Reputation: 87
I am building a small program currently consisting of one .js file that outputs all tracks of a specific Spotify list. Currently I have not managed to build a system that automatically refreshes the access token, this breaking the program after an hour. I am unsure how to implement this feature so I am asking here for help.
I have the access token and refresh token. This is my code, which currently works for an hour.
var request = require("request");
var user = USERNAME;
var token = "Bearer BQBpRXd...Yfofi8A";
var playlists_url = "https://api.spotify.com/v1/users/"+user+"/playlists";
request({url:playlists_url, headers:{"Authorization":token}}, function(err, res){
if (res){
var playlists = JSON.parse(res.body);
playlists.items.forEach(function(playlist, i){
if (playlists.items[i].id === "4N2...2PDX") {
var playlist_url = playlists.items[i].href
request({url:playlist_url, headers:{"Authorization":token}}, function(err, res){
if (res){
var playlist = JSON.parse(res.body);
playlist.tracks.items.slice().reverse().forEach(function(track){
console.log(track.track.name);
});
}
});
}
});
}
});
I hope someone can help me with this, and maybe provide some better code for me that can help me on my journey.
Upvotes: 2
Views: 5122
Reputation: 4054
One way to do this would be to perform a token refresh once you get an unauthorized/expired token response in your request. See the Spotify API docs.
For example you could do the following:
NOTE: This code is untested and may need tweaks on your end.
var request = require("request");
var user = USERNAME;
const refresh_token = "REFRESH_TOKEN_FROM_INITIAL_AUTH";
let access_token = "AUTH_TOKEN_FROM_INITIAL_AUTH";
let token = "BASE64_ENCODED_USER:ACCESS_TOKEN?";
getPlaylists();
function refreshAuthToken(callback) {
const refreshBody = querystring.stringify({
grant_type: 'refresh_token',
refresh_token: refresh_token,
});
const req = request(
{
// Assuming you have this setup as: https://accounts.spotify.com/api/token
url: refresh_token_url,
method: 'POST',
headers:{
// Authorization: Basic <base64 encoded client_id:client_secret>
'Authorization': token
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(refreshBody)
}
},
(err, res) => {
if (res) {
const resData = JSON.parse(res.body);
// Set new access tokens
access_token = resData.access_token;
// setup your Authorization token, e.g.
token = btoa(access_token);
callback();
} else if (err) {
// Handle error...
}
}
);
req.write(refreshBody);
}
function getPlaylists() {
request(
{
url: playlists_url,
headers:{
"Authorization": token
}
},
function(err, res) {
if (res) {
var playlists = JSON.parse(res.body);
playlists.items.forEach(function(playlist, i) {
if (playlists.items[i].id === "4N2...2PDX") {
var playlist_url = playlists.items[i].href;
request(
{
url:playlist_url,
headers:{"Authorization":token}
},
function(err, res) {
if (res) {
var playlist = JSON.parse(res.body);
playlist.tracks.items.slice().reverse().forEach(function(track){
console.log(track.track.name);
});
}
}
);
}
});
} else if (err) {
// Check what type of error
if (res.statusCode === 401) {
// Refresh the token, if possible
refreshAuthentication(getPlaylists);
}
}
}
);
}
Upvotes: 3