mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
:Sparkles: Add create playlist and get new releases - Spotify (#1520)
* ✨ Create playlist in Spotify node * Add create operation to Spotify node * Add description and public properties to playlist resource type * ⚡ Refactor playlist:create * ⚡ Add album:getNewReleases * 🎨 Replace PNG with SVG icon * ⚡ Small improvements Co-authored-by: Gerard Louw <gerardlouw@gmail.com> Co-authored-by: ricardo <ricardoespinoza105@gmail.com>
This commit is contained in:
parent
15ec1f1f4d
commit
1842c7158b
|
@ -1,4 +1,6 @@
|
||||||
import { OptionsWithUri } from 'request';
|
import {
|
||||||
|
OptionsWithUri,
|
||||||
|
} from 'request';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IExecuteFunctions,
|
IExecuteFunctions,
|
||||||
|
|
1000
packages/nodes-base/nodes/Spotify/IsoCountryCodes.ts
Normal file
1000
packages/nodes-base/nodes/Spotify/IsoCountryCodes.ts
Normal file
File diff suppressed because it is too large
Load diff
|
@ -14,11 +14,15 @@ import {
|
||||||
spotifyApiRequestAllItems,
|
spotifyApiRequestAllItems,
|
||||||
} from './GenericFunctions';
|
} from './GenericFunctions';
|
||||||
|
|
||||||
|
import {
|
||||||
|
isoCountryCodes
|
||||||
|
} from './IsoCountryCodes';
|
||||||
|
|
||||||
export class Spotify implements INodeType {
|
export class Spotify implements INodeType {
|
||||||
description: INodeTypeDescription = {
|
description: INodeTypeDescription = {
|
||||||
displayName: 'Spotify',
|
displayName: 'Spotify',
|
||||||
name: 'spotify',
|
name: 'spotify',
|
||||||
icon: 'file:spotify.png',
|
icon: 'file:spotify.svg',
|
||||||
group: ['input'],
|
group: ['input'],
|
||||||
version: 1,
|
version: 1,
|
||||||
description: 'Access public song data via the Spotify API.',
|
description: 'Access public song data via the Spotify API.',
|
||||||
|
@ -183,6 +187,11 @@ export class Spotify implements INodeType {
|
||||||
value: 'get',
|
value: 'get',
|
||||||
description: 'Get an album by URI or ID.',
|
description: 'Get an album by URI or ID.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Get New Releases',
|
||||||
|
value: 'getNewReleases',
|
||||||
|
description: 'Get a list of new album releases.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: `Get Tracks`,
|
name: `Get Tracks`,
|
||||||
value: 'getTracks',
|
value: 'getTracks',
|
||||||
|
@ -203,6 +212,10 @@ export class Spotify implements INodeType {
|
||||||
resource: [
|
resource: [
|
||||||
'album',
|
'album',
|
||||||
],
|
],
|
||||||
|
operation: [
|
||||||
|
'get',
|
||||||
|
'getTracks',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
placeholder: 'spotify:album:1YZ3k65Mqw3G8FzYlW1mmp',
|
placeholder: 'spotify:album:1YZ3k65Mqw3G8FzYlW1mmp',
|
||||||
|
@ -304,6 +317,11 @@ export class Spotify implements INodeType {
|
||||||
value: 'add',
|
value: 'add',
|
||||||
description: 'Add tracks from a playlist by track and playlist URI or ID.',
|
description: 'Add tracks from a playlist by track and playlist URI or ID.',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Create a Playlist',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a new playlist.',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Get',
|
name: 'Get',
|
||||||
value: 'get',
|
value: 'get',
|
||||||
|
@ -350,6 +368,59 @@ export class Spotify implements INodeType {
|
||||||
placeholder: 'spotify:playlist:37i9dQZF1DWUhI3iC1khPH',
|
placeholder: 'spotify:playlist:37i9dQZF1DWUhI3iC1khPH',
|
||||||
description: `The playlist's Spotify URI or its ID.`,
|
description: `The playlist's Spotify URI or its ID.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Name',
|
||||||
|
name: 'name',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'playlist',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
placeholder: 'Favorite Songs',
|
||||||
|
description: 'Name of the playlist to create.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Additional Fields',
|
||||||
|
name: 'additionalFields',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Field',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'playlist',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Description',
|
||||||
|
name: 'description',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
placeholder: 'These are all my favorite songs.',
|
||||||
|
description: 'Description for the playlist to create.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Public',
|
||||||
|
name: 'public',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
description: 'Whether the playlist is publicly accessible.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Track ID',
|
displayName: 'Track ID',
|
||||||
name: 'trackID',
|
name: 'trackID',
|
||||||
|
@ -433,6 +504,7 @@ export class Spotify implements INodeType {
|
||||||
'getTracks',
|
'getTracks',
|
||||||
'getAlbums',
|
'getAlbums',
|
||||||
'getUserPlaylists',
|
'getUserPlaylists',
|
||||||
|
'getNewReleases',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -455,6 +527,7 @@ export class Spotify implements INodeType {
|
||||||
'getTracks',
|
'getTracks',
|
||||||
'getAlbums',
|
'getAlbums',
|
||||||
'getUserPlaylists',
|
'getUserPlaylists',
|
||||||
|
'getNewReleases',
|
||||||
],
|
],
|
||||||
returnAll: [
|
returnAll: [
|
||||||
false,
|
false,
|
||||||
|
@ -489,6 +562,33 @@ export class Spotify implements INodeType {
|
||||||
},
|
},
|
||||||
description: `The number of items to return.`,
|
description: `The number of items to return.`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Filters',
|
||||||
|
name: 'filters',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Filter',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'album',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'getNewReleases',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Country',
|
||||||
|
name: 'country',
|
||||||
|
type: 'options',
|
||||||
|
default: 'US',
|
||||||
|
options: isoCountryCodes.map(({ name, alpha2 }) => ({ name, value: alpha2 })),
|
||||||
|
description: 'Country to filter new releases by.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -605,18 +705,44 @@ export class Spotify implements INodeType {
|
||||||
// Album Operations
|
// Album Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
} else if (resource === 'album') {
|
} else if (resource === 'album') {
|
||||||
|
|
||||||
|
if (operation === 'get') {
|
||||||
const uri = this.getNodeParameter('id', i) as string;
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
const id = uri.replace('spotify:album:', '');
|
const id = uri.replace('spotify:album:', '');
|
||||||
|
|
||||||
requestMethod = 'GET';
|
requestMethod = 'GET';
|
||||||
|
|
||||||
if(operation === 'get') {
|
|
||||||
endpoint = `/albums/${id}`;
|
endpoint = `/albums/${id}`;
|
||||||
|
|
||||||
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||||
|
|
||||||
|
} else if (operation === 'getNewReleases') {
|
||||||
|
|
||||||
|
endpoint = '/browse/new-releases';
|
||||||
|
requestMethod = 'GET';
|
||||||
|
|
||||||
|
const filters = this.getNodeParameter('filters', i) as IDataObject;
|
||||||
|
|
||||||
|
if (Object.keys(filters).length) {
|
||||||
|
Object.assign(qs, filters);
|
||||||
|
}
|
||||||
|
|
||||||
|
returnAll = this.getNodeParameter('returnAll', i) as boolean;
|
||||||
|
|
||||||
|
if (!returnAll) {
|
||||||
|
qs.limit = this.getNodeParameter('limit', i);
|
||||||
|
responseData = await spotifyApiRequest.call(this, requestMethod, endpoint, body, qs);
|
||||||
|
responseData = responseData.albums.items;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (operation === 'getTracks') {
|
} else if (operation === 'getTracks') {
|
||||||
|
const uri = this.getNodeParameter('id', i) as string;
|
||||||
|
|
||||||
|
const id = uri.replace('spotify:album:', '');
|
||||||
|
|
||||||
|
requestMethod = 'GET';
|
||||||
|
|
||||||
endpoint = `/albums/${id}/tracks`;
|
endpoint = `/albums/${id}/tracks`;
|
||||||
|
|
||||||
propertyName = 'tracks';
|
propertyName = 'tracks';
|
||||||
|
@ -780,7 +906,22 @@ export class Spotify implements INodeType {
|
||||||
|
|
||||||
responseData = responseData.items;
|
responseData = responseData.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (operation === 'create') {
|
||||||
|
|
||||||
|
// https://developer.spotify.com/console/post-playlists/
|
||||||
|
|
||||||
|
body.name = this.getNodeParameter('name', i) as string;
|
||||||
|
|
||||||
|
const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject;
|
||||||
|
|
||||||
|
if (Object.keys(additionalFields).length) {
|
||||||
|
Object.assign(body, additionalFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
responseData = await spotifyApiRequest.call(this, 'POST', '/me/playlists', body, qs);
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
// Track Operations
|
// Track Operations
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB |
1
packages/nodes-base/nodes/Spotify/spotify.svg
Normal file
1
packages/nodes-base/nodes/Spotify/spotify.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 66 65" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><path d="M32 0C14.3 0 0 14.337 0 32c0 17.7 14.337 32 32 32 17.7 0 32-14.337 32-32S49.663 0 32 0zm14.68 46.184c-.573.956-1.797 1.223-2.753.65-7.532-4.588-16.975-5.62-28.14-3.097-1.07.23-2.14-.42-2.37-1.5s.42-2.14 1.5-2.37c12.196-2.8 22.67-1.606 31.082 3.556a2 2 0 0 1 .688 2.753zm3.9-8.717c-.726 1.185-2.256 1.53-3.44.84-8.602-5.276-21.716-6.805-31.885-3.747-1.338.382-2.714-.344-3.097-1.644-.382-1.338.344-2.714 1.682-3.097 11.622-3.517 26.074-1.835 35.976 4.244 1.147.688 1.5 2.217.765 3.403zm.344-9.1c-10.323-6.117-27.336-6.7-37.2-3.708-1.568.497-3.25-.42-3.747-1.988s.42-3.25 1.988-3.747c11.317-3.44 30.127-2.753 41.98 4.282 1.415.84 1.873 2.676 1.032 4.1-.765 1.453-2.638 1.912-4.053 1.07z" stroke="none" fill="#1ed760" fill-rule="nonzero"/></symbol></svg>
|
After Width: | Height: | Size: 1 KiB |
Loading…
Reference in a new issue