n8n-nodes-multi-upload-tool 0.1.0 → 0.2.0
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.
|
@@ -9,7 +9,7 @@ const PLATFORMS = [
|
|
|
9
9
|
{ name: 'Instagram', value: 'instagram' },
|
|
10
10
|
{ name: 'LinkedIn', value: 'linkedin' },
|
|
11
11
|
{ name: 'Pinterest', value: 'pinterest' },
|
|
12
|
-
{ name: '
|
|
12
|
+
{ name: 'Threads', value: 'threads' },
|
|
13
13
|
{ name: 'TikTok', value: 'tiktok' },
|
|
14
14
|
{ name: 'YouTube', value: 'youtube' },
|
|
15
15
|
];
|
|
@@ -43,6 +43,7 @@ class MultiUploadTool {
|
|
|
43
43
|
options: [
|
|
44
44
|
{ name: 'Account', value: 'account' },
|
|
45
45
|
{ name: 'Pinterest', value: 'pinterest' },
|
|
46
|
+
{ name: 'Pool', value: 'pool' },
|
|
46
47
|
{ name: 'Short Link', value: 'shortLink' },
|
|
47
48
|
{ name: 'Upload', value: 'upload' },
|
|
48
49
|
{ name: 'Webhook', value: 'webhook' },
|
|
@@ -69,6 +70,18 @@ class MultiUploadTool {
|
|
|
69
70
|
description: 'Upload to multiple connected accounts at once',
|
|
70
71
|
action: 'Bulk create uploads',
|
|
71
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: 'Upload Text',
|
|
75
|
+
value: 'uploadText',
|
|
76
|
+
description: 'Post text-only content (Facebook, LinkedIn, Bluesky)',
|
|
77
|
+
action: 'Upload text post',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'Upload Document',
|
|
81
|
+
value: 'uploadDocument',
|
|
82
|
+
description: 'Upload a document (PDF, DOCX) — LinkedIn only',
|
|
83
|
+
action: 'Upload a document',
|
|
84
|
+
},
|
|
72
85
|
{
|
|
73
86
|
name: 'Get',
|
|
74
87
|
value: 'get',
|
|
@@ -87,6 +100,24 @@ class MultiUploadTool {
|
|
|
87
100
|
description: 'Update the metadata of an existing upload',
|
|
88
101
|
action: 'Update an upload',
|
|
89
102
|
},
|
|
103
|
+
{
|
|
104
|
+
name: 'List Scheduled',
|
|
105
|
+
value: 'listScheduled',
|
|
106
|
+
description: 'Retrieve all scheduled (pending) posts',
|
|
107
|
+
action: 'List scheduled posts',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
name: 'Cancel Scheduled',
|
|
111
|
+
value: 'cancelScheduled',
|
|
112
|
+
description: 'Cancel a scheduled post',
|
|
113
|
+
action: 'Cancel a scheduled post',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'Edit Scheduled',
|
|
117
|
+
value: 'editScheduled',
|
|
118
|
+
description: 'Update the date or content of a scheduled post',
|
|
119
|
+
action: 'Edit a scheduled post',
|
|
120
|
+
},
|
|
90
121
|
],
|
|
91
122
|
default: 'create',
|
|
92
123
|
},
|
|
@@ -142,6 +173,53 @@ class MultiUploadTool {
|
|
|
142
173
|
],
|
|
143
174
|
default: 'getBoards',
|
|
144
175
|
},
|
|
176
|
+
// ─── POOL: OPERATIONS ──────────────────────────────────────────────────
|
|
177
|
+
{
|
|
178
|
+
displayName: 'Operation',
|
|
179
|
+
name: 'operation',
|
|
180
|
+
type: 'options',
|
|
181
|
+
noDataExpression: true,
|
|
182
|
+
displayOptions: { show: { resource: ['pool'] } },
|
|
183
|
+
options: [
|
|
184
|
+
{
|
|
185
|
+
name: 'List Pools',
|
|
186
|
+
value: 'listPools',
|
|
187
|
+
description: 'Get all upload pools',
|
|
188
|
+
action: 'List all pools',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'Get Pool',
|
|
192
|
+
value: 'getPool',
|
|
193
|
+
description: 'Get details of a specific pool',
|
|
194
|
+
action: 'Get a pool',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: 'Check Capacity',
|
|
198
|
+
value: 'checkCapacity',
|
|
199
|
+
description: 'Preview how many upcoming slots a pool has',
|
|
200
|
+
action: 'Check pool capacity',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'Add Video',
|
|
204
|
+
value: 'addVideo',
|
|
205
|
+
description: 'Add a video or photo carousel to a pool queue',
|
|
206
|
+
action: 'Add a video to pool',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: 'List Videos',
|
|
210
|
+
value: 'listVideos',
|
|
211
|
+
description: 'Get all queued videos in a pool',
|
|
212
|
+
action: 'List videos in pool',
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: 'Remove Video',
|
|
216
|
+
value: 'removeVideo',
|
|
217
|
+
description: 'Remove a queued item from a pool',
|
|
218
|
+
action: 'Remove video from pool',
|
|
219
|
+
},
|
|
220
|
+
],
|
|
221
|
+
default: 'listPools',
|
|
222
|
+
},
|
|
145
223
|
// ─── WEBHOOK: OPERATIONS ──────────────────────────────────────────────
|
|
146
224
|
{
|
|
147
225
|
displayName: 'Operation',
|
|
@@ -219,7 +297,7 @@ class MultiUploadTool {
|
|
|
219
297
|
default: 'create',
|
|
220
298
|
},
|
|
221
299
|
// ═══════════════════════════════════════════════════════════════════════
|
|
222
|
-
// UPLOAD › CREATE
|
|
300
|
+
// UPLOAD › CREATE / BULK CREATE
|
|
223
301
|
// ═══════════════════════════════════════════════════════════════════════
|
|
224
302
|
{
|
|
225
303
|
displayName: 'Account ID',
|
|
@@ -299,8 +377,54 @@ class MultiUploadTool {
|
|
|
299
377
|
default: '',
|
|
300
378
|
description: 'Comma-separated hashtags or tags (YouTube, TikTok). Do not include the # symbol.',
|
|
301
379
|
},
|
|
380
|
+
// ── Universal scheduling ──────────────────────────────────────────
|
|
381
|
+
{
|
|
382
|
+
displayName: 'Scheduled Date',
|
|
383
|
+
name: 'scheduledDate',
|
|
384
|
+
type: 'dateTime',
|
|
385
|
+
default: '',
|
|
386
|
+
description: 'Schedule the post for a future date/time. Applied to all platforms (TikTok, Instagram, YouTube, etc.).',
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
displayName: 'Timezone',
|
|
390
|
+
name: 'timezone',
|
|
391
|
+
type: 'string',
|
|
392
|
+
default: 'UTC',
|
|
393
|
+
description: 'IANA timezone for the scheduled date (e.g. America/New_York). Stored as metadata.',
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
displayName: 'Wait For Completion',
|
|
397
|
+
name: 'waitForCompletion',
|
|
398
|
+
type: 'boolean',
|
|
399
|
+
default: false,
|
|
400
|
+
description: 'Whether to wait synchronously for the upload job to finish (up to 10 min). If false, returns a job ID immediately.',
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
displayName: 'First Comment',
|
|
404
|
+
name: 'firstComment',
|
|
405
|
+
type: 'string',
|
|
406
|
+
typeOptions: { rows: 3 },
|
|
407
|
+
default: '',
|
|
408
|
+
description: 'First comment to post after publishing. NOTE: stored in metadata, not yet processed by the backend — reserved for future use.',
|
|
409
|
+
},
|
|
410
|
+
// ── YouTube ───────────────────────────────────────────────────────
|
|
411
|
+
{
|
|
412
|
+
displayName: 'YouTube Title',
|
|
413
|
+
name: 'youtube_title',
|
|
414
|
+
type: 'string',
|
|
415
|
+
default: '',
|
|
416
|
+
description: 'Override the generic title for YouTube only',
|
|
417
|
+
},
|
|
302
418
|
{
|
|
303
|
-
displayName: '
|
|
419
|
+
displayName: 'YouTube Description',
|
|
420
|
+
name: 'youtube_description',
|
|
421
|
+
type: 'string',
|
|
422
|
+
typeOptions: { rows: 4 },
|
|
423
|
+
default: '',
|
|
424
|
+
description: 'Override the generic description for YouTube only',
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
displayName: 'YouTube Privacy Status',
|
|
304
428
|
name: 'privacyStatus',
|
|
305
429
|
type: 'options',
|
|
306
430
|
options: [
|
|
@@ -309,7 +433,7 @@ class MultiUploadTool {
|
|
|
309
433
|
{ name: 'Unlisted', value: 'unlisted' },
|
|
310
434
|
],
|
|
311
435
|
default: 'public',
|
|
312
|
-
description: 'Privacy level
|
|
436
|
+
description: 'Privacy level (YouTube)',
|
|
313
437
|
},
|
|
314
438
|
{
|
|
315
439
|
displayName: 'YouTube Category ID',
|
|
@@ -319,12 +443,45 @@ class MultiUploadTool {
|
|
|
319
443
|
description: 'YouTube category ID (e.g. 22 for People & Blogs). See the YouTube API for the full list.',
|
|
320
444
|
},
|
|
321
445
|
{
|
|
322
|
-
displayName: '
|
|
323
|
-
name: '
|
|
324
|
-
type: '
|
|
446
|
+
displayName: 'YouTube Thumbnail URL',
|
|
447
|
+
name: 'thumbnail_url',
|
|
448
|
+
type: 'string',
|
|
325
449
|
default: '',
|
|
326
|
-
description: '
|
|
450
|
+
description: 'Public URL of the thumbnail image (YouTube)',
|
|
327
451
|
},
|
|
452
|
+
{
|
|
453
|
+
displayName: 'YouTube Embeddable',
|
|
454
|
+
name: 'embeddable',
|
|
455
|
+
type: 'boolean',
|
|
456
|
+
default: true,
|
|
457
|
+
description: 'Whether to allow the video to be embedded (YouTube)',
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
displayName: 'YouTube Notify Subscribers',
|
|
461
|
+
name: 'notifySubscribers',
|
|
462
|
+
type: 'boolean',
|
|
463
|
+
default: true,
|
|
464
|
+
description: 'Whether to notify subscribers when the video is published (YouTube)',
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
displayName: 'YouTube Made For Kids',
|
|
468
|
+
name: 'madeForKids',
|
|
469
|
+
type: 'boolean',
|
|
470
|
+
default: false,
|
|
471
|
+
description: 'Whether the content is made for kids — COPPA compliance (YouTube)',
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
displayName: 'YouTube License',
|
|
475
|
+
name: 'license',
|
|
476
|
+
type: 'options',
|
|
477
|
+
options: [
|
|
478
|
+
{ name: 'Standard YouTube License', value: 'youtube' },
|
|
479
|
+
{ name: 'Creative Commons', value: 'creativeCommon' },
|
|
480
|
+
],
|
|
481
|
+
default: 'youtube',
|
|
482
|
+
description: 'License type (YouTube)',
|
|
483
|
+
},
|
|
484
|
+
// ── TikTok ────────────────────────────────────────────────────────
|
|
328
485
|
{
|
|
329
486
|
displayName: 'TikTok Privacy Level',
|
|
330
487
|
name: 'privacy_level',
|
|
@@ -338,6 +495,106 @@ class MultiUploadTool {
|
|
|
338
495
|
default: 'PUBLIC_TO_EVERYONE',
|
|
339
496
|
description: 'Audience visibility (TikTok only)',
|
|
340
497
|
},
|
|
498
|
+
{
|
|
499
|
+
displayName: 'TikTok Disable Comment',
|
|
500
|
+
name: 'disable_comment',
|
|
501
|
+
type: 'boolean',
|
|
502
|
+
default: false,
|
|
503
|
+
description: 'Whether to disable comments (TikTok only)',
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
displayName: 'TikTok Disable Duet',
|
|
507
|
+
name: 'disable_duet',
|
|
508
|
+
type: 'boolean',
|
|
509
|
+
default: false,
|
|
510
|
+
description: 'Whether to disable Duet (TikTok only)',
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
displayName: 'TikTok Disable Stitch',
|
|
514
|
+
name: 'disable_stitch',
|
|
515
|
+
type: 'boolean',
|
|
516
|
+
default: false,
|
|
517
|
+
description: 'Whether to disable Stitch (TikTok only)',
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
displayName: 'TikTok Brand Content',
|
|
521
|
+
name: 'brand_content_toggle',
|
|
522
|
+
type: 'boolean',
|
|
523
|
+
default: false,
|
|
524
|
+
description: 'Whether to mark as branded content / paid partnership (TikTok only)',
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
displayName: 'TikTok Brand Organic',
|
|
528
|
+
name: 'brand_organic_toggle',
|
|
529
|
+
type: 'boolean',
|
|
530
|
+
default: false,
|
|
531
|
+
description: 'Whether to mark as promoting own brand organically (TikTok only)',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
displayName: 'TikTok AI Generated Content',
|
|
535
|
+
name: 'is_aigc',
|
|
536
|
+
type: 'boolean',
|
|
537
|
+
default: false,
|
|
538
|
+
description: 'Whether to declare the content as AI-generated (TikTok only)',
|
|
539
|
+
},
|
|
540
|
+
// ── Instagram ─────────────────────────────────────────────────────
|
|
541
|
+
{
|
|
542
|
+
displayName: 'Instagram Media Type',
|
|
543
|
+
name: 'media_type',
|
|
544
|
+
type: 'options',
|
|
545
|
+
options: [
|
|
546
|
+
{ name: 'Auto Detect', value: '' },
|
|
547
|
+
{ name: 'Image', value: 'IMAGE' },
|
|
548
|
+
{ name: 'Reels', value: 'REELS' },
|
|
549
|
+
{ name: 'Stories', value: 'STORIES' },
|
|
550
|
+
{ name: 'Carousel', value: 'CAROUSEL' },
|
|
551
|
+
],
|
|
552
|
+
default: '',
|
|
553
|
+
description: 'Override media type for Instagram posts. Leave as Auto Detect in most cases.',
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
displayName: 'Instagram Share to Feed',
|
|
557
|
+
name: 'share_to_feed',
|
|
558
|
+
type: 'boolean',
|
|
559
|
+
default: true,
|
|
560
|
+
description: 'Whether to share Reels/Stories to the main feed grid (Instagram only)',
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
displayName: 'Instagram Cover URL',
|
|
564
|
+
name: 'cover_url',
|
|
565
|
+
type: 'string',
|
|
566
|
+
default: '',
|
|
567
|
+
description: 'Cover image URL for Instagram video posts',
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
displayName: 'Instagram Audio Name',
|
|
571
|
+
name: 'audio_name',
|
|
572
|
+
type: 'string',
|
|
573
|
+
default: '',
|
|
574
|
+
description: 'Audio track name (Instagram only)',
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
displayName: 'Instagram Thumbnail Offset (ms)',
|
|
578
|
+
name: 'thumb_offset',
|
|
579
|
+
type: 'string',
|
|
580
|
+
default: '',
|
|
581
|
+
description: 'Thumbnail frame offset in milliseconds (Instagram only)',
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
displayName: 'Instagram Collaborators',
|
|
585
|
+
name: 'collaborators',
|
|
586
|
+
type: 'string',
|
|
587
|
+
default: '',
|
|
588
|
+
description: 'Comma-separated Instagram usernames to tag as collaborators',
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
displayName: 'Instagram Location ID',
|
|
592
|
+
name: 'location_id',
|
|
593
|
+
type: 'string',
|
|
594
|
+
default: '',
|
|
595
|
+
description: 'Location ID for Instagram posts',
|
|
596
|
+
},
|
|
597
|
+
// ── LinkedIn ──────────────────────────────────────────────────────
|
|
341
598
|
{
|
|
342
599
|
displayName: 'LinkedIn Visibility',
|
|
343
600
|
name: 'visibility',
|
|
@@ -349,6 +606,22 @@ class MultiUploadTool {
|
|
|
349
606
|
default: 'PUBLIC',
|
|
350
607
|
description: 'Post visibility (LinkedIn only)',
|
|
351
608
|
},
|
|
609
|
+
{
|
|
610
|
+
displayName: 'LinkedIn Target Page ID',
|
|
611
|
+
name: 'targetPageId',
|
|
612
|
+
type: 'string',
|
|
613
|
+
default: '',
|
|
614
|
+
description: 'Post as a LinkedIn Page/Organization instead of the personal profile. Get the ID from the Get LinkedIn Pages operation.',
|
|
615
|
+
},
|
|
616
|
+
// ── Facebook ──────────────────────────────────────────────────────
|
|
617
|
+
{
|
|
618
|
+
displayName: 'Facebook / Pinterest Link',
|
|
619
|
+
name: 'link',
|
|
620
|
+
type: 'string',
|
|
621
|
+
default: '',
|
|
622
|
+
description: 'URL to attach to a Facebook link post or Pinterest pin',
|
|
623
|
+
},
|
|
624
|
+
// ── Pinterest ─────────────────────────────────────────────────────
|
|
352
625
|
{
|
|
353
626
|
displayName: 'Pinterest Board ID',
|
|
354
627
|
name: 'board_id',
|
|
@@ -356,24 +629,225 @@ class MultiUploadTool {
|
|
|
356
629
|
default: '',
|
|
357
630
|
description: 'Board ID to pin to — required for Pinterest posts',
|
|
358
631
|
},
|
|
632
|
+
{
|
|
633
|
+
displayName: 'Pinterest Alt Text',
|
|
634
|
+
name: 'alt_text',
|
|
635
|
+
type: 'string',
|
|
636
|
+
default: '',
|
|
637
|
+
description: 'Alt text for the Pinterest pin image',
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
displayName: 'Pinterest Cover Image URL',
|
|
641
|
+
name: 'cover_image_url',
|
|
642
|
+
type: 'string',
|
|
643
|
+
default: '',
|
|
644
|
+
description: 'Cover image URL for Pinterest video pins',
|
|
645
|
+
},
|
|
646
|
+
// ── Bluesky ───────────────────────────────────────────────────────
|
|
647
|
+
{
|
|
648
|
+
displayName: 'Bluesky Languages',
|
|
649
|
+
name: 'bluesky_langs',
|
|
650
|
+
type: 'string',
|
|
651
|
+
default: '',
|
|
652
|
+
description: 'Comma-separated BCP-47 language codes (e.g. en,fr) (Bluesky only)',
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
displayName: 'Bluesky Content Labels',
|
|
656
|
+
name: 'bluesky_labels',
|
|
657
|
+
type: 'string',
|
|
658
|
+
default: '',
|
|
659
|
+
description: 'Comma-separated content warning labels (e.g. nsfw,nudity) (Bluesky only)',
|
|
660
|
+
},
|
|
661
|
+
// ── Threads ───────────────────────────────────────────────────────
|
|
662
|
+
{
|
|
663
|
+
displayName: 'Threads Reply Control',
|
|
664
|
+
name: 'threads_reply_control',
|
|
665
|
+
type: 'options',
|
|
666
|
+
default: '',
|
|
667
|
+
description: 'Who can reply to this Threads post (Threads only)',
|
|
668
|
+
options: [
|
|
669
|
+
{ name: 'Everyone', value: 'everyone' },
|
|
670
|
+
{ name: 'Accounts You Follow', value: 'accounts_you_follow' },
|
|
671
|
+
{ name: 'Mentioned Only', value: 'mentioned_only' },
|
|
672
|
+
{ name: 'Followers Only', value: 'followers_only' },
|
|
673
|
+
{ name: 'Author Only', value: 'parent_post_author_only' },
|
|
674
|
+
],
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
displayName: 'Threads Alt Text',
|
|
678
|
+
name: 'threads_alt_text',
|
|
679
|
+
type: 'string',
|
|
680
|
+
default: '',
|
|
681
|
+
description: 'Alt text for the media (Threads only)',
|
|
682
|
+
},
|
|
683
|
+
],
|
|
684
|
+
},
|
|
685
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
686
|
+
// UPLOAD › UPLOAD TEXT
|
|
687
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
688
|
+
{
|
|
689
|
+
displayName: 'Account ID',
|
|
690
|
+
name: 'accountId',
|
|
691
|
+
type: 'string',
|
|
692
|
+
required: true,
|
|
693
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadText'] } },
|
|
694
|
+
default: '',
|
|
695
|
+
description: 'ID of the connected account to post to',
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
displayName: 'Text Content',
|
|
699
|
+
name: 'textContent',
|
|
700
|
+
type: 'string',
|
|
701
|
+
required: true,
|
|
702
|
+
typeOptions: { rows: 6 },
|
|
703
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadText'] } },
|
|
704
|
+
default: '',
|
|
705
|
+
description: 'The text body of the post',
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
displayName: 'Additional Fields',
|
|
709
|
+
name: 'additionalFields',
|
|
710
|
+
type: 'collection',
|
|
711
|
+
placeholder: 'Add Field',
|
|
712
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadText'] } },
|
|
713
|
+
default: {},
|
|
714
|
+
options: [
|
|
715
|
+
{
|
|
716
|
+
displayName: 'Scheduled Date',
|
|
717
|
+
name: 'scheduledDate',
|
|
718
|
+
type: 'dateTime',
|
|
719
|
+
default: '',
|
|
720
|
+
description: 'Schedule the post for a future date/time',
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
displayName: 'Timezone',
|
|
724
|
+
name: 'timezone',
|
|
725
|
+
type: 'string',
|
|
726
|
+
default: 'UTC',
|
|
727
|
+
description: 'IANA timezone (e.g. America/New_York)',
|
|
728
|
+
},
|
|
729
|
+
{
|
|
730
|
+
displayName: 'LinkedIn Visibility',
|
|
731
|
+
name: 'visibility',
|
|
732
|
+
type: 'options',
|
|
733
|
+
options: [
|
|
734
|
+
{ name: 'Public', value: 'PUBLIC' },
|
|
735
|
+
{ name: 'Connections Only', value: 'CONNECTIONS' },
|
|
736
|
+
],
|
|
737
|
+
default: 'PUBLIC',
|
|
738
|
+
},
|
|
739
|
+
{
|
|
740
|
+
displayName: 'LinkedIn Target Page ID',
|
|
741
|
+
name: 'targetPageId',
|
|
742
|
+
type: 'string',
|
|
743
|
+
default: '',
|
|
744
|
+
description: 'Post as a LinkedIn Page instead of personal profile',
|
|
745
|
+
},
|
|
359
746
|
{
|
|
360
747
|
displayName: 'Facebook / Pinterest Link',
|
|
361
748
|
name: 'link',
|
|
362
749
|
type: 'string',
|
|
363
750
|
default: '',
|
|
364
|
-
description: 'URL to attach
|
|
751
|
+
description: 'URL to attach as a link preview (Facebook)',
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
displayName: 'Wait For Completion',
|
|
755
|
+
name: 'waitForCompletion',
|
|
756
|
+
type: 'boolean',
|
|
757
|
+
default: false,
|
|
758
|
+
description: 'Whether to wait synchronously for the post to be processed (up to 10 min)',
|
|
759
|
+
},
|
|
760
|
+
],
|
|
761
|
+
},
|
|
762
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
763
|
+
// UPLOAD › UPLOAD DOCUMENT
|
|
764
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
765
|
+
{
|
|
766
|
+
displayName: 'Account ID',
|
|
767
|
+
name: 'accountId',
|
|
768
|
+
type: 'string',
|
|
769
|
+
required: true,
|
|
770
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadDocument'] } },
|
|
771
|
+
default: '',
|
|
772
|
+
description: 'ID of the connected account to post to',
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
displayName: 'Binary Property',
|
|
776
|
+
name: 'binaryPropertyName',
|
|
777
|
+
type: 'string',
|
|
778
|
+
required: true,
|
|
779
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadDocument'] } },
|
|
780
|
+
default: 'data',
|
|
781
|
+
description: 'Name of the binary property containing the document file (PDF, DOCX, etc.)',
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
displayName: 'Title',
|
|
785
|
+
name: 'title',
|
|
786
|
+
type: 'string',
|
|
787
|
+
required: true,
|
|
788
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadDocument'] } },
|
|
789
|
+
default: '',
|
|
790
|
+
description: 'Title / filename for the document post (required for LinkedIn)',
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
displayName: 'Additional Fields',
|
|
794
|
+
name: 'additionalFields',
|
|
795
|
+
type: 'collection',
|
|
796
|
+
placeholder: 'Add Field',
|
|
797
|
+
displayOptions: { show: { resource: ['upload'], operation: ['uploadDocument'] } },
|
|
798
|
+
default: {},
|
|
799
|
+
options: [
|
|
800
|
+
{
|
|
801
|
+
displayName: 'Description / Caption',
|
|
802
|
+
name: 'description',
|
|
803
|
+
type: 'string',
|
|
804
|
+
typeOptions: { rows: 4 },
|
|
805
|
+
default: '',
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
displayName: 'LinkedIn Visibility',
|
|
809
|
+
name: 'visibility',
|
|
810
|
+
type: 'options',
|
|
811
|
+
options: [
|
|
812
|
+
{ name: 'Public', value: 'PUBLIC' },
|
|
813
|
+
{ name: 'Connections Only', value: 'CONNECTIONS' },
|
|
814
|
+
],
|
|
815
|
+
default: 'PUBLIC',
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
displayName: 'LinkedIn Target Page ID',
|
|
819
|
+
name: 'targetPageId',
|
|
820
|
+
type: 'string',
|
|
821
|
+
default: '',
|
|
822
|
+
},
|
|
823
|
+
{
|
|
824
|
+
displayName: 'Scheduled Date',
|
|
825
|
+
name: 'scheduledDate',
|
|
826
|
+
type: 'dateTime',
|
|
827
|
+
default: '',
|
|
828
|
+
},
|
|
829
|
+
{
|
|
830
|
+
displayName: 'Wait For Completion',
|
|
831
|
+
name: 'waitForCompletion',
|
|
832
|
+
type: 'boolean',
|
|
833
|
+
default: false,
|
|
365
834
|
},
|
|
366
835
|
],
|
|
367
836
|
},
|
|
368
837
|
// ═══════════════════════════════════════════════════════════════════════
|
|
369
|
-
// UPLOAD › GET / UPDATE
|
|
838
|
+
// UPLOAD › GET / UPDATE / CANCEL SCHEDULED / EDIT SCHEDULED
|
|
370
839
|
// ═══════════════════════════════════════════════════════════════════════
|
|
371
840
|
{
|
|
372
841
|
displayName: 'Upload ID',
|
|
373
842
|
name: 'uploadId',
|
|
374
843
|
type: 'string',
|
|
375
844
|
required: true,
|
|
376
|
-
displayOptions: {
|
|
845
|
+
displayOptions: {
|
|
846
|
+
show: {
|
|
847
|
+
resource: ['upload'],
|
|
848
|
+
operation: ['get', 'update', 'cancelScheduled', 'editScheduled'],
|
|
849
|
+
},
|
|
850
|
+
},
|
|
377
851
|
default: '',
|
|
378
852
|
description: 'ID of the upload',
|
|
379
853
|
},
|
|
@@ -406,15 +880,45 @@ class MultiUploadTool {
|
|
|
406
880
|
},
|
|
407
881
|
],
|
|
408
882
|
},
|
|
883
|
+
{
|
|
884
|
+
displayName: 'Update Fields',
|
|
885
|
+
name: 'scheduleUpdateFields',
|
|
886
|
+
type: 'collection',
|
|
887
|
+
placeholder: 'Add Field',
|
|
888
|
+
displayOptions: { show: { resource: ['upload'], operation: ['editScheduled'] } },
|
|
889
|
+
default: {},
|
|
890
|
+
options: [
|
|
891
|
+
{
|
|
892
|
+
displayName: 'New Scheduled Date',
|
|
893
|
+
name: 'scheduledFor',
|
|
894
|
+
type: 'dateTime',
|
|
895
|
+
default: '',
|
|
896
|
+
description: 'New date/time for the scheduled post',
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
displayName: 'Title',
|
|
900
|
+
name: 'title',
|
|
901
|
+
type: 'string',
|
|
902
|
+
default: '',
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
displayName: 'Description',
|
|
906
|
+
name: 'description',
|
|
907
|
+
type: 'string',
|
|
908
|
+
typeOptions: { rows: 4 },
|
|
909
|
+
default: '',
|
|
910
|
+
},
|
|
911
|
+
],
|
|
912
|
+
},
|
|
409
913
|
// ═══════════════════════════════════════════════════════════════════════
|
|
410
|
-
// UPLOAD › LIST
|
|
914
|
+
// UPLOAD › LIST / LIST SCHEDULED
|
|
411
915
|
// ═══════════════════════════════════════════════════════════════════════
|
|
412
916
|
{
|
|
413
917
|
displayName: 'Filters',
|
|
414
918
|
name: 'filters',
|
|
415
919
|
type: 'collection',
|
|
416
920
|
placeholder: 'Add Filter',
|
|
417
|
-
displayOptions: { show: { resource: ['upload'], operation: ['list'] } },
|
|
921
|
+
displayOptions: { show: { resource: ['upload'], operation: ['list', 'listScheduled'] } },
|
|
418
922
|
default: {},
|
|
419
923
|
options: [
|
|
420
924
|
{
|
|
@@ -436,6 +940,7 @@ class MultiUploadTool {
|
|
|
436
940
|
{ name: 'Processing', value: 'processing' },
|
|
437
941
|
],
|
|
438
942
|
default: '',
|
|
943
|
+
description: 'Not used for List Scheduled (always filters to scheduled)',
|
|
439
944
|
},
|
|
440
945
|
{
|
|
441
946
|
displayName: 'Search',
|
|
@@ -496,6 +1001,13 @@ class MultiUploadTool {
|
|
|
496
1001
|
],
|
|
497
1002
|
default: '',
|
|
498
1003
|
},
|
|
1004
|
+
{
|
|
1005
|
+
displayName: 'Tags',
|
|
1006
|
+
name: 'tags',
|
|
1007
|
+
type: 'string',
|
|
1008
|
+
default: '',
|
|
1009
|
+
description: 'Filter accounts by tag (partial match)',
|
|
1010
|
+
},
|
|
499
1011
|
],
|
|
500
1012
|
},
|
|
501
1013
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -511,6 +1023,104 @@ class MultiUploadTool {
|
|
|
511
1023
|
description: 'ID of the Pinterest connected account',
|
|
512
1024
|
},
|
|
513
1025
|
// ═══════════════════════════════════════════════════════════════════════
|
|
1026
|
+
// POOL › FIELDS
|
|
1027
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
1028
|
+
{
|
|
1029
|
+
displayName: 'Pool ID',
|
|
1030
|
+
name: 'poolId',
|
|
1031
|
+
type: 'string',
|
|
1032
|
+
required: true,
|
|
1033
|
+
displayOptions: {
|
|
1034
|
+
show: {
|
|
1035
|
+
resource: ['pool'],
|
|
1036
|
+
operation: ['getPool', 'checkCapacity', 'addVideo', 'listVideos', 'removeVideo'],
|
|
1037
|
+
},
|
|
1038
|
+
},
|
|
1039
|
+
default: '',
|
|
1040
|
+
description: 'ID of the pool',
|
|
1041
|
+
},
|
|
1042
|
+
{
|
|
1043
|
+
displayName: 'Count',
|
|
1044
|
+
name: 'count',
|
|
1045
|
+
type: 'number',
|
|
1046
|
+
displayOptions: { show: { resource: ['pool'], operation: ['checkCapacity'] } },
|
|
1047
|
+
default: 1,
|
|
1048
|
+
description: 'Number of videos to check capacity for',
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
displayName: 'Title',
|
|
1052
|
+
name: 'title',
|
|
1053
|
+
type: 'string',
|
|
1054
|
+
required: true,
|
|
1055
|
+
displayOptions: { show: { resource: ['pool'], operation: ['addVideo'] } },
|
|
1056
|
+
default: '',
|
|
1057
|
+
description: 'Title / caption for the content',
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
displayName: 'Media',
|
|
1061
|
+
name: 'media',
|
|
1062
|
+
type: 'string',
|
|
1063
|
+
displayOptions: { show: { resource: ['pool'], operation: ['addVideo'] } },
|
|
1064
|
+
default: 'data',
|
|
1065
|
+
description: 'Comma-separated list of binary property names and/or public URLs. For a single file: <code>data</code>. For a photo carousel: <code>data0,data1,data2</code>. You can also mix binary names and URLs: <code>data0,https://cdn.example.com/slide2.jpg</code>.',
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
displayName: 'Additional Fields',
|
|
1069
|
+
name: 'additionalFields',
|
|
1070
|
+
type: 'collection',
|
|
1071
|
+
placeholder: 'Add Field',
|
|
1072
|
+
displayOptions: { show: { resource: ['pool'], operation: ['addVideo'] } },
|
|
1073
|
+
default: {},
|
|
1074
|
+
options: [
|
|
1075
|
+
{
|
|
1076
|
+
displayName: 'Description',
|
|
1077
|
+
name: 'description',
|
|
1078
|
+
type: 'string',
|
|
1079
|
+
typeOptions: { rows: 4 },
|
|
1080
|
+
default: '',
|
|
1081
|
+
},
|
|
1082
|
+
{
|
|
1083
|
+
displayName: 'Metadata (JSON)',
|
|
1084
|
+
name: 'metadata',
|
|
1085
|
+
type: 'string',
|
|
1086
|
+
typeOptions: { rows: 4 },
|
|
1087
|
+
default: '',
|
|
1088
|
+
description: 'JSON object with platform-specific options, e.g. <code>{"privacy_level":"PUBLIC_TO_EVERYONE","disable_comment":false}</code>',
|
|
1089
|
+
},
|
|
1090
|
+
],
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
displayName: 'Item ID',
|
|
1094
|
+
name: 'itemId',
|
|
1095
|
+
type: 'string',
|
|
1096
|
+
required: true,
|
|
1097
|
+
displayOptions: { show: { resource: ['pool'], operation: ['removeVideo'] } },
|
|
1098
|
+
default: '',
|
|
1099
|
+
description: 'ID of the queued item to remove',
|
|
1100
|
+
},
|
|
1101
|
+
{
|
|
1102
|
+
displayName: 'Filters',
|
|
1103
|
+
name: 'filters',
|
|
1104
|
+
type: 'collection',
|
|
1105
|
+
placeholder: 'Add Filter',
|
|
1106
|
+
displayOptions: { show: { resource: ['pool'], operation: ['listVideos'] } },
|
|
1107
|
+
default: {},
|
|
1108
|
+
options: [
|
|
1109
|
+
{
|
|
1110
|
+
displayName: 'Status',
|
|
1111
|
+
name: 'status',
|
|
1112
|
+
type: 'options',
|
|
1113
|
+
options: [
|
|
1114
|
+
{ name: 'All', value: '' },
|
|
1115
|
+
{ name: 'Queued', value: 'queued' },
|
|
1116
|
+
{ name: 'Posted', value: 'posted' },
|
|
1117
|
+
{ name: 'Failed', value: 'failed' },
|
|
1118
|
+
],
|
|
1119
|
+
default: '',
|
|
1120
|
+
},
|
|
1121
|
+
],
|
|
1122
|
+
},
|
|
1123
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
514
1124
|
// WEBHOOK › CREATE
|
|
515
1125
|
// ═══════════════════════════════════════════════════════════════════════
|
|
516
1126
|
{
|
|
@@ -820,14 +1430,14 @@ class MultiUploadTool {
|
|
|
820
1430
|
};
|
|
821
1431
|
}
|
|
822
1432
|
async execute() {
|
|
823
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
1433
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
|
|
824
1434
|
const items = this.getInputData();
|
|
825
1435
|
const returnData = [];
|
|
826
1436
|
const credentials = await this.getCredentials('multiUploadToolApi');
|
|
827
1437
|
const apiToken = credentials.apiToken;
|
|
828
1438
|
const defaultHeaders = {
|
|
829
1439
|
'x-api-key': apiToken,
|
|
830
|
-
'User-Agent': 'n8n-nodes-multi-upload-tool/0.
|
|
1440
|
+
'User-Agent': 'n8n-nodes-multi-upload-tool/0.2.0',
|
|
831
1441
|
};
|
|
832
1442
|
// ── JSON request helper ───────────────────────────────────────────────────
|
|
833
1443
|
const apiRequest = async (method, endpoint, body, qs) => {
|
|
@@ -888,15 +1498,22 @@ class MultiUploadTool {
|
|
|
888
1498
|
const blob = new Blob([fileBuffer], { type: mimeType });
|
|
889
1499
|
formData.set(fieldName, blob, fileName);
|
|
890
1500
|
}
|
|
1501
|
+
const waitForCompletion = additionalFields.waitForCompletion === true;
|
|
891
1502
|
for (const [key, value] of Object.entries(additionalFields)) {
|
|
892
|
-
if (value
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1503
|
+
if (value === undefined || value === '' || value === null)
|
|
1504
|
+
continue;
|
|
1505
|
+
if (key === 'waitForCompletion')
|
|
1506
|
+
continue; // handled via query param
|
|
1507
|
+
if (key === 'scheduledDate') {
|
|
1508
|
+
// Send to both field names the backend uses
|
|
1509
|
+
formData.set('scheduledDate', String(value)); // YouTube
|
|
1510
|
+
formData.set('schedule_date', String(value)); // TikTok / Instagram
|
|
1511
|
+
continue;
|
|
897
1512
|
}
|
|
1513
|
+
formData.set(key, String(value));
|
|
898
1514
|
}
|
|
899
|
-
const
|
|
1515
|
+
const qs = waitForCompletion ? '?async=false' : '';
|
|
1516
|
+
const endpoint = operation === 'create' ? `/upload${qs}` : '/upload/bulk';
|
|
900
1517
|
responseData = (await this.helpers.httpRequest({
|
|
901
1518
|
method: 'POST',
|
|
902
1519
|
url: `${BASE_URL}${endpoint}`,
|
|
@@ -905,6 +1522,69 @@ class MultiUploadTool {
|
|
|
905
1522
|
json: true,
|
|
906
1523
|
}));
|
|
907
1524
|
}
|
|
1525
|
+
else if (operation === 'uploadText') {
|
|
1526
|
+
const accountId = this.getNodeParameter('accountId', i);
|
|
1527
|
+
const textContent = this.getNodeParameter('textContent', i);
|
|
1528
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
1529
|
+
const formData = new FormData();
|
|
1530
|
+
formData.set('accountId', accountId);
|
|
1531
|
+
formData.set('description', textContent);
|
|
1532
|
+
formData.set('media_type', 'TEXT');
|
|
1533
|
+
if (additionalFields.scheduledDate) {
|
|
1534
|
+
formData.set('scheduledDate', String(additionalFields.scheduledDate));
|
|
1535
|
+
formData.set('schedule_date', String(additionalFields.scheduledDate));
|
|
1536
|
+
}
|
|
1537
|
+
if (additionalFields.visibility)
|
|
1538
|
+
formData.set('visibility', String(additionalFields.visibility));
|
|
1539
|
+
if (additionalFields.targetPageId)
|
|
1540
|
+
formData.set('targetPageId', String(additionalFields.targetPageId));
|
|
1541
|
+
if (additionalFields.link)
|
|
1542
|
+
formData.set('link', String(additionalFields.link));
|
|
1543
|
+
const waitForCompletion = additionalFields.waitForCompletion === true;
|
|
1544
|
+
const qs = waitForCompletion ? '?async=false' : '';
|
|
1545
|
+
responseData = (await this.helpers.httpRequest({
|
|
1546
|
+
method: 'POST',
|
|
1547
|
+
url: `${BASE_URL}/upload${qs}`,
|
|
1548
|
+
headers: { 'x-api-key': apiToken },
|
|
1549
|
+
body: formData,
|
|
1550
|
+
json: true,
|
|
1551
|
+
}));
|
|
1552
|
+
}
|
|
1553
|
+
else if (operation === 'uploadDocument') {
|
|
1554
|
+
const accountId = this.getNodeParameter('accountId', i);
|
|
1555
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
|
1556
|
+
const title = this.getNodeParameter('title', i);
|
|
1557
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
1558
|
+
const binaryItem = items[i].binary[binaryPropertyName];
|
|
1559
|
+
const fileBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
|
|
1560
|
+
const fileName = (_d = binaryItem.fileName) !== null && _d !== void 0 ? _d : 'document';
|
|
1561
|
+
const mimeType = (_e = binaryItem.mimeType) !== null && _e !== void 0 ? _e : 'application/octet-stream';
|
|
1562
|
+
const formData = new FormData();
|
|
1563
|
+
formData.set('accountId', accountId);
|
|
1564
|
+
formData.set('title', title);
|
|
1565
|
+
formData.set('media_type', 'DOCUMENT');
|
|
1566
|
+
const blob = new Blob([fileBuffer], { type: mimeType });
|
|
1567
|
+
formData.set('file', blob, fileName);
|
|
1568
|
+
if (additionalFields.description)
|
|
1569
|
+
formData.set('description', String(additionalFields.description));
|
|
1570
|
+
if (additionalFields.visibility)
|
|
1571
|
+
formData.set('visibility', String(additionalFields.visibility));
|
|
1572
|
+
if (additionalFields.targetPageId)
|
|
1573
|
+
formData.set('targetPageId', String(additionalFields.targetPageId));
|
|
1574
|
+
if (additionalFields.scheduledDate) {
|
|
1575
|
+
formData.set('scheduledDate', String(additionalFields.scheduledDate));
|
|
1576
|
+
formData.set('schedule_date', String(additionalFields.scheduledDate));
|
|
1577
|
+
}
|
|
1578
|
+
const waitForCompletion = additionalFields.waitForCompletion === true;
|
|
1579
|
+
const qs = waitForCompletion ? '?async=false' : '';
|
|
1580
|
+
responseData = (await this.helpers.httpRequest({
|
|
1581
|
+
method: 'POST',
|
|
1582
|
+
url: `${BASE_URL}/upload${qs}`,
|
|
1583
|
+
headers: { 'x-api-key': apiToken },
|
|
1584
|
+
body: formData,
|
|
1585
|
+
json: true,
|
|
1586
|
+
}));
|
|
1587
|
+
}
|
|
908
1588
|
else if (operation === 'list') {
|
|
909
1589
|
const filters = this.getNodeParameter('filters', i, {});
|
|
910
1590
|
const qs = {};
|
|
@@ -919,12 +1599,26 @@ class MultiUploadTool {
|
|
|
919
1599
|
if (filters.limit)
|
|
920
1600
|
qs.limit = filters.limit;
|
|
921
1601
|
const res = await apiRequest('GET', '/upload', undefined, qs);
|
|
922
|
-
responseData = (
|
|
1602
|
+
responseData = (_f = res.data) !== null && _f !== void 0 ? _f : [];
|
|
1603
|
+
}
|
|
1604
|
+
else if (operation === 'listScheduled') {
|
|
1605
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1606
|
+
const qs = { status: 'scheduled' };
|
|
1607
|
+
if (filters.platform)
|
|
1608
|
+
qs.platform = filters.platform;
|
|
1609
|
+
if (filters.search)
|
|
1610
|
+
qs.search = filters.search;
|
|
1611
|
+
if (filters.page)
|
|
1612
|
+
qs.page = filters.page;
|
|
1613
|
+
if (filters.limit)
|
|
1614
|
+
qs.limit = filters.limit;
|
|
1615
|
+
const res = await apiRequest('GET', '/upload', undefined, qs);
|
|
1616
|
+
responseData = (_g = res.data) !== null && _g !== void 0 ? _g : [];
|
|
923
1617
|
}
|
|
924
1618
|
else if (operation === 'get') {
|
|
925
1619
|
const uploadId = this.getNodeParameter('uploadId', i);
|
|
926
1620
|
const res = await apiRequest('GET', `/upload/${uploadId}`);
|
|
927
|
-
responseData = (
|
|
1621
|
+
responseData = (_h = res.data) !== null && _h !== void 0 ? _h : {};
|
|
928
1622
|
}
|
|
929
1623
|
else if (operation === 'update') {
|
|
930
1624
|
const uploadId = this.getNodeParameter('uploadId', i);
|
|
@@ -937,7 +1631,25 @@ class MultiUploadTool {
|
|
|
937
1631
|
if (updateFields.scheduledFor !== undefined)
|
|
938
1632
|
body.scheduledFor = updateFields.scheduledFor;
|
|
939
1633
|
const res = await apiRequest('PATCH', `/upload/${uploadId}`, body);
|
|
940
|
-
responseData = (
|
|
1634
|
+
responseData = (_j = res.data) !== null && _j !== void 0 ? _j : {};
|
|
1635
|
+
}
|
|
1636
|
+
else if (operation === 'cancelScheduled') {
|
|
1637
|
+
const uploadId = this.getNodeParameter('uploadId', i);
|
|
1638
|
+
const res = await apiRequest('PATCH', `/upload/${uploadId}`, { status: 'cancelled' });
|
|
1639
|
+
responseData = (_k = res.data) !== null && _k !== void 0 ? _k : {};
|
|
1640
|
+
}
|
|
1641
|
+
else if (operation === 'editScheduled') {
|
|
1642
|
+
const uploadId = this.getNodeParameter('uploadId', i);
|
|
1643
|
+
const scheduleUpdateFields = this.getNodeParameter('scheduleUpdateFields', i, {});
|
|
1644
|
+
const body = {};
|
|
1645
|
+
if (scheduleUpdateFields.scheduledFor)
|
|
1646
|
+
body.scheduledFor = scheduleUpdateFields.scheduledFor;
|
|
1647
|
+
if (scheduleUpdateFields.title)
|
|
1648
|
+
body.title = scheduleUpdateFields.title;
|
|
1649
|
+
if (scheduleUpdateFields.description !== undefined)
|
|
1650
|
+
body.description = scheduleUpdateFields.description;
|
|
1651
|
+
const res = await apiRequest('PATCH', `/upload/${uploadId}`, body);
|
|
1652
|
+
responseData = (_l = res.data) !== null && _l !== void 0 ? _l : {};
|
|
941
1653
|
}
|
|
942
1654
|
}
|
|
943
1655
|
// ══════════════════════════════════════════════════════════════════
|
|
@@ -946,9 +1658,8 @@ class MultiUploadTool {
|
|
|
946
1658
|
else if (resource === 'pinterest') {
|
|
947
1659
|
if (operation === 'getBoards') {
|
|
948
1660
|
const accountId = this.getNodeParameter('accountId', i);
|
|
949
|
-
// Endpoint: /pinterest/boards (returns raw data or data wrapper)
|
|
950
1661
|
const res = await apiRequest('GET', '/pinterest/boards', undefined, { accountId });
|
|
951
|
-
responseData = (
|
|
1662
|
+
responseData = (_m = res.data) !== null && _m !== void 0 ? _m : [];
|
|
952
1663
|
}
|
|
953
1664
|
}
|
|
954
1665
|
// ══════════════════════════════════════════════════════════════════
|
|
@@ -962,13 +1673,15 @@ class MultiUploadTool {
|
|
|
962
1673
|
qs.platform = filters.platform;
|
|
963
1674
|
if (filters.status)
|
|
964
1675
|
qs.status = filters.status;
|
|
1676
|
+
if (filters.tags)
|
|
1677
|
+
qs.tags = filters.tags;
|
|
965
1678
|
const res = await apiRequest('GET', '/accounts', undefined, qs);
|
|
966
|
-
responseData = (
|
|
1679
|
+
responseData = (_o = res.data) !== null && _o !== void 0 ? _o : [];
|
|
967
1680
|
}
|
|
968
1681
|
else if (operation === 'get') {
|
|
969
1682
|
const accountId = this.getNodeParameter('accountId', i);
|
|
970
1683
|
const res = await apiRequest('GET', `/accounts/${accountId}`);
|
|
971
|
-
responseData = (
|
|
1684
|
+
responseData = (_p = res.data) !== null && _p !== void 0 ? _p : {};
|
|
972
1685
|
}
|
|
973
1686
|
else if (operation === 'delete') {
|
|
974
1687
|
const accountId = this.getNodeParameter('accountId', i);
|
|
@@ -977,7 +1690,82 @@ class MultiUploadTool {
|
|
|
977
1690
|
else if (operation === 'linkedinPages') {
|
|
978
1691
|
const accountId = this.getNodeParameter('accountId', i);
|
|
979
1692
|
const res = await apiRequest('GET', '/accounts/linkedin/pages', undefined, { accountId });
|
|
980
|
-
responseData = (
|
|
1693
|
+
responseData = (_q = res.pages) !== null && _q !== void 0 ? _q : [];
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
// ══════════════════════════════════════════════════════════════════
|
|
1697
|
+
// POOL
|
|
1698
|
+
// ══════════════════════════════════════════════════════════════════
|
|
1699
|
+
else if (resource === 'pool') {
|
|
1700
|
+
if (operation === 'listPools') {
|
|
1701
|
+
const res = await apiRequest('GET', '/pools');
|
|
1702
|
+
responseData = (_r = res.pools) !== null && _r !== void 0 ? _r : [];
|
|
1703
|
+
}
|
|
1704
|
+
else if (operation === 'getPool') {
|
|
1705
|
+
const poolId = this.getNodeParameter('poolId', i);
|
|
1706
|
+
const res = await apiRequest('GET', `/pools/${poolId}`);
|
|
1707
|
+
responseData = (_s = res.pool) !== null && _s !== void 0 ? _s : {};
|
|
1708
|
+
}
|
|
1709
|
+
else if (operation === 'checkCapacity') {
|
|
1710
|
+
const poolId = this.getNodeParameter('poolId', i);
|
|
1711
|
+
const count = this.getNodeParameter('count', i, 1);
|
|
1712
|
+
const res = await apiRequest('GET', `/pools/${poolId}/capacity`, undefined, { count: String(count) });
|
|
1713
|
+
responseData = res;
|
|
1714
|
+
}
|
|
1715
|
+
else if (operation === 'listVideos') {
|
|
1716
|
+
const poolId = this.getNodeParameter('poolId', i);
|
|
1717
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
1718
|
+
const qs = {};
|
|
1719
|
+
if (filters.status)
|
|
1720
|
+
qs.status = filters.status;
|
|
1721
|
+
const res = await apiRequest('GET', `/pools/${poolId}/videos`, undefined, qs);
|
|
1722
|
+
responseData = (_t = res.items) !== null && _t !== void 0 ? _t : [];
|
|
1723
|
+
}
|
|
1724
|
+
else if (operation === 'removeVideo') {
|
|
1725
|
+
const poolId = this.getNodeParameter('poolId', i);
|
|
1726
|
+
const itemId = this.getNodeParameter('itemId', i);
|
|
1727
|
+
responseData = await apiRequest('DELETE', `/pools/${poolId}/videos/${itemId}`);
|
|
1728
|
+
}
|
|
1729
|
+
else if (operation === 'addVideo') {
|
|
1730
|
+
const poolId = this.getNodeParameter('poolId', i);
|
|
1731
|
+
const title = this.getNodeParameter('title', i);
|
|
1732
|
+
const media = this.getNodeParameter('media', i, 'data');
|
|
1733
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
1734
|
+
const formData = new FormData();
|
|
1735
|
+
formData.set('title', title);
|
|
1736
|
+
if (additionalFields.description)
|
|
1737
|
+
formData.set('description', String(additionalFields.description));
|
|
1738
|
+
if (additionalFields.metadata)
|
|
1739
|
+
formData.set('metadata', String(additionalFields.metadata));
|
|
1740
|
+
// Parse comma-separated list — each entry is either a binary property name or a URL.
|
|
1741
|
+
// Mirrors the Upload-Post approach: mix of binary keys and URLs is fully supported.
|
|
1742
|
+
const mediaItems = media.split(',').map(s => s.trim()).filter(Boolean);
|
|
1743
|
+
for (const entry of mediaItems) {
|
|
1744
|
+
const isUrl = entry.startsWith('http://') || entry.startsWith('https://');
|
|
1745
|
+
if (isUrl) {
|
|
1746
|
+
const isVideo = /\.(mp4|mov|avi|mkv|webm)$/i.test(entry.split('?')[0]);
|
|
1747
|
+
formData.append(isVideo ? 'video' : 'photo', entry);
|
|
1748
|
+
}
|
|
1749
|
+
else {
|
|
1750
|
+
// Binary property name
|
|
1751
|
+
if (!((_u = items[i].binary) === null || _u === void 0 ? void 0 : _u[entry]))
|
|
1752
|
+
continue;
|
|
1753
|
+
const binaryItem = items[i].binary[entry];
|
|
1754
|
+
const fileBuffer = await this.helpers.getBinaryDataBuffer(i, entry);
|
|
1755
|
+
const fileName = (_v = binaryItem.fileName) !== null && _v !== void 0 ? _v : entry;
|
|
1756
|
+
const fileMime = (_w = binaryItem.mimeType) !== null && _w !== void 0 ? _w : 'application/octet-stream';
|
|
1757
|
+
const isVideo = fileMime.startsWith('video/');
|
|
1758
|
+
const blob = new Blob([fileBuffer], { type: fileMime });
|
|
1759
|
+
formData.append(isVideo ? 'video' : 'photo', blob, fileName);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
responseData = (await this.helpers.httpRequest({
|
|
1763
|
+
method: 'POST',
|
|
1764
|
+
url: `${BASE_URL}/pools/${poolId}/videos`,
|
|
1765
|
+
headers: { 'x-api-key': apiToken },
|
|
1766
|
+
body: formData,
|
|
1767
|
+
json: true,
|
|
1768
|
+
}));
|
|
981
1769
|
}
|
|
982
1770
|
}
|
|
983
1771
|
// ══════════════════════════════════════════════════════════════════
|
|
@@ -992,11 +1780,11 @@ class MultiUploadTool {
|
|
|
992
1780
|
if (description)
|
|
993
1781
|
body.description = description;
|
|
994
1782
|
const res = await apiRequest('POST', '/webhooks', body);
|
|
995
|
-
responseData = (
|
|
1783
|
+
responseData = (_x = res.data) !== null && _x !== void 0 ? _x : {};
|
|
996
1784
|
}
|
|
997
1785
|
else if (operation === 'list') {
|
|
998
1786
|
const res = await apiRequest('GET', '/webhooks');
|
|
999
|
-
responseData = (
|
|
1787
|
+
responseData = (_y = res.data) !== null && _y !== void 0 ? _y : [];
|
|
1000
1788
|
}
|
|
1001
1789
|
else if (operation === 'delete') {
|
|
1002
1790
|
const webhookId = this.getNodeParameter('webhookId', i);
|
|
@@ -1013,7 +1801,6 @@ class MultiUploadTool {
|
|
|
1013
1801
|
else if (resource === 'shortLink') {
|
|
1014
1802
|
if (operation === 'create') {
|
|
1015
1803
|
const url = this.getNodeParameter('url', i);
|
|
1016
|
-
// Handle rules
|
|
1017
1804
|
const rulesContainer = this.getNodeParameter('rules', i, {});
|
|
1018
1805
|
const rules = rulesContainer.rule || undefined;
|
|
1019
1806
|
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
@@ -1036,20 +1823,18 @@ class MultiUploadTool {
|
|
|
1036
1823
|
if (additionalFields.safeUrl)
|
|
1037
1824
|
body.safeUrl = additionalFields.safeUrl;
|
|
1038
1825
|
const res = await apiRequest('POST', '/short-links', body);
|
|
1039
|
-
responseData = (
|
|
1826
|
+
responseData = (_z = res.data) !== null && _z !== void 0 ? _z : {};
|
|
1040
1827
|
}
|
|
1041
1828
|
else if (operation === 'list') {
|
|
1042
1829
|
const res = await apiRequest('GET', '/short-links');
|
|
1043
|
-
responseData = (
|
|
1830
|
+
responseData = (_0 = res.data) !== null && _0 !== void 0 ? _0 : [];
|
|
1044
1831
|
}
|
|
1045
1832
|
else if (operation === 'get') {
|
|
1046
1833
|
const linkId = this.getNodeParameter('linkId', i);
|
|
1047
|
-
// Backend returns the link directly (no { data: ... } wrapper)
|
|
1048
1834
|
responseData = await apiRequest('GET', `/short-links/${linkId}`);
|
|
1049
1835
|
}
|
|
1050
1836
|
else if (operation === 'update') {
|
|
1051
1837
|
const linkId = this.getNodeParameter('linkId', i);
|
|
1052
|
-
// Handle rules
|
|
1053
1838
|
const rulesContainer = this.getNodeParameter('rules', i, {});
|
|
1054
1839
|
const rules = rulesContainer.rule || undefined;
|
|
1055
1840
|
const updateFields = this.getNodeParameter('updateFields', i, {});
|
|
@@ -1073,7 +1858,6 @@ class MultiUploadTool {
|
|
|
1073
1858
|
body.botProtection = updateFields.botProtection;
|
|
1074
1859
|
if (updateFields.safeUrl)
|
|
1075
1860
|
body.safeUrl = updateFields.safeUrl;
|
|
1076
|
-
// Backend returns the link directly (no { data: ... } wrapper)
|
|
1077
1861
|
responseData = await apiRequest('PUT', `/short-links/${linkId}`, body);
|
|
1078
1862
|
}
|
|
1079
1863
|
else if (operation === 'delete') {
|