n8n-nodes-upload-post 0.1.7 → 0.1.10

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.
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UploadPost = void 0;
4
- const n8n_workflow_1 = require("n8n-workflow");
5
4
  class UploadPost {
6
5
  constructor() {
7
6
  this.description = {
@@ -23,12 +22,6 @@ class UploadPost {
23
22
  required: true,
24
23
  },
25
24
  ],
26
- requestDefaults: {
27
- baseURL: 'https://api.upload-post.com/api',
28
- headers: {
29
- 'Accept': 'application/json',
30
- },
31
- },
32
25
  properties: [
33
26
  {
34
27
  displayName: 'Operation',
@@ -40,40 +33,19 @@ class UploadPost {
40
33
  name: 'Upload Photo(s)',
41
34
  value: 'uploadPhotos',
42
35
  action: 'Upload photos',
43
- description: 'Upload one or more photos',
44
- routing: {
45
- request: {
46
- method: 'POST',
47
- url: '/upload_photos',
48
- body: {},
49
- },
50
- },
36
+ description: 'Upload one or more photos (Supports: TikTok, Instagram, LinkedIn, Facebook, X, Threads)',
51
37
  },
52
38
  {
53
39
  name: 'Upload Video',
54
40
  value: 'uploadVideo',
55
41
  action: 'Upload a video',
56
- description: 'Upload a single video',
57
- routing: {
58
- request: {
59
- method: 'POST',
60
- url: '/upload',
61
- body: {},
62
- },
63
- },
42
+ description: 'Upload a single video (Supports: TikTok, Instagram, LinkedIn, YouTube, Facebook, X, Threads)',
64
43
  },
65
44
  {
66
45
  name: 'Upload Text',
67
46
  value: 'uploadText',
68
47
  action: 'Upload a text post',
69
- description: 'Upload a text-based post',
70
- routing: {
71
- request: {
72
- method: 'POST',
73
- url: '/upload_text',
74
- body: {},
75
- },
76
- },
48
+ description: 'Upload a text-based post (Supports: X, LinkedIn, Facebook, Threads)',
77
49
  },
78
50
  ],
79
51
  default: 'uploadPhotos',
@@ -85,12 +57,6 @@ class UploadPost {
85
57
  required: true,
86
58
  default: '',
87
59
  description: 'User identifier for Upload-Post',
88
- routing: {
89
- send: {
90
- type: 'body',
91
- property: 'user',
92
- }
93
- }
94
60
  },
95
61
  {
96
62
  displayName: 'Platform(s)',
@@ -107,27 +73,15 @@ class UploadPost {
107
73
  { name: 'YouTube', value: 'youtube' },
108
74
  ],
109
75
  default: [],
110
- description: 'Platform(s) to upload to',
111
- routing: {
112
- send: {
113
- type: 'body',
114
- property: 'platform[]',
115
- }
116
- }
76
+ description: 'Platform(s) to upload to. Supported platforms vary by operation.',
117
77
  },
118
78
  {
119
- displayName: 'Title',
79
+ displayName: 'Title / Main Content',
120
80
  name: 'title',
121
81
  type: 'string',
122
82
  required: true,
123
83
  default: '',
124
- description: 'Title of the post/video/text',
125
- routing: {
126
- send: {
127
- type: 'body',
128
- property: 'title',
129
- }
130
- }
84
+ description: 'Title of the post. For Upload Text, this is the main text content. For some video platforms, this acts as a fallback for description if a specific description is not provided.',
131
85
  },
132
86
  {
133
87
  displayName: 'Photos (Files or URLs)',
@@ -145,31 +99,18 @@ class UploadPost {
145
99
  multiple: true,
146
100
  multipleValueButtonText: 'Add Photo',
147
101
  },
148
- routing: {
149
- send: {
150
- type: 'body',
151
- property: 'photos[]',
152
- value: '={{ $value.startsWith("http") ? $value : { "data": $value, "isBinary": true } }}',
153
- }
154
- }
155
102
  },
156
103
  {
157
- displayName: 'Caption',
104
+ displayName: 'Caption (Photo/Video Commentary)',
158
105
  name: 'caption',
159
106
  type: 'string',
160
107
  default: '',
161
- description: 'Caption/description for the photos (post commentary)',
108
+ description: 'General caption/commentary for Photo or Video posts. For some video platforms, a specific \'Description\' field might be used instead (see platform-specific options). Not used for Upload Text.',
162
109
  displayOptions: {
163
110
  show: {
164
- operation: ['uploadPhotos'],
111
+ operation: ['uploadPhotos', 'uploadVideo'],
165
112
  },
166
113
  },
167
- routing: {
168
- send: {
169
- type: 'body',
170
- property: 'caption',
171
- }
172
- }
173
114
  },
174
115
  {
175
116
  displayName: 'Video (File or URL)',
@@ -183,13 +124,6 @@ class UploadPost {
183
124
  operation: ['uploadVideo'],
184
125
  },
185
126
  },
186
- routing: {
187
- send: {
188
- type: 'body',
189
- property: 'video',
190
- value: '={{ $value.startsWith("http") ? $value : { "data": $value, "isBinary": true } }}',
191
- }
192
- }
193
127
  },
194
128
  {
195
129
  displayName: 'LinkedIn Visibility',
@@ -197,62 +131,44 @@ class UploadPost {
197
131
  type: 'options',
198
132
  options: [
199
133
  { name: 'Public', value: 'PUBLIC' },
200
- { name: 'Connections', value: 'CONNECTIONS', displayOptions: { show: { operation: ['uploadVideo'] } } },
134
+ { name: 'Connections', value: 'CONNECTIONS' },
201
135
  { name: 'Logged In', value: 'LOGGED_IN', displayOptions: { show: { operation: ['uploadVideo'] } } },
202
136
  { name: 'Container', value: 'CONTAINER', displayOptions: { show: { operation: ['uploadVideo'] } } },
203
137
  ],
204
138
  default: 'PUBLIC',
205
- description: 'Visibility setting for the LinkedIn post',
139
+ description: 'Visibility for LinkedIn. For Photos, only PUBLIC is supported by API. For Video, CONNECTIONS, PUBLIC, LOGGED_IN, CONTAINER. Not used for Upload Text.',
206
140
  displayOptions: {
207
141
  show: {
208
- operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
142
+ operation: ['uploadPhotos', 'uploadVideo'],
209
143
  platform: ['linkedin']
210
144
  },
211
145
  },
212
- routing: {
213
- send: {
214
- type: 'body',
215
- property: 'visibility',
216
- }
217
- }
218
146
  },
219
147
  {
220
148
  displayName: 'Target LinkedIn Page ID',
221
149
  name: 'targetLinkedinPageId',
222
150
  type: 'string',
223
151
  default: '',
224
- description: 'LinkedIn page ID to upload to an organization (optional)',
152
+ description: 'LinkedIn page ID to upload to an organization (optional). Used for Photos, Video, and Text operations.',
225
153
  displayOptions: {
226
154
  show: {
227
155
  operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
228
156
  platform: ['linkedin']
229
157
  },
230
158
  },
231
- routing: {
232
- send: {
233
- type: 'body',
234
- property: 'target_linkedin_page_id',
235
- }
236
- }
237
159
  },
238
160
  {
239
- displayName: 'LinkedIn Description',
161
+ displayName: 'LinkedIn Video Description',
240
162
  name: 'linkedinDescription',
241
163
  type: 'string',
242
164
  default: '',
243
- description: 'The user generated commentary for the post (LinkedIn Video/Text). If not provided, title is used for video.',
165
+ description: 'User commentary for LinkedIn Video. If not provided, Title is used. Not for Photos/Text.',
244
166
  displayOptions: {
245
167
  show: {
246
- operation: ['uploadVideo', 'uploadText'],
168
+ operation: ['uploadVideo'],
247
169
  platform: ['linkedin']
248
170
  },
249
171
  },
250
- routing: {
251
- send: {
252
- type: 'body',
253
- property: 'description',
254
- }
255
- }
256
172
  },
257
173
  {
258
174
  displayName: 'Facebook Page ID',
@@ -260,38 +176,26 @@ class UploadPost {
260
176
  type: 'string',
261
177
  required: true,
262
178
  default: '',
263
- description: 'Facebook Page ID where the content will be posted',
179
+ description: 'Facebook Page ID. Required for Photos, Video, and Text operations.',
264
180
  displayOptions: {
265
181
  show: {
266
182
  operation: ['uploadPhotos', 'uploadVideo', 'uploadText'],
267
183
  platform: ['facebook']
268
184
  },
269
185
  },
270
- routing: {
271
- send: {
272
- type: 'body',
273
- property: 'facebook_page_id',
274
- }
275
- }
276
186
  },
277
187
  {
278
188
  displayName: 'Facebook Video Description',
279
189
  name: 'facebookVideoDescription',
280
190
  type: 'string',
281
191
  default: '',
282
- description: 'Description of the video for Facebook. If not provided, title is used.',
192
+ description: 'Description for Facebook Video. If not provided, Title is used. Not for Photos/Text.',
283
193
  displayOptions: {
284
194
  show: {
285
195
  operation: ['uploadVideo'],
286
196
  platform: ['facebook']
287
197
  },
288
198
  },
289
- routing: {
290
- send: {
291
- type: 'body',
292
- property: 'description',
293
- }
294
- }
295
199
  },
296
200
  {
297
201
  displayName: 'Facebook Video State',
@@ -303,95 +207,65 @@ class UploadPost {
303
207
  { name: 'Scheduled', value: 'SCHEDULED' },
304
208
  ],
305
209
  default: 'PUBLISHED',
306
- description: 'Desired state of the video on Facebook',
210
+ description: 'State for Facebook Video (DRAFT, PUBLISHED, SCHEDULED). Not for Photos/Text.',
307
211
  displayOptions: {
308
212
  show: {
309
213
  operation: ['uploadVideo'],
310
214
  platform: ['facebook']
311
215
  },
312
216
  },
313
- routing: {
314
- send: {
315
- type: 'body',
316
- property: 'video_state',
317
- }
318
- }
319
217
  },
320
218
  {
321
- displayName: 'TikTok Auto Add Music',
219
+ displayName: 'TikTok Auto Add Music (Photo)',
322
220
  name: 'tiktokAutoAddMusic',
323
221
  type: 'boolean',
324
222
  default: false,
325
- description: 'Whether to automatically add background music to photos on TikTok',
223
+ description: 'Whether to auto add music to TikTok photos. Only for Upload Photos.',
326
224
  displayOptions: {
327
225
  show: {
328
226
  operation: ['uploadPhotos'],
329
227
  platform: ['tiktok']
330
228
  },
331
229
  },
332
- routing: {
333
- send: {
334
- type: 'body',
335
- property: 'auto_add_music',
336
- }
337
- }
338
230
  },
339
231
  {
340
232
  displayName: 'TikTok Disable Comment',
341
233
  name: 'tiktokDisableComment',
342
234
  type: 'boolean',
343
235
  default: false,
344
- description: 'Whether to disable comments on the TikTok post',
236
+ description: 'Whether to disable comments on TikTok post. For Photos & Video.',
345
237
  displayOptions: {
346
238
  show: {
347
239
  operation: ['uploadPhotos', 'uploadVideo'],
348
240
  platform: ['tiktok']
349
241
  },
350
242
  },
351
- routing: {
352
- send: {
353
- type: 'body',
354
- property: 'disable_comment',
355
- }
356
- }
357
243
  },
358
244
  {
359
245
  displayName: 'TikTok Branded Content (Photo)',
360
246
  name: 'tiktokBrandedContentPhoto',
361
247
  type: 'boolean',
362
248
  default: false,
363
- description: 'Whether to indicate if the photo post is branded content (requires Disclose Commercial to be true)',
249
+ description: 'Whether to indicate photo post is branded content (requires Disclose Commercial). Only for Upload Photos.',
364
250
  displayOptions: {
365
251
  show: {
366
252
  operation: ['uploadPhotos'],
367
253
  platform: ['tiktok']
368
254
  },
369
255
  },
370
- routing: {
371
- send: {
372
- type: 'body',
373
- property: 'branded_content',
374
- }
375
- }
376
256
  },
377
257
  {
378
258
  displayName: 'TikTok Disclose Commercial (Photo)',
379
259
  name: 'tiktokDiscloseCommercialPhoto',
380
260
  type: 'boolean',
381
261
  default: false,
382
- description: 'Whether to disclose the commercial nature of the photo post (used with Branded Content)',
262
+ description: 'Whether to disclose commercial nature of photo post. Only for Upload Photos.',
383
263
  displayOptions: {
384
264
  show: {
385
265
  operation: ['uploadPhotos'],
386
266
  platform: ['tiktok']
387
267
  },
388
268
  },
389
- routing: {
390
- send: {
391
- type: 'body',
392
- property: 'disclose_commercial',
393
- }
394
- }
395
269
  },
396
270
  {
397
271
  displayName: 'TikTok Photo Cover Index',
@@ -399,41 +273,29 @@ class UploadPost {
399
273
  type: 'number',
400
274
  default: 0,
401
275
  typeOptions: { minValue: 0 },
402
- description: 'Index (starting at 0) of the photo to use as the cover/thumbnail for the TikTok photo post',
276
+ description: 'Index (0-based) of photo to use as cover for TikTok photo post. Only for Upload Photos.',
403
277
  displayOptions: {
404
278
  show: {
405
279
  operation: ['uploadPhotos'],
406
280
  platform: ['tiktok']
407
281
  },
408
282
  },
409
- routing: {
410
- send: {
411
- type: 'body',
412
- property: 'photo_cover_index',
413
- }
414
- }
415
283
  },
416
284
  {
417
285
  displayName: 'TikTok Photo Description',
418
286
  name: 'tiktokPhotoDescription',
419
287
  type: 'string',
420
288
  default: '',
421
- description: 'Description for the TikTok photo post. If not provided, the common Title value will be used.',
289
+ description: 'Description for TikTok photo post. If not provided, Title is used. Only for Upload Photos.',
422
290
  displayOptions: {
423
291
  show: {
424
292
  operation: ['uploadPhotos'],
425
293
  platform: ['tiktok']
426
294
  },
427
295
  },
428
- routing: {
429
- send: {
430
- type: 'body',
431
- property: 'description',
432
- }
433
- }
434
296
  },
435
297
  {
436
- displayName: 'TikTok Privacy Level',
298
+ displayName: 'TikTok Privacy Level (Video)',
437
299
  name: 'tiktokPrivacyLevel',
438
300
  type: 'options',
439
301
  options: [
@@ -443,408 +305,265 @@ class UploadPost {
443
305
  { name: 'Self Only', value: 'SELF_ONLY' },
444
306
  ],
445
307
  default: 'PUBLIC_TO_EVERYONE',
446
- description: 'Privacy setting for the TikTok video',
308
+ description: 'Privacy setting for TikTok video (PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, etc.). Only for Upload Video.',
447
309
  displayOptions: {
448
310
  show: {
449
311
  operation: ['uploadVideo'],
450
312
  platform: ['tiktok']
451
313
  },
452
314
  },
453
- routing: {
454
- send: {
455
- type: 'body',
456
- property: 'privacy_level',
457
- }
458
- }
459
315
  },
460
316
  {
461
- displayName: 'TikTok Disable Duet',
317
+ displayName: 'TikTok Disable Duet (Video)',
462
318
  name: 'tiktokDisableDuet',
463
319
  type: 'boolean',
464
320
  default: false,
465
- description: 'Whether to disable duet feature for the TikTok video',
321
+ description: 'Whether to disable duet for TikTok video. Only for Upload Video.',
466
322
  displayOptions: {
467
323
  show: {
468
324
  operation: ['uploadVideo'],
469
325
  platform: ['tiktok']
470
326
  },
471
327
  },
472
- routing: {
473
- send: {
474
- type: 'body',
475
- property: 'disable_duet',
476
- }
477
- }
478
328
  },
479
329
  {
480
- displayName: 'TikTok Disable Stitch',
330
+ displayName: 'TikTok Disable Stitch (Video)',
481
331
  name: 'tiktokDisableStitch',
482
332
  type: 'boolean',
483
333
  default: false,
484
- description: 'Whether to disable stitch feature for the TikTok video',
334
+ description: 'Whether to disable stitch for TikTok video. Only for Upload Video.',
485
335
  displayOptions: {
486
336
  show: {
487
337
  operation: ['uploadVideo'],
488
338
  platform: ['tiktok']
489
339
  },
490
340
  },
491
- routing: {
492
- send: {
493
- type: 'body',
494
- property: 'disable_stitch',
495
- }
496
- }
497
341
  },
498
342
  {
499
- displayName: 'TikTok Cover Timestamp (Ms)',
343
+ displayName: 'TikTok Cover Timestamp (Ms, Video)',
500
344
  name: 'tiktokCoverTimestamp',
501
345
  type: 'number',
502
346
  default: 1000,
503
- description: 'Timestamp in milliseconds for video cover on TikTok',
347
+ description: 'Timestamp (ms) for video cover on TikTok. Only for Upload Video.',
504
348
  displayOptions: {
505
349
  show: {
506
350
  operation: ['uploadVideo'],
507
351
  platform: ['tiktok']
508
352
  },
509
353
  },
510
- routing: {
511
- send: {
512
- type: 'body',
513
- property: 'cover_timestamp',
514
- }
515
- }
516
354
  },
517
355
  {
518
- displayName: 'TikTok Brand Content Toggle',
356
+ displayName: 'TikTok Brand Content Toggle (Video)',
519
357
  name: 'tiktokBrandContentToggle',
520
358
  type: 'boolean',
521
359
  default: false,
522
- description: 'Whether to enable branded content for TikTok video',
360
+ description: 'Whether to enable branded content for TikTok video. Only for Upload Video.',
523
361
  displayOptions: {
524
362
  show: {
525
363
  operation: ['uploadVideo'],
526
364
  platform: ['tiktok']
527
365
  },
528
366
  },
529
- routing: {
530
- send: {
531
- type: 'body',
532
- property: 'brand_content_toggle',
533
- }
534
- }
535
367
  },
536
368
  {
537
- displayName: 'TikTok Brand Organic',
369
+ displayName: 'TikTok Brand Organic (Video)',
538
370
  name: 'tiktokBrandOrganic',
539
371
  type: 'boolean',
540
372
  default: false,
541
- description: 'Whether to enable organic branded content for TikTok video',
373
+ description: 'Whether to enable organic branded content for TikTok video. Only for Upload Video.',
542
374
  displayOptions: {
543
375
  show: {
544
376
  operation: ['uploadVideo'],
545
377
  platform: ['tiktok']
546
378
  },
547
379
  },
548
- routing: {
549
- send: {
550
- type: 'body',
551
- property: 'brand_organic',
552
- }
553
- }
554
380
  },
555
381
  {
556
382
  displayName: 'TikTok Branded Content (Video)',
557
383
  name: 'tiktokBrandedContentVideo',
558
384
  type: 'boolean',
559
385
  default: false,
560
- description: 'Whether to enable branded content with disclosure for TikTok video',
386
+ description: 'Whether to enable branded content with disclosure for TikTok video. Only for Upload Video.',
561
387
  displayOptions: {
562
388
  show: {
563
389
  operation: ['uploadVideo'],
564
390
  platform: ['tiktok']
565
391
  },
566
392
  },
567
- routing: {
568
- send: {
569
- type: 'body',
570
- property: 'branded_content',
571
- }
572
- }
573
393
  },
574
394
  {
575
- displayName: 'TikTok Brand Organic Toggle',
395
+ displayName: 'TikTok Brand Organic Toggle (Video)',
576
396
  name: 'tiktokBrandOrganicToggle',
577
397
  type: 'boolean',
578
398
  default: false,
579
- description: 'Whether to enable organic branded content toggle for TikTok video',
399
+ description: 'Whether to enable organic branded content toggle for TikTok video. Only for Upload Video.',
580
400
  displayOptions: {
581
401
  show: {
582
402
  operation: ['uploadVideo'],
583
403
  platform: ['tiktok']
584
404
  },
585
405
  },
586
- routing: {
587
- send: {
588
- type: 'body',
589
- property: 'brand_organic_toggle',
590
- }
591
- }
592
406
  },
593
407
  {
594
- displayName: 'TikTok Is AIGC',
408
+ displayName: 'TikTok Is AIGC (Video)',
595
409
  name: 'tiktokIsAigc',
596
410
  type: 'boolean',
597
411
  default: false,
598
- description: 'Whether to indicate if content is AI-generated for TikTok video',
412
+ description: 'Whether to indicate if content is AI-generated for TikTok video. Only for Upload Video.',
599
413
  displayOptions: {
600
414
  show: {
601
415
  operation: ['uploadVideo'],
602
416
  platform: ['tiktok']
603
417
  },
604
418
  },
605
- routing: {
606
- send: {
607
- type: 'body',
608
- property: 'is_aigc',
609
- }
610
- }
611
419
  },
612
420
  {
613
- displayName: 'Instagram Photo Media Type',
614
- name: 'instagramPhotoMediaType',
421
+ displayName: 'Instagram Media Type',
422
+ name: 'instagramMediaType',
615
423
  type: 'options',
616
424
  options: [
617
- { name: 'Image (Feed)', value: 'IMAGE' },
618
- { name: 'Stories', value: 'STORIES' },
425
+ { name: 'Image (Feed - Photo)', value: 'IMAGE', displayOptions: { show: { operation: ['uploadPhotos'] } } },
426
+ { name: 'Stories (Photo/Video)', value: 'STORIES' },
427
+ { name: 'Reels (Video)', value: 'REELS', displayOptions: { show: { operation: ['uploadVideo'] } } },
619
428
  ],
620
429
  default: 'IMAGE',
621
- description: 'Type of media for Instagram photo upload',
430
+ description: 'Type of media for Instagram. IMAGE/STORIES for Photos. REELS/STORIES for Video.',
622
431
  displayOptions: {
623
432
  show: {
624
- operation: ['uploadPhotos'],
433
+ operation: ['uploadPhotos', 'uploadVideo'],
625
434
  platform: ['instagram']
626
435
  },
627
436
  },
628
- routing: {
629
- send: {
630
- type: 'body',
631
- property: 'media_type',
632
- }
633
- }
634
437
  },
635
438
  {
636
- displayName: 'Instagram Video Media Type',
637
- name: 'instagramVideoMediaType',
638
- type: 'options',
639
- options: [
640
- { name: 'Reels', value: 'REELS' },
641
- { name: 'Stories', value: 'STORIES' },
642
- ],
643
- default: 'REELS',
644
- description: 'Type of media for Instagram video upload',
645
- displayOptions: {
646
- show: {
647
- operation: ['uploadVideo'],
648
- platform: ['instagram']
649
- },
650
- },
651
- routing: {
652
- send: {
653
- type: 'body',
654
- property: 'media_type',
655
- }
656
- }
657
- },
658
- {
659
- displayName: 'Instagram Share to Feed',
439
+ displayName: 'Instagram Share to Feed (Video)',
660
440
  name: 'instagramShareToFeed',
661
441
  type: 'boolean',
662
442
  default: true,
663
- description: 'Whether to share the Instagram video (Reel/Story) to feed',
443
+ description: 'Whether to share Instagram video (Reel/Story) to feed. Only for Upload Video.',
664
444
  displayOptions: {
665
445
  show: {
666
446
  operation: ['uploadVideo'],
667
447
  platform: ['instagram']
668
448
  },
669
449
  },
670
- routing: {
671
- send: {
672
- type: 'body',
673
- property: 'share_to_feed',
674
- }
675
- }
676
450
  },
677
451
  {
678
- displayName: 'Instagram Collaborators',
452
+ displayName: 'Instagram Collaborators (Video)',
679
453
  name: 'instagramCollaborators',
680
454
  type: 'string',
681
455
  default: '',
682
- description: 'Comma-separated list of collaborator usernames for Instagram video',
456
+ description: 'Comma-separated collaborator usernames for Instagram video. Sent as a string. Only for Upload Video.',
683
457
  displayOptions: {
684
458
  show: {
685
459
  operation: ['uploadVideo'],
686
460
  platform: ['instagram']
687
461
  },
688
462
  },
689
- routing: {
690
- send: {
691
- type: 'body',
692
- property: 'collaborators',
693
- }
694
- }
695
463
  },
696
464
  {
697
- displayName: 'Instagram Cover URL',
465
+ displayName: 'Instagram Cover URL (Video)',
698
466
  name: 'instagramCoverUrl',
699
467
  type: 'string',
700
468
  default: '',
701
- description: 'URL for custom video cover on Instagram',
469
+ description: 'URL for custom video cover on Instagram. Only for Upload Video.',
702
470
  displayOptions: {
703
471
  show: {
704
472
  operation: ['uploadVideo'],
705
473
  platform: ['instagram']
706
474
  },
707
475
  },
708
- routing: {
709
- send: {
710
- type: 'body',
711
- property: 'cover_url',
712
- }
713
- }
714
476
  },
715
477
  {
716
- displayName: 'Instagram Audio Name',
478
+ displayName: 'Instagram Audio Name (Video)',
717
479
  name: 'instagramAudioName',
718
480
  type: 'string',
719
481
  default: '',
720
- description: 'Name of the audio track for Instagram video',
482
+ description: 'Name of the audio track for Instagram video. Only for Upload Video.',
721
483
  displayOptions: {
722
484
  show: {
723
485
  operation: ['uploadVideo'],
724
486
  platform: ['instagram']
725
487
  },
726
488
  },
727
- routing: {
728
- send: {
729
- type: 'body',
730
- property: 'audio_name',
731
- }
732
- }
733
489
  },
734
490
  {
735
- displayName: 'Instagram User Tags',
491
+ displayName: 'Instagram User Tags (Video)',
736
492
  name: 'instagramUserTags',
737
493
  type: 'string',
738
494
  default: '',
739
- description: 'Comma-separated list of user tags for Instagram video',
495
+ description: 'Comma-separated user tags for Instagram video. Sent as a string. Only for Upload Video.',
740
496
  displayOptions: {
741
497
  show: {
742
498
  operation: ['uploadVideo'],
743
499
  platform: ['instagram']
744
500
  },
745
501
  },
746
- routing: {
747
- send: {
748
- type: 'body',
749
- property: 'user_tags',
750
- }
751
- }
752
502
  },
753
503
  {
754
- displayName: 'Instagram Location ID',
504
+ displayName: 'Instagram Location ID (Video)',
755
505
  name: 'instagramLocationId',
756
506
  type: 'string',
757
507
  default: '',
758
- description: 'Instagram location ID for the video',
508
+ description: 'Instagram location ID for the video. Only for Upload Video.',
759
509
  displayOptions: {
760
510
  show: {
761
511
  operation: ['uploadVideo'],
762
512
  platform: ['instagram']
763
513
  },
764
514
  },
765
- routing: {
766
- send: {
767
- type: 'body',
768
- property: 'location_id',
769
- }
770
- }
771
515
  },
772
516
  {
773
- displayName: 'Instagram Thumb Offset',
517
+ displayName: 'Instagram Thumb Offset (Video)',
774
518
  name: 'instagramThumbOffset',
775
519
  type: 'string',
776
520
  default: '',
777
- description: 'Timestamp offset for video thumbnail on Instagram',
521
+ description: 'Timestamp offset for video thumbnail on Instagram. Only for Upload Video.',
778
522
  displayOptions: {
779
523
  show: {
780
524
  operation: ['uploadVideo'],
781
525
  platform: ['instagram']
782
526
  },
783
527
  },
784
- routing: {
785
- send: {
786
- type: 'body',
787
- property: 'thumb_offset',
788
- }
789
- }
790
528
  },
791
529
  {
792
- displayName: 'YouTube Description',
530
+ displayName: 'YouTube Video Description',
793
531
  name: 'youtubeDescription',
794
532
  type: 'string',
795
533
  default: '',
796
- description: 'Description of the video for YouTube. If not provided, title is used.',
534
+ description: 'Description of the video for YouTube. If not provided, Title is used. Only for Upload Video.',
797
535
  displayOptions: {
798
536
  show: {
799
537
  operation: ['uploadVideo'],
800
538
  platform: ['youtube']
801
539
  },
802
540
  },
803
- routing: {
804
- send: {
805
- type: 'body',
806
- property: 'description',
807
- }
808
- }
809
541
  },
810
542
  {
811
543
  displayName: 'YouTube Tags',
812
544
  name: 'youtubeTags',
813
545
  type: 'string',
814
546
  default: '',
815
- description: 'Comma-separated list of tags for YouTube video. These will be sent as an array.',
547
+ description: 'Comma-separated list of tags for YouTube video. Will be sent as an array. Only for Upload Video.',
816
548
  displayOptions: {
817
549
  show: {
818
550
  operation: ['uploadVideo'],
819
551
  platform: ['youtube']
820
552
  },
821
553
  },
822
- routing: {
823
- send: {
824
- type: 'body',
825
- property: 'tags',
826
- value: '={{ $value ? $value.split(",").map(tag => tag.trim()) : [] }}',
827
- }
828
- }
829
554
  },
830
555
  {
831
556
  displayName: 'YouTube Category ID',
832
557
  name: 'youtubeCategoryId',
833
558
  type: 'string',
834
559
  default: '22',
835
- description: 'Video category for YouTube',
560
+ description: 'Video category ID for YouTube (e.g., 22 for People & Blogs). Only for Upload Video.',
836
561
  displayOptions: {
837
562
  show: {
838
563
  operation: ['uploadVideo'],
839
564
  platform: ['youtube']
840
565
  },
841
566
  },
842
- routing: {
843
- send: {
844
- type: 'body',
845
- property: 'categoryId',
846
- }
847
- }
848
567
  },
849
568
  {
850
569
  displayName: 'YouTube Privacy Status',
@@ -856,38 +575,26 @@ class UploadPost {
856
575
  { name: 'Private', value: 'private' },
857
576
  ],
858
577
  default: 'public',
859
- description: 'Privacy setting for YouTube video',
578
+ description: 'Privacy setting for YouTube video (public, unlisted, private). Only for Upload Video.',
860
579
  displayOptions: {
861
580
  show: {
862
581
  operation: ['uploadVideo'],
863
582
  platform: ['youtube']
864
583
  },
865
584
  },
866
- routing: {
867
- send: {
868
- type: 'body',
869
- property: 'privacyStatus',
870
- }
871
- }
872
585
  },
873
586
  {
874
587
  displayName: 'YouTube Embeddable',
875
588
  name: 'youtubeEmbeddable',
876
589
  type: 'boolean',
877
590
  default: true,
878
- description: 'Whether the YouTube video is embeddable',
591
+ description: 'Whether the YouTube video is embeddable. Only for Upload Video.',
879
592
  displayOptions: {
880
593
  show: {
881
594
  operation: ['uploadVideo'],
882
595
  platform: ['youtube']
883
596
  },
884
597
  },
885
- routing: {
886
- send: {
887
- type: 'body',
888
- property: 'embeddable',
889
- }
890
- }
891
598
  },
892
599
  {
893
600
  displayName: 'YouTube License',
@@ -898,99 +605,68 @@ class UploadPost {
898
605
  { name: 'Creative Commons - Attribution', value: 'creativeCommon' },
899
606
  ],
900
607
  default: 'youtube',
901
- description: 'Video license for YouTube',
608
+ description: 'Video license for YouTube (youtube, creativeCommon). Only for Upload Video.',
902
609
  displayOptions: {
903
610
  show: {
904
611
  operation: ['uploadVideo'],
905
612
  platform: ['youtube']
906
613
  },
907
614
  },
908
- routing: {
909
- send: {
910
- type: 'body',
911
- property: 'license',
912
- }
913
- }
914
615
  },
915
616
  {
916
617
  displayName: 'YouTube Public Stats Viewable',
917
618
  name: 'youtubePublicStatsViewable',
918
619
  type: 'boolean',
919
620
  default: true,
920
- description: 'Whether public stats are viewable for the YouTube video',
621
+ description: 'Whether public stats are viewable for the YouTube video. Only for Upload Video.',
921
622
  displayOptions: {
922
623
  show: {
923
624
  operation: ['uploadVideo'],
924
625
  platform: ['youtube']
925
626
  },
926
627
  },
927
- routing: {
928
- send: {
929
- type: 'body',
930
- property: 'publicStatsViewable',
931
- }
932
- }
933
628
  },
934
629
  {
935
630
  displayName: 'YouTube Made For Kids',
936
631
  name: 'youtubeMadeForKids',
937
632
  type: 'boolean',
938
633
  default: false,
939
- description: 'Whether the YouTube video is made for kids',
634
+ description: 'Whether the YouTube video is made for kids. Only for Upload Video.',
940
635
  displayOptions: {
941
636
  show: {
942
637
  operation: ['uploadVideo'],
943
638
  platform: ['youtube']
944
639
  },
945
640
  },
946
- routing: {
947
- send: {
948
- type: 'body',
949
- property: 'madeForKids',
950
- }
951
- }
952
641
  },
953
642
  {
954
- displayName: 'Threads Description',
643
+ displayName: 'Threads Video Description',
955
644
  name: 'threadsDescription',
956
645
  type: 'string',
957
646
  default: '',
958
- description: 'The user generated commentary for the post on Threads. If not provided, title is used.',
647
+ description: 'User commentary for Threads video. If not provided, Title is used. Not for Photos/Text.',
959
648
  displayOptions: {
960
649
  show: {
961
- operation: ['uploadVideo', 'uploadText'],
650
+ operation: ['uploadVideo'],
962
651
  platform: ['threads']
963
652
  },
964
653
  },
965
- routing: {
966
- send: {
967
- type: 'body',
968
- property: 'description',
969
- }
970
- }
971
654
  },
972
655
  {
973
- displayName: 'X Tagged User IDs',
656
+ displayName: 'X Tagged User IDs (Video/Text)',
974
657
  name: 'xTaggedUserIds',
975
658
  type: 'string',
976
659
  default: '',
977
- description: 'Comma-separated list of user IDs to tag for X (Twitter) video/text. These will be sent as an array.',
660
+ description: 'Comma-separated list of user IDs to tag for X (Twitter). Not for Photos.',
978
661
  displayOptions: {
979
662
  show: {
980
663
  operation: ['uploadVideo', 'uploadText'],
981
664
  platform: ['x']
982
665
  },
983
666
  },
984
- routing: {
985
- send: {
986
- type: 'body',
987
- property: 'tagged_user_ids',
988
- value: '={{ $value ? $value.split(",").map(id => id.trim()) : [] }}',
989
- }
990
- }
991
667
  },
992
668
  {
993
- displayName: 'X Reply Settings',
669
+ displayName: 'X Reply Settings (Video/Text)',
994
670
  name: 'xReplySettings',
995
671
  type: 'options',
996
672
  options: [
@@ -999,96 +675,65 @@ class UploadPost {
999
675
  { name: 'Everyone', value: 'everyone' },
1000
676
  ],
1001
677
  default: 'following',
1002
- description: 'Who can reply to the X (Twitter) video/text post',
678
+ description: 'Who can reply to the post on X (Twitter) (following, mentionedUsers, everyone). Not for Photos.',
1003
679
  displayOptions: {
1004
680
  show: {
1005
681
  operation: ['uploadVideo', 'uploadText'],
1006
682
  platform: ['x']
1007
683
  },
1008
684
  },
1009
- routing: {
1010
- send: {
1011
- type: 'body',
1012
- property: 'reply_settings',
1013
- }
1014
- }
1015
685
  },
1016
686
  {
1017
687
  displayName: 'X Nullcast (Video)',
1018
688
  name: 'xNullcastVideo',
1019
689
  type: 'boolean',
1020
690
  default: false,
1021
- description: 'Whether to publish X (Twitter) video without broadcasting',
691
+ description: 'Whether to publish X (Twitter) video without broadcasting. Not for Text/Photos.',
1022
692
  displayOptions: {
1023
693
  show: {
1024
694
  operation: ['uploadVideo'],
1025
695
  platform: ['x']
1026
696
  },
1027
697
  },
1028
- routing: {
1029
- send: {
1030
- type: 'body',
1031
- property: 'nullcast',
1032
- }
1033
- }
1034
698
  },
1035
699
  {
1036
700
  displayName: 'X Place ID (Video)',
1037
701
  name: 'xPlaceIdVideo',
1038
702
  type: 'string',
1039
703
  default: '',
1040
- description: 'Location place ID for X (Twitter) video',
704
+ description: 'Location place ID for X (Twitter) video. Not for Text/Photos.',
1041
705
  displayOptions: {
1042
706
  show: {
1043
707
  operation: ['uploadVideo'],
1044
708
  platform: ['x']
1045
709
  },
1046
710
  },
1047
- routing: {
1048
- send: {
1049
- type: 'body',
1050
- property: 'place_id',
1051
- }
1052
- }
1053
711
  },
1054
712
  {
1055
713
  displayName: 'X Poll Duration (Minutes, Video)',
1056
714
  name: 'xPollDurationVideo',
1057
715
  type: 'number',
1058
716
  default: 1440,
1059
- description: 'Poll duration in minutes for X (Twitter) video post. Requires Poll Options.',
717
+ description: 'Poll duration in minutes for X (Twitter) video post (requires Poll Options). Not for Text/Photos.',
1060
718
  displayOptions: {
1061
719
  show: {
1062
720
  operation: ['uploadVideo'],
1063
721
  platform: ['x']
1064
722
  },
1065
723
  },
1066
- routing: {
1067
- send: {
1068
- type: 'body',
1069
- property: 'poll_duration',
1070
- }
1071
- }
1072
724
  },
1073
725
  {
1074
726
  displayName: 'X Poll Options (Video)',
1075
727
  name: 'xPollOptionsVideo',
1076
728
  type: 'string',
1077
729
  default: '',
1078
- description: 'Comma-separated list of poll options for X (Twitter) video post. These will be sent as an array.',
730
+ description: 'Comma-separated list of poll options for X (Twitter) video post. Will be sent as an array. Not for Text/Photos.',
1079
731
  displayOptions: {
1080
732
  show: {
1081
733
  operation: ['uploadVideo'],
1082
734
  platform: ['x']
1083
735
  },
1084
736
  },
1085
- routing: {
1086
- send: {
1087
- type: 'body',
1088
- property: 'poll_options',
1089
- value: '={{ $value ? $value.split(",").map(opt => opt.trim()) : [] }}',
1090
- }
1091
- }
1092
737
  },
1093
738
  {
1094
739
  displayName: 'X Poll Reply Settings (Video)',
@@ -1100,86 +745,318 @@ class UploadPost {
1100
745
  { name: 'Everyone', value: 'everyone' },
1101
746
  ],
1102
747
  default: 'following',
1103
- description: 'Who can reply to the poll in X (Twitter) video post',
748
+ description: 'Who can reply to the poll in X (Twitter) video post (following, mentionedUsers, everyone). Not for Text/Photos.',
1104
749
  displayOptions: {
1105
750
  show: {
1106
751
  operation: ['uploadVideo'],
1107
752
  platform: ['x']
1108
753
  },
1109
754
  },
1110
- routing: {
1111
- send: {
1112
- type: 'body',
1113
- property: 'poll_reply_settings',
1114
- }
1115
- }
1116
755
  },
1117
756
  {
1118
757
  displayName: 'X Post URL (Text)',
1119
758
  name: 'xPostUrlText',
1120
759
  type: 'string',
1121
760
  default: '',
1122
- description: 'URL to attach to the X (Twitter) text post',
761
+ description: 'URL to attach to the X (Twitter) text post. Only for Upload Text.',
1123
762
  displayOptions: {
1124
763
  show: {
1125
764
  operation: ['uploadText'],
1126
765
  platform: ['x']
1127
766
  },
1128
767
  },
1129
- routing: {
1130
- send: {
1131
- type: 'body',
1132
- property: 'post_url',
1133
- }
1134
- }
1135
768
  },
1136
769
  ],
1137
770
  };
1138
771
  }
1139
772
  async execute() {
1140
- var _a;
1141
773
  const items = this.getInputData();
1142
774
  const returnData = [];
1143
- const length = items.length;
1144
- const nodeDescription = this.description;
1145
- const defaultBaseUrl = (_a = nodeDescription.requestDefaults) === null || _a === void 0 ? void 0 : _a.baseURL;
1146
- for (let i = 0; i < length; i++) {
1147
- try {
1148
- const operation = this.getNodeParameter('operation', i);
1149
- const operationProperty = nodeDescription.properties.find((prop) => prop.name === 'operation');
1150
- const operationOptions = operationProperty === null || operationProperty === void 0 ? void 0 : operationProperty.options;
1151
- const operationConfig = operationOptions === null || operationOptions === void 0 ? void 0 : operationOptions.find(opt => opt.value === operation);
1152
- const routingInfo = operationConfig === null || operationConfig === void 0 ? void 0 : operationConfig.routing;
1153
- if (!routingInfo || !routingInfo.request || !routingInfo.request.url || !routingInfo.request.method) {
1154
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Routing information incomplete for operation: ${operation}`);
775
+ for (let i = 0; i < items.length; i++) {
776
+ const operation = this.getNodeParameter('operation', i);
777
+ const user = this.getNodeParameter('user', i);
778
+ let platforms = this.getNodeParameter('platform', i);
779
+ const title = this.getNodeParameter('title', i);
780
+ let endpoint = '';
781
+ const formData = {};
782
+ formData.user = user;
783
+ formData.title = title;
784
+ switch (operation) {
785
+ case 'uploadPhotos':
786
+ endpoint = '/upload_photos';
787
+ const photoCaption = this.getNodeParameter('caption', i);
788
+ let photosInput = this.getNodeParameter('photos', i, []);
789
+ let photosToProcess;
790
+ if (typeof photosInput === 'string') {
791
+ photosToProcess = photosInput ? [photosInput] : [];
792
+ }
793
+ else {
794
+ photosToProcess = photosInput;
795
+ }
796
+ const allowedPhotoPlatforms = ['tiktok', 'instagram', 'linkedin', 'facebook', 'x', 'threads'];
797
+ platforms = platforms.filter(p => allowedPhotoPlatforms.includes(p));
798
+ formData['platform[]'] = platforms;
799
+ if (photosToProcess.length > 0) {
800
+ const photoArray = [];
801
+ for (const photoItem of photosToProcess) {
802
+ if (typeof photoItem === 'string' && photoItem.startsWith('{{$binary')) {
803
+ const binaryPropertyName = photoItem.substring('{{$binary.'.length, photoItem.length - 2);
804
+ const binaryData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
805
+ photoArray.push(binaryData);
806
+ }
807
+ else if (typeof photoItem === 'string' && photoItem) {
808
+ photoArray.push(photoItem);
809
+ }
810
+ }
811
+ if (photoArray.length > 0) {
812
+ formData['photos[]'] = photoArray;
813
+ }
814
+ }
815
+ if (photoCaption)
816
+ formData.caption = photoCaption;
817
+ break;
818
+ case 'uploadVideo':
819
+ endpoint = '/upload';
820
+ const video = this.getNodeParameter('video', i);
821
+ const allowedVideoPlatforms = ['tiktok', 'instagram', 'linkedin', 'youtube', 'facebook', 'x', 'threads'];
822
+ platforms = platforms.filter(p => allowedVideoPlatforms.includes(p));
823
+ formData['platform[]'] = platforms;
824
+ if (video) {
825
+ if (video.startsWith('{{$binary')) {
826
+ const binaryPropertyName = video.substring('{{$binary.'.length, video.length - 2);
827
+ const binaryData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
828
+ formData.video = binaryData;
829
+ }
830
+ else {
831
+ formData.video = video;
832
+ }
833
+ }
834
+ break;
835
+ case 'uploadText':
836
+ endpoint = '/upload_text';
837
+ const allowedTextPlatforms = ['x', 'linkedin', 'facebook', 'threads'];
838
+ platforms = platforms.filter(p => allowedTextPlatforms.includes(p));
839
+ formData['platform[]'] = platforms;
840
+ break;
841
+ }
842
+ if (platforms.includes('linkedin')) {
843
+ const targetLinkedinPageId = this.getNodeParameter('targetLinkedinPageId', i);
844
+ if (targetLinkedinPageId)
845
+ formData.target_linkedin_page_id = targetLinkedinPageId;
846
+ if (operation === 'uploadPhotos') {
847
+ const linkedinVisibility = this.getNodeParameter('linkedinVisibility', i);
848
+ if (linkedinVisibility === 'PUBLIC') {
849
+ formData.visibility = 'PUBLIC';
850
+ }
851
+ }
852
+ else if (operation === 'uploadVideo') {
853
+ const linkedinVisibility = this.getNodeParameter('linkedinVisibility', i);
854
+ const linkedinDescription = this.getNodeParameter('linkedinDescription', i);
855
+ formData.visibility = linkedinVisibility;
856
+ if (linkedinDescription)
857
+ formData.description = linkedinDescription;
858
+ }
859
+ }
860
+ if (platforms.includes('facebook')) {
861
+ const facebookPageId = this.getNodeParameter('facebookPageId', i);
862
+ formData.facebook_page_id = facebookPageId;
863
+ if (operation === 'uploadVideo') {
864
+ const facebookVideoDescription = this.getNodeParameter('facebookVideoDescription', i);
865
+ const facebookVideoState = this.getNodeParameter('facebookVideoState', i);
866
+ if (facebookVideoDescription)
867
+ formData.description = facebookVideoDescription;
868
+ if (facebookVideoState)
869
+ formData.video_state = facebookVideoState;
1155
870
  }
1156
- const requestDetails = routingInfo.request;
1157
- const relativeUrl = requestDetails.url;
1158
- const httpMethod = requestDetails.method;
1159
- if (!defaultBaseUrl) {
1160
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Base URL is not defined in node requestDefaults.');
871
+ }
872
+ if (platforms.includes('tiktok')) {
873
+ if (operation === 'uploadPhotos') {
874
+ const tiktokAutoAddMusic = this.getNodeParameter('tiktokAutoAddMusic', i);
875
+ const tiktokDisableComment = this.getNodeParameter('tiktokDisableComment', i);
876
+ const tiktokBrandedContentPhoto = this.getNodeParameter('tiktokBrandedContentPhoto', i);
877
+ const tiktokDiscloseCommercialPhoto = this.getNodeParameter('tiktokDiscloseCommercialPhoto', i);
878
+ const tiktokPhotoCoverIndex = this.getNodeParameter('tiktokPhotoCoverIndex', i);
879
+ const tiktokPhotoDescription = this.getNodeParameter('tiktokPhotoDescription', i);
880
+ if (tiktokAutoAddMusic !== undefined)
881
+ formData.auto_add_music = String(tiktokAutoAddMusic);
882
+ if (tiktokDisableComment !== undefined)
883
+ formData.disable_comment = String(tiktokDisableComment);
884
+ if (tiktokBrandedContentPhoto !== undefined)
885
+ formData.branded_content = String(tiktokBrandedContentPhoto);
886
+ if (tiktokDiscloseCommercialPhoto !== undefined)
887
+ formData.disclose_commercial = String(tiktokDiscloseCommercialPhoto);
888
+ if (tiktokPhotoCoverIndex !== undefined)
889
+ formData.photo_cover_index = tiktokPhotoCoverIndex;
890
+ if (tiktokPhotoDescription)
891
+ formData.description = tiktokPhotoDescription;
892
+ }
893
+ else if (operation === 'uploadVideo') {
894
+ const tiktokPrivacyLevel = this.getNodeParameter('tiktokPrivacyLevel', i);
895
+ const tiktokDisableDuet = this.getNodeParameter('tiktokDisableDuet', i);
896
+ const tiktokDisableComment = this.getNodeParameter('tiktokDisableComment', i);
897
+ const tiktokDisableStitch = this.getNodeParameter('tiktokDisableStitch', i);
898
+ const tiktokCoverTimestamp = this.getNodeParameter('tiktokCoverTimestamp', i);
899
+ const tiktokBrandContentToggle = this.getNodeParameter('tiktokBrandContentToggle', i);
900
+ const tiktokBrandOrganic = this.getNodeParameter('tiktokBrandOrganic', i);
901
+ const tiktokBrandedContentVideo = this.getNodeParameter('tiktokBrandedContentVideo', i);
902
+ const tiktokBrandOrganicToggle = this.getNodeParameter('tiktokBrandOrganicToggle', i);
903
+ const tiktokIsAigc = this.getNodeParameter('tiktokIsAigc', i);
904
+ if (tiktokPrivacyLevel)
905
+ formData.privacy_level = tiktokPrivacyLevel;
906
+ if (tiktokDisableDuet !== undefined)
907
+ formData.disable_duet = String(tiktokDisableDuet);
908
+ if (tiktokDisableComment !== undefined)
909
+ formData.disable_comment = String(tiktokDisableComment);
910
+ if (tiktokDisableStitch !== undefined)
911
+ formData.disable_stitch = String(tiktokDisableStitch);
912
+ if (tiktokCoverTimestamp !== undefined)
913
+ formData.cover_timestamp = tiktokCoverTimestamp;
914
+ if (tiktokBrandContentToggle !== undefined)
915
+ formData.brand_content_toggle = String(tiktokBrandContentToggle);
916
+ if (tiktokBrandOrganic !== undefined)
917
+ formData.brand_organic = String(tiktokBrandOrganic);
918
+ if (tiktokBrandedContentVideo !== undefined)
919
+ formData.branded_content = String(tiktokBrandedContentVideo);
920
+ if (tiktokBrandOrganicToggle !== undefined)
921
+ formData.brand_organic_toggle = String(tiktokBrandOrganicToggle);
922
+ if (tiktokIsAigc !== undefined)
923
+ formData.is_aigc = String(tiktokIsAigc);
1161
924
  }
1162
- const requestOptions = {
1163
- method: httpMethod,
1164
- uri: relativeUrl,
1165
- };
1166
- this.logger.debug(`[UploadPost Node] Calling request helper with method: ${httpMethod}, relative URI: ${relativeUrl}, baseURL from defaults: ${defaultBaseUrl}`);
1167
- const responseData = await this.helpers.requestWithAuthentication.call(this, 'uploadPostApi', requestOptions);
1168
- returnData.push({ json: responseData, pairedItem: i });
1169
925
  }
1170
- catch (error) {
1171
- if (this.continueOnFail()) {
1172
- returnData.push({ json: { error: error.message }, pairedItem: i });
1173
- continue;
926
+ if (platforms.includes('instagram')) {
927
+ const instagramMediaTypeInput = this.getNodeParameter('instagramMediaType', i);
928
+ let finalInstagramMediaType = instagramMediaTypeInput;
929
+ if (operation === 'uploadPhotos') {
930
+ if (!instagramMediaTypeInput || !['IMAGE', 'STORIES'].includes(instagramMediaTypeInput)) {
931
+ finalInstagramMediaType = 'IMAGE';
932
+ }
933
+ }
934
+ else if (operation === 'uploadVideo') {
935
+ if (!instagramMediaTypeInput || !['REELS', 'STORIES'].includes(instagramMediaTypeInput)) {
936
+ finalInstagramMediaType = 'REELS';
937
+ }
1174
938
  }
1175
- if (error.context) {
1176
- error.context.itemIndex = i;
1177
- throw error;
939
+ if (finalInstagramMediaType)
940
+ formData.media_type = finalInstagramMediaType;
941
+ if (operation === 'uploadVideo') {
942
+ const instagramShareToFeed = this.getNodeParameter('instagramShareToFeed', i);
943
+ const instagramCollaborators = this.getNodeParameter('instagramCollaborators', i);
944
+ const instagramCoverUrl = this.getNodeParameter('instagramCoverUrl', i);
945
+ const instagramAudioName = this.getNodeParameter('instagramAudioName', i);
946
+ const instagramUserTags = this.getNodeParameter('instagramUserTags', i);
947
+ const instagramLocationId = this.getNodeParameter('instagramLocationId', i);
948
+ const instagramThumbOffset = this.getNodeParameter('instagramThumbOffset', i);
949
+ if (instagramShareToFeed !== undefined)
950
+ formData.share_to_feed = String(instagramShareToFeed);
951
+ if (instagramCollaborators)
952
+ formData.collaborators = instagramCollaborators;
953
+ if (instagramCoverUrl)
954
+ formData.cover_url = instagramCoverUrl;
955
+ if (instagramAudioName)
956
+ formData.audio_name = instagramAudioName;
957
+ if (instagramUserTags)
958
+ formData.user_tags = instagramUserTags;
959
+ if (instagramLocationId)
960
+ formData.location_id = instagramLocationId;
961
+ if (instagramThumbOffset)
962
+ formData.thumb_offset = instagramThumbOffset;
1178
963
  }
1179
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
1180
- itemIndex: i,
1181
- });
1182
964
  }
965
+ if (platforms.includes('youtube') && operation === 'uploadVideo') {
966
+ const youtubeDescription = this.getNodeParameter('youtubeDescription', i);
967
+ const youtubeTagsRaw = this.getNodeParameter('youtubeTags', i);
968
+ const youtubeCategoryId = this.getNodeParameter('youtubeCategoryId', i);
969
+ const youtubePrivacyStatus = this.getNodeParameter('youtubePrivacyStatus', i);
970
+ const youtubeEmbeddable = this.getNodeParameter('youtubeEmbeddable', i);
971
+ const youtubeLicense = this.getNodeParameter('youtubeLicense', i);
972
+ const youtubePublicStatsViewable = this.getNodeParameter('youtubePublicStatsViewable', i);
973
+ const youtubeMadeForKids = this.getNodeParameter('youtubeMadeForKids', i);
974
+ if (youtubeDescription)
975
+ formData.description = youtubeDescription;
976
+ if (youtubeTagsRaw)
977
+ formData.tags = youtubeTagsRaw.split(',').map(tag => tag.trim());
978
+ if (youtubeCategoryId)
979
+ formData.categoryId = youtubeCategoryId;
980
+ if (youtubePrivacyStatus)
981
+ formData.privacyStatus = youtubePrivacyStatus;
982
+ if (youtubeEmbeddable !== undefined)
983
+ formData.embeddable = String(youtubeEmbeddable);
984
+ if (youtubeLicense)
985
+ formData.license = youtubeLicense;
986
+ if (youtubePublicStatsViewable !== undefined)
987
+ formData.publicStatsViewable = String(youtubePublicStatsViewable);
988
+ if (youtubeMadeForKids !== undefined)
989
+ formData.madeForKids = String(youtubeMadeForKids);
990
+ }
991
+ if (platforms.includes('threads')) {
992
+ if (operation === 'uploadVideo') {
993
+ const threadsDescription = this.getNodeParameter('threadsDescription', i);
994
+ if (threadsDescription)
995
+ formData.description = threadsDescription;
996
+ }
997
+ }
998
+ if (platforms.includes('x')) {
999
+ if (operation === 'uploadText') {
1000
+ const xPostUrlText = this.getNodeParameter('xPostUrlText', i);
1001
+ if (xPostUrlText)
1002
+ formData.post_url = xPostUrlText;
1003
+ const xTaggedUserIdsText = this.getNodeParameter('xTaggedUserIds', i);
1004
+ const xReplySettingsText = this.getNodeParameter('xReplySettings', i);
1005
+ if (xTaggedUserIdsText)
1006
+ formData.tagged_user_ids = xTaggedUserIdsText.split(',').map(id => id.trim());
1007
+ if (xReplySettingsText)
1008
+ formData.reply_settings = xReplySettingsText;
1009
+ delete formData.nullcast;
1010
+ delete formData.place_id;
1011
+ delete formData.poll_duration;
1012
+ delete formData.poll_options;
1013
+ delete formData.poll_reply_settings;
1014
+ }
1015
+ else if (operation === 'uploadVideo') {
1016
+ const xTaggedUserIds = this.getNodeParameter('xTaggedUserIds', i);
1017
+ const xReplySettings = this.getNodeParameter('xReplySettings', i);
1018
+ const xNullcastVideo = this.getNodeParameter('xNullcastVideo', i);
1019
+ const xPlaceIdVideo = this.getNodeParameter('xPlaceIdVideo', i);
1020
+ const xPollDurationVideo = this.getNodeParameter('xPollDurationVideo', i);
1021
+ const xPollOptionsVideoRaw = this.getNodeParameter('xPollOptionsVideo', i);
1022
+ const xPollReplySettingsVideo = this.getNodeParameter('xPollReplySettingsVideo', i);
1023
+ if (xTaggedUserIds)
1024
+ formData.tagged_user_ids = xTaggedUserIds.split(',').map(id => id.trim());
1025
+ if (xReplySettings)
1026
+ formData.reply_settings = xReplySettings;
1027
+ if (xNullcastVideo !== undefined)
1028
+ formData.nullcast = String(xNullcastVideo);
1029
+ if (xPlaceIdVideo)
1030
+ formData.place_id = xPlaceIdVideo;
1031
+ if (xPollDurationVideo !== undefined)
1032
+ formData.poll_duration = xPollDurationVideo;
1033
+ if (xPollOptionsVideoRaw)
1034
+ formData.poll_options = xPollOptionsVideoRaw.split(',').map(opt => opt.trim());
1035
+ if (xPollReplySettingsVideo)
1036
+ formData.poll_reply_settings = xPollReplySettingsVideo;
1037
+ }
1038
+ }
1039
+ const credentials = await this.getCredentials('uploadPostApi');
1040
+ const apiKey = credentials.apiKey;
1041
+ const options = {
1042
+ uri: `https://api.upload-post.com/api${endpoint}`,
1043
+ method: 'POST',
1044
+ headers: {
1045
+ 'Authorization': `Apikey ${apiKey}`,
1046
+ },
1047
+ formData,
1048
+ json: true,
1049
+ };
1050
+ this.logger.info(`[UploadPost] Request: ${options.method} ${options.uri}`);
1051
+ this.logger.info(`[UploadPost] Request Headers: ${JSON.stringify(options.headers)}`);
1052
+ this.logger.info(`[UploadPost] Request FormData: ${JSON.stringify(formData)}`);
1053
+ const responseData = await this.helpers.request(options);
1054
+ returnData.push({
1055
+ json: responseData,
1056
+ pairedItem: {
1057
+ item: i,
1058
+ },
1059
+ });
1183
1060
  }
1184
1061
  return [returnData];
1185
1062
  }