n8n-nodes-upload-post 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -35
- package/dist/nodes/UploadPost/UploadPost.node.d.ts +2 -0
- package/dist/nodes/UploadPost/UploadPost.node.js +654 -196
- package/dist/nodes/UploadPost/UploadPost.node.js.map +1 -1
- package/dist/package.json +4 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.UploadPost = void 0;
|
|
4
4
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const MANUAL_USER_VALUE = '__manual_user__';
|
|
6
|
+
const MANUAL_FACEBOOK_VALUE = '__manual_facebook__';
|
|
7
|
+
const MANUAL_LINKEDIN_VALUE = '__manual_linkedin__';
|
|
8
|
+
const MANUAL_PINTEREST_VALUE = '__manual_pinterest__';
|
|
5
9
|
class UploadPost {
|
|
6
10
|
constructor() {
|
|
7
11
|
this.description = {
|
|
@@ -81,12 +85,14 @@ class UploadPost {
|
|
|
81
85
|
displayOptions: { show: { resource: ['users'] } },
|
|
82
86
|
},
|
|
83
87
|
{
|
|
84
|
-
displayName: 'User Identifier',
|
|
88
|
+
displayName: 'User Identifier Name or ID',
|
|
85
89
|
name: 'user',
|
|
86
|
-
type: '
|
|
90
|
+
type: 'options',
|
|
91
|
+
noDataExpression: true,
|
|
87
92
|
required: true,
|
|
88
93
|
default: '',
|
|
89
|
-
description: '
|
|
94
|
+
description: 'Choose from your created profiles, or specify a profile name using an <a href="https://docs.n8n.io/code/expressions/">expression</a>. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
|
|
95
|
+
typeOptions: { loadOptionsMethod: 'getUserProfiles' },
|
|
90
96
|
displayOptions: {
|
|
91
97
|
show: {
|
|
92
98
|
resource: ['uploads', 'users'],
|
|
@@ -95,22 +101,28 @@ class UploadPost {
|
|
|
95
101
|
},
|
|
96
102
|
},
|
|
97
103
|
{
|
|
98
|
-
displayName: '
|
|
104
|
+
displayName: 'User Identifier (Manual Entry)',
|
|
105
|
+
name: 'userManual',
|
|
106
|
+
type: 'string',
|
|
107
|
+
required: true,
|
|
108
|
+
default: '',
|
|
109
|
+
description: 'Provide a profile name or ID when it does not appear in the list',
|
|
110
|
+
displayOptions: {
|
|
111
|
+
show: {
|
|
112
|
+
resource: ['uploads', 'users'],
|
|
113
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText', 'generateJwt'],
|
|
114
|
+
user: [MANUAL_USER_VALUE]
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
displayName: 'Platform Names or IDs',
|
|
99
120
|
name: 'platform',
|
|
100
121
|
type: 'multiOptions',
|
|
101
122
|
required: true,
|
|
102
|
-
|
|
103
|
-
{ name: 'Facebook', value: 'facebook' },
|
|
104
|
-
{ name: 'Instagram', value: 'instagram' },
|
|
105
|
-
{ name: 'LinkedIn', value: 'linkedin' },
|
|
106
|
-
{ name: 'Pinterest', value: 'pinterest' },
|
|
107
|
-
{ name: 'Threads', value: 'threads' },
|
|
108
|
-
{ name: 'TikTok', value: 'tiktok' },
|
|
109
|
-
{ name: 'X (Twitter)', value: 'x' },
|
|
110
|
-
{ name: 'YouTube', value: 'youtube' },
|
|
111
|
-
],
|
|
123
|
+
typeOptions: { loadOptionsMethod: 'getPlatforms' },
|
|
112
124
|
default: [],
|
|
113
|
-
description: '
|
|
125
|
+
description: 'Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
114
126
|
displayOptions: { show: { resource: ['uploads'], operation: ['uploadPhotos', 'uploadVideo', 'uploadText'] } },
|
|
115
127
|
},
|
|
116
128
|
{
|
|
@@ -178,6 +190,14 @@ class UploadPost {
|
|
|
178
190
|
description: 'Optional override for Pinterest title',
|
|
179
191
|
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['pinterest'] } },
|
|
180
192
|
},
|
|
193
|
+
{
|
|
194
|
+
displayName: 'Threads Title (Override)',
|
|
195
|
+
name: 'threadsTitle',
|
|
196
|
+
type: 'string',
|
|
197
|
+
default: '',
|
|
198
|
+
description: 'Optional override for Threads title',
|
|
199
|
+
displayOptions: { show: { operation: ['uploadText'], platform: ['threads'] } },
|
|
200
|
+
},
|
|
181
201
|
{
|
|
182
202
|
displayName: 'Description (Optional)',
|
|
183
203
|
name: 'description',
|
|
@@ -487,9 +507,10 @@ class UploadPost {
|
|
|
487
507
|
displayName: 'Target LinkedIn Page Name or ID',
|
|
488
508
|
name: 'targetLinkedinPageId',
|
|
489
509
|
type: 'options',
|
|
510
|
+
noDataExpression: true,
|
|
490
511
|
default: '',
|
|
491
512
|
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
492
|
-
typeOptions: { loadOptionsMethod: 'getLinkedinPages' },
|
|
513
|
+
typeOptions: { loadOptionsMethod: 'getLinkedinPages', loadOptionsDependsOn: ['user'] },
|
|
493
514
|
displayOptions: {
|
|
494
515
|
show: {
|
|
495
516
|
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
@@ -497,6 +518,21 @@ class UploadPost {
|
|
|
497
518
|
}
|
|
498
519
|
},
|
|
499
520
|
},
|
|
521
|
+
{
|
|
522
|
+
displayName: 'LinkedIn Page Name or ID (Manual Entry)',
|
|
523
|
+
name: 'targetLinkedinPageIdManual',
|
|
524
|
+
type: 'string',
|
|
525
|
+
required: true,
|
|
526
|
+
default: '',
|
|
527
|
+
description: 'Provide the LinkedIn page identifier when it does not appear in the list',
|
|
528
|
+
displayOptions: {
|
|
529
|
+
show: {
|
|
530
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
531
|
+
platform: ['linkedin'],
|
|
532
|
+
targetLinkedinPageId: [MANUAL_LINKEDIN_VALUE]
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
},
|
|
500
536
|
{
|
|
501
537
|
displayName: 'LinkedIn Video Description',
|
|
502
538
|
name: 'linkedinDescription',
|
|
@@ -514,10 +550,11 @@ class UploadPost {
|
|
|
514
550
|
displayName: 'Facebook Page Name or ID',
|
|
515
551
|
name: 'facebookPageId',
|
|
516
552
|
type: 'options',
|
|
553
|
+
noDataExpression: true,
|
|
517
554
|
required: true,
|
|
518
555
|
default: '',
|
|
519
556
|
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
520
|
-
typeOptions: { loadOptionsMethod: 'getFacebookPages' },
|
|
557
|
+
typeOptions: { loadOptionsMethod: 'getFacebookPages', loadOptionsDependsOn: ['user'] },
|
|
521
558
|
displayOptions: {
|
|
522
559
|
show: {
|
|
523
560
|
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
@@ -525,6 +562,21 @@ class UploadPost {
|
|
|
525
562
|
}
|
|
526
563
|
},
|
|
527
564
|
},
|
|
565
|
+
{
|
|
566
|
+
displayName: 'Facebook Page Name or ID (Manual Entry)',
|
|
567
|
+
name: 'facebookPageIdManual',
|
|
568
|
+
type: 'string',
|
|
569
|
+
required: true,
|
|
570
|
+
default: '',
|
|
571
|
+
description: 'Provide the Facebook page identifier when it does not appear in the list',
|
|
572
|
+
displayOptions: {
|
|
573
|
+
show: {
|
|
574
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
575
|
+
platform: ['facebook'],
|
|
576
|
+
facebookPageId: [MANUAL_FACEBOOK_VALUE]
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
},
|
|
528
580
|
{
|
|
529
581
|
displayName: 'Facebook Link (Text)',
|
|
530
582
|
name: 'facebookLink',
|
|
@@ -558,10 +610,9 @@ class UploadPost {
|
|
|
558
610
|
options: [
|
|
559
611
|
{ name: 'Published', value: 'PUBLISHED' },
|
|
560
612
|
{ name: 'Draft', value: 'DRAFT' },
|
|
561
|
-
{ name: 'Scheduled', value: 'SCHEDULED' },
|
|
562
613
|
],
|
|
563
614
|
default: 'PUBLISHED',
|
|
564
|
-
description: 'State for Facebook Video (DRAFT
|
|
615
|
+
description: 'State for Facebook Video (DRAFT or PUBLISHED). Use Scheduled Date field for scheduling.',
|
|
565
616
|
displayOptions: {
|
|
566
617
|
show: {
|
|
567
618
|
operation: ['uploadVideo'],
|
|
@@ -613,11 +664,12 @@ class UploadPost {
|
|
|
613
664
|
},
|
|
614
665
|
},
|
|
615
666
|
{
|
|
616
|
-
displayName: 'TikTok
|
|
617
|
-
name: '
|
|
618
|
-
type: '
|
|
619
|
-
default:
|
|
620
|
-
|
|
667
|
+
displayName: 'TikTok Photo Cover Index',
|
|
668
|
+
name: 'tiktokPhotoCoverIndex',
|
|
669
|
+
type: 'number',
|
|
670
|
+
default: 0,
|
|
671
|
+
typeOptions: { minValue: 0 },
|
|
672
|
+
description: 'Index (0-based) of photo to use as cover for TikTok photo post. Only for Upload Photos.',
|
|
621
673
|
displayOptions: {
|
|
622
674
|
show: {
|
|
623
675
|
operation: ['uploadPhotos'],
|
|
@@ -626,11 +678,11 @@ class UploadPost {
|
|
|
626
678
|
},
|
|
627
679
|
},
|
|
628
680
|
{
|
|
629
|
-
displayName: 'TikTok
|
|
630
|
-
name: '
|
|
631
|
-
type: '
|
|
632
|
-
default:
|
|
633
|
-
description: '
|
|
681
|
+
displayName: 'TikTok Photo Description',
|
|
682
|
+
name: 'tiktokPhotoDescription',
|
|
683
|
+
type: 'string',
|
|
684
|
+
default: '',
|
|
685
|
+
description: 'Description for TikTok photo post. If not provided, Title is used. Only for Upload Photos.',
|
|
634
686
|
displayOptions: {
|
|
635
687
|
show: {
|
|
636
688
|
operation: ['uploadPhotos'],
|
|
@@ -639,12 +691,11 @@ class UploadPost {
|
|
|
639
691
|
},
|
|
640
692
|
},
|
|
641
693
|
{
|
|
642
|
-
displayName: 'TikTok
|
|
643
|
-
name: '
|
|
644
|
-
type: '
|
|
645
|
-
default:
|
|
646
|
-
|
|
647
|
-
description: 'Index (0-based) of photo to use as cover for TikTok photo post. Only for Upload Photos.',
|
|
694
|
+
displayName: 'TikTok Brand Content Toggle (Photo)',
|
|
695
|
+
name: 'brand_content_toggle',
|
|
696
|
+
type: 'boolean',
|
|
697
|
+
default: false,
|
|
698
|
+
description: 'Whether to set as true for paid partnerships that promote third-party brands',
|
|
648
699
|
displayOptions: {
|
|
649
700
|
show: {
|
|
650
701
|
operation: ['uploadPhotos'],
|
|
@@ -653,11 +704,11 @@ class UploadPost {
|
|
|
653
704
|
},
|
|
654
705
|
},
|
|
655
706
|
{
|
|
656
|
-
displayName: 'TikTok Photo
|
|
657
|
-
name: '
|
|
658
|
-
type: '
|
|
659
|
-
default:
|
|
660
|
-
description: '
|
|
707
|
+
displayName: 'TikTok Brand Organic Toggle (Photo)',
|
|
708
|
+
name: 'brand_organic_toggle',
|
|
709
|
+
type: 'boolean',
|
|
710
|
+
default: false,
|
|
711
|
+
description: 'Whether to set as true when promoting the creator\'s own business',
|
|
661
712
|
displayOptions: {
|
|
662
713
|
show: {
|
|
663
714
|
operation: ['uploadPhotos'],
|
|
@@ -725,36 +776,10 @@ class UploadPost {
|
|
|
725
776
|
},
|
|
726
777
|
{
|
|
727
778
|
displayName: 'TikTok Brand Content Toggle (Video)',
|
|
728
|
-
name: '
|
|
779
|
+
name: 'brand_content_toggle',
|
|
729
780
|
type: 'boolean',
|
|
730
781
|
default: false,
|
|
731
|
-
description: 'Whether to enable
|
|
732
|
-
displayOptions: {
|
|
733
|
-
show: {
|
|
734
|
-
operation: ['uploadVideo'],
|
|
735
|
-
platform: ['tiktok']
|
|
736
|
-
},
|
|
737
|
-
},
|
|
738
|
-
},
|
|
739
|
-
{
|
|
740
|
-
displayName: 'TikTok Brand Organic (Video)',
|
|
741
|
-
name: 'tiktokBrandOrganic',
|
|
742
|
-
type: 'boolean',
|
|
743
|
-
default: false,
|
|
744
|
-
description: 'Whether to enable organic branded content for TikTok video. Only for Upload Video.',
|
|
745
|
-
displayOptions: {
|
|
746
|
-
show: {
|
|
747
|
-
operation: ['uploadVideo'],
|
|
748
|
-
platform: ['tiktok']
|
|
749
|
-
},
|
|
750
|
-
},
|
|
751
|
-
},
|
|
752
|
-
{
|
|
753
|
-
displayName: 'TikTok Branded Content (Video)',
|
|
754
|
-
name: 'tiktokBrandedContentVideo',
|
|
755
|
-
type: 'boolean',
|
|
756
|
-
default: false,
|
|
757
|
-
description: 'Whether to enable branded content with disclosure for TikTok video. Only for Upload Video.',
|
|
782
|
+
description: 'Whether to enable brand content toggle for paid partnerships that promote third-party brands',
|
|
758
783
|
displayOptions: {
|
|
759
784
|
show: {
|
|
760
785
|
operation: ['uploadVideo'],
|
|
@@ -764,10 +789,10 @@ class UploadPost {
|
|
|
764
789
|
},
|
|
765
790
|
{
|
|
766
791
|
displayName: 'TikTok Brand Organic Toggle (Video)',
|
|
767
|
-
name: '
|
|
792
|
+
name: 'brand_organic_toggle',
|
|
768
793
|
type: 'boolean',
|
|
769
794
|
default: false,
|
|
770
|
-
description: 'Whether to enable organic
|
|
795
|
+
description: 'Whether to enable brand organic toggle when promoting the creator\'s own business',
|
|
771
796
|
displayOptions: {
|
|
772
797
|
show: {
|
|
773
798
|
operation: ['uploadVideo'],
|
|
@@ -914,6 +939,31 @@ class UploadPost {
|
|
|
914
939
|
}
|
|
915
940
|
},
|
|
916
941
|
},
|
|
942
|
+
{
|
|
943
|
+
displayName: 'Threads Long Text as Single Post',
|
|
944
|
+
name: 'threadsLongTextAsPost',
|
|
945
|
+
type: 'boolean',
|
|
946
|
+
default: false,
|
|
947
|
+
description: 'Whether long text is published as a single post. If false (default), a thread is created if the text exceeds 500 characters.',
|
|
948
|
+
displayOptions: { show: { operation: ['uploadText'], platform: ['threads'] } },
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
displayName: 'Reddit Subreddit',
|
|
952
|
+
name: 'redditSubreddit',
|
|
953
|
+
type: 'string',
|
|
954
|
+
required: true,
|
|
955
|
+
default: '',
|
|
956
|
+
description: 'Destination subreddit, without r/ (e.g., python)',
|
|
957
|
+
displayOptions: { show: { operation: ['uploadText'], platform: ['reddit'] } },
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
displayName: 'Reddit Flair ID',
|
|
961
|
+
name: 'redditFlairId',
|
|
962
|
+
type: 'string',
|
|
963
|
+
default: '',
|
|
964
|
+
description: 'ID of the flair template to apply to the post',
|
|
965
|
+
displayOptions: { show: { operation: ['uploadText'], platform: ['reddit'] } },
|
|
966
|
+
},
|
|
917
967
|
{
|
|
918
968
|
displayName: 'YouTube Tags',
|
|
919
969
|
name: 'youtubeTags',
|
|
@@ -1027,20 +1077,142 @@ class UploadPost {
|
|
|
1027
1077
|
},
|
|
1028
1078
|
},
|
|
1029
1079
|
},
|
|
1080
|
+
{
|
|
1081
|
+
displayName: 'YouTube Self Declared Made For Kids',
|
|
1082
|
+
name: 'youtubeSelfDeclaredMadeForKids',
|
|
1083
|
+
type: 'boolean',
|
|
1084
|
+
default: false,
|
|
1085
|
+
description: 'Whether this is an explicit declaration for children content (COPPA compliance). Only for Upload Video.',
|
|
1086
|
+
displayOptions: {
|
|
1087
|
+
show: {
|
|
1088
|
+
operation: ['uploadVideo'],
|
|
1089
|
+
platform: ['youtube']
|
|
1090
|
+
},
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
displayName: 'YouTube Contains Synthetic Media',
|
|
1095
|
+
name: 'youtubeContainsSyntheticMedia',
|
|
1096
|
+
type: 'boolean',
|
|
1097
|
+
default: false,
|
|
1098
|
+
description: 'Whether this is a declaration for AI/synthetic content transparency. Only for Upload Video.',
|
|
1099
|
+
displayOptions: {
|
|
1100
|
+
show: {
|
|
1101
|
+
operation: ['uploadVideo'],
|
|
1102
|
+
platform: ['youtube']
|
|
1103
|
+
},
|
|
1104
|
+
},
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
displayName: 'YouTube Default Language',
|
|
1108
|
+
name: 'youtubeDefaultLanguage',
|
|
1109
|
+
type: 'string',
|
|
1110
|
+
default: '',
|
|
1111
|
+
description: 'Title/description language (BCP-47 codes like "es", "en"). Only for Upload Video.',
|
|
1112
|
+
displayOptions: {
|
|
1113
|
+
show: {
|
|
1114
|
+
operation: ['uploadVideo'],
|
|
1115
|
+
platform: ['youtube']
|
|
1116
|
+
},
|
|
1117
|
+
},
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
displayName: 'YouTube Default Audio Language',
|
|
1121
|
+
name: 'youtubeDefaultAudioLanguage',
|
|
1122
|
+
type: 'string',
|
|
1123
|
+
default: '',
|
|
1124
|
+
description: 'Video audio language (BCP-47 codes like "es-ES", "en-US"). Only for Upload Video.',
|
|
1125
|
+
displayOptions: {
|
|
1126
|
+
show: {
|
|
1127
|
+
operation: ['uploadVideo'],
|
|
1128
|
+
platform: ['youtube']
|
|
1129
|
+
},
|
|
1130
|
+
},
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
displayName: 'YouTube Allowed Countries',
|
|
1134
|
+
name: 'youtubeAllowedCountries',
|
|
1135
|
+
type: 'string',
|
|
1136
|
+
default: '',
|
|
1137
|
+
description: 'Comma-separated country codes for allowed regions (ISO 3166-1 alpha-2). Cannot be used with blocked countries. Only for Upload Video.',
|
|
1138
|
+
displayOptions: {
|
|
1139
|
+
show: {
|
|
1140
|
+
operation: ['uploadVideo'],
|
|
1141
|
+
platform: ['youtube']
|
|
1142
|
+
},
|
|
1143
|
+
},
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
displayName: 'YouTube Blocked Countries',
|
|
1147
|
+
name: 'youtubeBlockedCountries',
|
|
1148
|
+
type: 'string',
|
|
1149
|
+
default: '',
|
|
1150
|
+
description: 'Comma-separated country codes for blocked regions (ISO 3166-1 alpha-2). Cannot be used with allowed countries. Only for Upload Video.',
|
|
1151
|
+
displayOptions: {
|
|
1152
|
+
show: {
|
|
1153
|
+
operation: ['uploadVideo'],
|
|
1154
|
+
platform: ['youtube']
|
|
1155
|
+
},
|
|
1156
|
+
},
|
|
1157
|
+
},
|
|
1158
|
+
{
|
|
1159
|
+
displayName: 'YouTube Has Paid Product Placement',
|
|
1160
|
+
name: 'youtubeHasPaidProductPlacement',
|
|
1161
|
+
type: 'boolean',
|
|
1162
|
+
default: false,
|
|
1163
|
+
description: 'Whether this is a declaration for paid product placements (FTC compliance). Only for Upload Video.',
|
|
1164
|
+
displayOptions: {
|
|
1165
|
+
show: {
|
|
1166
|
+
operation: ['uploadVideo'],
|
|
1167
|
+
platform: ['youtube']
|
|
1168
|
+
},
|
|
1169
|
+
},
|
|
1170
|
+
},
|
|
1171
|
+
{
|
|
1172
|
+
displayName: 'YouTube Recording Date',
|
|
1173
|
+
name: 'youtubeRecordingDate',
|
|
1174
|
+
type: 'dateTime',
|
|
1175
|
+
default: '',
|
|
1176
|
+
description: 'Recording timestamp (ISO 8601 format). Only for Upload Video.',
|
|
1177
|
+
displayOptions: {
|
|
1178
|
+
show: {
|
|
1179
|
+
operation: ['uploadVideo'],
|
|
1180
|
+
platform: ['youtube']
|
|
1181
|
+
},
|
|
1182
|
+
},
|
|
1183
|
+
},
|
|
1030
1184
|
{
|
|
1031
1185
|
displayName: 'Pinterest Board Name or ID',
|
|
1032
1186
|
name: 'pinterestBoardId',
|
|
1033
1187
|
type: 'options',
|
|
1188
|
+
noDataExpression: true,
|
|
1034
1189
|
default: '',
|
|
1035
1190
|
description: 'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>',
|
|
1036
|
-
typeOptions: { loadOptionsMethod: 'getPinterestBoards' },
|
|
1191
|
+
typeOptions: { loadOptionsMethod: 'getPinterestBoards', loadOptionsDependsOn: ['user'] },
|
|
1037
1192
|
displayOptions: {
|
|
1038
1193
|
show: {
|
|
1039
1194
|
resource: ['uploads'],
|
|
1195
|
+
operation: ['uploadPhotos', 'uploadVideo'],
|
|
1040
1196
|
platform: ['pinterest']
|
|
1041
1197
|
},
|
|
1042
1198
|
},
|
|
1043
1199
|
},
|
|
1200
|
+
{
|
|
1201
|
+
displayName: 'Pinterest Board Name or ID (Manual Entry)',
|
|
1202
|
+
name: 'pinterestBoardIdManual',
|
|
1203
|
+
type: 'string',
|
|
1204
|
+
required: true,
|
|
1205
|
+
default: '',
|
|
1206
|
+
description: 'Provide the Pinterest board identifier when it does not appear in the list',
|
|
1207
|
+
displayOptions: {
|
|
1208
|
+
show: {
|
|
1209
|
+
resource: ['uploads'],
|
|
1210
|
+
operation: ['uploadPhotos', 'uploadVideo'],
|
|
1211
|
+
platform: ['pinterest'],
|
|
1212
|
+
pinterestBoardId: [MANUAL_PINTEREST_VALUE]
|
|
1213
|
+
},
|
|
1214
|
+
},
|
|
1215
|
+
},
|
|
1044
1216
|
{
|
|
1045
1217
|
displayName: 'Pinterest Link (Photo/Video)',
|
|
1046
1218
|
name: 'pinterestLink',
|
|
@@ -1113,45 +1285,47 @@ class UploadPost {
|
|
|
1113
1285
|
},
|
|
1114
1286
|
},
|
|
1115
1287
|
{
|
|
1116
|
-
displayName: 'X Tagged User IDs
|
|
1288
|
+
displayName: 'X Tagged User IDs',
|
|
1117
1289
|
name: 'xTaggedUserIds',
|
|
1118
1290
|
type: 'string',
|
|
1119
1291
|
default: '',
|
|
1120
|
-
description: 'Comma-separated list of user IDs to tag for X (Twitter)
|
|
1292
|
+
description: 'Comma-separated list of user IDs to tag for X (Twitter)',
|
|
1121
1293
|
displayOptions: {
|
|
1122
1294
|
show: {
|
|
1123
|
-
operation: ['
|
|
1295
|
+
operation: ['uploadPhotos', 'uploadVideo'],
|
|
1124
1296
|
platform: ['x']
|
|
1125
1297
|
},
|
|
1126
1298
|
},
|
|
1127
1299
|
},
|
|
1128
1300
|
{
|
|
1129
|
-
displayName: 'X Reply Settings
|
|
1301
|
+
displayName: 'X Reply Settings',
|
|
1130
1302
|
name: 'xReplySettings',
|
|
1131
1303
|
type: 'options',
|
|
1132
1304
|
options: [
|
|
1305
|
+
{ name: 'Everyone', value: 'everyone' },
|
|
1133
1306
|
{ name: 'Following', value: 'following' },
|
|
1134
1307
|
{ name: 'Mentioned Users', value: 'mentionedUsers' },
|
|
1135
|
-
{ name: '
|
|
1308
|
+
{ name: 'Subscribers', value: 'subscribers' },
|
|
1309
|
+
{ name: 'Verified', value: 'verified' },
|
|
1136
1310
|
],
|
|
1137
|
-
default: '
|
|
1138
|
-
description: 'Who can reply to the post on X (Twitter)
|
|
1311
|
+
default: 'everyone',
|
|
1312
|
+
description: 'Who can reply to the post on X (Twitter)',
|
|
1139
1313
|
displayOptions: {
|
|
1140
1314
|
show: {
|
|
1141
|
-
operation: ['uploadVideo', 'uploadText'],
|
|
1315
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1142
1316
|
platform: ['x']
|
|
1143
1317
|
},
|
|
1144
1318
|
},
|
|
1145
1319
|
},
|
|
1146
1320
|
{
|
|
1147
|
-
displayName: 'X Nullcast
|
|
1321
|
+
displayName: 'X Nullcast',
|
|
1148
1322
|
name: 'xNullcastVideo',
|
|
1149
1323
|
type: 'boolean',
|
|
1150
1324
|
default: false,
|
|
1151
|
-
description: 'Whether to publish X (Twitter)
|
|
1325
|
+
description: 'Whether to publish X (Twitter) post without broadcasting (promoted-only posts)',
|
|
1152
1326
|
displayOptions: {
|
|
1153
1327
|
show: {
|
|
1154
|
-
operation: ['uploadVideo'],
|
|
1328
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1155
1329
|
platform: ['x']
|
|
1156
1330
|
},
|
|
1157
1331
|
},
|
|
@@ -1170,47 +1344,48 @@ class UploadPost {
|
|
|
1170
1344
|
},
|
|
1171
1345
|
},
|
|
1172
1346
|
{
|
|
1173
|
-
displayName: 'X Poll Duration (Minutes
|
|
1174
|
-
name: '
|
|
1347
|
+
displayName: 'X Poll Duration (Minutes)',
|
|
1348
|
+
name: 'xPollDuration',
|
|
1175
1349
|
type: 'number',
|
|
1176
1350
|
default: 1440,
|
|
1177
|
-
description: 'Poll duration in minutes for X (Twitter)
|
|
1351
|
+
description: 'Poll duration in minutes for X (Twitter) post (requires Poll Options)',
|
|
1178
1352
|
displayOptions: {
|
|
1179
1353
|
show: {
|
|
1180
|
-
operation: ['
|
|
1354
|
+
operation: ['uploadText'],
|
|
1181
1355
|
platform: ['x']
|
|
1182
|
-
}
|
|
1356
|
+
}
|
|
1183
1357
|
},
|
|
1184
1358
|
},
|
|
1185
1359
|
{
|
|
1186
|
-
displayName: 'X Poll Options
|
|
1187
|
-
name: '
|
|
1360
|
+
displayName: 'X Poll Options',
|
|
1361
|
+
name: 'xPollOptions',
|
|
1188
1362
|
type: 'string',
|
|
1189
1363
|
default: '',
|
|
1190
|
-
description: 'Comma-separated list of poll options for X (Twitter)
|
|
1364
|
+
description: 'Comma-separated list of poll options for X (Twitter) post',
|
|
1191
1365
|
displayOptions: {
|
|
1192
1366
|
show: {
|
|
1193
|
-
operation: ['
|
|
1367
|
+
operation: ['uploadText'],
|
|
1194
1368
|
platform: ['x']
|
|
1195
|
-
}
|
|
1369
|
+
}
|
|
1196
1370
|
},
|
|
1197
1371
|
},
|
|
1198
1372
|
{
|
|
1199
|
-
displayName: 'X Poll Reply Settings
|
|
1200
|
-
name: '
|
|
1373
|
+
displayName: 'X Poll Reply Settings',
|
|
1374
|
+
name: 'xPollReplySettings',
|
|
1201
1375
|
type: 'options',
|
|
1202
1376
|
options: [
|
|
1203
1377
|
{ name: 'Following', value: 'following' },
|
|
1204
1378
|
{ name: 'Mentioned Users', value: 'mentionedUsers' },
|
|
1205
1379
|
{ name: 'Everyone', value: 'everyone' },
|
|
1380
|
+
{ name: 'Subscribers', value: 'subscribers' },
|
|
1206
1381
|
],
|
|
1207
1382
|
default: 'following',
|
|
1208
|
-
description: 'Who can reply to the poll in X (Twitter)
|
|
1383
|
+
description: 'Who can reply to the poll in X (Twitter) post',
|
|
1209
1384
|
displayOptions: {
|
|
1210
1385
|
show: {
|
|
1211
|
-
operation: ['
|
|
1386
|
+
operation: ['uploadText'],
|
|
1212
1387
|
platform: ['x']
|
|
1213
|
-
}
|
|
1388
|
+
}
|
|
1214
1389
|
},
|
|
1215
1390
|
},
|
|
1216
1391
|
{
|
|
@@ -1226,6 +1401,97 @@ class UploadPost {
|
|
|
1226
1401
|
},
|
|
1227
1402
|
},
|
|
1228
1403
|
},
|
|
1404
|
+
{
|
|
1405
|
+
displayName: 'X Quote Tweet ID',
|
|
1406
|
+
name: 'xQuoteTweetId',
|
|
1407
|
+
type: 'string',
|
|
1408
|
+
default: '',
|
|
1409
|
+
description: 'ID of the tweet to quote in a quote tweet',
|
|
1410
|
+
displayOptions: {
|
|
1411
|
+
show: {
|
|
1412
|
+
operation: ['uploadText'],
|
|
1413
|
+
platform: ['x']
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
},
|
|
1417
|
+
{
|
|
1418
|
+
displayName: 'X Geo Place ID',
|
|
1419
|
+
name: 'xGeoPlaceId',
|
|
1420
|
+
type: 'string',
|
|
1421
|
+
default: '',
|
|
1422
|
+
description: 'Geographic place ID to add location to the tweet',
|
|
1423
|
+
displayOptions: {
|
|
1424
|
+
show: {
|
|
1425
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1426
|
+
platform: ['x']
|
|
1427
|
+
},
|
|
1428
|
+
},
|
|
1429
|
+
},
|
|
1430
|
+
{
|
|
1431
|
+
displayName: 'X For Super Followers Only',
|
|
1432
|
+
name: 'xForSuperFollowersOnly',
|
|
1433
|
+
type: 'boolean',
|
|
1434
|
+
default: false,
|
|
1435
|
+
description: 'Whether the tweet is exclusive for super followers',
|
|
1436
|
+
displayOptions: {
|
|
1437
|
+
show: {
|
|
1438
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1439
|
+
platform: ['x']
|
|
1440
|
+
},
|
|
1441
|
+
},
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
displayName: 'X Community ID',
|
|
1445
|
+
name: 'xCommunityId',
|
|
1446
|
+
type: 'string',
|
|
1447
|
+
default: '',
|
|
1448
|
+
description: 'Community ID for posting in specific communities',
|
|
1449
|
+
displayOptions: {
|
|
1450
|
+
show: {
|
|
1451
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1452
|
+
platform: ['x']
|
|
1453
|
+
},
|
|
1454
|
+
},
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
displayName: 'X Share with Followers',
|
|
1458
|
+
name: 'xShareWithFollowers',
|
|
1459
|
+
type: 'boolean',
|
|
1460
|
+
default: false,
|
|
1461
|
+
description: 'Whether to share community post with followers',
|
|
1462
|
+
displayOptions: {
|
|
1463
|
+
show: {
|
|
1464
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1465
|
+
platform: ['x']
|
|
1466
|
+
},
|
|
1467
|
+
},
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
displayName: 'X Direct Message Deep Link',
|
|
1471
|
+
name: 'xDirectMessageDeepLink',
|
|
1472
|
+
type: 'string',
|
|
1473
|
+
default: '',
|
|
1474
|
+
description: 'Link to take the conversation from public timeline to private Direct Message',
|
|
1475
|
+
displayOptions: {
|
|
1476
|
+
show: {
|
|
1477
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
|
|
1478
|
+
platform: ['x']
|
|
1479
|
+
}
|
|
1480
|
+
},
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
displayName: 'X Card URI',
|
|
1484
|
+
name: 'xCardUri',
|
|
1485
|
+
type: 'string',
|
|
1486
|
+
default: '',
|
|
1487
|
+
description: 'URI of card (for Twitter Cards/ads/promoted content)',
|
|
1488
|
+
displayOptions: {
|
|
1489
|
+
show: {
|
|
1490
|
+
operation: ['uploadText'],
|
|
1491
|
+
platform: ['x']
|
|
1492
|
+
}
|
|
1493
|
+
},
|
|
1494
|
+
},
|
|
1229
1495
|
{
|
|
1230
1496
|
displayName: 'X Long Text as Single Post',
|
|
1231
1497
|
name: 'xLongTextAsPost',
|
|
@@ -1243,59 +1509,150 @@ class UploadPost {
|
|
|
1243
1509
|
};
|
|
1244
1510
|
this.methods = {
|
|
1245
1511
|
loadOptions: {
|
|
1246
|
-
async
|
|
1247
|
-
const
|
|
1248
|
-
const
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1512
|
+
async getPlatforms() {
|
|
1513
|
+
const operation = this.getCurrentNodeParameter('operation');
|
|
1514
|
+
const allPlatforms = [
|
|
1515
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
1516
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
1517
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
1518
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
1519
|
+
{ name: 'Reddit', value: 'reddit' },
|
|
1520
|
+
{ name: 'Threads', value: 'threads' },
|
|
1521
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
1522
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
1523
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
1524
|
+
];
|
|
1525
|
+
const platformSupport = {
|
|
1526
|
+
uploadPhotos: ['facebook', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x'],
|
|
1527
|
+
uploadVideo: ['facebook', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x', 'youtube'],
|
|
1528
|
+
uploadText: ['facebook', 'linkedin', 'reddit', 'threads', 'x'],
|
|
1259
1529
|
};
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
|
|
1530
|
+
const supportedPlatforms = platformSupport[operation] || [];
|
|
1531
|
+
return allPlatforms.filter(platform => supportedPlatforms.includes(platform.value));
|
|
1532
|
+
},
|
|
1533
|
+
async getFacebookPages() {
|
|
1534
|
+
try {
|
|
1535
|
+
const credentials = await this.getCredentials('uploadPostApi');
|
|
1536
|
+
const apiKey = credentials.apiKey;
|
|
1537
|
+
const profile = this.getCurrentNodeParameter('user') || '';
|
|
1538
|
+
const qs = {};
|
|
1539
|
+
if (profile)
|
|
1540
|
+
qs.profile = profile;
|
|
1541
|
+
const options = {
|
|
1542
|
+
uri: 'https://api.upload-post.com/api/uploadposts/facebook/pages',
|
|
1543
|
+
method: 'GET',
|
|
1544
|
+
headers: { Authorization: `ApiKey ${apiKey}` },
|
|
1545
|
+
qs,
|
|
1546
|
+
json: true,
|
|
1547
|
+
};
|
|
1548
|
+
const resp = await this.helpers.request(options);
|
|
1549
|
+
const pages = (resp && (resp.pages || resp.data || []));
|
|
1550
|
+
const pageOptions = (pages || []).map(p => ({ name: p.name ? `${p.name} (${p.id})` : p.id, value: p.id }));
|
|
1551
|
+
return [
|
|
1552
|
+
{ name: 'Manual entry...', value: MANUAL_FACEBOOK_VALUE },
|
|
1553
|
+
...pageOptions
|
|
1554
|
+
];
|
|
1555
|
+
}
|
|
1556
|
+
catch (error) {
|
|
1557
|
+
return [
|
|
1558
|
+
{ name: 'Manual entry...', value: MANUAL_FACEBOOK_VALUE }
|
|
1559
|
+
];
|
|
1560
|
+
}
|
|
1263
1561
|
},
|
|
1264
1562
|
async getLinkedinPages() {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1563
|
+
try {
|
|
1564
|
+
const credentials = await this.getCredentials('uploadPostApi');
|
|
1565
|
+
const apiKey = credentials.apiKey;
|
|
1566
|
+
const profile = this.getCurrentNodeParameter('user') || '';
|
|
1567
|
+
const qs = {};
|
|
1568
|
+
if (profile)
|
|
1569
|
+
qs.profile = profile;
|
|
1570
|
+
const options = {
|
|
1571
|
+
uri: 'https://api.upload-post.com/api/uploadposts/linkedin/pages',
|
|
1572
|
+
method: 'GET',
|
|
1573
|
+
headers: { Authorization: `ApiKey ${apiKey}` },
|
|
1574
|
+
qs,
|
|
1575
|
+
json: true,
|
|
1576
|
+
};
|
|
1577
|
+
const resp = await this.helpers.request(options);
|
|
1578
|
+
const pages = (resp && (resp.pages || resp.data || []));
|
|
1579
|
+
const pageOptions = (pages || []).map(p => ({ name: p.name ? `${p.name} (${p.id})` : p.id, value: p.id }));
|
|
1580
|
+
return [
|
|
1581
|
+
{ name: 'Manual entry...', value: MANUAL_LINKEDIN_VALUE },
|
|
1582
|
+
{ name: 'Me (Personal Profile)', value: 'me' },
|
|
1583
|
+
...pageOptions
|
|
1584
|
+
];
|
|
1585
|
+
}
|
|
1586
|
+
catch (error) {
|
|
1587
|
+
return [
|
|
1588
|
+
{ name: 'Manual entry...', value: MANUAL_LINKEDIN_VALUE },
|
|
1589
|
+
{ name: 'Me (Personal Profile)', value: 'me' }
|
|
1590
|
+
];
|
|
1591
|
+
}
|
|
1281
1592
|
},
|
|
1282
1593
|
async getPinterestBoards() {
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1594
|
+
try {
|
|
1595
|
+
const credentials = await this.getCredentials('uploadPostApi');
|
|
1596
|
+
const apiKey = credentials.apiKey;
|
|
1597
|
+
const profile = this.getCurrentNodeParameter('user') || '';
|
|
1598
|
+
const qs = {};
|
|
1599
|
+
if (profile)
|
|
1600
|
+
qs.profile = profile;
|
|
1601
|
+
const options = {
|
|
1602
|
+
uri: 'https://api.upload-post.com/api/uploadposts/pinterest/boards',
|
|
1603
|
+
method: 'GET',
|
|
1604
|
+
headers: { Authorization: `ApiKey ${apiKey}` },
|
|
1605
|
+
qs,
|
|
1606
|
+
json: true,
|
|
1607
|
+
};
|
|
1608
|
+
const resp = await this.helpers.request(options);
|
|
1609
|
+
const boards = (resp && (resp.boards || resp.data || []));
|
|
1610
|
+
const boardOptions = (boards || []).map(b => ({ name: b.name ? `${b.name} (${b.id})` : b.id, value: b.id }));
|
|
1611
|
+
return [
|
|
1612
|
+
{ name: 'Manual entry...', value: MANUAL_PINTEREST_VALUE },
|
|
1613
|
+
...boardOptions
|
|
1614
|
+
];
|
|
1615
|
+
}
|
|
1616
|
+
catch (error) {
|
|
1617
|
+
return [
|
|
1618
|
+
{ name: 'Manual entry...', value: MANUAL_PINTEREST_VALUE }
|
|
1619
|
+
];
|
|
1620
|
+
}
|
|
1621
|
+
},
|
|
1622
|
+
async getUserProfiles() {
|
|
1623
|
+
try {
|
|
1624
|
+
const credentials = await this.getCredentials('uploadPostApi');
|
|
1625
|
+
const apiKey = credentials.apiKey;
|
|
1626
|
+
const options = {
|
|
1627
|
+
uri: 'https://api.upload-post.com/api/uploadposts/users',
|
|
1628
|
+
method: 'GET',
|
|
1629
|
+
headers: { Authorization: `ApiKey ${apiKey}` },
|
|
1630
|
+
json: true,
|
|
1631
|
+
};
|
|
1632
|
+
const resp = await this.helpers.request(options);
|
|
1633
|
+
const profiles = (resp && resp.profiles);
|
|
1634
|
+
const profileOptions = (profiles || []).map(profile => {
|
|
1635
|
+
const connectedPlatforms = Object.keys(profile.social_accounts || {})
|
|
1636
|
+
.filter(platform => profile.social_accounts[platform] && typeof profile.social_accounts[platform] === 'object')
|
|
1637
|
+
.join(', ');
|
|
1638
|
+
const displayName = connectedPlatforms
|
|
1639
|
+
? `${profile.username} (${connectedPlatforms})`
|
|
1640
|
+
: profile.username;
|
|
1641
|
+
return {
|
|
1642
|
+
name: displayName,
|
|
1643
|
+
value: profile.username
|
|
1644
|
+
};
|
|
1645
|
+
});
|
|
1646
|
+
return [
|
|
1647
|
+
{ name: 'Manual entry...', value: MANUAL_USER_VALUE },
|
|
1648
|
+
...profileOptions
|
|
1649
|
+
];
|
|
1650
|
+
}
|
|
1651
|
+
catch (error) {
|
|
1652
|
+
return [
|
|
1653
|
+
{ name: 'Manual entry...', value: MANUAL_USER_VALUE }
|
|
1654
|
+
];
|
|
1655
|
+
}
|
|
1299
1656
|
},
|
|
1300
1657
|
},
|
|
1301
1658
|
};
|
|
@@ -1308,7 +1665,13 @@ class UploadPost {
|
|
|
1308
1665
|
const operation = this.getNodeParameter('operation', i);
|
|
1309
1666
|
const isUploadOperation = ['uploadPhotos', 'uploadVideo', 'uploadText'].includes(operation);
|
|
1310
1667
|
const needsUser = isUploadOperation || operation === 'generateJwt';
|
|
1311
|
-
const
|
|
1668
|
+
const userSelection = needsUser ? this.getNodeParameter('user', i) : '';
|
|
1669
|
+
const userManualValue = needsUser && userSelection === MANUAL_USER_VALUE
|
|
1670
|
+
? this.getNodeParameter('userManual', i)
|
|
1671
|
+
: '';
|
|
1672
|
+
const user = needsUser
|
|
1673
|
+
? (userSelection === MANUAL_USER_VALUE ? userManualValue : userSelection)
|
|
1674
|
+
: '';
|
|
1312
1675
|
let platforms = isUploadOperation ? this.getNodeParameter('platform', i) : [];
|
|
1313
1676
|
const title = isUploadOperation ? this.getNodeParameter('title', i) : '';
|
|
1314
1677
|
let endpoint = '';
|
|
@@ -1514,7 +1877,7 @@ class UploadPost {
|
|
|
1514
1877
|
break;
|
|
1515
1878
|
case 'uploadText':
|
|
1516
1879
|
endpoint = '/upload_text';
|
|
1517
|
-
const allowedTextPlatforms = ['x', 'linkedin', 'facebook', 'threads'];
|
|
1880
|
+
const allowedTextPlatforms = ['x', 'linkedin', 'facebook', 'threads', 'reddit'];
|
|
1518
1881
|
platforms = platforms.filter(p => allowedTextPlatforms.includes(p));
|
|
1519
1882
|
formData['platform[]'] = platforms;
|
|
1520
1883
|
break;
|
|
@@ -1606,7 +1969,11 @@ class UploadPost {
|
|
|
1606
1969
|
break;
|
|
1607
1970
|
}
|
|
1608
1971
|
if (isUploadOperation && platforms.includes('pinterest')) {
|
|
1609
|
-
const
|
|
1972
|
+
const pinterestSelection = this.getNodeParameter('pinterestBoardId', i);
|
|
1973
|
+
const pinterestManual = pinterestSelection === MANUAL_PINTEREST_VALUE
|
|
1974
|
+
? this.getNodeParameter('pinterestBoardIdManual', i)
|
|
1975
|
+
: '';
|
|
1976
|
+
const pinterestBoardId = pinterestSelection === MANUAL_PINTEREST_VALUE ? pinterestManual : pinterestSelection;
|
|
1610
1977
|
if (pinterestBoardId)
|
|
1611
1978
|
formData.pinterest_board_id = pinterestBoardId;
|
|
1612
1979
|
const pinterestLink = this.getNodeParameter('pinterestLink', i);
|
|
@@ -1635,8 +2002,12 @@ class UploadPost {
|
|
|
1635
2002
|
}
|
|
1636
2003
|
}
|
|
1637
2004
|
if (isUploadOperation && platforms.includes('linkedin')) {
|
|
1638
|
-
const
|
|
1639
|
-
|
|
2005
|
+
const targetLinkedinSelection = this.getNodeParameter('targetLinkedinPageId', i);
|
|
2006
|
+
const targetLinkedinManual = targetLinkedinSelection === MANUAL_LINKEDIN_VALUE
|
|
2007
|
+
? this.getNodeParameter('targetLinkedinPageIdManual', i)
|
|
2008
|
+
: '';
|
|
2009
|
+
const targetLinkedinPageId = targetLinkedinSelection === MANUAL_LINKEDIN_VALUE ? targetLinkedinManual : targetLinkedinSelection;
|
|
2010
|
+
if (targetLinkedinPageId && targetLinkedinPageId !== 'me') {
|
|
1640
2011
|
const match = targetLinkedinPageId.match(/(\d+)$/);
|
|
1641
2012
|
if (match) {
|
|
1642
2013
|
formData.target_linkedin_page_id = match[1];
|
|
@@ -1657,7 +2028,11 @@ class UploadPost {
|
|
|
1657
2028
|
}
|
|
1658
2029
|
}
|
|
1659
2030
|
if (isUploadOperation && platforms.includes('facebook')) {
|
|
1660
|
-
const
|
|
2031
|
+
const facebookPageSelection = this.getNodeParameter('facebookPageId', i);
|
|
2032
|
+
const facebookPageManual = facebookPageSelection === MANUAL_FACEBOOK_VALUE
|
|
2033
|
+
? this.getNodeParameter('facebookPageIdManual', i)
|
|
2034
|
+
: '';
|
|
2035
|
+
const facebookPageId = facebookPageSelection === MANUAL_FACEBOOK_VALUE ? facebookPageManual : facebookPageSelection;
|
|
1661
2036
|
formData.facebook_page_id = facebookPageId;
|
|
1662
2037
|
if (operation === 'uploadVideo') {
|
|
1663
2038
|
const facebookVideoState = this.getNodeParameter('facebookVideoState', i);
|
|
@@ -1673,25 +2048,25 @@ class UploadPost {
|
|
|
1673
2048
|
else if (operation === 'uploadText') {
|
|
1674
2049
|
const facebookLink = this.getNodeParameter('facebookLink', i);
|
|
1675
2050
|
if (facebookLink)
|
|
1676
|
-
formData.
|
|
2051
|
+
formData.facebook_link_url = facebookLink;
|
|
1677
2052
|
}
|
|
1678
2053
|
}
|
|
1679
2054
|
if (isUploadOperation && platforms.includes('tiktok')) {
|
|
1680
2055
|
if (operation === 'uploadPhotos') {
|
|
1681
2056
|
const tiktokAutoAddMusic = this.getNodeParameter('tiktokAutoAddMusic', i);
|
|
1682
2057
|
const tiktokDisableComment = this.getNodeParameter('tiktokDisableComment', i);
|
|
1683
|
-
const
|
|
1684
|
-
const
|
|
2058
|
+
const brandContentToggle = this.getNodeParameter('brand_content_toggle', i);
|
|
2059
|
+
const brandOrganicToggle = this.getNodeParameter('brand_organic_toggle', i);
|
|
1685
2060
|
const tiktokPhotoCoverIndex = this.getNodeParameter('tiktokPhotoCoverIndex', i);
|
|
1686
2061
|
const tiktokPhotoDescription = this.getNodeParameter('tiktokPhotoDescription', i);
|
|
1687
2062
|
if (tiktokAutoAddMusic !== undefined)
|
|
1688
2063
|
formData.auto_add_music = String(tiktokAutoAddMusic);
|
|
1689
2064
|
if (tiktokDisableComment !== undefined)
|
|
1690
2065
|
formData.disable_comment = String(tiktokDisableComment);
|
|
1691
|
-
if (
|
|
1692
|
-
formData.
|
|
1693
|
-
if (
|
|
1694
|
-
formData.
|
|
2066
|
+
if (brandContentToggle !== undefined)
|
|
2067
|
+
formData.brand_content_toggle = String(brandContentToggle);
|
|
2068
|
+
if (brandOrganicToggle !== undefined)
|
|
2069
|
+
formData.brand_organic_toggle = String(brandOrganicToggle);
|
|
1695
2070
|
if (tiktokPhotoCoverIndex !== undefined)
|
|
1696
2071
|
formData.photo_cover_index = tiktokPhotoCoverIndex;
|
|
1697
2072
|
if (tiktokPhotoDescription && formData.description === undefined)
|
|
@@ -1703,10 +2078,8 @@ class UploadPost {
|
|
|
1703
2078
|
const tiktokDisableComment = this.getNodeParameter('tiktokDisableComment', i);
|
|
1704
2079
|
const tiktokDisableStitch = this.getNodeParameter('tiktokDisableStitch', i);
|
|
1705
2080
|
const tiktokCoverTimestamp = this.getNodeParameter('tiktokCoverTimestamp', i);
|
|
1706
|
-
const
|
|
1707
|
-
const
|
|
1708
|
-
const tiktokBrandedContentVideo = this.getNodeParameter('tiktokBrandedContentVideo', i);
|
|
1709
|
-
const tiktokBrandOrganicToggle = this.getNodeParameter('tiktokBrandOrganicToggle', i);
|
|
2081
|
+
const brandContentToggle = this.getNodeParameter('brand_content_toggle', i);
|
|
2082
|
+
const brandOrganicToggle = this.getNodeParameter('brand_organic_toggle', i);
|
|
1710
2083
|
const tiktokIsAigc = this.getNodeParameter('tiktokIsAigc', i);
|
|
1711
2084
|
const tiktokPostMode = this.getNodeParameter('tiktokPostMode', i);
|
|
1712
2085
|
if (tiktokPrivacyLevel)
|
|
@@ -1719,14 +2092,10 @@ class UploadPost {
|
|
|
1719
2092
|
formData.disable_stitch = String(tiktokDisableStitch);
|
|
1720
2093
|
if (tiktokCoverTimestamp !== undefined)
|
|
1721
2094
|
formData.cover_timestamp = tiktokCoverTimestamp;
|
|
1722
|
-
if (
|
|
1723
|
-
formData.brand_content_toggle = String(
|
|
1724
|
-
if (
|
|
1725
|
-
formData.
|
|
1726
|
-
if (tiktokBrandedContentVideo !== undefined)
|
|
1727
|
-
formData.branded_content = String(tiktokBrandedContentVideo);
|
|
1728
|
-
if (tiktokBrandOrganicToggle !== undefined)
|
|
1729
|
-
formData.brand_organic_toggle = String(tiktokBrandOrganicToggle);
|
|
2095
|
+
if (brandContentToggle !== undefined)
|
|
2096
|
+
formData.brand_content_toggle = String(brandContentToggle);
|
|
2097
|
+
if (brandOrganicToggle !== undefined)
|
|
2098
|
+
formData.brand_organic_toggle = String(brandOrganicToggle);
|
|
1730
2099
|
if (tiktokIsAigc !== undefined)
|
|
1731
2100
|
formData.is_aigc = String(tiktokIsAigc);
|
|
1732
2101
|
if (tiktokPostMode)
|
|
@@ -1782,7 +2151,7 @@ class UploadPost {
|
|
|
1782
2151
|
const youtubeMadeForKids = this.getNodeParameter('youtubeMadeForKids', i);
|
|
1783
2152
|
const youtubeThumbnail = this.getNodeParameter('youtubeThumbnail', i);
|
|
1784
2153
|
if (youtubeTagsRaw)
|
|
1785
|
-
formData
|
|
2154
|
+
formData['tags[]'] = youtubeTagsRaw.split(',').map(tag => tag.trim());
|
|
1786
2155
|
if (youtubeCategoryId)
|
|
1787
2156
|
formData.categoryId = youtubeCategoryId;
|
|
1788
2157
|
if (youtubePrivacyStatus)
|
|
@@ -1817,18 +2186,96 @@ class UploadPost {
|
|
|
1817
2186
|
}
|
|
1818
2187
|
}
|
|
1819
2188
|
}
|
|
2189
|
+
const youtubeSelfDeclaredMadeForKids = this.getNodeParameter('youtubeSelfDeclaredMadeForKids', i);
|
|
2190
|
+
const youtubeContainsSyntheticMedia = this.getNodeParameter('youtubeContainsSyntheticMedia', i);
|
|
2191
|
+
const youtubeDefaultLanguage = this.getNodeParameter('youtubeDefaultLanguage', i);
|
|
2192
|
+
const youtubeDefaultAudioLanguage = this.getNodeParameter('youtubeDefaultAudioLanguage', i);
|
|
2193
|
+
const youtubeAllowedCountries = this.getNodeParameter('youtubeAllowedCountries', i);
|
|
2194
|
+
const youtubeBlockedCountries = this.getNodeParameter('youtubeBlockedCountries', i);
|
|
2195
|
+
const youtubeHasPaidProductPlacement = this.getNodeParameter('youtubeHasPaidProductPlacement', i);
|
|
2196
|
+
const youtubeRecordingDate = this.getNodeParameter('youtubeRecordingDate', i);
|
|
2197
|
+
if (youtubeSelfDeclaredMadeForKids !== undefined)
|
|
2198
|
+
formData.selfDeclaredMadeForKids = String(youtubeSelfDeclaredMadeForKids);
|
|
2199
|
+
if (youtubeContainsSyntheticMedia !== undefined)
|
|
2200
|
+
formData.containsSyntheticMedia = String(youtubeContainsSyntheticMedia);
|
|
2201
|
+
if (youtubeDefaultLanguage)
|
|
2202
|
+
formData.defaultLanguage = youtubeDefaultLanguage;
|
|
2203
|
+
if (youtubeDefaultAudioLanguage)
|
|
2204
|
+
formData.defaultAudioLanguage = youtubeDefaultAudioLanguage;
|
|
2205
|
+
if (youtubeAllowedCountries)
|
|
2206
|
+
formData.allowedCountries = youtubeAllowedCountries;
|
|
2207
|
+
if (youtubeBlockedCountries)
|
|
2208
|
+
formData.blockedCountries = youtubeBlockedCountries;
|
|
2209
|
+
if (youtubeHasPaidProductPlacement !== undefined)
|
|
2210
|
+
formData.hasPaidProductPlacement = String(youtubeHasPaidProductPlacement);
|
|
2211
|
+
if (youtubeRecordingDate)
|
|
2212
|
+
formData.recordingDate = youtubeRecordingDate;
|
|
1820
2213
|
}
|
|
1821
2214
|
if (isUploadOperation && platforms.includes('x')) {
|
|
2215
|
+
const xQuoteTweetId = this.getNodeParameter('xQuoteTweetId', i, '');
|
|
2216
|
+
const xGeoPlaceId = this.getNodeParameter('xGeoPlaceId', i, '');
|
|
2217
|
+
const xForSuperFollowersOnly = this.getNodeParameter('xForSuperFollowersOnly', i, false);
|
|
2218
|
+
const xCommunityId = this.getNodeParameter('xCommunityId', i, '');
|
|
2219
|
+
const xShareWithFollowers = this.getNodeParameter('xShareWithFollowers', i, false);
|
|
2220
|
+
const xDirectMessageDeepLink = this.getNodeParameter('xDirectMessageDeepLink', i, '');
|
|
2221
|
+
const xCardUri = this.getNodeParameter('xCardUri', i, '');
|
|
2222
|
+
if (xQuoteTweetId)
|
|
2223
|
+
formData.quote_tweet_id = xQuoteTweetId;
|
|
2224
|
+
if (xGeoPlaceId)
|
|
2225
|
+
formData.geo_place_id = xGeoPlaceId;
|
|
2226
|
+
if (xForSuperFollowersOnly)
|
|
2227
|
+
formData.for_super_followers_only = String(xForSuperFollowersOnly);
|
|
2228
|
+
if (xCommunityId)
|
|
2229
|
+
formData.community_id = xCommunityId;
|
|
2230
|
+
if (xShareWithFollowers)
|
|
2231
|
+
formData.share_with_followers = String(xShareWithFollowers);
|
|
2232
|
+
if (xDirectMessageDeepLink)
|
|
2233
|
+
formData.direct_message_deep_link = xDirectMessageDeepLink;
|
|
2234
|
+
if (xCardUri)
|
|
2235
|
+
formData.card_uri = xCardUri;
|
|
1822
2236
|
if (operation === 'uploadText') {
|
|
1823
2237
|
const xPostUrlText = this.getNodeParameter('xPostUrlText', i);
|
|
1824
2238
|
if (xPostUrlText)
|
|
1825
2239
|
formData.post_url = xPostUrlText;
|
|
1826
|
-
const xTaggedUserIdsText = this.getNodeParameter('xTaggedUserIds', i);
|
|
1827
2240
|
const xReplySettingsText = this.getNodeParameter('xReplySettings', i);
|
|
1828
|
-
if (
|
|
1829
|
-
formData.tagged_user_ids = xTaggedUserIdsText.split(',').map(id => id.trim());
|
|
1830
|
-
if (xReplySettingsText)
|
|
2241
|
+
if (xReplySettingsText && xReplySettingsText !== 'everyone')
|
|
1831
2242
|
formData.reply_settings = xReplySettingsText;
|
|
2243
|
+
const xPollDuration = this.getNodeParameter('xPollDuration', i, 1440);
|
|
2244
|
+
const xPollOptionsRaw = this.getNodeParameter('xPollOptions', i, '');
|
|
2245
|
+
const xPollReplySettings = this.getNodeParameter('xPollReplySettings', i, 'following');
|
|
2246
|
+
const xCardUri = this.getNodeParameter('xCardUri', i, '');
|
|
2247
|
+
const xQuoteTweetId = this.getNodeParameter('xQuoteTweetId', i, '');
|
|
2248
|
+
const xDirectMessageDeepLink = this.getNodeParameter('xDirectMessageDeepLink', i, '');
|
|
2249
|
+
const hasPollOptions = xPollOptionsRaw && xPollOptionsRaw.trim();
|
|
2250
|
+
const hasCardUri = xCardUri && xCardUri.trim();
|
|
2251
|
+
const hasQuoteTweetId = xQuoteTweetId && xQuoteTweetId.trim();
|
|
2252
|
+
const hasDirectMessageDeepLink = xDirectMessageDeepLink && xDirectMessageDeepLink.trim();
|
|
2253
|
+
if (hasPollOptions && (hasCardUri || hasQuoteTweetId || hasDirectMessageDeepLink)) {
|
|
2254
|
+
const conflictingFields = [];
|
|
2255
|
+
if (hasCardUri)
|
|
2256
|
+
conflictingFields.push('X Card URI');
|
|
2257
|
+
if (hasQuoteTweetId)
|
|
2258
|
+
conflictingFields.push('X Quote Tweet ID');
|
|
2259
|
+
if (hasDirectMessageDeepLink)
|
|
2260
|
+
conflictingFields.push('X Direct Message Deep Link');
|
|
2261
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `X Poll Options cannot be used with: ${conflictingFields.join(', ')}. These fields are mutually exclusive.`);
|
|
2262
|
+
}
|
|
2263
|
+
if (hasPollOptions) {
|
|
2264
|
+
const pollOptions = xPollOptionsRaw.split(',').map(opt => opt.trim()).filter(opt => opt.length > 0);
|
|
2265
|
+
if (pollOptions.length < 2 || pollOptions.length > 4) {
|
|
2266
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `X Poll Options must contain between 2 and 4 non-empty options. Found: ${pollOptions.length}`);
|
|
2267
|
+
}
|
|
2268
|
+
const invalidOptions = pollOptions.filter(opt => opt.length > 25);
|
|
2269
|
+
if (invalidOptions.length > 0) {
|
|
2270
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `X Poll Options cannot exceed 25 characters each. Invalid options: ${invalidOptions.join(', ')}`);
|
|
2271
|
+
}
|
|
2272
|
+
if (xPollDuration < 5 || xPollDuration > 10080) {
|
|
2273
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `X Poll Duration must be between 5 and 10080 minutes (5 minutes to 7 days). Provided: ${xPollDuration}`);
|
|
2274
|
+
}
|
|
2275
|
+
formData['poll_options[]'] = pollOptions;
|
|
2276
|
+
formData.poll_duration = xPollDuration;
|
|
2277
|
+
formData.poll_reply_settings = xPollReplySettings;
|
|
2278
|
+
}
|
|
1832
2279
|
try {
|
|
1833
2280
|
const xLongTextAsPostText = this.getNodeParameter('xLongTextAsPost', i, false);
|
|
1834
2281
|
if (xLongTextAsPostText)
|
|
@@ -1837,35 +2284,44 @@ class UploadPost {
|
|
|
1837
2284
|
catch { }
|
|
1838
2285
|
delete formData.nullcast;
|
|
1839
2286
|
delete formData.place_id;
|
|
1840
|
-
delete formData.poll_duration;
|
|
1841
|
-
delete formData.poll_options;
|
|
1842
|
-
delete formData.poll_reply_settings;
|
|
1843
2287
|
}
|
|
1844
|
-
else if (operation === 'uploadVideo') {
|
|
2288
|
+
else if (operation === 'uploadVideo' || operation === 'uploadPhotos') {
|
|
1845
2289
|
const xTaggedUserIds = this.getNodeParameter('xTaggedUserIds', i);
|
|
1846
2290
|
const xReplySettings = this.getNodeParameter('xReplySettings', i);
|
|
1847
2291
|
const xNullcastVideo = this.getNodeParameter('xNullcastVideo', i);
|
|
1848
|
-
const xPlaceIdVideo = this.getNodeParameter('xPlaceIdVideo', i);
|
|
1849
|
-
const xPollDurationVideo = this.getNodeParameter('xPollDurationVideo', i);
|
|
1850
|
-
const xPollOptionsVideoRaw = this.getNodeParameter('xPollOptionsVideo', i);
|
|
1851
|
-
const xPollReplySettingsVideo = this.getNodeParameter('xPollReplySettingsVideo', i);
|
|
1852
|
-
const xLongTextAsPost = this.getNodeParameter('xLongTextAsPost', i, false);
|
|
1853
2292
|
if (xTaggedUserIds)
|
|
1854
|
-
formData
|
|
1855
|
-
if (xReplySettings)
|
|
2293
|
+
formData['tagged_user_ids[]'] = xTaggedUserIds.split(',').map(id => id.trim());
|
|
2294
|
+
if (xReplySettings && xReplySettings !== 'everyone')
|
|
1856
2295
|
formData.reply_settings = xReplySettings;
|
|
1857
2296
|
if (xNullcastVideo !== undefined)
|
|
1858
2297
|
formData.nullcast = String(xNullcastVideo);
|
|
1859
|
-
if (
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
2298
|
+
if (operation === 'uploadVideo') {
|
|
2299
|
+
try {
|
|
2300
|
+
const xLongTextAsPost = this.getNodeParameter('xLongTextAsPost', i, false);
|
|
2301
|
+
if (xLongTextAsPost)
|
|
2302
|
+
formData.x_long_text_as_post = String(xLongTextAsPost);
|
|
2303
|
+
}
|
|
2304
|
+
catch { }
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
if (isUploadOperation && platforms.includes('threads')) {
|
|
2309
|
+
if (operation === 'uploadText') {
|
|
2310
|
+
const threadsTitle = this.getNodeParameter('threadsTitle', i, '');
|
|
2311
|
+
if (threadsTitle)
|
|
2312
|
+
formData.threads_title = threadsTitle;
|
|
2313
|
+
const threadsLongTextAsPost = this.getNodeParameter('threadsLongTextAsPost', i, false);
|
|
2314
|
+
if (threadsLongTextAsPost)
|
|
2315
|
+
formData.threads_long_text_as_post = String(threadsLongTextAsPost);
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
if (isUploadOperation && platforms.includes('reddit')) {
|
|
2319
|
+
if (operation === 'uploadText') {
|
|
2320
|
+
const redditSubreddit = this.getNodeParameter('redditSubreddit', i);
|
|
2321
|
+
formData.subreddit = redditSubreddit;
|
|
2322
|
+
const redditFlairId = this.getNodeParameter('redditFlairId', i, '');
|
|
2323
|
+
if (redditFlairId)
|
|
2324
|
+
formData.flair_id = redditFlairId;
|
|
1869
2325
|
}
|
|
1870
2326
|
}
|
|
1871
2327
|
const credentials = await this.getCredentials('uploadPostApi');
|
|
@@ -1899,6 +2355,8 @@ class UploadPost {
|
|
|
1899
2355
|
options.qs = qs;
|
|
1900
2356
|
}
|
|
1901
2357
|
}
|
|
2358
|
+
this.logger.info(`Operation: ${operation}, Is Upload Operation: ${isUploadOperation}`);
|
|
2359
|
+
this.logger.info('Complete Form Data being sent (JSON): ' + JSON.stringify(formData, null, 2));
|
|
1902
2360
|
const responseData = await this.helpers.request(options);
|
|
1903
2361
|
const shouldConsiderPolling = operation === 'uploadPhotos' || operation === 'uploadVideo' || operation === 'uploadText';
|
|
1904
2362
|
const waitForCompletion = shouldConsiderPolling ? this.getNodeParameter('waitForCompletion', i, false) : false;
|