spotify-api / spotify-api.js Goto Github PK
View Code? Open in Web Editor NEWA complete wrapper for spotify web api for deno, node.js and the browser.
Home Page: https://spotify-api.js.org
License: MIT License
A complete wrapper for spotify web api for deno, node.js and the browser.
Home Page: https://spotify-api.js.org
License: MIT License
Hey :)
i have some problems with the refresh tokens. Not sure if it's a bug or just me doing something wrong.
After about one hour form when I started the client I get a "access token expired" error message from the spotify api.
I'm creating the spotify client like this: (pseudo code)
const params = new URLSearchParams();
params.append('grant_type', 'authorization_code');
params.append('code', code);
params.append('redirect_uri', store.redirectURL);
const config = {
headers: {
'Authorization': 'Basic ' + (new Buffer(store.clientID + ':' + store.clientSecret).toString('base64')),
'Content-Type': 'application/x-www-form-urlencoded',
},
};
const tokens = (await axios.post('https://accounts.spotify.com/api/token', params, config))?.data;
await Client.create({
refreshToken: true,
retryOnRateLimit: true,
token: {
clientID: store.clientID,
clientSecret: store.clientSecret,
redirectURL: store.redirectURL,
refreshToken: tokens.refresh_token,
},
async onRefresh() {
await UserStore.findOneAndUpdate(
{ 'spotify.userId': client.user.id },
{ spotify: { refreshToken: client.refreshMeta.refreshToken } },
);
},
});
I also tried to pass code
directly without manually requesting a refresh token from the spotify api before.
The client acctually stores the the correct refreshToken in client.refreshMeta.refreshToken, but it doesn't automatically requests a new token, when needed apparently.
Originally posted by @adb-sh in #14 (comment)
I expected the client to have a user property like the docs state.
Instead client.user is undefined.
Get a token from Spotify. I am using the Authorization Code Flow with Proof Key for Code Exchange flow.
I am using enough scopes to get the user data.
I make a client like this:
import {Client, UserClient} from "spotify-api.js";
const token = get_token();
const client = await new Client({
token,
userAuthorizedToken: true,
cacheSettings: { cacheUser: true }});
console.log(Client.user)
console.log(await new UserClient(client))
This gives me back:
undefined
UserClient {type: "user", player: Player, client: Client}
Why is there no user property? The user client also does not have any of the properties described in the docs.
However, if I open up the userclient in the console that does have a user property and actually has my user's information in there but if I access it then it is undefined.
As per the docs, when removing tracks from a playlist, URIs should be wrapped in an object. However, I believe the current state of the code misses this.
I'm using this code to remove items, which is almost identical to my code for adding items (which is working):
export const removeFromPlaylist = async (
playlist : Playlist,
uris : Array<SpotifyURI>,
throwError : (error : Error) => void,
) => {
let offset = 0;
do {
const result = await playlist.remove(uris.slice(offset, offset + spotifyTrackRemoveLimit))
.catch(throwError);
if (!result) return false;
offset += spotifyTrackRemoveLimit;
} while (offset < uris.length);
return true;
};
I'm attaching stack traces and whatnot, but I think I've pretty much already diagnosed the problem:
The highest version in the registry of yarn is only 8.1.1
I would like to use version 9 but if I try to do
yarn add https://github.com/spotify-api/spotify-api.js.git
I get the message error Package "api-types" refers to a non-existing file '"C:\....\projectname\apiTypes"'.
When I create a directory called apiTypes it does install but I still can't import the module.
How can I install version 9 with yarn?
const test = await spot.playlists.getTracks("0vRxeAksQ8ppt6TzxGV7qG");
console.log(`π ~ loadPodcastInfos ~ test`, test);
Expected output:
https://developer.spotify.com/console/get-playlist-tracks/
"items": [
{
"added_at": "2022-05-11T19:49:45Z",
"added_by": {
"external_urls": {
"spotify": "https://open.spotify.com/user/6xq5zvte0qs0lytr6ccb5wne8"
},
"href": "https://api.spotify.com/v1/users/6xq5zvte0qs0lytr6ccb5wne8",
"id": "6xq5zvte0qs0lytr6ccb5wne8",
"type": "user",
"uri": "spotify:user:6xq5zvte0qs0lytr6ccb5wne8"
},
"is_local": false,
"primary_color": null,
"track": {
"album": {
"album_type": "compilation",
"artists": [
{
"external_urls": {
"spotify": "https://open.spotify.com/show/79CkJF3UJTHFV8Dse3Oy0P"
},
"href": "https://api.spotify.com/v1/shows/79CkJF3UJTHFV8Dse3Oy0P",
"id": "79CkJF3UJTHFV8Dse3Oy0P",
"name": "Huberman Lab",
"type": "show",
"uri": "spotify:show:79CkJF3UJTHFV8Dse3Oy0P"
}
Node Version: 18.3
Library Version: 9.2.1
[] I have already checked issues regarding this bug.
[] This problem is generated due to version migration.
addition of the /recommendations api
Hello! When creating my bot on Dialogflow using the Fulfillment Editor, I found that when using " const track = await spotify.tracks. search ()", the result is empty. Although the access token output works. Can you tell me what the problem is?
Here is my code:
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
async function search(agent) {
const Spotify = require("spotify-api.js");
const Auth = new Spotify.Auth();
var token = await Auth.get({
client_id: "<client_id>",
client_secret: "<client_secret>",
});
const { Client } = require("spotify-api.js");
const spotify = new Client(token);
const track = await spotify.tracks.search("oh my god by alec benjamin");
agent.add(token + ' ' + track);
}
let intentMap = new Map();
intentMap.set('Spotify', search);
// intentMap.set('your intent name here', yourFunctionHandler);
agent.handleRequest(intentMap);
});
Using eventemitter.
I have viewed the documentation and found that there are no events to know when cache is ready. But then i found this on README
const Client = new Spotify.Client("USER_TOKEN", { cacheCurrentuser: true });
function onCacheReady(){
console.log('Client cache is ready!');
}
if(!Client.madeCache) Client.cacheOnReady = onCacheReady;
else onCacheReady();
This seems ugly. Can you use guys events
package so the code looks like this:
client.on('ready', ...
Something like discord.js? It would be fine right?
I make playlists that contain full albums. It would be nice to have a method to skip to the first track of the next unique album.
I have had success creating new playlists and adding/filtering tracks, but when I try to upload a playlist image, I keep hitting a bad request error on the PUT:
export const createPlaylist = async (
client : Client,
throwError : (error : Error) => void,
) => {
const playlistOptions : CreatePlaylist = {
name: `...name...`,
description: `...desc...`,
public: false,
collaborative: false,
};
const playlist = await client.playlists.create(playlistOptions).catch(throwError);
if (playlist) {
playlist.uploadImage(`data:image/jpeg;base64,...`);
}
return playlist;
}
The console on the Spotify docs isn't capable of taking URIs, always outputting a bad request. So, I couldn't test it there.
The auth/playlist is certainly valid, since I can still add tracks to it successfully, and I have all the necessary scopes on my token. I have tried multiple image URIs, small and large, and they all give me the same error. I checked the library source and couldn't find any issues either (with respect to the docs).
Am I missing something?
This is on version 8.0.0.
In this page, there are some typos in the const user
code block.
I wanted to use const client = await Client.create(...);
as specified in the example.
TypeScript complains that create doesn't exist on the Client class:
Looking into the source code, create appears to be a Class member, and not a static method.
This codesandbox shows the same error
Node Version: 16.13.0
Library Version: 9.0.1
I have already checked issues regarding this bug.
[] This problem is generated due to version migration.
5.0.3
Results for queries that contain spaces
const album = (await this.client.albums.search("Made In Lagos", {
limit: 1,
})) as Album;
// Result: album = []
This search returned an empty response but when I made the equivalent curl request I received results. Tried a few more searches and noticed a pattern of queries with spaces not working.
Getting these errors when compiling TS using spotify-api.js
src/spotify.ts:41:20 - error TS2554: Expected 2 arguments, but got 0.
const user = new Spotify.UserClient();
~~~~~~~~~~~~~~~~~~
node_modules/spotify-api.js/dist/UserClient.d.ts:50:17
constructor(token: string | undefined, client: Client);
~~~~~~~~~~~~~~~~
An argument for 'token' was not provided.
src/spotify.ts:80:22 - error TS2554: Expected 2 arguments, but got 1.
const userPlayer = new Spotify.UserPlayer(token);
~~~~~~~~~~~~~~~~
node_modules/spotify-api.js/dist/UserPlayer.d.ts:11:28
constructor(data: any, client: Client);
~~~~~~~~~~~~~
An argument for 'client' was not provided.
src/spotify.ts:86:16 - error TS2554: Expected 2 arguments, but got 1.
const user = new Spotify.UserClient(token);
~~~~~~~~~~~~~~~~~~~~~~
node_modules/spotify-api.js/dist/UserClient.d.ts:50:44
constructor(token: string | undefined, client: Client);
~~~~~~~~~~
An argument for 'client' was not provided.
Version 6.0.0
These errors are new since the update from v5.0.3 to v6.0.0. I'm not seeing any arguments that match "client: Client" in the docs here -> https://spotify-api-js-test.netlify.app/#/class/userplayer
Getting an error stating that there are missing arguments for Spotify.UserClient & Spotify.UserPlayer. The docs do not address these arguments.
spotify-api.js/src/Interface.ts
Line 272 in f0579b0
Why not add this Scopes
in the spotify-types
package itself?
I am using this library with vue in a client side application.
In version 8 I was able to get the user info with something like this:
const token = this.get_access_token_from_params(this.params) // after doing an implicit grant with a redirect
console.log("Token:", token)
await this.$spotify.login(token)
const user_info = await this.$spotify.user.info()
How would this work in version 9? From the welcome page it really seems like I need to give the client secret but this would be a bad idea as this code will be running on the client.
I got this now:
const token = this.get_access_token_from_params(this.params) // after doing an implicit grant with a redirect
console.log("Token:", token)
const userClient = await this.$spotify.create({"token": token}) // this.$spotify is new Client
const me = userClient.user?.displayName
console.log(me) // This is undefined
this .user has undefined for displayName and images. It seemed really easy to get the user info in v8. What am I missing here?
Some Spotify APIs use a paginated response model. For example in the ArtistManager
class, the search()
and getAlbums()
functions take a limit and offset parameter which can be used to specify the page number and size.
Unfortunately these functions do not expose the total
number of items, so in general the developer doesn't know whether or not there are more items able to be read. In this case it could be necessary to make one api call more than necessary to ensure that all items have been fetched.
In these instances it would be useful to return the raw response data (which includes the .total
member) instead of the .items
data member, to allow the developer to optimize performance.
8.0.0
Using the getUserToken() method in AuthManager with refresh_token passed, I would expect to get a new access and refresh token
What happened instead is I get an error that says 'Invalid authentication code', making me believe that it is requesting an authentication code instead of a refresh token. Upon further inspection into the source code this seems to be the case, as it just populates the code
field. Maybe this is what the spotify API wanted before, but has since changed? I'm not sure
Sadly, I don't have the code I was using anymore since I switched to a different spotify API node layer
Since
Line 130 in 967f949
.catch(...)
after it, Node will exit if the promise returned by this._init()
rejects.
It's a bit tricky because it is called in the constructor which means we can't just add await
in front of it and I don't know enough about the codebase to suggest how to refactor it at the moment.
A failed API request should not make the process exit.
A bad response when trying to refresh the token causes the process to exit
/Users/richardmiller/srv/ricky-js-monorepo/node_modules/axios/lib/core/settle.js:19
reject(new AxiosError(
^
AxiosError: Request failed with status code 503
at settle (/Users/richardmiller/srv/ricky-js-monorepo/node_modules/axios/lib/core/settle.js:19:12)
at Unzip.handleStreamEnd (/Users/richardmiller/srv/ricky-js-monorepo/node_modules/axios/lib/adapters/http.js:548:11)
at Unzip.emit (node:events:538:35)
at Unzip.emit (node:domain:475:12)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
code: 'ERR_BAD_RESPONSE',
(... removed unrelated stuff ...)
url: 'https://accounts.spotify.com/api/token',
params: {
grant_type: 'refresh_token',
code: undefined,
(... removed unrelated stuff ...)
Difficult to reproduce because it is caused by 503 from Spotify.
Node Version:
Library Version:
I have already checked issues regarding this bug.
This problem is generated due to version migration.
hello I see on the documentation you guys use const spotify = new Client("NO TOKEN");
what am I supposed to put in the strings because what ever I try I keep getting undefined from token
Can I get an updated link? I can't get this to work at all in my Next project . . .
The PlaylistManager.removeItems() method uses a deprecated format for the request.
The DELETE request to succeed and the track to be deleted.
I get the error message
SpotifyAPIError: {"error":{"status":400,"message":"JSON body doesn't conform to specification"}}
Upon investigating I found that the call looks like this:Β
url: 'https://api.spotify.com/v1/playlists/16N...Unimd/tracks',
method: 'delete',
data: '{"uris":[{"uri":"spotify:track:2wwXXU...5"}]}' <--- WRONG SYNTAX HERE
Note the "uris" before the array of track objects.
The Spotify API docs describe the API as expecting this format:
"tracks": [ { "uri": "string" } ],
(Source)
Which causes the issue.
Create a client (here I do it with an existing refresh token):
import * as Spotify from "spotify-api.js"
const client = await Spotify.Client.create({
token: {
clientID: SPOTIFY_CLIENT_ID,
clientSecret: SPOTIFY_CLIENT_SECRET,
refreshToken: refresh_token
}
});
Then use the removeItems method to make the DELETE request to the API:
await client.playlists.removeItems(playlist.spotify_uri, [`spotify:track:${song_uri}`])
Anyway, thanks for your work! Itβs made my life easier in the instances where it does work.
Replacing tracks in a playlist should work using the spotifyApi.playlists.reorderItems(...)
API.
Replacing tracks no longer works, because there is a wrong body property uri
instead of uris
(plural)
This is likely because in this line the uri
parameter is used instead of uris
. (See Spotify API reference)
const spotifyApi = await Client.create({
token: {
clientID: SPOTIFY_CLIENT_ID,
clientSecret: SPOTIFY_CLIENT_SECRET,
refreshToken: spotifyUser.refreshToken,
},
userAuthorizedToken: true,
refreshToken: true,
});
const playlistId = "VALID PLAYLIST ID"
const trackUris = ['VALID TRACK URIS']
await spotifyApi.playlists.reorderItems(playlistId, {
uris: trackUris,
});
Node Version: 16.15.1
Library Version: 9.2.2
I have already checked issues regarding this bug.
This problem is generated due to version migration.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.