Open Ge0rg3 opened 7 years ago
I got the same error, i didn't know how to fix that shiit.
I am having the same issue
Having the same issue. Is there anyone using this module with success?
idem :/
Yes. I've had success with this. I use a helper in my app to handle the credential flow.
let spotify = new SpotifyWebApi({
clientId: 'YOUR_CLIENT_ID'
clientSecret: 'YOUR_CLIENT_SECRET',
redirectUri: 'YOUR_REDIRECT_URI'
})
// Can wrap the following methods in a class for ease of use
async initialize () {
const token = await getToken()
spotify.setAccessToken(token)
}
async refreshToken () {
const token = await getRefreshToken()
spotify.setAccessToken(token)
}
async getToken () {
const result = await spotify.clientCredentialsGrant()
return result.body.access_token
}
async getRefreshToken () {
const result = await spotify.refreshAccessToken()
return result.body.access_token
}
async useApi () {
// initialize or refreshToken as desired
await spotify.initialize()
// use api
await spotify.search(....)
}
Having same issue, but python wrapper works fine with the same credentials.
This is most likely because you didn't set the scopes correctly. This library gives a general 403 error but I went into the package code and verified that the token is set correctly. After that I send a request to get user's albums for example using Curl on the command line to verify the output:
curl -H "Authorization: Bearer yourAccessToken" https://api.spotify.com/v1/me/albums
If you see this
{
"error" : {
"status" : 403,
"message" : "Insufficient client scope"
}
it means you are not setting the scopes correctly. Check them here
For example, you won't be able to get the albums until you set the "user-library-read" scope:
const spotifyConfig = {
clientId: "YYYYYY",
clientSecret: "ZZZZZZZZZZZZZ",
redirectUri: "http://localhost:3000/api/mycallback",
scopes: [
"user-read-private",
"user-read-email",
"playlist-modify-public",
"playlist-read-private",
"playlist-modify-private",
"user-read-currently-playing",
"user-library-read",
"user-library-modify"
]
};
export default spotifyConfig;
Keep trying to add scopes and throwing curl requests until you get a response.
If you want to check that your package version is setting the access token correctly you can go into node_modules/spotify-web-api-node/src/spotify-web-api.js and for example you can check the getMySavedAlbums function
getMySavedAlbums: function(options, callback) {
return WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums')
.withQueryParameters(options)
.build()
.execute(HttpManager.get, callback);
}
modify it to
getMySavedAlbums: async function(options, callback) {
await builtReq = WebApiRequest.builder(this.getAccessToken())
.withPath('/v1/me/albums')
.withQueryParameters(options)
.build()
console.log(builtReq)
},
and run your program again to check if the header is setting the Bearer token correctly so you can rule out any problems with your package version....
@prashanthr 's async-await approach works when using the client authorization flow. I am still inexperienced at Node.js, but I suspect it's due to Node's non-blocking nature that it'll perform the search query while it's waiting for the clientCredentialsGrant() method to return its response.
I'm still having the same issue! I don't see how the async-await approach helps since functions in this API are using fetch. When I .searchTracks(), I get as response the following data.body: { tracks: { href: 'https://api.spotify.com/v1/search?query=track%3Asexual+artist%3Amarvin+gaye&type=track&offset=0&limit=20', items: [Array], limit: 20, next: 'https://api.spotify.com/v1/search?query=track%3Asexual+artist%3Amarvin+gaye&type=track&offset=20&limit=20', offset: 0, previous: null, total: 33 }
Links give me 401 error, no token provided. Right now I'm a bit lost on which token I'm supposed to have since when I make the call on the data.statusCode I'm getting a 200 and I'm using clientCredentalsGrant() to set the access token, simple client credentials flow.
@SnowPrimate It looks like you're getting a valid response after using the client credentials flow. The links you see are API paths but they won't work unless you use the same instance of SpotifyWebApi
that you used to make the initial call. Furthermore you will get a 401 if your access_token
expires. When you go through the credentials grant, you'll get an access token (short lived) and a refresh token (never expires). Upon getting a 401, you can use the refresh token to get a new access token (via the refreshAccessToken
method on the object) and then use that token to make any future requests. The key here for reproducibility is to always use the refresh token flow as shown below (when you get 401s) to ensure you always have a valid access token before making any requests to the Spotify API.
Note(s):
.then
callback correctly let swa = new SpotifyWebApi({
clientId: 'myClientId',
clientSecret: 'myClientSecret'
redirectUri: 'http://www.example.com/callback'
accessToken: 'my-original-access-token-that-probably-expired'
refreshToken: 'my-refresh-token-after-client-credential-grant-that-i-saved'
});
const response = await swa.refreshAccessToken()
const { access_token, refresh_token } = response.body
swa.setAccessToken(access_token)
swa.setRefreshToken(refresh_token) // Optional - also save the refresh token for future use separately
const searchResultsPageOne = await swa.searchTracks('artist:marvin gaye') // gives you the first page with 20 results as that is the default limit if not specified
const searchResultsPageTwo = await swa.searchTracks('artist:marvin gaye', { limit: 50, offset: 20 }) // gives you the second page
Docs:
Hey @prashanthr ! really appreaciate your help! I'm still having some issues! My idea is to use the spotifyapi to constantly receive requests of music and automatically put it in a playlist. Do I need to use the refresh token constantly to retrieve a new access token when it expires? Should I build a state which checks for when access_token_expired => refreshAccessToken()? I feel like I'm in a limbo on the refresh token. Would you mind if I PM'd you?
@SnowPrimate You're welcome! Yes that is the right idea. To build a completely stateless application that does what you want when you run it or on schedule, you'll need to save your refresh token once and inject it into your app or program on start/whenever it runs. Possible options to store this are:
Here's the general idea
let instance = new SpotifyWebApi({...})
instance.refreshAccessToken()
and set the access token on the SpotifyWebApi instance instance.setAccessToken(access_token)
. Else proceed to next step on a 2xx response.Refs:
Hi,
My access tokens do not seem to be set correctly. My code is taken from the example (and I have relplaced my id & secret):
I receive the access token and expiration time, but then if I attempt to search for songs/artists/related artists/anything else, I also receive:
{ [WebapiError: Unauthorized] name: 'WebapiError', message: 'Unauthorized', statusCode: 401 }
even though the setAccessToken has been completed.Furthermore, unlike the other closed issues similar to this, the searches that I am attempting should not require any scopes as they require no user data.
Any help appreciated :)