Code Monkey home page Code Monkey logo

spotify-api.js's People

Contributors

abh80 avatar adb-sh avatar arakmar avatar cutiecat6778 avatar dependabot[bot] avatar peterjuras avatar scientific-dev avatar venables avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

spotify-api.js's Issues

auto refreshing token not working

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)

Client.user is undefined with user authorized token.

Bug Report

What I expected:

I expected the client to have a user property like the docs state.

What happened:

Instead client.user is undefined.

To reproduce this bug:

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.

  • Library Version: v9.0.1

Incorrect JSON body for removing items from playlists

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:

image
image

How do you install version 9 with yarn?

Question and Help

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?

Podcast track returning null

Bug Report

What i expected:

 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"
            }

What actually happened:

image
track:null

To reproduce this bug:

  • 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.

Can't return track search result

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);
});

Use eventemitter

Feature Request

Simple subject of my feature...

Using eventemitter.

Feature description in brief...

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?

Could you add album skip?

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.

Bad request (400) on playlist image upload

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.

spotify-api-js-org documentation typo's

In this page, there are some typos in the const user code block.

  • clientId should be clientID
  • client_secret should be clientSecret
  • redirect_uri should be redirectUri
    Also, a small one, but 'Authentication' in the side bar 'Examples' has a typo as well: 'Authenication'

Client.create is not a static method

Bug Report

What i expected:

I wanted to use const client = await Client.create(...); as specified in the example.

What actually happened:

TypeScript complains that create doesn't exist on the Client class:

image

Looking into the source code, create appears to be a Class member, and not a static method.

To reproduce this bug:

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.

Search query param encoding

Bug Report

My version of spotify-api.js

5.0.3

What i expected...

Results for queries that contain spaces

But what happened is...

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.

Breaking changes from v5.0.3 to v6.0.0?

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.

My version of spotify-api.js

Version 6.0.0

What i expected...

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

But what happened is...

Getting an error stating that there are missing arguments for Spotify.UserClient & Spotify.UserPlayer. The docs do not address these arguments.

How to get user info from currently logged in user.

Question and Help

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?

Expose total for paginated APIs

Feature Request

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.

AuthManager's getUserToken only tries to obtain authentication code, not refresh token

Bug Report

My version of spotify-api.js

8.0.0

What i expected...

Using the getUserToken() method in AuthManager with refresh_token passed, I would expect to get a new access and refresh token

But what happened is...

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

Uncaught promise rejection causing program to crash

Bug Report

Since

this._init(options);
is not awaited or called with .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.

What i expected:

A failed API request should not make the process exit.

What actually happened:

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 ...)

To reproduce this bug:

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.

Unclear instrusctions

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

Discord link is expired

Question and Help

Can I get an updated link? I can't get this to work at all in my Next project . . .

playlists.removeItems uses wrong format in body of request

Bug Report

The PlaylistManager.removeItems() method uses a deprecated format for the request.

What i expected:

The DELETE request to succeed and the track to be deleted.

What actually happened:

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.

To reproduce this bug:

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}`])
  • Library Version: 9.2.5

Anyway, thanks for your work! It’s made my life easier in the instances where it does work.

Replacing playlist tracks broken in v9.2.2

Bug Report

What i expected:

Replacing tracks in a playlist should work using the spotifyApi.playlists.reorderItems(...) API.

What actually happened:

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)

To reproduce this bug:

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.