diff --git a/packages/nodes-base/credentials/YouTubeOAuth2Api.credentials.ts b/packages/nodes-base/credentials/YouTubeOAuth2Api.credentials.ts index 46171f511..5f1e6bfb9 100644 --- a/packages/nodes-base/credentials/YouTubeOAuth2Api.credentials.ts +++ b/packages/nodes-base/credentials/YouTubeOAuth2Api.credentials.ts @@ -9,6 +9,7 @@ const scopes = [ 'https://www.googleapis.com/auth/youtubepartner', 'https://www.googleapis.com/auth/youtube.force-ssl', 'https://www.googleapis.com/auth/youtube.upload', + 'https://www.googleapis.com/auth/youtubepartner-channel-audit', ]; export class YouTubeOAuth2Api implements ICredentialType { diff --git a/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts b/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts index 1d02dbae6..6db5d3a99 100644 --- a/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts +++ b/packages/nodes-base/nodes/Google/YouTube/ChannelDescription.ts @@ -142,8 +142,8 @@ export const channelFields = [ description: 'How many results to return.', }, { - displayName: 'Options', - name: 'options', + displayName: 'Filters', + name: 'filters', type: 'collection', placeholder: 'Add Option', default: {}, @@ -193,6 +193,25 @@ export const channelFields = [ default: false, description: `This parameter can only be used in a properly authorized request. Set this parameter's value to true to instruct the API to only return channels owned by the authenticated user.`, }, + ], + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'channel', + ], + }, + }, + options: [ { displayName: 'Language Code', name: 'h1', diff --git a/packages/nodes-base/nodes/Google/YouTube/CountryCodes.ts b/packages/nodes-base/nodes/Google/YouTube/CountryCodes.ts new file mode 100644 index 000000000..3c41a76c7 --- /dev/null +++ b/packages/nodes-base/nodes/Google/YouTube/CountryCodes.ts @@ -0,0 +1,1579 @@ +export const countriesCodes = [ + { + 'name': 'Afghanistan', + 'alpha2': 'AF', + 'alpha3': 'AFG', + 'numeric': '004' + }, + { + 'name': 'Åland Islands', + 'alpha2': 'AX', + 'alpha3': 'ALA', + 'numeric': '248', + 'altName': 'Aland Islands' + }, + { + 'name': 'Albania', + 'alpha2': 'AL', + 'alpha3': 'ALB', + 'numeric': '008' + }, + { + 'name': 'Algeria', + 'alpha2': 'DZ', + 'alpha3': 'DZA', + 'numeric': '012' + }, + { + 'name': 'American Samoa', + 'alpha2': 'AS', + 'alpha3': 'ASM', + 'numeric': '016' + }, + { + 'name': 'Andorra', + 'alpha2': 'AD', + 'alpha3': 'AND', + 'numeric': '020' + }, + { + 'name': 'Angola', + 'alpha2': 'AO', + 'alpha3': 'AGO', + 'numeric': '024' + }, + { + 'name': 'Anguilla', + 'alpha2': 'AI', + 'alpha3': 'AIA', + 'numeric': '660' + }, + { + 'name': 'Antarctica', + 'alpha2': 'AQ', + 'alpha3': 'ATA', + 'numeric': '010' + }, + { + 'name': 'Antigua and Barbuda', + 'alpha2': 'AG', + 'alpha3': 'ATG', + 'numeric': '028' + }, + { + 'name': 'Argentina', + 'alpha2': 'AR', + 'alpha3': 'ARG', + 'numeric': '032' + }, + { + 'name': 'Armenia', + 'alpha2': 'AM', + 'alpha3': 'ARM', + 'numeric': '051' + }, + { + 'name': 'Aruba', + 'alpha2': 'AW', + 'alpha3': 'ABW', + 'numeric': '533' + }, + { + 'name': 'Australia', + 'alpha2': 'AU', + 'alpha3': 'AUS', + 'numeric': '036' + }, + { + 'name': 'Austria', + 'alpha2': 'AT', + 'alpha3': 'AUT', + 'numeric': '040' + }, + { + 'name': 'Azerbaijan', + 'alpha2': 'AZ', + 'alpha3': 'AZE', + 'numeric': '031' + }, + { + 'name': 'Bahamas (the)', + 'alpha2': 'BS', + 'alpha3': 'BHS', + 'numeric': '044', + 'altName': 'Bahamas' + }, + { + 'name': 'Bahrain', + 'alpha2': 'BH', + 'alpha3': 'BHR', + 'numeric': '048' + }, + { + 'name': 'Bangladesh', + 'alpha2': 'BD', + 'alpha3': 'BGD', + 'numeric': '050' + }, + { + 'name': 'Barbados', + 'alpha2': 'BB', + 'alpha3': 'BRB', + 'numeric': '052' + }, + { + 'name': 'Belarus', + 'alpha2': 'BY', + 'alpha3': 'BLR', + 'numeric': '112' + }, + { + 'name': 'Belgium', + 'alpha2': 'BE', + 'alpha3': 'BEL', + 'numeric': '056' + }, + { + 'name': 'Belize', + 'alpha2': 'BZ', + 'alpha3': 'BLZ', + 'numeric': '084' + }, + { + 'name': 'Benin', + 'alpha2': 'BJ', + 'alpha3': 'BEN', + 'numeric': '204' + }, + { + 'name': 'Bermuda', + 'alpha2': 'BM', + 'alpha3': 'BMU', + 'numeric': '060' + }, + { + 'name': 'Bhutan', + 'alpha2': 'BT', + 'alpha3': 'BTN', + 'numeric': '064' + }, + { + 'name': 'Bolivia (Plurinational State of)', + 'alpha2': 'BO', + 'alpha3': 'BOL', + 'numeric': '068', + 'altName': 'Bolivia' + }, + { + 'name': 'Bonaire, Sint Eustatius and Saba', + 'alpha2': 'BQ', + 'alpha3': 'BES', + 'numeric': '535' + }, + { + 'name': 'Bosnia and Herzegovina', + 'alpha2': 'BA', + 'alpha3': 'BIH', + 'numeric': '070' + }, + { + 'name': 'Botswana', + 'alpha2': 'BW', + 'alpha3': 'BWA', + 'numeric': '072' + }, + { + 'name': 'Bouvet Island', + 'alpha2': 'BV', + 'alpha3': 'BVT', + 'numeric': '074' + }, + { + 'name': 'Brazil', + 'alpha2': 'BR', + 'alpha3': 'BRA', + 'numeric': '076' + }, + { + 'name': 'British Indian Ocean Territory (the)', + 'alpha2': 'IO', + 'alpha3': 'IOT', + 'numeric': '086', + 'altName': 'British Indian Ocean Territory' + }, + { + 'name': 'Brunei Darussalam', + 'alpha2': 'BN', + 'alpha3': 'BRN', + 'numeric': '096', + 'shortName': 'Brunei' + }, + { + 'name': 'Bulgaria', + 'alpha2': 'BG', + 'alpha3': 'BGR', + 'numeric': '100' + }, + { + 'name': 'Burkina Faso', + 'alpha2': 'BF', + 'alpha3': 'BFA', + 'numeric': '854' + }, + { + 'name': 'Burundi', + 'alpha2': 'BI', + 'alpha3': 'BDI', + 'numeric': '108' + }, + { + 'name': 'Cabo Verde', + 'alpha2': 'CV', + 'alpha3': 'CPV', + 'numeric': '132', + 'altName': 'Cape Verde' + }, + { + 'name': 'Cambodia', + 'alpha2': 'KH', + 'alpha3': 'KHM', + 'numeric': '116' + }, + { + 'name': 'Cameroon', + 'alpha2': 'CM', + 'alpha3': 'CMR', + 'numeric': '120' + }, + { + 'name': 'Canada', + 'alpha2': 'CA', + 'alpha3': 'CAN', + 'numeric': '124' + }, + { + 'name': 'Cayman Islands (the)', + 'alpha2': 'KY', + 'alpha3': 'CYM', + 'numeric': '136', + 'altName': 'Cayman Islands' + }, + { + 'name': 'Central African Republic (the)', + 'alpha2': 'CF', + 'alpha3': 'CAF', + 'numeric': '140', + 'altName': 'Central African Republic' + }, + { + 'name': 'Chad', + 'alpha2': 'TD', + 'alpha3': 'TCD', + 'numeric': '148' + }, + { + 'name': 'Chile', + 'alpha2': 'CL', + 'alpha3': 'CHL', + 'numeric': '152' + }, + { + 'name': 'China', + 'alpha2': 'CN', + 'alpha3': 'CHN', + 'numeric': '156' + }, + { + 'name': 'Christmas Island', + 'alpha2': 'CX', + 'alpha3': 'CXR', + 'numeric': '162' + }, + { + 'name': 'Cocos (Keeling) Islands (the)', + 'alpha2': 'CC', + 'alpha3': 'CCK', + 'numeric': '166', + 'altName': 'Cocos (Keeling) Islands', + 'shortName': 'Cocos Islands' + }, + { + 'name': 'Colombia', + 'alpha2': 'CO', + 'alpha3': 'COL', + 'numeric': '170' + }, + { + 'name': 'Comoros (the)', + 'alpha2': 'KM', + 'alpha3': 'COM', + 'numeric': '174', + 'altName': 'Comoros' + }, + { + 'name': 'Congo (the Democratic Republic of the)', + 'alpha2': 'CD', + 'alpha3': 'COD', + 'numeric': '180', + 'altName': 'Congo, (Kinshasa)', + 'shortName': 'Democratic Republic of the Congo' + }, + { + 'name': 'Congo (the)', + 'alpha2': 'CG', + 'alpha3': 'COG', + 'numeric': '178', + 'altName': 'Congo (Brazzaville)', + 'shortName': 'Republic of the Congo' + }, + { + 'name': 'Cook Islands (the)', + 'alpha2': 'CK', + 'alpha3': 'COK', + 'numeric': '184', + 'altName': 'Cook Islands' + }, + { + 'name': 'Costa Rica', + 'alpha2': 'CR', + 'alpha3': 'CRI', + 'numeric': '188' + }, + { + 'name': 'Côte d\'Ivoire', + 'alpha2': 'CI', + 'alpha3': 'CIV', + 'numeric': '384', + 'shortName': 'Ivory Coast' + }, + { + 'name': 'Croatia', + 'alpha2': 'HR', + 'alpha3': 'HRV', + 'numeric': '191' + }, + { + 'name': 'Cuba', + 'alpha2': 'CU', + 'alpha3': 'CUB', + 'numeric': '192' + }, + { + 'name': 'Curaçao', + 'alpha2': 'CW', + 'alpha3': 'CUW', + 'numeric': '531', + 'shortName': 'Curacao' + }, + { + 'name': 'Cyprus', + 'alpha2': 'CY', + 'alpha3': 'CYP', + 'numeric': '196' + }, + { + 'name': 'Czechia', + 'alpha2': 'CZ', + 'alpha3': 'CZE', + 'numeric': '203', + 'altName': 'Czech Republic' + }, + { + 'name': 'Denmark', + 'alpha2': 'DK', + 'alpha3': 'DNK', + 'numeric': '208' + }, + { + 'name': 'Djibouti', + 'alpha2': 'DJ', + 'alpha3': 'DJI', + 'numeric': '262' + }, + { + 'name': 'Dominica', + 'alpha2': 'DM', + 'alpha3': 'DMA', + 'numeric': '212' + }, + { + 'name': 'Dominican Republic (the)', + 'alpha2': 'DO', + 'alpha3': 'DOM', + 'numeric': '214', + 'altName': 'Dominican Republic' + }, + { + 'name': 'Ecuador', + 'alpha2': 'EC', + 'alpha3': 'ECU', + 'numeric': '218' + }, + { + 'name': 'Egypt', + 'alpha2': 'EG', + 'alpha3': 'EGY', + 'numeric': '818' + }, + { + 'name': 'El Salvador', + 'alpha2': 'SV', + 'alpha3': 'SLV', + 'numeric': '222' + }, + { + 'name': 'Equatorial Guinea', + 'alpha2': 'GQ', + 'alpha3': 'GNQ', + 'numeric': '226' + }, + { + 'name': 'Eritrea', + 'alpha2': 'ER', + 'alpha3': 'ERI', + 'numeric': '232' + }, + { + 'name': 'Estonia', + 'alpha2': 'EE', + 'alpha3': 'EST', + 'numeric': '233' + }, + { + 'name': 'Ethiopia', + 'alpha2': 'ET', + 'alpha3': 'ETH', + 'numeric': '231' + }, + { + 'name': 'Falkland Islands (the) [Malvinas]', + 'alpha2': 'FK', + 'alpha3': 'FLK', + 'numeric': '238', + 'altName': 'Falkland Islands (Malvinas)', + 'shortName': 'Falkland Islands' + }, + { + 'name': 'Faroe Islands (the)', + 'alpha2': 'FO', + 'alpha3': 'FRO', + 'numeric': '234', + 'altName': 'Faroe Islands' + }, + { + 'name': 'Fiji', + 'alpha2': 'FJ', + 'alpha3': 'FJI', + 'numeric': '242' + }, + { + 'name': 'Finland', + 'alpha2': 'FI', + 'alpha3': 'FIN', + 'numeric': '246' + }, + { + 'name': 'France', + 'alpha2': 'FR', + 'alpha3': 'FRA', + 'numeric': '250' + }, + { + 'name': 'French Guiana', + 'alpha2': 'GF', + 'alpha3': 'GUF', + 'numeric': '254' + }, + { + 'name': 'French Polynesia', + 'alpha2': 'PF', + 'alpha3': 'PYF', + 'numeric': '258' + }, + { + 'name': 'French Southern Territories (the)', + 'alpha2': 'TF', + 'alpha3': 'ATF', + 'numeric': '260', + 'altName': 'French Southern Territories' + }, + { + 'name': 'Gabon', + 'alpha2': 'GA', + 'alpha3': 'GAB', + 'numeric': '266' + }, + { + 'name': 'Gambia (the)', + 'alpha2': 'GM', + 'alpha3': 'GMB', + 'numeric': '270', + 'altName': 'Gambia' + }, + { + 'name': 'Georgia', + 'alpha2': 'GE', + 'alpha3': 'GEO', + 'numeric': '268' + }, + { + 'name': 'Germany', + 'alpha2': 'DE', + 'alpha3': 'DEU', + 'numeric': '276' + }, + { + 'name': 'Ghana', + 'alpha2': 'GH', + 'alpha3': 'GHA', + 'numeric': '288' + }, + { + 'name': 'Gibraltar', + 'alpha2': 'GI', + 'alpha3': 'GIB', + 'numeric': '292' + }, + { + 'name': 'Greece', + 'alpha2': 'GR', + 'alpha3': 'GRC', + 'numeric': '300' + }, + { + 'name': 'Greenland', + 'alpha2': 'GL', + 'alpha3': 'GRL', + 'numeric': '304' + }, + { + 'name': 'Grenada', + 'alpha2': 'GD', + 'alpha3': 'GRD', + 'numeric': '308' + }, + { + 'name': 'Guadeloupe', + 'alpha2': 'GP', + 'alpha3': 'GLP', + 'numeric': '312' + }, + { + 'name': 'Guam', + 'alpha2': 'GU', + 'alpha3': 'GUM', + 'numeric': '316' + }, + { + 'name': 'Guatemala', + 'alpha2': 'GT', + 'alpha3': 'GTM', + 'numeric': '320' + }, + { + 'name': 'Guernsey', + 'alpha2': 'GG', + 'alpha3': 'GGY', + 'numeric': '831' + }, + { + 'name': 'Guinea', + 'alpha2': 'GN', + 'alpha3': 'GIN', + 'numeric': '324' + }, + { + 'name': 'Guinea-Bissau', + 'alpha2': 'GW', + 'alpha3': 'GNB', + 'numeric': '624' + }, + { + 'name': 'Guyana', + 'alpha2': 'GY', + 'alpha3': 'GUY', + 'numeric': '328' + }, + { + 'name': 'Haiti', + 'alpha2': 'HT', + 'alpha3': 'HTI', + 'numeric': '332' + }, + { + 'name': 'Heard Island and McDonald Islands', + 'alpha2': 'HM', + 'alpha3': 'HMD', + 'numeric': '334', + 'altName': 'Heard and Mcdonald Islands' + }, + { + 'name': 'Holy See (the)', + 'alpha2': 'VA', + 'alpha3': 'VAT', + 'numeric': '336', + 'altName': 'Holy See (Vatican City State)', + 'shortName': 'Vatican' + }, + { + 'name': 'Honduras', + 'alpha2': 'HN', + 'alpha3': 'HND', + 'numeric': '340' + }, + { + 'name': 'Hong Kong', + 'alpha2': 'HK', + 'alpha3': 'HKG', + 'numeric': '344', + 'altName': 'Hong Kong, SAR China' + }, + { + 'name': 'Hungary', + 'alpha2': 'HU', + 'alpha3': 'HUN', + 'numeric': '348' + }, + { + 'name': 'Iceland', + 'alpha2': 'IS', + 'alpha3': 'ISL', + 'numeric': '352' + }, + { + 'name': 'India', + 'alpha2': 'IN', + 'alpha3': 'IND', + 'numeric': '356' + }, + { + 'name': 'Indonesia', + 'alpha2': 'ID', + 'alpha3': 'IDN', + 'numeric': '360' + }, + { + 'name': 'Iran (Islamic Republic of)', + 'alpha2': 'IR', + 'alpha3': 'IRN', + 'numeric': '364', + 'altName': 'Iran, Islamic Republic of', + 'shortName': 'Iran' + }, + { + 'name': 'Iraq', + 'alpha2': 'IQ', + 'alpha3': 'IRQ', + 'numeric': '368' + }, + { + 'name': 'Ireland', + 'alpha2': 'IE', + 'alpha3': 'IRL', + 'numeric': '372' + }, + { + 'name': 'Isle of Man', + 'alpha2': 'IM', + 'alpha3': 'IMN', + 'numeric': '833' + }, + { + 'name': 'Israel', + 'alpha2': 'IL', + 'alpha3': 'ISR', + 'numeric': '376' + }, + { + 'name': 'Italy', + 'alpha2': 'IT', + 'alpha3': 'ITA', + 'numeric': '380' + }, + { + 'name': 'Jamaica', + 'alpha2': 'JM', + 'alpha3': 'JAM', + 'numeric': '388' + }, + { + 'name': 'Japan', + 'alpha2': 'JP', + 'alpha3': 'JPN', + 'numeric': '392' + }, + { + 'name': 'Jersey', + 'alpha2': 'JE', + 'alpha3': 'JEY', + 'numeric': '832' + }, + { + 'name': 'Jordan', + 'alpha2': 'JO', + 'alpha3': 'JOR', + 'numeric': '400' + }, + { + 'name': 'Kazakhstan', + 'alpha2': 'KZ', + 'alpha3': 'KAZ', + 'numeric': '398' + }, + { + 'name': 'Kenya', + 'alpha2': 'KE', + 'alpha3': 'KEN', + 'numeric': '404' + }, + { + 'name': 'Kiribati', + 'alpha2': 'KI', + 'alpha3': 'KIR', + 'numeric': '296' + }, + { + 'name': 'Korea (the Democratic People\'s Republic of)', + 'alpha2': 'KP', + 'alpha3': 'PRK', + 'numeric': '408', + 'altName': 'Korea (North)', + 'shortName': 'North Korea' + }, + { + 'name': 'Korea (the Republic of)', + 'alpha2': 'KR', + 'alpha3': 'KOR', + 'numeric': '410', + 'altName': 'Korea (South)', + 'shortName': 'South Korea' + }, + { + 'name': 'Kuwait', + 'alpha2': 'KW', + 'alpha3': 'KWT', + 'numeric': '414' + }, + { + 'name': 'Kyrgyzstan', + 'alpha2': 'KG', + 'alpha3': 'KGZ', + 'numeric': '417' + }, + { + 'name': 'Lao People\'s Democratic Republic (the)', + 'alpha2': 'LA', + 'alpha3': 'LAO', + 'numeric': '418', + 'altName': 'Lao PDR', + 'shortName': 'Laos' + }, + { + 'name': 'Latvia', + 'alpha2': 'LV', + 'alpha3': 'LVA', + 'numeric': '428' + }, + { + 'name': 'Lebanon', + 'alpha2': 'LB', + 'alpha3': 'LBN', + 'numeric': '422' + }, + { + 'name': 'Lesotho', + 'alpha2': 'LS', + 'alpha3': 'LSO', + 'numeric': '426' + }, + { + 'name': 'Liberia', + 'alpha2': 'LR', + 'alpha3': 'LBR', + 'numeric': '430' + }, + { + 'name': 'Libya', + 'alpha2': 'LY', + 'alpha3': 'LBY', + 'numeric': '434' + }, + { + 'name': 'Liechtenstein', + 'alpha2': 'LI', + 'alpha3': 'LIE', + 'numeric': '438' + }, + { + 'name': 'Lithuania', + 'alpha2': 'LT', + 'alpha3': 'LTU', + 'numeric': '440' + }, + { + 'name': 'Luxembourg', + 'alpha2': 'LU', + 'alpha3': 'LUX', + 'numeric': '442' + }, + { + 'name': 'Macao', + 'alpha2': 'MO', + 'alpha3': 'MAC', + 'numeric': '446', + 'altName': 'Macao, SAR China', + 'shortName': 'Macau' + }, + { + 'name': 'Macedonia (the former Yugoslav Republic of)', + 'alpha2': 'MK', + 'alpha3': 'MKD', + 'numeric': '807', + 'altName': 'Macedonia, Republic of', + 'shortName': 'Macedonia' + }, + { + 'name': 'Madagascar', + 'alpha2': 'MG', + 'alpha3': 'MDG', + 'numeric': '450' + }, + { + 'name': 'Malawi', + 'alpha2': 'MW', + 'alpha3': 'MWI', + 'numeric': '454' + }, + { + 'name': 'Malaysia', + 'alpha2': 'MY', + 'alpha3': 'MYS', + 'numeric': '458' + }, + { + 'name': 'Maldives', + 'alpha2': 'MV', + 'alpha3': 'MDV', + 'numeric': '462' + }, + { + 'name': 'Mali', + 'alpha2': 'ML', + 'alpha3': 'MLI', + 'numeric': '466' + }, + { + 'name': 'Malta', + 'alpha2': 'MT', + 'alpha3': 'MLT', + 'numeric': '470' + }, + { + 'name': 'Marshall Islands (the)', + 'alpha2': 'MH', + 'alpha3': 'MHL', + 'numeric': '584', + 'altName': 'Marshall Islands' + }, + { + 'name': 'Martinique', + 'alpha2': 'MQ', + 'alpha3': 'MTQ', + 'numeric': '474' + }, + { + 'name': 'Mauritania', + 'alpha2': 'MR', + 'alpha3': 'MRT', + 'numeric': '478' + }, + { + 'name': 'Mauritius', + 'alpha2': 'MU', + 'alpha3': 'MUS', + 'numeric': '480' + }, + { + 'name': 'Mayotte', + 'alpha2': 'YT', + 'alpha3': 'MYT', + 'numeric': '175' + }, + { + 'name': 'Mexico', + 'alpha2': 'MX', + 'alpha3': 'MEX', + 'numeric': '484' + }, + { + 'name': 'Micronesia (Federated States of)', + 'alpha2': 'FM', + 'alpha3': 'FSM', + 'numeric': '583', + 'altName': 'Micronesia, Federated States of', + 'shortName': 'Micronesia' + }, + { + 'name': 'Moldova (the Republic of)', + 'alpha2': 'MD', + 'alpha3': 'MDA', + 'numeric': '498', + 'altName': 'Moldova' + }, + { + 'name': 'Monaco', + 'alpha2': 'MC', + 'alpha3': 'MCO', + 'numeric': '492' + }, + { + 'name': 'Mongolia', + 'alpha2': 'MN', + 'alpha3': 'MNG', + 'numeric': '496' + }, + { + 'name': 'Montenegro', + 'alpha2': 'ME', + 'alpha3': 'MNE', + 'numeric': '499' + }, + { + 'name': 'Montserrat', + 'alpha2': 'MS', + 'alpha3': 'MSR', + 'numeric': '500' + }, + { + 'name': 'Morocco', + 'alpha2': 'MA', + 'alpha3': 'MAR', + 'numeric': '504' + }, + { + 'name': 'Mozambique', + 'alpha2': 'MZ', + 'alpha3': 'MOZ', + 'numeric': '508' + }, + { + 'name': 'Myanmar', + 'alpha2': 'MM', + 'alpha3': 'MMR', + 'numeric': '104' + }, + { + 'name': 'Namibia', + 'alpha2': 'NA', + 'alpha3': 'NAM', + 'numeric': '516' + }, + { + 'name': 'Nauru', + 'alpha2': 'NR', + 'alpha3': 'NRU', + 'numeric': '520' + }, + { + 'name': 'Nepal', + 'alpha2': 'NP', + 'alpha3': 'NPL', + 'numeric': '524' + }, + { + 'name': 'Netherlands (the)', + 'alpha2': 'NL', + 'alpha3': 'NLD', + 'numeric': '528', + 'altName': 'Netherlands' + }, + { + 'name': 'New Caledonia', + 'alpha2': 'NC', + 'alpha3': 'NCL', + 'numeric': '540' + }, + { + 'name': 'New Zealand', + 'alpha2': 'NZ', + 'alpha3': 'NZL', + 'numeric': '554' + }, + { + 'name': 'Nicaragua', + 'alpha2': 'NI', + 'alpha3': 'NIC', + 'numeric': '558' + }, + { + 'name': 'Niger (the)', + 'alpha2': 'NE', + 'alpha3': 'NER', + 'numeric': '562', + 'altName': 'Niger' + }, + { + 'name': 'Nigeria', + 'alpha2': 'NG', + 'alpha3': 'NGA', + 'numeric': '566' + }, + { + 'name': 'Niue', + 'alpha2': 'NU', + 'alpha3': 'NIU', + 'numeric': '570' + }, + { + 'name': 'Norfolk Island', + 'alpha2': 'NF', + 'alpha3': 'NFK', + 'numeric': '574' + }, + { + 'name': 'Northern Mariana Islands (the)', + 'alpha2': 'MP', + 'alpha3': 'MNP', + 'numeric': '580', + 'altName': 'Northern Mariana Islands' + }, + { + 'name': 'Norway', + 'alpha2': 'NO', + 'alpha3': 'NOR', + 'numeric': '578' + }, + { + 'name': 'Oman', + 'alpha2': 'OM', + 'alpha3': 'OMN', + 'numeric': '512' + }, + { + 'name': 'Pakistan', + 'alpha2': 'PK', + 'alpha3': 'PAK', + 'numeric': '586' + }, + { + 'name': 'Palau', + 'alpha2': 'PW', + 'alpha3': 'PLW', + 'numeric': '585' + }, + { + 'name': 'Palestine, State of', + 'alpha2': 'PS', + 'alpha3': 'PSE', + 'numeric': '275', + 'altName': 'Palestinian Territory', + 'shortName': 'Palestine' + }, + { + 'name': 'Panama', + 'alpha2': 'PA', + 'alpha3': 'PAN', + 'numeric': '591' + }, + { + 'name': 'Papua New Guinea', + 'alpha2': 'PG', + 'alpha3': 'PNG', + 'numeric': '598' + }, + { + 'name': 'Paraguay', + 'alpha2': 'PY', + 'alpha3': 'PRY', + 'numeric': '600' + }, + { + 'name': 'Peru', + 'alpha2': 'PE', + 'alpha3': 'PER', + 'numeric': '604' + }, + { + 'name': 'Philippines (the)', + 'alpha2': 'PH', + 'alpha3': 'PHL', + 'numeric': '608', + 'altName': 'Philippines' + }, + { + 'name': 'Pitcairn', + 'alpha2': 'PN', + 'alpha3': 'PCN', + 'numeric': '612' + }, + { + 'name': 'Poland', + 'alpha2': 'PL', + 'alpha3': 'POL', + 'numeric': '616' + }, + { + 'name': 'Portugal', + 'alpha2': 'PT', + 'alpha3': 'PRT', + 'numeric': '620' + }, + { + 'name': 'Puerto Rico', + 'alpha2': 'PR', + 'alpha3': 'PRI', + 'numeric': '630' + }, + { + 'name': 'Qatar', + 'alpha2': 'QA', + 'alpha3': 'QAT', + 'numeric': '634' + }, + { + 'name': 'Réunion', + 'alpha2': 'RE', + 'alpha3': 'REU', + 'numeric': '638', + 'shortName': 'Reunion' + }, + { + 'name': 'Romania', + 'alpha2': 'RO', + 'alpha3': 'ROU', + 'numeric': '642' + }, + { + 'name': 'Russian Federation (the)', + 'alpha2': 'RU', + 'alpha3': 'RUS', + 'numeric': '643', + 'altName': 'Russian Federation', + 'shortName': 'Russia' + }, + { + 'name': 'Rwanda', + 'alpha2': 'RW', + 'alpha3': 'RWA', + 'numeric': '646' + }, + { + 'name': 'Saint Barthélemy', + 'alpha2': 'BL', + 'alpha3': 'BLM', + 'numeric': '652', + 'altName': 'Saint-Barthélemy', + 'shortName': 'Saint Barthelemy' + }, + { + 'name': 'Saint Helena, Ascension and Tristan da Cunha', + 'alpha2': 'SH', + 'alpha3': 'SHN', + 'numeric': '654', + 'altName': 'Saint Helena' + }, + { + 'name': 'Saint Kitts and Nevis', + 'alpha2': 'KN', + 'alpha3': 'KNA', + 'numeric': '659' + }, + { + 'name': 'Saint Lucia', + 'alpha2': 'LC', + 'alpha3': 'LCA', + 'numeric': '662' + }, + { + 'name': 'Saint Martin (French part)', + 'alpha2': 'MF', + 'alpha3': 'MAF', + 'numeric': '663', + 'altName': 'Saint-Martin (French part)', + 'shortName': 'Saint Martin' + }, + { + 'name': 'Saint Pierre and Miquelon', + 'alpha2': 'PM', + 'alpha3': 'SPM', + 'numeric': '666' + }, + { + 'name': 'Saint Vincent and the Grenadines', + 'alpha2': 'VC', + 'alpha3': 'VCT', + 'numeric': '670', + 'altName': 'Saint Vincent and Grenadines' + }, + { + 'name': 'Samoa', + 'alpha2': 'WS', + 'alpha3': 'WSM', + 'numeric': '882' + }, + { + 'name': 'San Marino', + 'alpha2': 'SM', + 'alpha3': 'SMR', + 'numeric': '674' + }, + { + 'name': 'Sao Tome and Principe', + 'alpha2': 'ST', + 'alpha3': 'STP', + 'numeric': '678' + }, + { + 'name': 'Saudi Arabia', + 'alpha2': 'SA', + 'alpha3': 'SAU', + 'numeric': '682' + }, + { + 'name': 'Senegal', + 'alpha2': 'SN', + 'alpha3': 'SEN', + 'numeric': '686' + }, + { + 'name': 'Serbia', + 'alpha2': 'RS', + 'alpha3': 'SRB', + 'numeric': '688' + }, + { + 'name': 'Seychelles', + 'alpha2': 'SC', + 'alpha3': 'SYC', + 'numeric': '690' + }, + { + 'name': 'Sierra Leone', + 'alpha2': 'SL', + 'alpha3': 'SLE', + 'numeric': '694' + }, + { + 'name': 'Singapore', + 'alpha2': 'SG', + 'alpha3': 'SGP', + 'numeric': '702' + }, + { + 'name': 'Sint Maarten (Dutch part)', + 'alpha2': 'SX', + 'alpha3': 'SXM', + 'numeric': '534', + 'shortName': 'Sint Maarten' + }, + { + 'name': 'Slovakia', + 'alpha2': 'SK', + 'alpha3': 'SVK', + 'numeric': '703' + }, + { + 'name': 'Slovenia', + 'alpha2': 'SI', + 'alpha3': 'SVN', + 'numeric': '705' + }, + { + 'name': 'Solomon Islands', + 'alpha2': 'SB', + 'alpha3': 'SLB', + 'numeric': '090' + }, + { + 'name': 'Somalia', + 'alpha2': 'SO', + 'alpha3': 'SOM', + 'numeric': '706' + }, + { + 'name': 'South Africa', + 'alpha2': 'ZA', + 'alpha3': 'ZAF', + 'numeric': '710' + }, + { + 'name': 'South Georgia and the South Sandwich Islands', + 'alpha2': 'GS', + 'alpha3': 'SGS', + 'numeric': '239' + }, + { + 'name': 'South Sudan', + 'alpha2': 'SS', + 'alpha3': 'SSD', + 'numeric': '728' + }, + { + 'name': 'Spain', + 'alpha2': 'ES', + 'alpha3': 'ESP', + 'numeric': '724' + }, + { + 'name': 'Sri Lanka', + 'alpha2': 'LK', + 'alpha3': 'LKA', + 'numeric': '144' + }, + { + 'name': 'Sudan (the)', + 'alpha2': 'SD', + 'alpha3': 'SDN', + 'numeric': '729', + 'altName': 'Sudan' + }, + { + 'name': 'Suriname', + 'alpha2': 'SR', + 'alpha3': 'SUR', + 'numeric': '740' + }, + { + 'name': 'Svalbard and Jan Mayen', + 'alpha2': 'SJ', + 'alpha3': 'SJM', + 'numeric': '744', + 'altName': 'Svalbard and Jan Mayen Islands' + }, + { + 'name': 'Swaziland', + 'alpha2': 'SZ', + 'alpha3': 'SWZ', + 'numeric': '748' + }, + { + 'name': 'Sweden', + 'alpha2': 'SE', + 'alpha3': 'SWE', + 'numeric': '752' + }, + { + 'name': 'Switzerland', + 'alpha2': 'CH', + 'alpha3': 'CHE', + 'numeric': '756' + }, + { + 'name': 'Syrian Arab Republic', + 'alpha2': 'SY', + 'alpha3': 'SYR', + 'numeric': '760', + 'altName': 'Syrian Arab Republic (Syria)', + 'shortName': 'Syria' + }, + { + 'name': 'Taiwan (Province of China)', + 'alpha2': 'TW', + 'alpha3': 'TWN', + 'numeric': '158', + 'altName': 'Taiwan, Republic of China', + 'shortName': 'Taiwan' + }, + { + 'name': 'Tajikistan', + 'alpha2': 'TJ', + 'alpha3': 'TJK', + 'numeric': '762' + }, + { + 'name': 'Tanzania, United Republic of', + 'alpha2': 'TZ', + 'alpha3': 'TZA', + 'numeric': '834', + 'shortName': 'Tanzania' + }, + { + 'name': 'Thailand', + 'alpha2': 'TH', + 'alpha3': 'THA', + 'numeric': '764' + }, + { + 'name': 'Timor-Leste', + 'alpha2': 'TL', + 'alpha3': 'TLS', + 'numeric': '626', + 'shortName': 'East Timor' + }, + { + 'name': 'Togo', + 'alpha2': 'TG', + 'alpha3': 'TGO', + 'numeric': '768' + }, + { + 'name': 'Tokelau', + 'alpha2': 'TK', + 'alpha3': 'TKL', + 'numeric': '772' + }, + { + 'name': 'Tonga', + 'alpha2': 'TO', + 'alpha3': 'TON', + 'numeric': '776' + }, + { + 'name': 'Trinidad and Tobago', + 'alpha2': 'TT', + 'alpha3': 'TTO', + 'numeric': '780' + }, + { + 'name': 'Tunisia', + 'alpha2': 'TN', + 'alpha3': 'TUN', + 'numeric': '788' + }, + { + 'name': 'Turkey', + 'alpha2': 'TR', + 'alpha3': 'TUR', + 'numeric': '792' + }, + { + 'name': 'Turkmenistan', + 'alpha2': 'TM', + 'alpha3': 'TKM', + 'numeric': '795' + }, + { + 'name': 'Turks and Caicos Islands (the)', + 'alpha2': 'TC', + 'alpha3': 'TCA', + 'numeric': '796', + 'altName': 'Turks and Caicos Islands' + }, + { + 'name': 'Tuvalu', + 'alpha2': 'TV', + 'alpha3': 'TUV', + 'numeric': '798' + }, + { + 'name': 'Uganda', + 'alpha2': 'UG', + 'alpha3': 'UGA', + 'numeric': '800' + }, + { + 'name': 'Ukraine', + 'alpha2': 'UA', + 'alpha3': 'UKR', + 'numeric': '804' + }, + { + 'name': 'United Arab Emirates (the)', + 'alpha2': 'AE', + 'alpha3': 'ARE', + 'numeric': '784', + 'altName': 'United Arab Emirates' + }, + { + 'name': 'United Kingdom of Great Britain and Northern Ireland (the)', + 'alpha2': 'GB', + 'alpha3': 'GBR', + 'numeric': '826', + 'altName': 'United Kingdom' + }, + { + 'name': 'United States Minor Outlying Islands (the)', + 'alpha2': 'UM', + 'alpha3': 'UMI', + 'numeric': '581', + 'altName': 'US Minor Outlying Islands' + }, + { + 'name': 'United States of America (the)', + 'alpha2': 'US', + 'alpha3': 'USA', + 'numeric': '840', + 'altName': 'United States of America', + 'shortName': 'United States' + }, + { + 'name': 'Uruguay', + 'alpha2': 'UY', + 'alpha3': 'URY', + 'numeric': '858' + }, + { + 'name': 'Uzbekistan', + 'alpha2': 'UZ', + 'alpha3': 'UZB', + 'numeric': '860' + }, + { + 'name': 'Vanuatu', + 'alpha2': 'VU', + 'alpha3': 'VUT', + 'numeric': '548' + }, + { + 'name': 'Venezuela (Bolivarian Republic of)', + 'alpha2': 'VE', + 'alpha3': 'VEN', + 'numeric': '862', + 'altName': 'Venezuela (Bolivarian Republic)', + 'shortName': 'Venezuela' + }, + { + 'name': 'Viet Nam', + 'alpha2': 'VN', + 'alpha3': 'VNM', + 'numeric': '704', + 'shortName': 'Vietnam' + }, + { + 'name': 'Virgin Islands (British)', + 'alpha2': 'VG', + 'alpha3': 'VGB', + 'numeric': '092', + 'altName': 'British Virgin Islands' + }, + { + 'name': 'Virgin Islands (U.S.)', + 'alpha2': 'VI', + 'alpha3': 'VIR', + 'numeric': '850', + 'altName': 'Virgin Islands, US', + 'shortName': 'U.S. Virgin Islands' + }, + { + 'name': 'Wallis and Futuna', + 'alpha2': 'WF', + 'alpha3': 'WLF', + 'numeric': '876', + 'altName': 'Wallis and Futuna Islands' + }, + { + 'name': 'Western Sahara*', + 'alpha2': 'EH', + 'alpha3': 'ESH', + 'numeric': '732', + 'altName': 'Western Sahara' + }, + { + 'name': 'Yemen', + 'alpha2': 'YE', + 'alpha3': 'YEM', + 'numeric': '887' + }, + { + 'name': 'Zambia', + 'alpha2': 'ZM', + 'alpha3': 'ZMB', + 'numeric': '894' + }, + { + 'name': 'Zimbabwe', + 'alpha2': 'ZW', + 'alpha3': 'ZWE', + 'numeric': '716' + } +]; diff --git a/packages/nodes-base/nodes/Google/YouTube/GenericFunctions.ts b/packages/nodes-base/nodes/Google/YouTube/GenericFunctions.ts index 174f5755d..65ed4f182 100644 --- a/packages/nodes-base/nodes/Google/YouTube/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Google/YouTube/GenericFunctions.ts @@ -29,14 +29,26 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF if (Object.keys(body).length === 0) { delete options.body; } + //@ts-ignore return await this.helpers.requestOAuth2.call(this, 'youTubeOAuth2Api', options); } catch (error) { - if (error.response && error.response.body && error.response.body.error) { - let errors = error.response.body.error.errors; + let errors; + + if (error.response && error.response.body) { + + if (resource === '/upload/youtube/v3/videos') { + error.response.body = JSON.parse(error.response.body); + } + + if (error.response.body.error) { + + errors = error.response.body.error.errors; + + errors = errors.map((e: IDataObject) => e.message); + } - errors = errors.map((e: IDataObject) => e.message); // Try to return the error prettier throw new Error( `YouTube error response [${error.statusCode}]: ${errors.join('|')}` diff --git a/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts b/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts new file mode 100644 index 000000000..55b90fb63 --- /dev/null +++ b/packages/nodes-base/nodes/Google/YouTube/PlaylistDescription.ts @@ -0,0 +1,449 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const playlistOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + name: 'Create', + value: 'create', + description: 'Create a playlist', + }, + { + name: 'Delete', + value: 'delete', + description: 'Delete a playlist', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Retrieve all playlists', + }, + { + name: 'Update', + value: 'update', + description: 'Update a playlist', + }, + ], + default: 'getAll', + description: 'The operation to perform.' + } +] as INodeProperties[]; + +export const playlistFields = [ + /* -------------------------------------------------------------------------- */ + /* playlist:create */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Title', + name: 'title', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'playlist', + ], + }, + }, + default: '', + description: `The playlist's title.`, + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'create', + ], + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `The playlist's description.`, + }, + { + displayName: 'Privacy Status', + name: 'privacyStatus', + type: 'options', + options: [ + { + name: 'Private', + value: 'private', + }, + { + name: 'Public', + value: 'public', + }, + { + name: 'Unlisted', + value: 'unlistef', + }, + ], + default: '', + description: `The playlist's privacy status.`, + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: `Keyword tags associated with the playlist. Mulplie can be defined separated by comma`, + }, + { + displayName: 'Default Language', + name: 'defaultLanguage', + type: 'string', + default: '', + description: `The language of the text in the playlist resource's title and description properties.`, + }, + { + displayName: 'On Behalf Of Content Owner Channel', + name: 'onBehalfOfContentOwnerChannel', + type: 'string', + default: '', + description: `The onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added.
+ This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter.`, + }, + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* playlist:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Playlist ID', + name: 'playlistId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'playlist', + ], + }, + }, + default: '', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* playlist:getAll */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Fields', + name: 'part', + type: 'multiOptions', + options: [ + { + name: 'Content Details', + value: 'contentDetails', + }, + { + name: 'ID', + value: 'id', + }, + { + name: 'Localizations', + value: 'localizations', + }, + { + name: 'Player', + value: 'player', + }, + { + name: 'Snippet', + value: 'snippet', + }, + { + name: 'Status', + value: 'status', + }, + ], + required: true, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'playlist', + ], + }, + }, + description: 'The fields parameter specifies a comma-separated list of one or more playlist resource properties that the API response will include.', + default: '' + }, + { + displayName: 'Return All', + name: 'returnAll', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'playlist', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'playlist', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 500, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + displayName: 'Channel ID', + name: 'channelId', + type: 'string', + default: '', + description: `This value indicates that the API should only return the specified channel's playlists.`, + }, + { + displayName: 'ID', + name: 'id', + type: 'string', + default: '', + description: `The id parameter specifies a comma-separated list of the YouTube playlist ID(s) for the resource(s) that are being retrieved. In a playlist resource, the id property specifies the playlist's YouTube playlist ID.`, + }, + { + displayName: 'Mine', + name: 'mine', + type: 'boolean', + default: false, + description: `Set this parameter's value to true to instruct the API to only return playlists owned by the authenticated user.`, + }, + ], + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + displayName: 'On Behalf Of Content Owner Channel', + name: 'onBehalfOfContentOwnerChannel', + type: 'string', + default: '', + description: `The onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added.
+ This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter.`, + }, + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* playlist:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Playlist ID', + name: 'playlistId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'playlist', + ], + }, + }, + default: '', + description: `The playlist's title.`, + }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'playlist', + ], + }, + }, + options: [ + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `The playlist's description.`, + }, + { + displayName: 'Privacy Status', + name: 'privacyStatus', + type: 'options', + options: [ + { + name: 'Private', + value: 'private', + }, + { + name: 'Public', + value: 'public', + }, + { + name: 'Unlisted', + value: 'unlistef', + }, + ], + default: '', + description: `The playlist's privacy status.`, + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: `Keyword tags associated with the playlist. Mulplie can be defined separated by comma`, + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + }, + { + displayName: 'Default Language', + name: 'defaultLanguage', + type: 'string', + default: '', + description: `The language of the text in the playlist resource's title and description properties.`, + }, + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts b/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts new file mode 100644 index 000000000..b7c4f9d29 --- /dev/null +++ b/packages/nodes-base/nodes/Google/YouTube/VideoDescription.ts @@ -0,0 +1,862 @@ +import { + INodeProperties, +} from 'n8n-workflow'; + +export const videoOperations = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + displayOptions: { + show: { + resource: [ + 'video', + ], + }, + }, + options: [ + { + name: 'Delete', + value: 'delete', + description: 'Delete a video', + }, + { + name: 'Get', + value: 'get', + description: 'Get a video', + }, + { + name: 'Get All', + value: 'getAll', + description: 'Retrieve all videos', + }, + { + name: 'Rate', + value: 'rate', + description: 'Rate a video', + }, + { + name: 'Update', + value: 'update', + description: 'Update a video', + }, + { + name: 'Upload', + value: 'upload', + description: 'Upload a video', + }, + ], + default: 'getAll', + description: 'The operation to perform.' + } +] as INodeProperties[]; + +export const videoFields = [ + /* -------------------------------------------------------------------------- */ + /* video:upload */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Title', + name: 'title', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'upload', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + { + displayName: 'Country Code', + name: 'countryCode', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getCountriesCodes', + }, + displayOptions: { + show: { + operation: [ + 'upload', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + { + displayName: 'Category ID', + name: 'categoryId', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getVideoCategories', + loadOptionsDependsOn: [ + 'countryCode', + ], + }, + displayOptions: { + show: { + operation: [ + 'upload', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + { + displayName: 'Binary Property', + name: 'binaryProperty', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'upload', + ], + resource: [ + 'video', + ], + }, + }, + default: 'data', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'upload', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'Default Language', + name: 'defaultLanguage', + type: 'string', + default: '', + description: `The language of the text in the playlist resource's title and description properties.`, + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `The playlist's description.`, + }, + { + displayName: 'Embeddable', + name: 'embeddable', + type: 'boolean', + default: false, + description: `This value indicates whether the video can be embedded on another website.`, + }, + { + displayName: 'License', + name: 'license', + type: 'options', + options: [ + { + name: 'Creative Common', + value: 'creativeCommon', + }, + { + name: 'Youtube', + value: 'youtube', + }, + ], + default: false, + description: `The video's license.`, + }, + { + displayName: 'Notify Subscribers', + name: 'notifySubscribers', + type: 'boolean', + default: false, + description: `The notifySubscribers parameter indicates whether YouTube should send a notification about the new video to users who subscribe to the video's channel`, + }, + { + displayName: 'Privacy Status', + name: 'privacyStatus', + type: 'options', + options: [ + { + name: 'Private', + value: 'private', + }, + { + name: 'Public', + value: 'public', + }, + { + name: 'Unlisted', + value: 'unlistef', + }, + ], + default: '', + description: `The playlist's privacy status.`, + }, + { + displayName: 'Public Stats Viewable', + name: 'publicStatsViewable', + type: 'boolean', + default: true, + description: `This value indicates whether the extended video statistics on the video's watch page are publicly viewable.`, + }, + { + displayName: 'Publish At', + name: 'publishAt', + type: 'dateTime', + default: '', + description: `If you set a value for this property, you must also set the status.privacyStatus property to private.`, + }, + { + displayName: 'Recording Date', + name: 'recordingDate', + type: 'dateTime', + default: '', + description: `The date and time when the video was recorded`, + }, + { + displayName: 'Self Declared Made For Kids', + name: 'selfDeclaredMadeForKids', + type: 'boolean', + default: false, + description: `This value indicates whether the video is designated as child-directed, and it contains the current "made for kids" status of the video`, + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: `Keyword tags associated with the playlist. Mulplie can be defined separated by comma`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* video:delete */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Video ID', + name: 'videoId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'delete', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* video:get */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Video ID', + name: 'videoId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'video', + ], + }, + }, + default: '' + }, + { + displayName: 'Fields', + name: 'part', + type: 'multiOptions', + options: [ + { + name: 'Content Details', + value: 'contentDetails', + }, + { + name: 'Field Details', + value: 'fieldDetails', + }, + { + name: 'ID', + value: 'id', + }, + { + name: 'Live Streaming Details', + value: 'liveStreamingDetails', + }, + { + name: 'Localizations', + value: 'localizations', + }, + { + name: 'Player', + value: 'player', + }, + { + name: 'Processing Details', + value: 'processingDetails', + }, + { + 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: [ + 'get', + ], + 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: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'get', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* video:getAll */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Fields', + name: 'part', + type: 'multiOptions', + options: [ + { + name: 'Content Details', + value: 'contentDetails', + }, + { + name: 'File Details', + value: 'fileDetails', + }, + { + name: 'ID', + value: 'id', + }, + { + name: 'Live Streaming Details', + value: 'liveStreamingDetails', + }, + { + name: 'Localizations', + value: 'localizations', + }, + { + name: 'Player', + value: 'player', + }, + { + name: 'Processing Details', + value: 'processingDetails', + }, + { + 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', + type: 'boolean', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'video', + ], + }, + }, + default: false, + description: 'If all results should be returned or only up to a given limit.', + }, + { + displayName: 'Limit', + name: 'limit', + type: 'number', + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'video', + ], + returnAll: [ + false, + ], + }, + }, + typeOptions: { + minValue: 1, + maxValue: 500, + }, + default: 100, + description: 'How many results to return.', + }, + { + displayName: 'Filters', + name: 'filters', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'ID', + name: 'id', + 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.`, + }, + { + displayName: 'My Rating', + name: 'myRating', + type: 'options', + options: [ + { + name: 'Dislike', + value: 'dislike', + }, + { + name: 'Like', + value: 'like', + }, + ], + 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.`, + }, + { + displayName: 'Region Code', + name: 'regionCode', + type: 'options', + typeOptions: { + loadOptionsMethod: 'getCountriesCodes', + }, + default: '', + description: `The regionCode parameter instructs the API to select a video chart available in the specified region.`, + }, + { + displayName: 'Video Category ID', + name: 'videoCategoryId', + type: 'string', + default: '', + description: `The videoCategoryId parameter identifies the video category for which the chart should be retrieved.`, + }, + ], + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'getAll', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'On Behalf Of Content Owner', + name: 'onBehalfOfContentOwner', + type: 'string', + 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`, + }, + ], + }, + /* -------------------------------------------------------------------------- */ + /* video:rate */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Video ID', + name: 'videoId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'rate', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + { + displayName: 'Rating', + name: 'rating', + type: 'options', + displayOptions: { + show: { + operation: [ + 'rate', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + name: 'Dislike', + value: 'dislike', + description: 'Records that the authenticated user disliked the video.', + }, + { + name: 'Like', + value: 'like', + description: 'Records that the authenticated user liked the video.', + }, + { + name: 'None', + value: 'none', + description: 'Removes any rating that the authenticated user had previously set for the video.', + }, + ], + default: '', + }, + /* -------------------------------------------------------------------------- */ + /* video:update */ + /* -------------------------------------------------------------------------- */ + { + displayName: 'Video ID', + name: 'videoId', + type: 'string', + required: true, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'video', + ], + }, + }, + default: '', + }, + // { + // displayName: 'Country Code', + // name: 'countryCode', + // type: 'options', + // typeOptions: { + // loadOptionsMethod: 'getCountriesCodes', + // }, + // displayOptions: { + // show: { + // operation: [ + // 'update', + // ], + // resource: [ + // 'video', + // ], + // }, + // }, + // default: '', + // }, + // { + // displayName: 'Category ID', + // name: 'categoryId', + // type: 'options', + // typeOptions: { + // loadOptionsMethod: 'getVideoCategories', + // loadOptionsDependsOn: [ + // 'countryCode', + // ], + // }, + // displayOptions: { + // show: { + // operation: [ + // 'update', + // ], + // resource: [ + // 'video', + // ], + // }, + // }, + // default: '', + // }, + { + displayName: 'Update Fields', + name: 'updateFields', + type: 'collection', + placeholder: 'Add Option', + default: {}, + displayOptions: { + show: { + operation: [ + 'update', + ], + resource: [ + 'video', + ], + }, + }, + options: [ + { + displayName: 'Default Language', + name: 'defaultLanguage', + type: 'string', + default: '', + description: `The language of the text in the playlist resource's title and description properties.`, + }, + { + displayName: 'Description', + name: 'description', + type: 'string', + default: '', + description: `The playlist's description.`, + }, + { + displayName: 'Embeddable', + name: 'embeddable', + type: 'boolean', + default: false, + description: `This value indicates whether the video can be embedded on another website.`, + }, + { + displayName: 'License', + name: 'license', + type: 'options', + options: [ + { + name: 'Creative Common', + value: 'creativeCommon', + }, + { + name: 'Youtube', + value: 'youtube', + }, + ], + default: false, + description: `The video's license.`, + }, + { + displayName: 'Notify Subscribers', + name: 'notifySubscribers', + type: 'boolean', + default: false, + description: `The notifySubscribers parameter indicates whether YouTube should send a notification about the new video to users who subscribe to the video's channel`, + }, + { + displayName: 'Privacy Status', + name: 'privacyStatus', + type: 'options', + options: [ + { + name: 'Private', + value: 'private', + }, + { + name: 'Public', + value: 'public', + }, + { + name: 'Unlisted', + value: 'unlistef', + }, + ], + default: '', + description: `The playlist's privacy status.`, + }, + { + displayName: 'Public Stats Viewable', + name: 'publicStatsViewable', + type: 'boolean', + default: true, + description: `This value indicates whether the extended video statistics on the video's watch page are publicly viewable.`, + }, + { + displayName: 'Publish At', + name: 'publishAt', + type: 'dateTime', + default: '', + description: `If you set a value for this property, you must also set the status.privacyStatus property to private.`, + }, + { + displayName: 'Recording Date', + name: 'recordingDate', + type: 'dateTime', + default: '', + description: `The date and time when the video was recorded`, + }, + { + displayName: 'Self Declared Made For Kids', + name: 'selfDeclaredMadeForKids', + type: 'boolean', + default: false, + description: `This value indicates whether the video is designated as child-directed, and it contains the current "made for kids" status of the video`, + }, + { + displayName: 'Tags', + name: 'tags', + type: 'string', + default: '', + description: `Keyword tags associated with the playlist. Mulplie can be defined separated by comma`, + }, + { + displayName: 'Title', + name: 'title', + type: 'string', + default: '', + }, + ], + }, +] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts index 4621c06d5..fe9c8d530 100644 --- a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts +++ b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts @@ -1,5 +1,6 @@ import { - IExecuteFunctions, BINARY_ENCODING, + IExecuteFunctions, + BINARY_ENCODING, } from 'n8n-core'; import { @@ -21,6 +22,20 @@ import { channelFields, } from './ChannelDescription'; +import { + playlistOperations, + playlistFields, +} from './PlaylistDescription'; + +import { + videoOperations, + videoFields, +} from './VideoDescription'; + +import { + countriesCodes, +} from './CountryCodes'; + export class YouTube implements INodeType { description: INodeTypeDescription = { displayName: 'Youtube', @@ -52,12 +67,26 @@ export class YouTube implements INodeType { name: 'Channel', value: 'channel', }, + { + name: 'Playlist', + value: 'playlist', + }, + { + name: 'Video', + value: 'video', + }, ], default: 'channel', description: 'The resource to operate on.' }, ...channelOperations, ...channelFields, + + ...playlistOperations, + ...playlistFields, + + ...videoOperations, + ...videoFields, ], }; @@ -85,6 +114,48 @@ export class YouTube implements INodeType { } return returnData; }, + // Get all the countries codes to display them to user so that he can + // select them easily + async getCountriesCodes(this: ILoadOptionsFunctions): Promise { + const returnData: INodePropertyOptions[] = []; + for (const countryCode of countriesCodes) { + const countryCodeName = `${countryCode.name} - ${countryCode.alpha2}`; + const countryCodeId = countryCode.alpha2; + returnData.push({ + name: countryCodeName, + value: countryCodeId, + }); + } + return returnData; + }, + // Get all the video categories to display them to user so that he can + // select them easily + async getVideoCategories( + this: ILoadOptionsFunctions + ): Promise { + const countryCode = this.getCurrentNodeParameter('countryCode') as string; + const returnData: INodePropertyOptions[] = []; + const qs: IDataObject = {}; + qs.regionCode = countryCode; + qs.part = 'snippet'; + const categories = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + '/youtube/v3/videoCategories', + {}, + qs, + ); + for (const category of categories) { + const categoryName = category.snippet.title; + const categoryId = category.id; + returnData.push({ + name: categoryName, + value: categoryId + }); + } + return returnData; + }, } }; @@ -103,23 +174,24 @@ export class YouTube implements INodeType { 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(','); - if (options.categoryId) { - qs.categoryId = options.categoryId as string; + if (filters.categoryId) { + qs.categoryId = filters.categoryId as string; } - if (options.forUsername) { - qs.forUsername = options.forUsername as string; + if (filters.forUsername) { + qs.forUsername = filters.forUsername as string; } - if (options.id) { - qs.id = options.id as string; + if (filters.id) { + qs.id = filters.id as string; } - if (options.managedByMe) { - qs.managedByMe = options.managedByMe as boolean; + if (filters.managedByMe) { + qs.managedByMe = filters.managedByMe as boolean; } - if (options.mine) { - qs.mine = options.mine as boolean; + if (filters.mine) { + qs.mine = filters.mine as boolean; } if (options.h1) { qs.h1 = options.h1 as string; @@ -298,6 +370,446 @@ export class YouTube implements INodeType { ); } } + if (resource === 'playlist') { + //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[]; + const options = this.getNodeParameter('options', i) as IDataObject; + const filters = this.getNodeParameter('filters', i) as IDataObject; + + qs.part = part.join(','); + + Object.assign(qs, options, filters); + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/playlists`, + {}, + qs + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/playlists`, + {}, + qs + ); + responseData = responseData.items; + } + } + //https://developers.google.com/youtube/v3/docs/playlists/insert + if (operation === 'create') { + const title = this.getNodeParameter('title', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.part = 'snippet'; + + const body: IDataObject = { + snippet: { + title, + }, + }; + + if (options.tags) { + //@ts-ignore + body.snippet.tags = (options.tags as string).split(',') as string[]; + } + + if (options.description) { + //@ts-ignore + body.snippet.privacyStatus = options.privacyStatus as string; + } + + if (options.defaultLanguage) { + //@ts-ignore + body.snippet.defaultLanguage = options.defaultLanguage as string; + } + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + if (options.onBehalfOfContentOwnerChannel) { + qs.onBehalfOfContentOwnerChannel = options.onBehalfOfContentOwnerChannel as string; + } + + responseData = await googleApiRequest.call( + this, + 'POST', + '/youtube/v3/playlists', + body, + qs + ); + } + //https://developers.google.com/youtube/v3/docs/playlists/update + if (operation === 'update') { + const playlistId = this.getNodeParameter('playlistId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + qs.part = 'snippet'; + + const body: IDataObject = { + id: playlistId, + snippet: { + } + }; + + if (updateFields.tags) { + //@ts-ignore + body.snippet.tags = (updateFields.tags as string).split(',') as string[]; + } + + if (updateFields.title) { + //@ts-ignore + body.snippet.title = updateFields.title as string + } + + if (updateFields.description) { + //@ts-ignore + body.snippet.description = updateFields.description as string; + } + + if (updateFields.defaultLanguage) { + //@ts-ignore + body.snippet.defaultLanguage = updateFields.defaultLanguage as string; + } + + if (updateFields.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = updateFields.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + '/youtube/v3/playlists', + body, + qs + ); + } + //https://developers.google.com/youtube/v3/docs/playlists/delete + if (operation === 'delete') { + const playlistId = this.getNodeParameter('playlistId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + id: playlistId, + }; + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'DELETE', + '/youtube/v3/playlists', + body, + ); + + responseData = { success: true }; + } + } + if (resource === 'video') { + //https://developers.google.com/youtube/v3/docs/videos/list?hl=en + 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.chart = 'mostPopular'; + + Object.assign(qs, options, filters); + + if (returnAll) { + responseData = await googleApiRequestAllItems.call( + this, + 'items', + 'GET', + `/youtube/v3/videos`, + {}, + qs + ); + } else { + qs.maxResults = this.getNodeParameter('limit', i) as number; + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/videos`, + {}, + qs + ); + responseData = responseData.items; + } + } + //https://developers.google.com/youtube/v3/docs/videos/list?hl=en + if (operation === 'get') { + const part = this.getNodeParameter('part', i) as string[]; + const videoId = this.getNodeParameter('videoId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + qs.part = part.join(','); + + qs.id = videoId; + + Object.assign(qs, options); + + responseData = await googleApiRequest.call( + this, + 'GET', + `/youtube/v3/videos`, + {}, + qs + ); + + responseData = responseData.items; + } + //https://developers.google.com/youtube/v3/guides/uploading_a_video?hl=en + if (operation === 'upload') { + const title = this.getNodeParameter('title', i) as string; + const categoryId = this.getNodeParameter('categoryId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + const binaryProperty = this.getNodeParameter('binaryProperty', i) as string; + + let mimeType; + + // Is binary file to upload + const item = items[i]; + + if (item.binary === undefined) { + throw new Error('No binary data exists on item!'); + } + + if (item.binary[binaryProperty] === undefined) { + throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); + } + + if (item.binary[binaryProperty].mimeType) { + mimeType = item.binary[binaryProperty].mimeType; + } + + const body = Buffer.from(item.binary[binaryProperty].data, BINARY_ENCODING); + + const requestOptions = { + headers: { + 'Content-Type': mimeType, + }, + json: false, + }; + + let response = await googleApiRequest.call(this, 'POST', '/upload/youtube/v3/videos', body, qs, undefined, requestOptions); + + const { id } = JSON.parse(response); + + qs.part = 'snippet, status, recordingDetails'; + + const data = { + id, + snippet: { + title, + categoryId, + }, + status: { + }, + recordingDetails: { + }, + } + + if (options.description) { + //@ts-ignore + data.snippet.description = options.description as string; + } + + if (options.privacyStatus) { + //@ts-ignore + data.status.privacyStatus = options.privacyStatus as string; + } + + if (options.tags) { + //@ts-ignore + data.snippet.tags = (options.tags as string).split(',') as string[]; + } + + if (options.embeddable) { + //@ts-ignore + data.status.embeddable = options.embeddable as boolean; + } + + if (options.publicStatsViewable) { + //@ts-ignore + data.status.publicStatsViewable = options.publicStatsViewable as boolean; + } + + if (options.publishAt) { + //@ts-ignore + data.status.publishAt = options.publishAt as string; + } + + if (options.recordingDate) { + //@ts-ignore + data.recordingDetails.recordingDate = options.recordingDate as string; + } + + if (options.selfDeclaredMadeForKids) { + //@ts-ignore + data.status.selfDeclaredMadeForKids = options.selfDeclaredMadeForKids as boolean; + } + + if (options.license) { + //@ts-ignore + data.status.license = options.license as string; + } + + if (options.defaultLanguage) { + //@ts-ignore + data.snippet.defaultLanguage = options.defaultLanguage as string; + } + + if (options.notifySubscribers) { + qs.notifySubscribers = options.notifySubscribers; + delete options.notifySubscribers; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + `/youtube/v3/videos`, + data, + qs, + ); + } + //https://developers.google.com/youtube/v3/docs/playlists/update + if (operation === 'update') { + const id = this.getNodeParameter('videoId', i) as string; + //const categoryId = this.getNodeParameter('categoryId', i) as string; + const updateFields = this.getNodeParameter('updateFields', i) as IDataObject; + + qs.part = 'snippet, status, recordingDetails'; + + const body = { + id, + snippet: { + //categoryId, + }, + status: { + }, + recordingDetails: { + }, + } + + if (updateFields.description) { + //@ts-ignore + data.snippet.description = updateFields.description as string; + } + + if (updateFields.privacyStatus) { + //@ts-ignore + data.status.privacyStatus = updateFields.privacyStatus as string; + } + + if (updateFields.tags) { + //@ts-ignore + data.snippet.tags = (updateFields.tags as string).split(',') as string[]; + } + + if (updateFields.description) { + //@ts-ignore + data.snippet.title = updateFields.title as string; + } + + if (updateFields.embeddable) { + //@ts-ignore + data.status.embeddable = updateFields.embeddable as boolean; + } + + if (updateFields.publicStatsViewable) { + //@ts-ignore + data.status.publicStatsViewable = updateFields.publicStatsViewable as boolean; + } + + if (updateFields.publishAt) { + //@ts-ignore + data.status.publishAt = updateFields.publishAt as string; + } + + if (updateFields.recordingDate) { + //@ts-ignore + data.recordingDetails.recordingDate = updateFields.recordingDate as string; + } + + if (updateFields.selfDeclaredMadeForKids) { + //@ts-ignore + data.status.selfDeclaredMadeForKids = updateFields.selfDeclaredMadeForKids as boolean; + } + + if (updateFields.license) { + //@ts-ignore + data.status.license = options.license as string; + } + + if (updateFields.defaultLanguage) { + //@ts-ignore + data.snippet.defaultLanguage = updateFields.defaultLanguage as string; + } + + responseData = await googleApiRequest.call( + this, + 'PUT', + '/youtube/v3/videos', + body, + qs + ); + } + //https://developers.google.com/youtube/v3/docs/videos/delete?hl=en + if (operation === 'delete') { + const videoId = this.getNodeParameter('videoId', i) as string; + const options = this.getNodeParameter('options', i) as IDataObject; + + const body: IDataObject = { + id: videoId, + }; + + if (options.onBehalfOfContentOwner) { + qs.onBehalfOfContentOwner = options.onBehalfOfContentOwner as string; + } + + responseData = await googleApiRequest.call( + this, + 'DELETE', + '/youtube/v3/video', + body, + ); + + responseData = { success: true }; + } + //https://developers.google.com/youtube/v3/docs/videos/rate?hl=en + if (operation === 'rate') { + const videoId = this.getNodeParameter('videoId', i) as string; + const rating = this.getNodeParameter('rating', i) as string; + + const body: IDataObject = { + id: videoId, + rating, + }; + + responseData = await googleApiRequest.call( + this, + 'POST', + '/youtube/v3/videos/rate', + body, + ); + + responseData = { success: true }; + } + } } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]);