diff --git a/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts b/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts index 5d08941aeb..6a45d7ec69 100644 --- a/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts +++ b/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts @@ -50,6 +50,10 @@ export const channelFields = [ name: 'part', type: 'multiOptions', options: [ + { + name: '*', + value: '*', + }, { name: 'Branding Settings', value: 'brandingSettings', @@ -137,9 +141,9 @@ export const channelFields = [ }, typeOptions: { minValue: 1, - maxValue: 500, + maxValue: 50, }, - default: 100, + default: 25, description: 'How many results to return.', }, { @@ -243,6 +247,7 @@ export const channelFields = [ ], }, }, + description: 'ID of the video', default: '', }, { @@ -250,6 +255,10 @@ export const channelFields = [ name: 'part', type: 'multiOptions', options: [ + { + name: '*', + value: '*', + }, { name: 'Branding Settings', value: 'brandingSettings', @@ -554,6 +563,7 @@ export const channelFields = [ ], }, }, + description: 'ID of the channel', default: '', }, { diff --git a/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts b/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts index 5cb58ee97b..8383ec6ef1 100644 --- a/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts +++ b/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts @@ -173,6 +173,10 @@ export const playlistFields = [ name: 'part', type: 'multiOptions', options: [ + { + name: '*', + value: '*', + }, { name: 'Content Details', value: 'contentDetails', @@ -301,6 +305,10 @@ export const playlistFields = [ name: 'part', type: 'multiOptions', options: [ + { + name: '*', + value: '*', + }, { name: 'Content Details', value: 'contentDetails', @@ -376,9 +384,9 @@ export const playlistFields = [ }, typeOptions: { minValue: 1, - maxValue: 500, + maxValue: 50, }, - default: 100, + default: 25, description: 'How many results to return.', }, { diff --git a/packages/nodes-base/nodes/Google/YouTube/VideoCategoryDescription.ts b/packages/nodes-base/nodes/Google/YouTube/VideoCategoryDescription.ts index fcb308e1a7..1f52ff23d9 100644 --- a/packages/nodes-base/nodes/Google/YouTube/VideoCategoryDescription.ts +++ b/packages/nodes-base/nodes/Google/YouTube/VideoCategoryDescription.ts @@ -87,9 +87,9 @@ export const videoCategoryFields = [ }, typeOptions: { minValue: 1, - maxValue: 500, + maxValue: 50, }, - default: 100, + default: 25, description: 'How many results to return.', }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts b/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts index 8c9b9ea80b..aee1d0bc66 100644 --- a/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts +++ b/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts @@ -1,6 +1,7 @@ import { INodeProperties, } from 'n8n-workflow'; +import { id } from 'rhea'; export const videoOperations = [ { @@ -271,6 +272,7 @@ export const videoFields = [ ], }, }, + description: 'ID of the video', default: '', }, { @@ -325,6 +327,10 @@ export const videoFields = [ name: 'part', type: 'multiOptions', options: [ + { + name: '*', + value: '*', + }, { name: 'Content Details', value: 'contentDetails', @@ -361,10 +367,6 @@ export const videoFields = [ name: 'Status', value: 'status', }, - { - name: 'Suggestions', - value: 'suggestions', - }, { name: 'Topic Details', value: 'topicDetails', @@ -414,70 +416,6 @@ export const videoFields = [ /* -------------------------------------------------------------------------- */ /* video:getAll */ /* -------------------------------------------------------------------------- */ - { - displayName: 'Fields', - name: 'part', - type: 'multiOptions', - options: [ - { - name: 'Content Details', - value: 'contentDetails', - }, - { - name: 'ID', - value: 'id', - }, - { - name: 'Live Streaming Details', - value: 'liveStreamingDetails', - }, - { - name: 'Localizations', - value: 'localizations', - }, - { - name: 'Player', - value: 'player', - }, - { - name: 'Recording Details', - value: 'recordingDetails', - }, - { - name: 'Snippet', - value: 'snippet', - }, - { - name: 'Statistics', - value: 'statistics', - }, - { - name: 'Status', - value: 'status', - }, - { - name: 'Suggestions', - value: 'suggestions', - }, - { - name: 'Topic Details', - value: 'topicDetails', - }, - ], - required: true, - displayOptions: { - show: { - operation: [ - 'getAll', - ], - resource: [ - 'video', - ], - }, - }, - description: 'The fields parameter specifies a comma-separated list of one or more video resource properties that the API response will include.', - default: '' - }, { displayName: 'Return All', name: 'returnAll', @@ -514,9 +452,9 @@ export const videoFields = [ }, typeOptions: { minValue: 1, - maxValue: 500, + maxValue: 50, }, - default: 100, + default: 25, description: 'How many results to return.', }, { @@ -537,28 +475,39 @@ export const videoFields = [ }, options: [ { - displayName: 'ID', - name: 'id', + displayName: 'Channel ID', + name: 'channelId', type: 'string', default: '', - description: `The id parameter specifies a comma-separated list of the YouTube video ID(s) for the resource(s) that are being retrieved. In a video resource, the id property specifies the video's YouTube video ID.`, + description: `The channelId parameter indicates that the API response should only contain resources created by the channel.`, }, { - displayName: 'My Rating', - name: 'myRating', - type: 'options', - options: [ - { - name: 'Dislike', - value: 'dislike', - }, - { - name: 'Like', - value: 'like', - }, - ], + displayName: 'For Developer', + name: 'forDeveloper', + type: 'boolean', + default: false, + description: `The forDeveloper parameter restricts the search to only retrieve videos uploaded via the developer's application or website`, + }, + { + displayName: 'Published After', + name: 'publishedAfter', + type: 'dateTime', default: '', - description: `Set this parameter's value to like or dislike to instruct the API to only return videos liked or disliked by the authenticated user.`, + description: `The publishedAfter parameter indicates that the API response should only contain resources created at or after the specified time.`, + }, + { + displayName: 'Published Before', + name: 'publishedBefore', + type: 'dateTime', + default: '', + description: `The publishedBefore parameter indicates that the API response should only contain resources created before or at the specified time.`, + }, + { + displayName: 'Query', + name: 'q', + type: 'string', + default: '', + description: `The q parameter specifies the query term to search for.`, }, { displayName: 'Region Code', @@ -570,6 +519,13 @@ export const videoFields = [ default: '', description: `The regionCode parameter instructs the API to select a video chart available in the specified region.`, }, + { + displayName: 'Related To Video ID', + name: 'relatedToVideoId', + type: 'string', + default: '', + description: 'The relatedToVideoId parameter retrieves a list of videos that are related to the video that the parameter value identifies', + }, { displayName: 'Video Category ID', name: 'videoCategoryId', @@ -577,6 +533,34 @@ export const videoFields = [ default: '', description: `The videoCategoryId parameter identifies the video category for which the chart should be retrieved.`, }, + { + displayName: 'Video Syndicated ', + name: 'videoSyndicated', + type: 'boolean', + default: false, + description: `The videoSyndicated parameter lets you to restrict a search to only videos that can be played outside youtube.com.`, + }, + { + displayName: 'Video Type', + name: 'videoType', + type: 'options', + options: [ + { + name: 'Any', + value: 'any', + }, + { + name: 'Episode', + value: 'episode', + }, + { + name: 'Movie', + value: 'movie', + }, + ], + default: '', + description: `The videoType parameter lets you restrict a search to a particular type of videos`, + }, ], }, { @@ -597,12 +581,43 @@ export const videoFields = [ }, options: [ { - displayName: 'On Behalf Of Content Owner', - name: 'onBehalfOfContentOwner', - type: 'string', + displayName: 'Order', + name: 'order', + type: 'options', + options: [ + { + name: 'Date', + value: 'date', + }, + { + name: 'Relevance', + value: 'relevance', + }, + ], + default: 'relevance', + }, + { + displayName: 'Safe Search', + name: 'safeSearch', + type: 'options', + options: [ + { + name: 'Moderate', + value: 'moderate', + description: 'YouTube will filter some content from search results and, at the least, will filter content that is restricted in your locale', + }, + { + name: 'none', + value: 'none', + description: 'YouTube will not filter the search result set', + }, + { + name: 'Strict', + value: 'strict', + description: 'YouTube will try to exclude all restricted content from the search result set', + }, + ], default: '', - description: `The onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify
- a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value`, }, ], }, diff --git a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts index 0c09c391dd..e838bdad46 100644 --- a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts +++ b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts @@ -184,9 +184,23 @@ export class YouTube implements INodeType { if (resource === 'channel') { if (operation === 'get') { //https://developers.google.com/youtube/v3/docs/channels/list - const part = this.getNodeParameter('part', i) as string[]; + let part = this.getNodeParameter('part', i) as string[]; const channelId = this.getNodeParameter('channelId', i) as string; + if (part.includes('*')) { + part = [ + 'brandingSettings', + 'contentDetails', + 'contentOwnerDetails', + 'id', + 'localizations', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; + } + qs.part = part.join(','); qs.id = channelId; @@ -204,10 +218,24 @@ export class YouTube implements INodeType { //https://developers.google.com/youtube/v3/docs/channels/list if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const part = this.getNodeParameter('part', i) as string[]; + let part = this.getNodeParameter('part', i) as string[]; const options = this.getNodeParameter('options', i) as IDataObject; const filters = this.getNodeParameter('filters', i) as IDataObject; + if (part.includes('*')) { + part = [ + 'brandingSettings', + 'contentDetails', + 'contentOwnerDetails', + 'id', + 'localizations', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; + } + qs.part = part.join(','); Object.assign(qs, options, filters); @@ -392,10 +420,21 @@ export class YouTube implements INodeType { if (resource === 'playlist') { //https://developers.google.com/youtube/v3/docs/playlists/list if (operation === 'get') { - const part = this.getNodeParameter('part', i) as string[]; + let part = this.getNodeParameter('part', i) as string[]; const playlistId = this.getNodeParameter('playlistId', i) as string; const options = this.getNodeParameter('options', i) as IDataObject; + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'localizations', + 'player', + 'snippet', + 'status', + ]; + } + qs.part = part.join(','); qs.id = playlistId; @@ -415,10 +454,21 @@ export class YouTube implements INodeType { //https://developers.google.com/youtube/v3/docs/playlists/list if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const part = this.getNodeParameter('part', i) as string[]; + let part = this.getNodeParameter('part', i) as string[]; const options = this.getNodeParameter('options', i) as IDataObject; const filters = this.getNodeParameter('filters', i) as IDataObject; + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'localizations', + 'player', + 'snippet', + 'status', + ]; + } + qs.part = part.join(','); Object.assign(qs, options, filters); @@ -567,21 +617,26 @@ export class YouTube implements INodeType { } } if (resource === 'video') { - //https://developers.google.com/youtube/v3/docs/videos/list?hl=en + //https://developers.google.com/youtube/v3/docs/search/list if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; - const part = this.getNodeParameter('part', i) as string[]; const options = this.getNodeParameter('options', i) as IDataObject; const filters = this.getNodeParameter('filters', i) as IDataObject; - qs.part = part.join(','); + qs.part = 'snippet'; - qs.chart = 'mostPopular'; + qs.type = 'video'; + + qs.forMine = true; Object.assign(qs, options, filters); - if (qs.myRating) { - delete qs.chart; + if (Object.keys(filters).length > 0) { + delete qs.forMine; + } + + if (qs.relatedToVideoId && qs.forDeveloper !== undefined) { + throw new Error(`When using the parameter 'related to video' the parameter 'for developer' cannot be set`); } if (returnAll) { @@ -589,7 +644,7 @@ export class YouTube implements INodeType { this, 'items', 'GET', - `/youtube/v3/videos`, + `/youtube/v3/search`, {}, qs ); @@ -598,7 +653,7 @@ export class YouTube implements INodeType { responseData = await googleApiRequest.call( this, 'GET', - `/youtube/v3/videos`, + `/youtube/v3/search`, {}, qs ); @@ -607,10 +662,25 @@ export class YouTube implements INodeType { } //https://developers.google.com/youtube/v3/docs/videos/list?hl=en if (operation === 'get') { - const part = this.getNodeParameter('part', i) as string[]; + let part = this.getNodeParameter('part', i) as string[]; const videoId = this.getNodeParameter('videoId', i) as string; const options = this.getNodeParameter('options', i) as IDataObject; + if (part.includes('*')) { + part = [ + 'contentDetails', + 'id', + 'liveStreamingDetails', + 'localizations', + 'player', + 'recordingDetails', + 'snippet', + 'statistics', + 'status', + 'topicDetails', + ]; + } + qs.part = part.join(','); qs.id = videoId; @@ -812,8 +882,6 @@ export class YouTube implements INodeType { body.snippet.defaultLanguage = updateFields.defaultLanguage as string; } - console.log(body) - responseData = await googleApiRequest.call( this, 'PUT', @@ -838,7 +906,7 @@ export class YouTube implements INodeType { responseData = await googleApiRequest.call( this, 'DELETE', - '/youtube/v3/video', + '/youtube/v3/videos', body, );