mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
✨ Fetch saved tracks in Spotify node (#1550)
* ✨ Fetch saved tracks in Spotify node * Add library resource type to Spotify node * Add getUserTracks operation to Spotify node * Add user-library-read to Spotify credential scope * 🐛 Fix bug in Spotify playlist remove item * No longer pass position 0 into request * ⚡ Minor improvements Co-authored-by: Gerard Louw <gerardlouw@gmail.com>
This commit is contained in:
parent
e37b89df4f
commit
9cec2a73c7
|
@ -36,7 +36,7 @@ export class SpotifyOAuth2Api implements ICredentialType {
|
||||||
displayName: 'Scope',
|
displayName: 'Scope',
|
||||||
name: 'scope',
|
name: 'scope',
|
||||||
type: 'hidden' as NodePropertyTypes,
|
type: 'hidden' as NodePropertyTypes,
|
||||||
default: 'user-read-playback-state playlist-read-collaborative user-modify-playback-state playlist-modify-public user-read-currently-playing playlist-read-private user-read-recently-played playlist-modify-private',
|
default: 'user-read-playback-state playlist-read-collaborative user-modify-playback-state playlist-modify-public user-read-currently-playing playlist-read-private user-read-recently-played playlist-modify-private user-library-read',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Auth URI Query Parameters',
|
displayName: 'Auth URI Query Parameters',
|
||||||
|
|
|
@ -57,6 +57,10 @@ export class Spotify implements INodeType {
|
||||||
name: 'Artist',
|
name: 'Artist',
|
||||||
value: 'artist',
|
value: 'artist',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Library',
|
||||||
|
value: 'library',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Player',
|
name: 'Player',
|
||||||
value: 'player',
|
value: 'player',
|
||||||
|
@ -487,6 +491,30 @@ export class Spotify implements INodeType {
|
||||||
placeholder: 'spotify:track:0xE4LEFzSNGsz1F6kvXsHU',
|
placeholder: 'spotify:track:0xE4LEFzSNGsz1F6kvXsHU',
|
||||||
description: `The track's Spotify URI or ID.`,
|
description: `The track's Spotify URI or ID.`,
|
||||||
},
|
},
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
// Library Operations
|
||||||
|
// Get liked tracks
|
||||||
|
// --------------------------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Operation',
|
||||||
|
name: 'operation',
|
||||||
|
type: 'options',
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'library',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Get Liked Tracks',
|
||||||
|
value: 'getLikedTracks',
|
||||||
|
description: `Get the user's liked tracks.`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default: 'getLikedTracks',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Return All',
|
displayName: 'Return All',
|
||||||
name: 'returnAll',
|
name: 'returnAll',
|
||||||
|
@ -498,6 +526,7 @@ export class Spotify implements INodeType {
|
||||||
resource: [
|
resource: [
|
||||||
'album',
|
'album',
|
||||||
'artist',
|
'artist',
|
||||||
|
'library',
|
||||||
'playlist',
|
'playlist',
|
||||||
],
|
],
|
||||||
operation: [
|
operation: [
|
||||||
|
@ -505,6 +534,7 @@ export class Spotify implements INodeType {
|
||||||
'getAlbums',
|
'getAlbums',
|
||||||
'getUserPlaylists',
|
'getUserPlaylists',
|
||||||
'getNewReleases',
|
'getNewReleases',
|
||||||
|
'getLikedTracks',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -521,6 +551,7 @@ export class Spotify implements INodeType {
|
||||||
resource: [
|
resource: [
|
||||||
'album',
|
'album',
|
||||||
'artist',
|
'artist',
|
||||||
|
'library',
|
||||||
'playlist',
|
'playlist',
|
||||||
],
|
],
|
||||||
operation: [
|
operation: [
|
||||||
|
@ -528,6 +559,7 @@ export class Spotify implements INodeType {
|
||||||
'getAlbums',
|
'getAlbums',
|
||||||
'getUserPlaylists',
|
'getUserPlaylists',
|
||||||
'getNewReleases',
|
'getNewReleases',
|
||||||
|
'getLikedTracks',
|
||||||
],
|
],
|
||||||
returnAll: [
|
returnAll: [
|
||||||
false,
|
false,
|
||||||
|
@ -620,10 +652,12 @@ export class Spotify implements INodeType {
|
||||||
returnAll = false;
|
returnAll = false;
|
||||||
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
// -----------------------------
|
|
||||||
// Player Operations
|
|
||||||
// -----------------------------
|
|
||||||
if (resource === 'player') {
|
if (resource === 'player') {
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// Player Operations
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
if (operation === 'pause') {
|
if (operation === 'pause') {
|
||||||
requestMethod = 'PUT';
|
requestMethod = 'PUT';
|
||||||
|
|
||||||
|
@ -701,10 +735,12 @@ export class Spotify implements INodeType {
|
||||||
|
|
||||||
responseData = { success: true };
|
responseData = { success: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'album') {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Album Operations
|
// Album Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
} else if (resource === 'album') {
|
|
||||||
|
|
||||||
if (operation === 'get') {
|
if (operation === 'get') {
|
||||||
const uri = this.getNodeParameter('id', i) as string;
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
@ -763,10 +799,13 @@ export class Spotify implements INodeType {
|
||||||
responseData = responseData.items;
|
responseData = responseData.items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'artist') {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Artist Operations
|
// Artist Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
} else if (resource === 'artist') {
|
|
||||||
const uri = this.getNodeParameter('id', i) as string;
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
const id = uri.replace('spotify:artist:', '');
|
const id = uri.replace('spotify:artist:', '');
|
||||||
|
@ -790,6 +829,7 @@ export class Spotify implements INodeType {
|
||||||
|
|
||||||
responseData = responseData.items;
|
responseData = responseData.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (operation === 'getRelatedArtists') {
|
} else if (operation === 'getRelatedArtists') {
|
||||||
|
|
||||||
endpoint = `/artists/${id}/related-artists`;
|
endpoint = `/artists/${id}/related-artists`;
|
||||||
|
@ -819,10 +859,13 @@ export class Spotify implements INodeType {
|
||||||
|
|
||||||
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'playlist') {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Playlist Operations
|
// Playlist Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
} else if (resource === 'playlist') {
|
|
||||||
if (['delete', 'get', 'getTracks', 'add'].includes(operation)) {
|
if (['delete', 'get', 'getTracks', 'add'].includes(operation)) {
|
||||||
const uri = this.getNodeParameter('id', i) as string;
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
@ -834,8 +877,7 @@ export class Spotify implements INodeType {
|
||||||
|
|
||||||
body.tracks = [
|
body.tracks = [
|
||||||
{
|
{
|
||||||
uri: `${trackId}`,
|
uri: trackId,
|
||||||
positions: [0],
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -922,10 +964,12 @@ export class Spotify implements INodeType {
|
||||||
responseData = await spotifyApiRequest.call(this, 'POST', '/me/playlists', body, qs);
|
responseData = await spotifyApiRequest.call(this, 'POST', '/me/playlists', body, qs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (resource === 'track') {
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Track Operations
|
// Track Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
} else if (resource === 'track') {
|
|
||||||
const uri = this.getNodeParameter('id', i) as string;
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
const id = uri.replace('spotify:track:', '');
|
const id = uri.replace('spotify:track:', '');
|
||||||
|
@ -939,6 +983,34 @@ export class Spotify implements INodeType {
|
||||||
}
|
}
|
||||||
|
|
||||||
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||||
|
|
||||||
|
} else if (resource === 'library') {
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// Library Operations
|
||||||
|
// -----------------------------
|
||||||
|
|
||||||
|
if (operation === 'getLikedTracks') {
|
||||||
|
requestMethod = 'GET';
|
||||||
|
|
||||||
|
endpoint = '/me/tracks';
|
||||||
|
|
||||||
|
returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
propertyName = 'items';
|
||||||
|
|
||||||
|
if (!returnAll) {
|
||||||
|
const limit = this.getNodeParameter('limit', i) as number;
|
||||||
|
|
||||||
|
qs = {
|
||||||
|
limit,
|
||||||
|
};
|
||||||
|
|
||||||
|
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||||
|
|
||||||
|
responseData = responseData.items;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnAll) {
|
if (returnAll) {
|
||||||
|
|
Loading…
Reference in a new issue