: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:
Iván Ovejero 2021-03-10 14:50:12 -03:00 committed by GitHub
parent 15ec1f1f4d
commit 1842c7158b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 1204 additions and 60 deletions

View file

@ -1,4 +1,6 @@
import { OptionsWithUri } from 'request'; import {
OptionsWithUri,
} from 'request';
import { import {
IExecuteFunctions, IExecuteFunctions,

File diff suppressed because it is too large Load diff

View file

@ -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

View 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