n8n-nodes-upload-post 0.4.0 → 0.5.1

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.
@@ -229,6 +229,14 @@ const prepareUploadBase = (ctx, operation) => {
229
229
  if (firstComment) {
230
230
  formData.first_comment = firstComment;
231
231
  }
232
+ const firstCommentMedia = ctx.node.getNodeParameter('firstCommentMedia', ctx.itemIndex, '');
233
+ if (firstCommentMedia) {
234
+ formData['first_comment_media[]'] = ensureArrayFromCommaSeparated(firstCommentMedia);
235
+ }
236
+ const replyToId = ctx.node.getNodeParameter('replyToId', ctx.itemIndex, '');
237
+ if (replyToId) {
238
+ formData.reply_to_id = replyToId;
239
+ }
232
240
  const altText = ctx.node.getNodeParameter('altText', ctx.itemIndex, '');
233
241
  if (altText) {
234
242
  formData.alt_text = altText;
@@ -291,6 +299,10 @@ const applyPinterestOptions = (ctx, operation, formData, isManualPlatform = fals
291
299
  if (pinterestLink) {
292
300
  formData.pinterest_link = pinterestLink;
293
301
  }
302
+ const pinterestBoardSectionId = ctx.node.getNodeParameter('pinterestBoardSectionId', ctx.itemIndex, '');
303
+ if (pinterestBoardSectionId) {
304
+ formData.pinterest_board_section_id = pinterestBoardSectionId;
305
+ }
294
306
  if (operation === 'uploadVideo') {
295
307
  const pinterestCoverImageUrl = ctx.node.getNodeParameter('pinterestCoverImageUrl', ctx.itemIndex, '');
296
308
  const pinterestCoverImageContentType = ctx.node.getNodeParameter('pinterestCoverImageContentType', ctx.itemIndex, '');
@@ -343,7 +355,19 @@ const applyLinkedinOptions = (ctx, operation, formData, isManualPlatform = false
343
355
  formData.linkedin_link_url = linkedinLink;
344
356
  }
345
357
  }
346
- else if (operation === 'uploadDocument') {
358
+ const linkedinAltText = ctx.node.getNodeParameter('linkedinAltText', ctx.itemIndex, '');
359
+ if (linkedinAltText)
360
+ formData.linkedin_alt_text = linkedinAltText;
361
+ const linkedinDisableReshare = ctx.node.getNodeParameter('linkedinDisableReshare', ctx.itemIndex, false);
362
+ if (linkedinDisableReshare)
363
+ formData.linkedin_disable_reshare = 'true';
364
+ const linkedinLinkTitle = ctx.node.getNodeParameter('linkedinLinkTitle', ctx.itemIndex, '');
365
+ if (linkedinLinkTitle)
366
+ formData.linkedin_link_title = linkedinLinkTitle;
367
+ const linkedinLinkDescription = ctx.node.getNodeParameter('linkedinLinkDescription', ctx.itemIndex, '');
368
+ if (linkedinLinkDescription)
369
+ formData.linkedin_link_description = linkedinLinkDescription;
370
+ if (operation === 'uploadDocument') {
347
371
  const linkedinVisibility = ctx.node.getNodeParameter('linkedinVisibility', ctx.itemIndex, 'PUBLIC');
348
372
  formData.visibility = linkedinVisibility;
349
373
  const documentDescription = ctx.node.getNodeParameter('documentDescription', ctx.itemIndex, '');
@@ -393,6 +417,22 @@ const applyFacebookOptions = (ctx, operation, formData, isManualPlatform = false
393
417
  if (facebookLink) {
394
418
  formData.facebook_link_url = facebookLink;
395
419
  }
420
+ const facebookCallToAction = ctx.node.getNodeParameter('facebookCallToAction', ctx.itemIndex, '');
421
+ if (facebookCallToAction)
422
+ formData.facebook_call_to_action = facebookCallToAction;
423
+ }
424
+ const facebookPlaceId = ctx.node.getNodeParameter('facebookPlaceId', ctx.itemIndex, '');
425
+ if (facebookPlaceId)
426
+ formData.facebook_place_id = facebookPlaceId;
427
+ if (operation === 'uploadPhotos') {
428
+ const facebookAltText = ctx.node.getNodeParameter('facebookAltText', ctx.itemIndex, '');
429
+ if (facebookAltText)
430
+ formData.facebook_alt_text = facebookAltText;
431
+ }
432
+ if (operation === 'uploadVideo') {
433
+ const facebookIsAiGenerated = ctx.node.getNodeParameter('facebookIsAiGenerated', ctx.itemIndex, false);
434
+ if (facebookIsAiGenerated)
435
+ formData.facebook_is_ai_generated = 'true';
396
436
  }
397
437
  };
398
438
  const applySharedTiktokFields = (ctx, formData) => {
@@ -465,6 +505,12 @@ const applyTiktokOptions = (ctx, operation, formData) => {
465
505
  const uploadToDraft = ctx.node.getNodeParameter('tiktokUploadToDraft', ctx.itemIndex, false);
466
506
  if (uploadToDraft)
467
507
  formData.tiktok_upload_to_draft = 'true';
508
+ const isAdsOnly = ctx.node.getNodeParameter('tiktokIsAdsOnly', ctx.itemIndex, false);
509
+ if (isAdsOnly)
510
+ formData.tiktok_is_ads_only = 'true';
511
+ const ttoInviteLink = ctx.node.getNodeParameter('tiktokTtoInviteLink', ctx.itemIndex, '');
512
+ if (ttoInviteLink)
513
+ formData.tiktok_tto_invite_link = ttoInviteLink;
468
514
  }
469
515
  };
470
516
  const applyInstagramOptions = async (ctx, operation, formData) => {
@@ -518,6 +564,11 @@ const applyInstagramOptions = async (ctx, operation, formData) => {
518
564
  if (thumbOffset)
519
565
  formData.thumb_offset = thumbOffset;
520
566
  }
567
+ if (operation === 'uploadPhotos') {
568
+ const instagramAltText = ctx.node.getNodeParameter('instagramAltText', ctx.itemIndex, '');
569
+ if (instagramAltText)
570
+ formData.instagram_alt_text = instagramAltText;
571
+ }
521
572
  };
522
573
  const applyYoutubeOptions = async (ctx, formData) => {
523
574
  const tagsRaw = ctx.node.getNodeParameter('youtubeTags', ctx.itemIndex, '');
@@ -592,6 +643,11 @@ const applyYoutubeOptions = async (ctx, formData) => {
592
643
  }
593
644
  }
594
645
  }
646
+ const notifySubscribers = ctx.node.getNodeParameter('youtubeNotifySubscribers', ctx.itemIndex, true);
647
+ formData.youtube_notify_subscribers = String(notifySubscribers);
648
+ const publishAt = ctx.node.getNodeParameter('youtubePublishAt', ctx.itemIndex, '');
649
+ if (publishAt)
650
+ formData.youtube_publish_at = publishAt;
595
651
  };
596
652
  const validateXPollConfiguration = (ctx, operation, formData) => {
597
653
  if (operation !== 'uploadText') {
@@ -695,6 +751,23 @@ const applyXOptions = (ctx, operation, formData) => {
695
751
  if (operation === 'uploadVideo' && xPlaceIdVideo) {
696
752
  formData.place_id = xPlaceIdVideo;
697
753
  }
754
+ const xAltText = ctx.node.getNodeParameter('xAltText', ctx.itemIndex, '');
755
+ if (xAltText)
756
+ formData.x_alt_text = xAltText;
757
+ const xSubtitlesUrl = ctx.node.getNodeParameter('xSubtitlesUrl', ctx.itemIndex, '');
758
+ if (xSubtitlesUrl)
759
+ formData.x_subtitles_url = xSubtitlesUrl;
760
+ }
761
+ const xPaidPartnership = ctx.node.getNodeParameter('xPaidPartnership', ctx.itemIndex, false);
762
+ if (xPaidPartnership)
763
+ formData.x_paid_partnership = 'true';
764
+ if (operation === 'uploadText') {
765
+ const xArticleTitle = ctx.node.getNodeParameter('xArticleTitle', ctx.itemIndex, '');
766
+ if (xArticleTitle)
767
+ formData.x_article_title = xArticleTitle;
768
+ const xArticleBody = ctx.node.getNodeParameter('xArticleBody', ctx.itemIndex, '');
769
+ if (xArticleBody)
770
+ formData.x_article_body = xArticleBody;
698
771
  }
699
772
  };
700
773
  const applyThreadsOptions = (ctx, formData) => {
@@ -713,6 +786,24 @@ const applyThreadsOptions = (ctx, formData) => {
713
786
  if (threadsTopicTag) {
714
787
  formData.threads_topic_tag = threadsTopicTag;
715
788
  }
789
+ const threadsReplyControl = ctx.node.getNodeParameter('threadsReplyControl', ctx.itemIndex, '');
790
+ if (threadsReplyControl)
791
+ formData.threads_reply_control = threadsReplyControl;
792
+ const threadsAltText = ctx.node.getNodeParameter('threadsAltText', ctx.itemIndex, '');
793
+ if (threadsAltText)
794
+ formData.threads_alt_text = threadsAltText;
795
+ const threadsReplyToId = ctx.node.getNodeParameter('threadsReplyToId', ctx.itemIndex, '');
796
+ if (threadsReplyToId)
797
+ formData.threads_reply_to_id = threadsReplyToId;
798
+ const threadsQuotePostId = ctx.node.getNodeParameter('threadsQuotePostId', ctx.itemIndex, '');
799
+ if (threadsQuotePostId)
800
+ formData.threads_quote_post_id = threadsQuotePostId;
801
+ const threadsLinkAttachment = ctx.node.getNodeParameter('threadsLinkAttachment', ctx.itemIndex, '');
802
+ if (threadsLinkAttachment)
803
+ formData.threads_link_attachment = threadsLinkAttachment;
804
+ const threadsPollOptions = ctx.node.getNodeParameter('threadsPollOptions', ctx.itemIndex, '');
805
+ if (threadsPollOptions)
806
+ formData.threads_poll_options = threadsPollOptions;
716
807
  };
717
808
  const applyGoogleBusinessOptions = (ctx, _operation, formData) => {
718
809
  const locationId = ctx.node.getNodeParameter('gbpLocationId', ctx.itemIndex, '');
@@ -768,6 +859,9 @@ const applyGoogleBusinessOptions = (ctx, _operation, formData) => {
768
859
  if (terms)
769
860
  formData.gbp_offer_terms = terms;
770
861
  }
862
+ const languageCode = ctx.node.getNodeParameter('gbpLanguageCode', ctx.itemIndex, '');
863
+ if (languageCode)
864
+ formData.gbp_language_code = languageCode;
771
865
  };
772
866
  const applyRedditOptions = (ctx, operation, formData) => {
773
867
  const subreddit = ctx.node.getNodeParameter('redditSubreddit', ctx.itemIndex);
@@ -782,6 +876,109 @@ const applyRedditOptions = (ctx, operation, formData) => {
782
876
  formData.reddit_link_url = redditLink;
783
877
  }
784
878
  }
879
+ const redditNsfw = ctx.node.getNodeParameter('redditNsfw', ctx.itemIndex, false);
880
+ if (redditNsfw)
881
+ formData.reddit_nsfw = 'true';
882
+ const redditSpoiler = ctx.node.getNodeParameter('redditSpoiler', ctx.itemIndex, false);
883
+ if (redditSpoiler)
884
+ formData.reddit_spoiler = 'true';
885
+ const redditFlairText = ctx.node.getNodeParameter('redditFlairText', ctx.itemIndex, '');
886
+ if (redditFlairText)
887
+ formData.reddit_flair_text = redditFlairText;
888
+ };
889
+ const setIfFilled = (formData, field, value) => {
890
+ if (value === undefined || value === null || value === '' || value === false)
891
+ return;
892
+ formData[field] = typeof value === 'boolean' ? 'true' : value;
893
+ };
894
+ const applyCredentialPlatformOptions = (ctx, platforms, formData) => {
895
+ const isManual = platforms.includes(MANUAL_PLATFORM_VALUE);
896
+ const has = (platform) => platforms.includes(platform) || isManual;
897
+ if (has('bluesky')) {
898
+ setIfFilled(formData, 'bluesky_alt_text', ctx.node.getNodeParameter('blueskyAltText', ctx.itemIndex, ''));
899
+ setIfFilled(formData, 'bluesky_langs', ctx.node.getNodeParameter('blueskyLangs', ctx.itemIndex, ''));
900
+ setIfFilled(formData, 'bluesky_labels', ctx.node.getNodeParameter('blueskyLabels', ctx.itemIndex, ''));
901
+ setIfFilled(formData, 'bluesky_threadgate', ctx.node.getNodeParameter('blueskyThreadgate', ctx.itemIndex, ''));
902
+ setIfFilled(formData, 'bluesky_quote_uri', ctx.node.getNodeParameter('blueskyQuoteUri', ctx.itemIndex, ''));
903
+ }
904
+ if (has('discord')) {
905
+ setIfFilled(formData, 'discord_thread_id', ctx.node.getNodeParameter('discordThreadId', ctx.itemIndex, ''));
906
+ setIfFilled(formData, 'discord_thread_name', ctx.node.getNodeParameter('discordThreadName', ctx.itemIndex, ''));
907
+ setIfFilled(formData, 'discord_username', ctx.node.getNodeParameter('discordUsername', ctx.itemIndex, ''));
908
+ setIfFilled(formData, 'discord_avatar_url', ctx.node.getNodeParameter('discordAvatarUrl', ctx.itemIndex, ''));
909
+ setIfFilled(formData, 'discord_embeds', ctx.node.getNodeParameter('discordEmbeds', ctx.itemIndex, ''));
910
+ setIfFilled(formData, 'discord_alt_text', ctx.node.getNodeParameter('discordAltText', ctx.itemIndex, ''));
911
+ setIfFilled(formData, 'discord_tts', ctx.node.getNodeParameter('discordTts', ctx.itemIndex, false));
912
+ }
913
+ if (has('telegram')) {
914
+ setIfFilled(formData, 'telegram_parse_mode', ctx.node.getNodeParameter('telegramParseMode', ctx.itemIndex, ''));
915
+ setIfFilled(formData, 'telegram_message_thread_id', ctx.node.getNodeParameter('telegramMessageThreadId', ctx.itemIndex, ''));
916
+ setIfFilled(formData, 'telegram_disable_notification', ctx.node.getNodeParameter('telegramDisableNotification', ctx.itemIndex, false));
917
+ setIfFilled(formData, 'telegram_protect_content', ctx.node.getNodeParameter('telegramProtectContent', ctx.itemIndex, false));
918
+ setIfFilled(formData, 'telegram_has_spoiler', ctx.node.getNodeParameter('telegramHasSpoiler', ctx.itemIndex, false));
919
+ setIfFilled(formData, 'telegram_as_document', ctx.node.getNodeParameter('telegramAsDocument', ctx.itemIndex, false));
920
+ }
921
+ if (has('mastodon')) {
922
+ setIfFilled(formData, 'mastodon_visibility', ctx.node.getNodeParameter('mastodonVisibility', ctx.itemIndex, ''));
923
+ setIfFilled(formData, 'mastodon_sensitive', ctx.node.getNodeParameter('mastodonSensitive', ctx.itemIndex, false));
924
+ setIfFilled(formData, 'mastodon_spoiler_text', ctx.node.getNodeParameter('mastodonSpoilerText', ctx.itemIndex, ''));
925
+ setIfFilled(formData, 'mastodon_language', ctx.node.getNodeParameter('mastodonLanguage', ctx.itemIndex, ''));
926
+ setIfFilled(formData, 'mastodon_alt_text', ctx.node.getNodeParameter('mastodonAltText', ctx.itemIndex, ''));
927
+ setIfFilled(formData, 'mastodon_poll_options', ctx.node.getNodeParameter('mastodonPollOptions', ctx.itemIndex, ''));
928
+ setIfFilled(formData, 'mastodon_poll_expires_in', ctx.node.getNodeParameter('mastodonPollExpiresIn', ctx.itemIndex, 0));
929
+ setIfFilled(formData, 'mastodon_poll_multiple', ctx.node.getNodeParameter('mastodonPollMultiple', ctx.itemIndex, false));
930
+ }
931
+ if (has('wordpress')) {
932
+ setIfFilled(formData, 'wordpress_status', ctx.node.getNodeParameter('wordpressStatus', ctx.itemIndex, ''));
933
+ setIfFilled(formData, 'wordpress_date', ctx.node.getNodeParameter('wordpressDate', ctx.itemIndex, ''));
934
+ setIfFilled(formData, 'wordpress_categories', ctx.node.getNodeParameter('wordpressCategories', ctx.itemIndex, ''));
935
+ setIfFilled(formData, 'wordpress_tags', ctx.node.getNodeParameter('wordpressTags', ctx.itemIndex, ''));
936
+ setIfFilled(formData, 'wordpress_excerpt', ctx.node.getNodeParameter('wordpressExcerpt', ctx.itemIndex, ''));
937
+ setIfFilled(formData, 'wordpress_slug', ctx.node.getNodeParameter('wordpressSlug', ctx.itemIndex, ''));
938
+ setIfFilled(formData, 'wordpress_alt_text', ctx.node.getNodeParameter('wordpressAltText', ctx.itemIndex, ''));
939
+ }
940
+ if (has('lemmy')) {
941
+ setIfFilled(formData, 'lemmy_community', ctx.node.getNodeParameter('lemmyCommunity', ctx.itemIndex, ''));
942
+ setIfFilled(formData, 'lemmy_url', ctx.node.getNodeParameter('lemmyUrl', ctx.itemIndex, ''));
943
+ setIfFilled(formData, 'lemmy_nsfw', ctx.node.getNodeParameter('lemmyNsfw', ctx.itemIndex, false));
944
+ setIfFilled(formData, 'lemmy_alt_text', ctx.node.getNodeParameter('lemmyAltText', ctx.itemIndex, ''));
945
+ }
946
+ if (has('slack')) {
947
+ setIfFilled(formData, 'slack_markdown', ctx.node.getNodeParameter('slackMarkdown', ctx.itemIndex, false));
948
+ setIfFilled(formData, 'slack_blocks', ctx.node.getNodeParameter('slackBlocks', ctx.itemIndex, ''));
949
+ setIfFilled(formData, 'slack_mrkdwn', ctx.node.getNodeParameter('slackMrkdwn', ctx.itemIndex, false));
950
+ }
951
+ if (has('nostr')) {
952
+ setIfFilled(formData, 'nostr_kind', ctx.node.getNodeParameter('nostrKind', ctx.itemIndex, ''));
953
+ setIfFilled(formData, 'nostr_long_form', ctx.node.getNodeParameter('nostrLongForm', ctx.itemIndex, false));
954
+ }
955
+ if (has('devto')) {
956
+ setIfFilled(formData, 'devto_tags', ctx.node.getNodeParameter('devtoTags', ctx.itemIndex, ''));
957
+ setIfFilled(formData, 'devto_canonical_url', ctx.node.getNodeParameter('devtoCanonicalUrl', ctx.itemIndex, ''));
958
+ setIfFilled(formData, 'devto_description', ctx.node.getNodeParameter('devtoDescription', ctx.itemIndex, ''));
959
+ setIfFilled(formData, 'devto_main_image', ctx.node.getNodeParameter('devtoMainImage', ctx.itemIndex, ''));
960
+ setIfFilled(formData, 'devto_series', ctx.node.getNodeParameter('devtoSeries', ctx.itemIndex, ''));
961
+ setIfFilled(formData, 'devto_published', ctx.node.getNodeParameter('devtoPublished', ctx.itemIndex, false));
962
+ }
963
+ if (has('hashnode')) {
964
+ setIfFilled(formData, 'hashnode_tags', ctx.node.getNodeParameter('hashnodeTags', ctx.itemIndex, ''));
965
+ setIfFilled(formData, 'hashnode_subtitle', ctx.node.getNodeParameter('hashnodeSubtitle', ctx.itemIndex, ''));
966
+ setIfFilled(formData, 'hashnode_cover_image_url', ctx.node.getNodeParameter('hashnodeCoverImageUrl', ctx.itemIndex, ''));
967
+ setIfFilled(formData, 'hashnode_body', ctx.node.getNodeParameter('hashnodeBody', ctx.itemIndex, ''));
968
+ setIfFilled(formData, 'hashnode_draft', ctx.node.getNodeParameter('hashnodeDraft', ctx.itemIndex, false));
969
+ }
970
+ if (has('whop')) {
971
+ setIfFilled(formData, 'whop_body', ctx.node.getNodeParameter('whopBody', ctx.itemIndex, ''));
972
+ setIfFilled(formData, 'whop_pinned', ctx.node.getNodeParameter('whopPinned', ctx.itemIndex, false));
973
+ setIfFilled(formData, 'whop_paywall_amount', ctx.node.getNodeParameter('whopPaywallAmount', ctx.itemIndex, ''));
974
+ setIfFilled(formData, 'whop_paywall_currency', ctx.node.getNodeParameter('whopPaywallCurrency', ctx.itemIndex, ''));
975
+ }
976
+ if (has('listmonk')) {
977
+ setIfFilled(formData, 'listmonk_content_type', ctx.node.getNodeParameter('listmonkContentType', ctx.itemIndex, ''));
978
+ setIfFilled(formData, 'listmonk_send_at', ctx.node.getNodeParameter('listmonkSendAt', ctx.itemIndex, ''));
979
+ setIfFilled(formData, 'listmonk_lists', ctx.node.getNodeParameter('listmonkLists', ctx.itemIndex, ''));
980
+ setIfFilled(formData, 'listmonk_template_id', ctx.node.getNodeParameter('listmonkTemplateId', ctx.itemIndex, ''));
981
+ }
785
982
  };
786
983
  const applyUploadPlatformOptions = async (ctx, operation, prep) => {
787
984
  const { formData, platforms } = prep;
@@ -822,6 +1019,7 @@ const applyUploadPlatformOptions = async (ctx, operation, prep) => {
822
1019
  formData.bluesky_link_url = blueskyLink;
823
1020
  }
824
1021
  }
1022
+ applyCredentialPlatformOptions(ctx, platforms, formData);
825
1023
  };
826
1024
  const buildUploadPhotosRequest = async (ctx) => {
827
1025
  const prep = prepareUploadBase(ctx, 'uploadPhotos');
@@ -1112,12 +1310,206 @@ const buildMonitoringRequest = (ctx) => {
1112
1310
  waitForCompletion: false,
1113
1311
  };
1114
1312
  }
1313
+ case 'getMedia': {
1314
+ const qs = {
1315
+ platform: ctx.node.getNodeParameter('mediaPlatform', ctx.itemIndex),
1316
+ user: ctx.node.getNodeParameter('mediaUser', ctx.itemIndex),
1317
+ };
1318
+ const pageUrn = ctx.node.getNodeParameter('mediaPageUrn', ctx.itemIndex, '');
1319
+ if (pageUrn)
1320
+ qs.page_urn = pageUrn;
1321
+ const limit = ctx.node.getNodeParameter('mediaLimit', ctx.itemIndex, 0);
1322
+ if (limit)
1323
+ qs.limit = limit;
1324
+ const cursor = ctx.node.getNodeParameter('mediaCursor', ctx.itemIndex, '');
1325
+ if (cursor)
1326
+ qs.cursor = cursor;
1327
+ return {
1328
+ endpoint: '/uploadposts/media',
1329
+ method: 'GET',
1330
+ qs,
1331
+ isUploadOperation: false,
1332
+ waitForCompletion: false,
1333
+ };
1334
+ }
1335
+ case 'getGoogleBusinessLocations': {
1336
+ const qs = {};
1337
+ const profile = ctx.node.getNodeParameter('gbpLocationsProfile', ctx.itemIndex, '');
1338
+ if (profile)
1339
+ qs.profile = profile;
1340
+ return {
1341
+ endpoint: '/uploadposts/google-business/locations',
1342
+ method: 'GET',
1343
+ qs,
1344
+ isUploadOperation: false,
1345
+ waitForCompletion: false,
1346
+ };
1347
+ }
1348
+ case 'getTiktokTrendingMusic': {
1349
+ const qs = {
1350
+ profile: ctx.node.getNodeParameter('tiktokDiscoveryProfile', ctx.itemIndex),
1351
+ };
1352
+ const genre = ctx.node.getNodeParameter('tiktokMusicGenre', ctx.itemIndex, '');
1353
+ if (genre)
1354
+ qs.genre = genre;
1355
+ const countryCode = ctx.node.getNodeParameter('tiktokMusicCountryCode', ctx.itemIndex, '');
1356
+ if (countryCode)
1357
+ qs.country_code = countryCode;
1358
+ return {
1359
+ endpoint: '/uploadposts/tiktok/music/trending',
1360
+ method: 'GET',
1361
+ qs,
1362
+ isUploadOperation: false,
1363
+ waitForCompletion: false,
1364
+ };
1365
+ }
1366
+ case 'searchTiktokMusic': {
1367
+ const qs = {
1368
+ profile: ctx.node.getNodeParameter('tiktokDiscoveryProfile', ctx.itemIndex),
1369
+ };
1370
+ const query = ctx.node.getNodeParameter('tiktokMusicQuery', ctx.itemIndex, '');
1371
+ if (query)
1372
+ qs.q = query;
1373
+ const genre = ctx.node.getNodeParameter('tiktokMusicGenre', ctx.itemIndex, '');
1374
+ if (genre)
1375
+ qs.genre = genre;
1376
+ const countryCode = ctx.node.getNodeParameter('tiktokMusicCountryCode', ctx.itemIndex, '');
1377
+ if (countryCode)
1378
+ qs.country_code = countryCode;
1379
+ const limit = ctx.node.getNodeParameter('tiktokMusicLimit', ctx.itemIndex, 0);
1380
+ if (limit)
1381
+ qs.limit = limit;
1382
+ return {
1383
+ endpoint: '/uploadposts/tiktok/music/search',
1384
+ method: 'GET',
1385
+ qs,
1386
+ isUploadOperation: false,
1387
+ waitForCompletion: false,
1388
+ };
1389
+ }
1390
+ case 'getTiktokLocations': {
1391
+ return {
1392
+ endpoint: '/uploadposts/tiktok/locations',
1393
+ method: 'GET',
1394
+ qs: {
1395
+ profile: ctx.node.getNodeParameter('tiktokDiscoveryProfile', ctx.itemIndex),
1396
+ q: ctx.node.getNodeParameter('tiktokLocationQuery', ctx.itemIndex),
1397
+ },
1398
+ isUploadOperation: false,
1399
+ waitForCompletion: false,
1400
+ };
1401
+ }
1402
+ case 'getTiktokSettings': {
1403
+ return {
1404
+ endpoint: '/uploadposts/tiktok/settings',
1405
+ method: 'GET',
1406
+ qs: {
1407
+ profile: ctx.node.getNodeParameter('tiktokDiscoveryProfile', ctx.itemIndex),
1408
+ },
1409
+ isUploadOperation: false,
1410
+ waitForCompletion: false,
1411
+ };
1412
+ }
1115
1413
  default:
1116
1414
  throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported monitoring operation: ${ctx.operation}`, {
1117
1415
  itemIndex: ctx.itemIndex,
1118
1416
  });
1119
1417
  }
1120
1418
  };
1419
+ const buildPostActionRequest = (ctx) => {
1420
+ switch (ctx.operation) {
1421
+ case 'retryPost': {
1422
+ const body = {};
1423
+ const requestId = ctx.node.getNodeParameter('retryRequestId', ctx.itemIndex, '');
1424
+ const jobId = ctx.node.getNodeParameter('retryJobId', ctx.itemIndex, '');
1425
+ if (requestId)
1426
+ body.request_id = requestId;
1427
+ if (jobId)
1428
+ body.job_id = jobId;
1429
+ if (!requestId && !jobId) {
1430
+ throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), 'Provide a Request ID or a Job ID to retry.', {
1431
+ itemIndex: ctx.itemIndex,
1432
+ });
1433
+ }
1434
+ return {
1435
+ endpoint: '/uploadposts/posts/retry',
1436
+ method: 'POST',
1437
+ body,
1438
+ isUploadOperation: false,
1439
+ waitForCompletion: false,
1440
+ };
1441
+ }
1442
+ case 'unpublishPost': {
1443
+ return {
1444
+ endpoint: '/uploadposts/posts/unpublish',
1445
+ method: 'POST',
1446
+ body: {
1447
+ platform: ctx.node.getNodeParameter('postActionPlatform', ctx.itemIndex),
1448
+ user: ctx.node.getNodeParameter('postActionUser', ctx.itemIndex),
1449
+ post_id: ctx.node.getNodeParameter('postActionPostId', ctx.itemIndex),
1450
+ },
1451
+ isUploadOperation: false,
1452
+ waitForCompletion: false,
1453
+ };
1454
+ }
1455
+ case 'editPost': {
1456
+ const body = {
1457
+ platform: ctx.node.getNodeParameter('postActionPlatform', ctx.itemIndex),
1458
+ user: ctx.node.getNodeParameter('postActionUser', ctx.itemIndex),
1459
+ post_id: ctx.node.getNodeParameter('postActionPostId', ctx.itemIndex),
1460
+ };
1461
+ const message = ctx.node.getNodeParameter('postActionMessage', ctx.itemIndex, '');
1462
+ if (message)
1463
+ body.message = message;
1464
+ return {
1465
+ endpoint: '/uploadposts/posts/edit',
1466
+ method: 'POST',
1467
+ body,
1468
+ isUploadOperation: false,
1469
+ waitForCompletion: false,
1470
+ };
1471
+ }
1472
+ case 'repostPost': {
1473
+ const body = {
1474
+ platform: ctx.node.getNodeParameter('repostPlatform', ctx.itemIndex),
1475
+ user: ctx.node.getNodeParameter('postActionUser', ctx.itemIndex),
1476
+ post_id: ctx.node.getNodeParameter('postActionPostId', ctx.itemIndex),
1477
+ };
1478
+ const commentary = ctx.node.getNodeParameter('postActionMessage', ctx.itemIndex, '');
1479
+ if (commentary)
1480
+ body.commentary = commentary;
1481
+ return {
1482
+ endpoint: '/uploadposts/posts/repost',
1483
+ method: 'POST',
1484
+ body,
1485
+ isUploadOperation: false,
1486
+ waitForCompletion: false,
1487
+ };
1488
+ }
1489
+ case 'savePin': {
1490
+ const body = {
1491
+ platform: 'pinterest',
1492
+ user: ctx.node.getNodeParameter('postActionUser', ctx.itemIndex),
1493
+ post_id: ctx.node.getNodeParameter('postActionPostId', ctx.itemIndex),
1494
+ pinterest_board_id: ctx.node.getNodeParameter('savePinBoardId', ctx.itemIndex),
1495
+ };
1496
+ const sectionId = ctx.node.getNodeParameter('savePinBoardSectionId', ctx.itemIndex, '');
1497
+ if (sectionId)
1498
+ body.pinterest_board_section_id = sectionId;
1499
+ return {
1500
+ endpoint: '/uploadposts/posts/save',
1501
+ method: 'POST',
1502
+ body,
1503
+ isUploadOperation: false,
1504
+ waitForCompletion: false,
1505
+ };
1506
+ }
1507
+ default:
1508
+ throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported post action: ${ctx.operation}`, {
1509
+ itemIndex: ctx.itemIndex,
1510
+ });
1511
+ }
1512
+ };
1121
1513
  const collectUiLabels = (ctx) => {
1122
1514
  var _a, _b;
1123
1515
  const raw = ctx.node.getNodeParameter('uiLabels', ctx.itemIndex, {});
@@ -1261,6 +1653,14 @@ const buildUserRequest = async (ctx) => {
1261
1653
  waitForCompletion: false,
1262
1654
  };
1263
1655
  }
1656
+ case 'testNotifications':
1657
+ return {
1658
+ endpoint: '/uploadposts/users/notifications/test',
1659
+ method: 'POST',
1660
+ body: {},
1661
+ isUploadOperation: false,
1662
+ waitForCompletion: false,
1663
+ };
1264
1664
  default:
1265
1665
  throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported user operation: ${ctx.operation}`, {
1266
1666
  itemIndex: ctx.itemIndex,
@@ -1321,6 +1721,50 @@ const buildInstagramRequest = (ctx) => {
1321
1721
  waitForCompletion: false,
1322
1722
  };
1323
1723
  }
1724
+ case 'createComment': {
1725
+ const user = ctx.node.getNodeParameter('instagramUser', ctx.itemIndex);
1726
+ const platform = ctx.node.getNodeParameter('commentPlatform', ctx.itemIndex, 'instagram');
1727
+ const body = {
1728
+ platform,
1729
+ user,
1730
+ message: ctx.node.getNodeParameter('createCommentMessage', ctx.itemIndex),
1731
+ };
1732
+ const commentId = ctx.node.getNodeParameter('createCommentCommentId', ctx.itemIndex, '');
1733
+ const postId = ctx.node.getNodeParameter('createCommentPostId', ctx.itemIndex, '');
1734
+ const postUrl = ctx.node.getNodeParameter('createCommentPostUrl', ctx.itemIndex, '');
1735
+ if (commentId)
1736
+ body.comment_id = commentId;
1737
+ if (postId)
1738
+ body.post_id = postId;
1739
+ if (postUrl && !postId)
1740
+ body.post_url = postUrl;
1741
+ return {
1742
+ endpoint: '/uploadposts/comments/create',
1743
+ method: 'POST',
1744
+ body,
1745
+ isUploadOperation: false,
1746
+ waitForCompletion: false,
1747
+ };
1748
+ }
1749
+ case 'deleteComment': {
1750
+ const user = ctx.node.getNodeParameter('instagramUser', ctx.itemIndex);
1751
+ const platform = ctx.node.getNodeParameter('commentPlatform', ctx.itemIndex, 'instagram');
1752
+ const body = {
1753
+ platform,
1754
+ user,
1755
+ comment_id: ctx.node.getNodeParameter('createCommentCommentId', ctx.itemIndex),
1756
+ };
1757
+ const postId = ctx.node.getNodeParameter('createCommentPostId', ctx.itemIndex, '');
1758
+ if (postId)
1759
+ body.post_id = postId;
1760
+ return {
1761
+ endpoint: '/uploadposts/comments/delete',
1762
+ method: 'DELETE',
1763
+ body,
1764
+ isUploadOperation: false,
1765
+ waitForCompletion: false,
1766
+ };
1767
+ }
1324
1768
  case 'commentAction': {
1325
1769
  const user = ctx.node.getNodeParameter('instagramUser', ctx.itemIndex);
1326
1770
  const platform = ctx.node.getNodeParameter('commentActionPlatform', ctx.itemIndex, 'tiktok');
@@ -1429,6 +1873,9 @@ const buildRequestConfig = async (ctx) => {
1429
1873
  if (resource === 'monitoring') {
1430
1874
  return buildMonitoringRequest(ctx);
1431
1875
  }
1876
+ if (resource === 'postActions') {
1877
+ return buildPostActionRequest(ctx);
1878
+ }
1432
1879
  if (resource === 'users') {
1433
1880
  return await buildUserRequest(ctx);
1434
1881
  }
@@ -1505,7 +1952,7 @@ class UploadPost {
1505
1952
  this.description = {
1506
1953
  displayName: 'Upload Post',
1507
1954
  name: 'uploadPost',
1508
- icon: 'file:uploadpost.svg',
1955
+ icon: { light: 'file:uploadpost.svg', dark: 'file:uploadpost.svg' },
1509
1956
  group: ['output'],
1510
1957
  version: 1,
1511
1958
  subtitle: '={{$parameter["operation"]}}',
@@ -1531,6 +1978,7 @@ class UploadPost {
1531
1978
  options: [
1532
1979
  { name: 'Comment', value: 'instagram' },
1533
1980
  { name: 'Insight', value: 'insights' },
1981
+ { name: 'Post Action', value: 'postActions' },
1534
1982
  { name: 'Status & History', value: 'monitoring' },
1535
1983
  { name: 'Upload', value: 'uploads' },
1536
1984
  { name: 'User', value: 'users' },
@@ -1544,9 +1992,9 @@ class UploadPost {
1544
1992
  noDataExpression: true,
1545
1993
  options: [
1546
1994
  { name: 'Upload Document', value: 'uploadDocument', action: 'Upload a document', description: 'Upload a document (PDF, PPT, PPTX, DOC, DOCX) as a native carousel/viewer (Supports: LinkedIn only)' },
1547
- { name: 'Upload Photo(s)', value: 'uploadPhotos', action: 'Upload photos', description: 'Upload one or more photos (Supports: TikTok, Instagram, LinkedIn, Facebook, X, Threads, Discord, Telegram)' },
1548
- { name: 'Upload Text', value: 'uploadText', action: 'Upload a text post', description: 'Upload a text-based post (Supports: X, LinkedIn, Facebook, Threads, Discord, Telegram)' },
1549
- { name: 'Upload Video', value: 'uploadVideo', action: 'Upload a video', description: 'Upload a single video (Supports: TikTok, Instagram, LinkedIn, YouTube, Facebook, X, Threads, Discord, Telegram)' },
1995
+ { name: 'Upload Photo(s)', value: 'uploadPhotos', action: 'Upload photos', description: 'Upload one or more photos (Supports: Bluesky, Discord, Facebook, Google Business, Instagram, Lemmy, LinkedIn, Mastodon, Pinterest, Reddit, Telegram, Threads, TikTok, WordPress, X)' },
1996
+ { name: 'Upload Text', value: 'uploadText', action: 'Upload a text post', description: 'Upload a text-based post (Supports: Bluesky, Dev.to, Discord, Facebook, Google Business, Hashnode, Lemmy, LinkedIn, Listmonk, Mastodon, Nostr, Reddit, Slack, Telegram, Threads, Whop, WordPress, X)' },
1997
+ { name: 'Upload Video', value: 'uploadVideo', action: 'Upload a video', description: 'Upload a single video (Supports: Bluesky, Discord, Facebook, Google Business, Instagram, LinkedIn, Mastodon, Pinterest, Reddit, Telegram, Threads, TikTok, WordPress, X, YouTube)' },
1550
1998
  ],
1551
1999
  default: 'uploadPhotos',
1552
2000
  displayOptions: { show: { resource: ['uploads'] } },
@@ -1561,15 +2009,21 @@ class UploadPost {
1561
2009
  { name: 'Edit Scheduled Post', value: 'editScheduled', action: 'Edit scheduled post', description: 'Edit schedule details (like date/time) by job ID' },
1562
2010
  { name: 'Get Analytics', value: 'getAnalytics', action: 'Get analytics', description: 'Retrieve aggregated analytics for uploads' },
1563
2011
  { name: 'Get Cached Post Analytics', value: 'getCachedPostAnalytics', action: 'Get cached post analytics', description: 'Replay per-post metrics already fetched for a profile instead of querying the platforms again, so it is not subject to the live analytics rate limit (100 requests / 5 minutes). Only contains posts previously fetched through Get Post Analytics; there is no background refresh, so captured_at is the last time that post was read live. Use Get Post Analytics to refresh a post, and this operation for bulk re-reads.' },
2012
+ { name: 'Get Google Business Locations', value: 'getGoogleBusinessLocations', action: 'Get google business locations', description: 'List Google Business Profile locations for a profile' },
1564
2013
  { name: 'Get Job Status', value: 'getJobStatus', action: 'Get job status', description: 'Check the status of a scheduled or queued post using the job_id' },
2014
+ { name: 'Get Media', value: 'getMedia', action: 'Get media', description: 'List published media for a connected network (LinkedIn, Facebook, Instagram, YouTube, and others the API exposes)' },
1565
2015
  { name: 'Get Platform Metrics', value: 'getPlatformMetrics', action: 'Get platform metrics', description: 'List the analytics metrics available for each platform' },
1566
2016
  { name: 'Get Post Analytics', value: 'getPostAnalytics', action: 'Get post analytics', description: 'Retrieve per-post analytics for an upload using its request_id. On TikTok post_metrics also carries retention, impression_sources, audience_types, new_followers, reach and the watch times.' },
1567
2017
  { name: 'Get Post Analytics by Platform ID', value: 'getPostAnalyticsByPlatformId', action: 'Get post analytics by platform id', description: 'Retrieve per-post analytics using the native platform post ID, for posts not published through Upload-Post' },
1568
2018
  { name: 'Get Reddit Detailed Posts', value: 'getRedditDetailedPosts', action: 'Get reddit detailed posts', description: 'Retrieve detailed Reddit posts with full media information' },
2019
+ { name: 'Get TikTok Locations', value: 'getTiktokLocations', action: 'Get tiktok locations', description: 'Search TikTok locations for a profile to use as tiktok_location_id' },
2020
+ { name: 'Get TikTok Publishing Settings', value: 'getTiktokSettings', action: 'Get tiktok publishing settings', description: 'Read the TikTok creator info and capabilities for a profile (privacy levels, music, comments, draft, ...)' },
2021
+ { name: 'Get TikTok Trending Music', value: 'getTiktokTrendingMusic', action: 'Get tiktok trending music', description: 'List trending TikTok tracks for a connected profile' },
1569
2022
  { name: 'Get Total Impressions', value: 'getTotalImpressions', action: 'Get total impressions', description: 'Retrieve impressions aggregated across connected platforms for a date range' },
1570
2023
  { name: 'Get Upload History', value: 'getHistory', action: 'Get upload history', description: 'List past uploads with optional filters' },
1571
2024
  { name: 'Get Upload Status', value: 'getStatus', action: 'Get upload status', description: 'Check the status of an upload using the request_id' },
1572
2025
  { name: 'List Scheduled Posts', value: 'listScheduled', action: 'List scheduled posts', description: 'List your scheduled (future) posts' },
2026
+ { name: 'Search TikTok Music', value: 'searchTiktokMusic', action: 'Search tiktok music', description: 'Search TikTok music by query for a connected profile' },
1573
2027
  ],
1574
2028
  default: 'getStatus',
1575
2029
  displayOptions: { show: { resource: ['monitoring'] } },
@@ -1586,6 +2040,7 @@ class UploadPost {
1586
2040
  { name: 'Get Notification Preferences', value: 'getNotificationPrefs', action: 'Get notification preferences', description: 'Get current webhook and notification settings' },
1587
2041
  { name: 'Get User Preferences', value: 'getUserPreferences', action: 'Get user preferences', description: 'Get user preferences including calendar week start day' },
1588
2042
  { name: 'List Users', value: 'listUsers', action: 'List users', description: 'List Upload-Post users (profiles)' },
2043
+ { name: 'Test Notifications', value: 'testNotifications', action: 'Test notifications', description: 'Send a test event to the configured webhook and notification channels' },
1589
2044
  { name: 'Update Notification Preferences', value: 'updateNotificationPrefs', action: 'Update notification preferences', description: 'Configure webhook URL and event types for real-time notifications (upload_completed, social_account.connected, social_account.disconnected, social_account.reauth_required)' },
1590
2045
  { name: 'Update User Preferences', value: 'updateUserPreferences', action: 'Update user preferences', description: 'Update user preferences including calendar week start day (0=Sunday, 1=Monday)' },
1591
2046
  { name: 'Validate JWT (for Platform Integration)', value: 'validateJwt', action: 'Validate jwt for platform integration', description: 'Validate a connection token from your backend. Only needed for custom platform integration.' },
@@ -1600,6 +2055,8 @@ class UploadPost {
1600
2055
  noDataExpression: true,
1601
2056
  options: [
1602
2057
  { name: 'Comment Action', value: 'commentAction', action: 'Act on a comment', description: 'Moderate one comment: hide, unhide, like, unlike, pin or unpin it. Platform says which connected network the comment lives on. Post ID is required to hide, unhide, pin or unpin, and is never sent for like or unlike.' },
2058
+ { name: 'Create Comment', value: 'createComment', action: 'Create a comment', description: 'Post a comment or a reply. Instagram only supports replies (comment ID required). TikTok always needs the video ID, plus comment ID to reply.' },
2059
+ { name: 'Delete Comment', value: 'deleteComment', action: 'Delete a comment', description: 'Delete a comment you own or that is on your post' },
1603
2060
  { name: 'Get Post Comments', value: 'getPostComments', action: 'Get post comments', description: 'Retrieve the comments on a post from the network given by Platform (Instagram, Facebook, YouTube, LinkedIn or TikTok). Fill Comment ID to get the replies to that comment instead of the top-level comments of the post.' },
1604
2061
  { name: 'Private Reply to Comment', value: 'privateReplyToComment', action: 'Private reply to comment', description: 'Send a private reply (DM) to the author of a comment. Instagram only.' },
1605
2062
  { name: 'Public Reply to Comment', value: 'publicReplyToComment', action: 'Public reply to comment', description: 'Post a public reply visible under the original comment. Instagram only.' },
@@ -1619,7 +2076,7 @@ class UploadPost {
1619
2076
  displayOptions: {
1620
2077
  show: {
1621
2078
  resource: ['instagram'],
1622
- operation: ['getPostComments', 'privateReplyToComment', 'publicReplyToComment', 'commentAction'],
2079
+ operation: ['getPostComments', 'privateReplyToComment', 'publicReplyToComment', 'commentAction', 'createComment', 'deleteComment'],
1623
2080
  },
1624
2081
  },
1625
2082
  },
@@ -1628,10 +2085,13 @@ class UploadPost {
1628
2085
  name: 'commentPlatform',
1629
2086
  type: 'options',
1630
2087
  options: [
2088
+ { name: 'Bluesky', value: 'bluesky' },
1631
2089
  { name: 'Facebook', value: 'facebook' },
1632
2090
  { name: 'Instagram', value: 'instagram' },
1633
2091
  { name: 'LinkedIn', value: 'linkedin' },
2092
+ { name: 'Threads', value: 'threads' },
1634
2093
  { name: 'TikTok', value: 'tiktok' },
2094
+ { name: 'X (Twitter)', value: 'x' },
1635
2095
  { name: 'YouTube', value: 'youtube' },
1636
2096
  ],
1637
2097
  default: 'instagram',
@@ -1639,7 +2099,7 @@ class UploadPost {
1639
2099
  displayOptions: {
1640
2100
  show: {
1641
2101
  resource: ['instagram'],
1642
- operation: ['getPostComments'],
2102
+ operation: ['getPostComments', 'createComment', 'deleteComment'],
1643
2103
  },
1644
2104
  },
1645
2105
  },
@@ -1743,45 +2203,225 @@ class UploadPost {
1743
2203
  },
1744
2204
  },
1745
2205
  },
2206
+ {
2207
+ displayName: 'Comment ID',
2208
+ name: 'createCommentCommentId',
2209
+ type: 'string',
2210
+ default: '',
2211
+ description: 'Reply to this comment. Required for Instagram. On TikTok add it together with Post ID to reply instead of posting a top-level comment.',
2212
+ displayOptions: {
2213
+ show: {
2214
+ resource: ['instagram'],
2215
+ operation: ['createComment', 'deleteComment'],
2216
+ },
2217
+ },
2218
+ },
2219
+ {
2220
+ displayName: 'Post ID',
2221
+ name: 'createCommentPostId',
2222
+ type: 'string',
2223
+ default: '',
2224
+ description: 'Native post ID for a top-level comment. Required on TikTok (video ID) even when replying. LinkedIn uses the post URN.',
2225
+ displayOptions: {
2226
+ show: {
2227
+ resource: ['instagram'],
2228
+ operation: ['createComment', 'deleteComment'],
2229
+ },
2230
+ },
2231
+ },
2232
+ {
2233
+ displayName: 'Post URL',
2234
+ name: 'createCommentPostUrl',
2235
+ type: 'string',
2236
+ default: '',
2237
+ description: 'Alternative to Post ID for a top-level comment. Ignored when Post ID is set.',
2238
+ displayOptions: {
2239
+ show: {
2240
+ resource: ['instagram'],
2241
+ operation: ['createComment'],
2242
+ },
2243
+ },
2244
+ },
2245
+ {
2246
+ displayName: 'Message',
2247
+ name: 'createCommentMessage',
2248
+ type: 'string',
2249
+ required: true,
2250
+ default: '',
2251
+ description: 'Comment text to publish',
2252
+ typeOptions: { rows: 3 },
2253
+ displayOptions: {
2254
+ show: {
2255
+ resource: ['instagram'],
2256
+ operation: ['createComment'],
2257
+ },
2258
+ },
2259
+ },
1746
2260
  {
1747
2261
  displayName: 'Operation',
1748
2262
  name: 'operation',
1749
2263
  type: 'options',
1750
2264
  noDataExpression: true,
1751
2265
  options: [
1752
- { name: 'Get Audience', value: 'getAudience', action: 'Get audience', description: 'Ask a connected network who follows the profile: audience countries, cities, age brackets and genders, how many followers are online each hour, daily followers gained and lost, profile actions and the bio. Platform says which network answers. Pass a Benchmark Category to also get that niche averages (comments, engagement rate, follower count and growth, likes, shares, video count and views) next to the numbers of the account; every response lists the 25 accepted categories in benchmark_categories. Use this to know WHO the audience is and WHEN to post; use Get Post Analytics for how a given post did.' },
1753
- { name: 'Get Suggestions', value: 'getSuggestions', action: 'Get suggestions', description: 'Ask a connected network what to write about: hashtags (each with its view count) or the searches people run, around a seed word. Type picks which of the two, Platform says which network answers. Use this before writing a caption to pick hashtags or find the wording an audience searches for.' },
2266
+ { name: 'Edit Post', value: 'editPost', action: 'Edit a published post', description: 'Update caption or metadata on a live post. Fields you omit are left unchanged.' },
2267
+ { name: 'Repost', value: 'repostPost', action: 'Repost a post', description: 'Repost on LinkedIn or X' },
2268
+ { name: 'Retry Post', value: 'retryPost', action: 'Retry a failed upload', description: 'Re-enqueue platforms that failed on an upload without re-uploading media. Provide request ID or job ID.' },
2269
+ { name: 'Save Pin', value: 'savePin', action: 'Save a pinterest pin', description: 'Save a Pinterest pin to a board' },
2270
+ { name: 'Unpublish Post', value: 'unpublishPost', action: 'Unpublish a post', description: 'Delete a live post from a platform. Instagram, TikTok and Threads are not supported.' },
1754
2271
  ],
1755
- default: 'getAudience',
1756
- displayOptions: { show: { resource: ['insights'] } },
2272
+ default: 'retryPost',
2273
+ displayOptions: { show: { resource: ['postActions'] } },
1757
2274
  },
1758
2275
  {
1759
2276
  displayName: 'User Identifier Name or ID',
1760
- name: 'insightsUser',
2277
+ name: 'postActionUser',
1761
2278
  type: 'options',
1762
2279
  noDataExpression: true,
1763
2280
  required: true,
1764
2281
  default: '',
1765
- description: 'Upload-Post profile whose connected account answers the question. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
2282
+ description: 'Choose from your created profiles. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
1766
2283
  typeOptions: { loadOptionsMethod: 'getUserProfiles' },
1767
- displayOptions: { show: { resource: ['insights'] } },
2284
+ displayOptions: {
2285
+ show: {
2286
+ resource: ['postActions'],
2287
+ operation: ['unpublishPost', 'editPost', 'repostPost', 'savePin'],
2288
+ },
2289
+ },
1768
2290
  },
1769
2291
  {
1770
2292
  displayName: 'Platform',
1771
- name: 'insightsPlatform',
2293
+ name: 'postActionPlatform',
1772
2294
  type: 'options',
1773
2295
  required: true,
1774
2296
  options: [
1775
- { name: 'TikTok', value: 'tiktok' },
2297
+ { name: 'Bluesky', value: 'bluesky' },
2298
+ { name: 'Discord', value: 'discord' },
2299
+ { name: 'Facebook', value: 'facebook' },
2300
+ { name: 'Google Business', value: 'google_business' },
2301
+ { name: 'LinkedIn', value: 'linkedin' },
2302
+ { name: 'Mastodon', value: 'mastodon' },
2303
+ { name: 'Pinterest', value: 'pinterest' },
2304
+ { name: 'Telegram', value: 'telegram' },
2305
+ { name: 'WordPress', value: 'wordpress' },
2306
+ { name: 'X (Twitter)', value: 'x' },
2307
+ { name: 'YouTube', value: 'youtube' },
1776
2308
  ],
1777
- default: 'tiktok',
1778
- description: 'Network that answers the question. TikTok is the network that answers this question today; any other one replies with platform_not_supported and the list of the ones that can. On TikTok the profile needs the "profile_analytics" capability (see the capabilities array returned by List Users).',
1779
- displayOptions: { show: { resource: ['insights'] } },
2309
+ default: 'facebook',
2310
+ description: 'Network to act on. Unpublish is not available for Instagram, TikTok or Threads.',
2311
+ displayOptions: {
2312
+ show: {
2313
+ resource: ['postActions'],
2314
+ operation: ['unpublishPost', 'editPost'],
2315
+ },
2316
+ },
1780
2317
  },
1781
2318
  {
1782
- displayName: 'Start Date',
1783
- name: 'audienceStartDate',
1784
- type: 'string',
2319
+ displayName: 'Platform',
2320
+ name: 'repostPlatform',
2321
+ type: 'options',
2322
+ required: true,
2323
+ options: [
2324
+ { name: 'LinkedIn', value: 'linkedin' },
2325
+ { name: 'X (Twitter)', value: 'x' },
2326
+ ],
2327
+ default: 'linkedin',
2328
+ description: 'Network to repost on',
2329
+ displayOptions: { show: { resource: ['postActions'], operation: ['repostPost'] } },
2330
+ },
2331
+ {
2332
+ displayName: 'Request ID',
2333
+ name: 'retryRequestId',
2334
+ type: 'string',
2335
+ default: '',
2336
+ description: 'Request ID of the original upload. Provide this or Job ID.',
2337
+ displayOptions: { show: { resource: ['postActions'], operation: ['retryPost'] } },
2338
+ },
2339
+ {
2340
+ displayName: 'Job ID',
2341
+ name: 'retryJobId',
2342
+ type: 'string',
2343
+ default: '',
2344
+ description: 'Scheduled job ID of the original upload. Alternative to Request ID.',
2345
+ displayOptions: { show: { resource: ['postActions'], operation: ['retryPost'] } },
2346
+ },
2347
+ {
2348
+ displayName: 'Post ID',
2349
+ name: 'postActionPostId',
2350
+ type: 'string',
2351
+ required: true,
2352
+ default: '',
2353
+ description: 'Native ID of the published post on the target network',
2354
+ displayOptions: {
2355
+ show: {
2356
+ resource: ['postActions'],
2357
+ operation: ['unpublishPost', 'editPost', 'repostPost', 'savePin'],
2358
+ },
2359
+ },
2360
+ },
2361
+ {
2362
+ displayName: 'Message',
2363
+ name: 'postActionMessage',
2364
+ type: 'string',
2365
+ default: '',
2366
+ description: 'New caption. Facebook uses message, X uses text, LinkedIn uses commentary.',
2367
+ displayOptions: { show: { resource: ['postActions'], operation: ['editPost', 'repostPost'] } },
2368
+ },
2369
+ {
2370
+ displayName: 'Pinterest Board ID',
2371
+ name: 'savePinBoardId',
2372
+ type: 'string',
2373
+ required: true,
2374
+ default: '',
2375
+ description: 'Board to save the pin to',
2376
+ displayOptions: { show: { resource: ['postActions'], operation: ['savePin'] } },
2377
+ },
2378
+ {
2379
+ displayName: 'Pinterest Board Section ID',
2380
+ name: 'savePinBoardSectionId',
2381
+ type: 'string',
2382
+ default: '',
2383
+ description: 'Optional board section to save the pin to',
2384
+ displayOptions: { show: { resource: ['postActions'], operation: ['savePin'] } },
2385
+ },
2386
+ {
2387
+ displayName: 'Operation',
2388
+ name: 'operation',
2389
+ type: 'options',
2390
+ noDataExpression: true,
2391
+ options: [
2392
+ { name: 'Get Audience', value: 'getAudience', action: 'Get audience', description: 'Ask a connected network who follows the profile: audience countries, cities, age brackets and genders, how many followers are online each hour, daily followers gained and lost, profile actions and the bio. Platform says which network answers. Pass a Benchmark Category to also get that niche averages (comments, engagement rate, follower count and growth, likes, shares, video count and views) next to the numbers of the account; every response lists the 25 accepted categories in benchmark_categories. Use this to know WHO the audience is and WHEN to post; use Get Post Analytics for how a given post did.' },
2393
+ { name: 'Get Suggestions', value: 'getSuggestions', action: 'Get suggestions', description: 'Ask a connected network what to write about: hashtags (each with its view count) or the searches people run, around a seed word. Type picks which of the two, Platform says which network answers. Use this before writing a caption to pick hashtags or find the wording an audience searches for.' },
2394
+ ],
2395
+ default: 'getAudience',
2396
+ displayOptions: { show: { resource: ['insights'] } },
2397
+ },
2398
+ {
2399
+ displayName: 'User Identifier Name or ID',
2400
+ name: 'insightsUser',
2401
+ type: 'options',
2402
+ noDataExpression: true,
2403
+ required: true,
2404
+ default: '',
2405
+ description: 'Upload-Post profile whose connected account answers the question. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
2406
+ typeOptions: { loadOptionsMethod: 'getUserProfiles' },
2407
+ displayOptions: { show: { resource: ['insights'] } },
2408
+ },
2409
+ {
2410
+ displayName: 'Platform',
2411
+ name: 'insightsPlatform',
2412
+ type: 'options',
2413
+ required: true,
2414
+ options: [
2415
+ { name: 'TikTok', value: 'tiktok' },
2416
+ ],
2417
+ default: 'tiktok',
2418
+ description: 'Network that answers the question. TikTok is the network that answers this question today; any other one replies with platform_not_supported and the list of the ones that can. On TikTok the profile needs the "profile_analytics" capability (see the capabilities array returned by List Users).',
2419
+ displayOptions: { show: { resource: ['insights'] } },
2420
+ },
2421
+ {
2422
+ displayName: 'Start Date',
2423
+ name: 'audienceStartDate',
2424
+ type: 'string',
1785
2425
  default: '',
1786
2426
  placeholder: 'YYYY-MM-DD',
1787
2427
  description: 'First day of the window. The server clamps the range to 60 days at most and always below today, so a wider window is trimmed instead of rejected. Leave empty for the default range.',
@@ -1901,6 +2541,22 @@ class UploadPost {
1901
2541
  description: 'Text to post as the first comment (or reply) immediately after publishing. Supported on Instagram, Facebook, X, Threads, YouTube, Reddit, Bluesky, LinkedIn and TikTok. On TikTok the profile needs the "comments" capability (see the capabilities array returned by List Users).',
1902
2542
  displayOptions: { show: { resource: ['uploads'], operation: ['uploadPhotos', 'uploadVideo', 'uploadText'] } },
1903
2543
  },
2544
+ {
2545
+ displayName: 'First Comment Media URLs',
2546
+ name: 'firstCommentMedia',
2547
+ type: 'string',
2548
+ default: '',
2549
+ description: 'Comma-separated media URLs to attach to the first comment, when the platform accepts it',
2550
+ displayOptions: { show: { resource: ['uploads'], operation: ['uploadPhotos', 'uploadVideo', 'uploadText'] } },
2551
+ },
2552
+ {
2553
+ displayName: 'Reply To ID',
2554
+ name: 'replyToId',
2555
+ type: 'string',
2556
+ default: '',
2557
+ description: 'ID of an existing post to reply to. X uses a tweet ID; Bluesky uses a post URL or AT-URI.',
2558
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['x', 'bluesky', '__manual_platform__'] } },
2559
+ },
1904
2560
  {
1905
2561
  displayName: 'Alt Text (Extended)',
1906
2562
  name: 'altText',
@@ -2662,6 +3318,112 @@ class UploadPost {
2662
3318
  description: 'Profile username whose Reddit posts you want',
2663
3319
  displayOptions: { show: { operation: ['getRedditDetailedPosts'] } },
2664
3320
  },
3321
+ {
3322
+ displayName: 'User Identifier Name or ID',
3323
+ name: 'mediaUser',
3324
+ type: 'options',
3325
+ noDataExpression: true,
3326
+ required: true,
3327
+ default: '',
3328
+ description: 'Choose from your created profiles. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
3329
+ typeOptions: { loadOptionsMethod: 'getUserProfiles' },
3330
+ displayOptions: { show: { operation: ['getMedia'] } },
3331
+ },
3332
+ {
3333
+ displayName: 'Platform',
3334
+ name: 'mediaPlatform',
3335
+ type: 'string',
3336
+ required: true,
3337
+ default: '',
3338
+ description: 'Network to list media from (e.g. linkedin, facebook, instagram, youtube)',
3339
+ displayOptions: { show: { operation: ['getMedia'] } },
3340
+ },
3341
+ {
3342
+ displayName: 'Page URN',
3343
+ name: 'mediaPageUrn',
3344
+ type: 'string',
3345
+ default: '',
3346
+ description: 'Optional LinkedIn page URN when listing page media',
3347
+ displayOptions: { show: { operation: ['getMedia'] } },
3348
+ },
3349
+ {
3350
+ displayName: 'Limit',
3351
+ name: 'mediaLimit',
3352
+ type: 'number',
3353
+ default: 0,
3354
+ description: 'Max items to return. 0 uses the API default.',
3355
+ displayOptions: { show: { operation: ['getMedia'] } },
3356
+ },
3357
+ {
3358
+ displayName: 'Cursor',
3359
+ name: 'mediaCursor',
3360
+ type: 'string',
3361
+ default: '',
3362
+ description: 'Pagination cursor from a previous Get Media response',
3363
+ displayOptions: { show: { operation: ['getMedia'] } },
3364
+ },
3365
+ {
3366
+ displayName: 'User Identifier Name or ID',
3367
+ name: 'gbpLocationsProfile',
3368
+ type: 'options',
3369
+ noDataExpression: true,
3370
+ default: '',
3371
+ description: 'Profile whose Google Business locations to list. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
3372
+ typeOptions: { loadOptionsMethod: 'getUserProfiles' },
3373
+ displayOptions: { show: { operation: ['getGoogleBusinessLocations'] } },
3374
+ },
3375
+ {
3376
+ displayName: 'User Identifier Name or ID',
3377
+ name: 'tiktokDiscoveryProfile',
3378
+ type: 'options',
3379
+ noDataExpression: true,
3380
+ required: true,
3381
+ default: '',
3382
+ description: 'TikTok-connected profile. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
3383
+ typeOptions: { loadOptionsMethod: 'getUserProfiles' },
3384
+ displayOptions: { show: { operation: ['getTiktokTrendingMusic', 'searchTiktokMusic', 'getTiktokLocations', 'getTiktokSettings'] } },
3385
+ },
3386
+ {
3387
+ displayName: 'Query',
3388
+ name: 'tiktokMusicQuery',
3389
+ type: 'string',
3390
+ default: '',
3391
+ description: 'Search text for TikTok music',
3392
+ displayOptions: { show: { operation: ['searchTiktokMusic'] } },
3393
+ },
3394
+ {
3395
+ displayName: 'Query',
3396
+ name: 'tiktokLocationQuery',
3397
+ type: 'string',
3398
+ required: true,
3399
+ default: '',
3400
+ description: 'Search text for TikTok locations',
3401
+ displayOptions: { show: { operation: ['getTiktokLocations'] } },
3402
+ },
3403
+ {
3404
+ displayName: 'Genre',
3405
+ name: 'tiktokMusicGenre',
3406
+ type: 'string',
3407
+ default: '',
3408
+ description: 'Optional TikTok music genre filter',
3409
+ displayOptions: { show: { operation: ['getTiktokTrendingMusic', 'searchTiktokMusic'] } },
3410
+ },
3411
+ {
3412
+ displayName: 'Country Code',
3413
+ name: 'tiktokMusicCountryCode',
3414
+ type: 'string',
3415
+ default: '',
3416
+ description: 'Optional country code for TikTok music (e.g. US, ES)',
3417
+ displayOptions: { show: { operation: ['getTiktokTrendingMusic', 'searchTiktokMusic'] } },
3418
+ },
3419
+ {
3420
+ displayName: 'Limit',
3421
+ name: 'tiktokMusicLimit',
3422
+ type: 'number',
3423
+ default: 0,
3424
+ description: 'Max tracks to return on search. 0 uses the API default.',
3425
+ displayOptions: { show: { operation: ['searchTiktokMusic'] } },
3426
+ },
2665
3427
  {
2666
3428
  displayName: 'New User Identifier',
2667
3429
  name: 'newUser',
@@ -2713,13 +3475,26 @@ class UploadPost {
2713
3475
  name: 'jwtPlatforms',
2714
3476
  type: 'multiOptions',
2715
3477
  options: [
3478
+ { name: 'Bluesky', value: 'bluesky' },
3479
+ { name: 'Dev.to', value: 'devto' },
2716
3480
  { name: 'Discord', value: 'discord' },
2717
3481
  { name: 'Facebook', value: 'facebook' },
3482
+ { name: 'Google Business', value: 'google_business' },
3483
+ { name: 'Hashnode', value: 'hashnode' },
2718
3484
  { name: 'Instagram', value: 'instagram' },
3485
+ { name: 'Lemmy', value: 'lemmy' },
2719
3486
  { name: 'LinkedIn', value: 'linkedin' },
3487
+ { name: 'Listmonk', value: 'listmonk' },
3488
+ { name: 'Mastodon', value: 'mastodon' },
3489
+ { name: 'Nostr', value: 'nostr' },
3490
+ { name: 'Pinterest', value: 'pinterest' },
3491
+ { name: 'Reddit', value: 'reddit' },
3492
+ { name: 'Slack', value: 'slack' },
2720
3493
  { name: 'Telegram', value: 'telegram' },
2721
3494
  { name: 'Threads', value: 'threads' },
2722
3495
  { name: 'TikTok', value: 'tiktok' },
3496
+ { name: 'Whop', value: 'whop' },
3497
+ { name: 'WordPress', value: 'wordpress' },
2723
3498
  { name: 'X (Twitter)', value: 'x' },
2724
3499
  { name: 'YouTube', value: 'youtube' },
2725
3500
  ],
@@ -2966,6 +3741,38 @@ class UploadPost {
2966
3741
  },
2967
3742
  },
2968
3743
  },
3744
+ {
3745
+ displayName: 'Facebook Place ID',
3746
+ name: 'facebookPlaceId',
3747
+ type: 'string',
3748
+ default: '',
3749
+ description: 'Facebook place ID to tag',
3750
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['facebook', '__manual_platform__'] } },
3751
+ },
3752
+ {
3753
+ displayName: 'Facebook Alt Text',
3754
+ name: 'facebookAltText',
3755
+ type: 'string',
3756
+ default: '',
3757
+ description: 'Alt text for Facebook photos',
3758
+ displayOptions: { show: { operation: ['uploadPhotos'], platform: ['facebook', '__manual_platform__'] } },
3759
+ },
3760
+ {
3761
+ displayName: 'Facebook Is AI Generated',
3762
+ name: 'facebookIsAiGenerated',
3763
+ type: 'boolean',
3764
+ default: false,
3765
+ description: 'Whether to disclose the Facebook video as AI-generated',
3766
+ displayOptions: { show: { operation: ['uploadVideo'], platform: ['facebook', '__manual_platform__'] } },
3767
+ },
3768
+ {
3769
+ displayName: 'Facebook Call to Action',
3770
+ name: 'facebookCallToAction',
3771
+ type: 'string',
3772
+ default: '',
3773
+ description: 'JSON call-to-action object for a Facebook text post',
3774
+ displayOptions: { show: { operation: ['uploadText'], platform: ['facebook', '__manual_platform__'] } },
3775
+ },
2969
3776
  {
2970
3777
  displayName: 'LinkedIn Link (Text)',
2971
3778
  name: 'linkedinLink',
@@ -2979,6 +3786,38 @@ class UploadPost {
2979
3786
  },
2980
3787
  },
2981
3788
  },
3789
+ {
3790
+ displayName: 'LinkedIn Alt Text',
3791
+ name: 'linkedinAltText',
3792
+ type: 'string',
3793
+ default: '',
3794
+ description: 'Alt text for LinkedIn media',
3795
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['linkedin', '__manual_platform__'] } },
3796
+ },
3797
+ {
3798
+ displayName: 'LinkedIn Disable Reshare',
3799
+ name: 'linkedinDisableReshare',
3800
+ type: 'boolean',
3801
+ default: false,
3802
+ description: 'Whether to disable resharing of the LinkedIn post',
3803
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText', 'uploadDocument'], platform: ['linkedin', '__manual_platform__'] } },
3804
+ },
3805
+ {
3806
+ displayName: 'LinkedIn Link Title',
3807
+ name: 'linkedinLinkTitle',
3808
+ type: 'string',
3809
+ default: '',
3810
+ description: 'Override title of the LinkedIn link preview card',
3811
+ displayOptions: { show: { operation: ['uploadText'], platform: ['linkedin', '__manual_platform__'] } },
3812
+ },
3813
+ {
3814
+ displayName: 'LinkedIn Link Description',
3815
+ name: 'linkedinLinkDescription',
3816
+ type: 'string',
3817
+ default: '',
3818
+ description: 'Override description of the LinkedIn link preview card',
3819
+ displayOptions: { show: { operation: ['uploadText'], platform: ['linkedin', '__manual_platform__'] } },
3820
+ },
2982
3821
  {
2983
3822
  displayName: 'Bluesky Link (Text)',
2984
3823
  name: 'blueskyLink',
@@ -3399,6 +4238,32 @@ class UploadPost {
3399
4238
  }
3400
4239
  },
3401
4240
  },
4241
+ {
4242
+ displayName: 'TikTok Ads Only',
4243
+ name: 'tiktokIsAdsOnly',
4244
+ type: 'boolean',
4245
+ default: false,
4246
+ description: 'Whether to mark the TikTok video as ads-only',
4247
+ displayOptions: {
4248
+ show: {
4249
+ operation: ['uploadVideo'],
4250
+ platform: ['tiktok', '__manual_platform__']
4251
+ }
4252
+ },
4253
+ },
4254
+ {
4255
+ displayName: 'TikTok TTO Invite Link',
4256
+ name: 'tiktokTtoInviteLink',
4257
+ type: 'string',
4258
+ default: '',
4259
+ description: 'TikTok One invite link for branded content',
4260
+ displayOptions: {
4261
+ show: {
4262
+ operation: ['uploadVideo'],
4263
+ platform: ['tiktok', '__manual_platform__']
4264
+ }
4265
+ },
4266
+ },
3402
4267
  {
3403
4268
  displayName: 'Instagram Media Type',
3404
4269
  name: 'instagramMediaType',
@@ -3521,6 +4386,14 @@ class UploadPost {
3521
4386
  }
3522
4387
  },
3523
4388
  },
4389
+ {
4390
+ displayName: 'Instagram Alt Text',
4391
+ name: 'instagramAltText',
4392
+ type: 'string',
4393
+ default: '',
4394
+ description: 'Alt text for Instagram photos',
4395
+ displayOptions: { show: { operation: ['uploadPhotos'], platform: ['instagram', '__manual_platform__'] } },
4396
+ },
3524
4397
  {
3525
4398
  displayName: 'Threads Long Text as Single Post',
3526
4399
  name: 'threadsLongTextAsPost',
@@ -3551,36 +4424,84 @@ class UploadPost {
3551
4424
  displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['threads', '__manual_platform__'] } },
3552
4425
  },
3553
4426
  {
3554
- displayName: 'Google Business Location ID',
3555
- name: 'gbpLocationId',
4427
+ displayName: 'Threads Reply Control',
4428
+ name: 'threadsReplyControl',
3556
4429
  type: 'string',
3557
4430
  default: '',
3558
- description: 'Location ID for accounts with multiple Google Business Profile locations (e.g., accounts/123/locations/456). If omitted, uses the default connected location.',
3559
- displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4431
+ description: 'Who can reply to the Threads post',
4432
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['threads', '__manual_platform__'] } },
3560
4433
  },
3561
4434
  {
3562
- displayName: 'Google Business Post Type',
3563
- name: 'gbpTopicType',
3564
- type: 'options',
3565
- options: [
3566
- { name: 'Standard', value: 'STANDARD' },
3567
- { name: 'Event', value: 'EVENT' },
3568
- { name: 'Offer', value: 'OFFER' },
3569
- ],
3570
- default: 'STANDARD',
3571
- description: 'Kind of Google Business post to publish',
3572
- displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4435
+ displayName: 'Threads Alt Text',
4436
+ name: 'threadsAltText',
4437
+ type: 'string',
4438
+ default: '',
4439
+ description: 'Alt text for Threads media',
4440
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['threads', '__manual_platform__'] } },
3573
4441
  },
3574
4442
  {
3575
- displayName: 'Google Business Media URL',
3576
- name: 'gbpMediaUrl',
4443
+ displayName: 'Threads Reply To ID',
4444
+ name: 'threadsReplyToId',
3577
4445
  type: 'string',
3578
4446
  default: '',
3579
- description: 'URL of the media attached to the Google Business post',
3580
- displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4447
+ description: 'Threads post ID to reply to',
4448
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['threads', '__manual_platform__'] } },
3581
4449
  },
3582
4450
  {
3583
- displayName: 'Google Business Media Format',
4451
+ displayName: 'Threads Quote Post ID',
4452
+ name: 'threadsQuotePostId',
4453
+ type: 'string',
4454
+ default: '',
4455
+ description: 'Threads post ID to quote',
4456
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['threads', '__manual_platform__'] } },
4457
+ },
4458
+ {
4459
+ displayName: 'Threads Link Attachment',
4460
+ name: 'threadsLinkAttachment',
4461
+ type: 'string',
4462
+ default: '',
4463
+ description: 'URL to attach to a Threads text post',
4464
+ displayOptions: { show: { operation: ['uploadText'], platform: ['threads', '__manual_platform__'] } },
4465
+ },
4466
+ {
4467
+ displayName: 'Threads Poll Options',
4468
+ name: 'threadsPollOptions',
4469
+ type: 'string',
4470
+ default: '',
4471
+ description: 'Comma-separated poll options for a Threads post',
4472
+ displayOptions: { show: { operation: ['uploadText'], platform: ['threads', '__manual_platform__'] } },
4473
+ },
4474
+ {
4475
+ displayName: 'Google Business Location ID',
4476
+ name: 'gbpLocationId',
4477
+ type: 'string',
4478
+ default: '',
4479
+ description: 'Location ID for accounts with multiple Google Business Profile locations (e.g., accounts/123/locations/456). If omitted, uses the default connected location.',
4480
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4481
+ },
4482
+ {
4483
+ displayName: 'Google Business Post Type',
4484
+ name: 'gbpTopicType',
4485
+ type: 'options',
4486
+ options: [
4487
+ { name: 'Standard', value: 'STANDARD' },
4488
+ { name: 'Event', value: 'EVENT' },
4489
+ { name: 'Offer', value: 'OFFER' },
4490
+ ],
4491
+ default: 'STANDARD',
4492
+ description: 'Kind of Google Business post to publish',
4493
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4494
+ },
4495
+ {
4496
+ displayName: 'Google Business Media URL',
4497
+ name: 'gbpMediaUrl',
4498
+ type: 'string',
4499
+ default: '',
4500
+ description: 'URL of the media attached to the Google Business post',
4501
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4502
+ },
4503
+ {
4504
+ displayName: 'Google Business Media Format',
3584
4505
  name: 'gbpMediaFormat',
3585
4506
  type: 'options',
3586
4507
  options: [
@@ -3722,6 +4643,530 @@ class UploadPost {
3722
4643
  description: 'Terms and conditions of the offer',
3723
4644
  displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
3724
4645
  },
4646
+ {
4647
+ displayName: 'Google Business Language Code',
4648
+ name: 'gbpLanguageCode',
4649
+ type: 'string',
4650
+ default: '',
4651
+ description: 'Language code for the Google Business post (e.g. en, es)',
4652
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
4653
+ },
4654
+ {
4655
+ displayName: 'Bluesky Alt Text',
4656
+ name: 'blueskyAltText',
4657
+ type: 'string',
4658
+ default: '',
4659
+ description: 'Alt text for Bluesky images',
4660
+ displayOptions: { show: { operation: ['uploadPhotos'], platform: ['bluesky', '__manual_platform__'] } },
4661
+ },
4662
+ {
4663
+ displayName: 'Bluesky Languages',
4664
+ name: 'blueskyLangs',
4665
+ type: 'string',
4666
+ default: '',
4667
+ description: 'Comma-separated language codes for the Bluesky post (e.g. en, es)',
4668
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['bluesky', '__manual_platform__'] } },
4669
+ },
4670
+ {
4671
+ displayName: 'Bluesky Labels',
4672
+ name: 'blueskyLabels',
4673
+ type: 'string',
4674
+ default: '',
4675
+ description: 'Content labels for the Bluesky post',
4676
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['bluesky', '__manual_platform__'] } },
4677
+ },
4678
+ {
4679
+ displayName: 'Bluesky Threadgate',
4680
+ name: 'blueskyThreadgate',
4681
+ type: 'string',
4682
+ default: '',
4683
+ description: 'Who can reply (threadgate) on Bluesky',
4684
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['bluesky', '__manual_platform__'] } },
4685
+ },
4686
+ {
4687
+ displayName: 'Bluesky Quote URI',
4688
+ name: 'blueskyQuoteUri',
4689
+ type: 'string',
4690
+ default: '',
4691
+ description: 'AT-URI or URL of a Bluesky post to quote',
4692
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['bluesky', '__manual_platform__'] } },
4693
+ },
4694
+ {
4695
+ displayName: 'Discord Thread ID',
4696
+ name: 'discordThreadId',
4697
+ type: 'string',
4698
+ default: '',
4699
+ description: 'Existing Discord thread ID to post into',
4700
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['discord', '__manual_platform__'] } },
4701
+ },
4702
+ {
4703
+ displayName: 'Discord Thread Name',
4704
+ name: 'discordThreadName',
4705
+ type: 'string',
4706
+ default: '',
4707
+ description: 'Name of a new Discord thread to create with this post',
4708
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['discord', '__manual_platform__'] } },
4709
+ },
4710
+ {
4711
+ displayName: 'Discord Username',
4712
+ name: 'discordUsername',
4713
+ type: 'string',
4714
+ default: '',
4715
+ description: 'Webhook username override',
4716
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['discord', '__manual_platform__'] } },
4717
+ },
4718
+ {
4719
+ displayName: 'Discord Avatar URL',
4720
+ name: 'discordAvatarUrl',
4721
+ type: 'string',
4722
+ default: '',
4723
+ description: 'Webhook avatar URL override',
4724
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['discord', '__manual_platform__'] } },
4725
+ },
4726
+ {
4727
+ displayName: 'Discord Embeds',
4728
+ name: 'discordEmbeds',
4729
+ type: 'string',
4730
+ default: '',
4731
+ description: 'JSON array of Discord embeds',
4732
+ displayOptions: { show: { operation: ['uploadText'], platform: ['discord', '__manual_platform__'] } },
4733
+ },
4734
+ {
4735
+ displayName: 'Discord Alt Text',
4736
+ name: 'discordAltText',
4737
+ type: 'string',
4738
+ default: '',
4739
+ description: 'Alt text for Discord attachments',
4740
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['discord', '__manual_platform__'] } },
4741
+ },
4742
+ {
4743
+ displayName: 'Discord TTS',
4744
+ name: 'discordTts',
4745
+ type: 'boolean',
4746
+ default: false,
4747
+ description: 'Whether to send the Discord message as text-to-speech',
4748
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['discord', '__manual_platform__'] } },
4749
+ },
4750
+ {
4751
+ displayName: 'Telegram Parse Mode',
4752
+ name: 'telegramParseMode',
4753
+ type: 'options',
4754
+ options: [
4755
+ { name: 'HTML', value: 'HTML' },
4756
+ { name: 'Markdown', value: 'Markdown' },
4757
+ { name: 'MarkdownV2', value: 'MarkdownV2' },
4758
+ { name: 'None', value: '' },
4759
+ ],
4760
+ default: '',
4761
+ description: 'How Telegram should parse the caption',
4762
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['telegram', '__manual_platform__'] } },
4763
+ },
4764
+ {
4765
+ displayName: 'Telegram Message Thread ID',
4766
+ name: 'telegramMessageThreadId',
4767
+ type: 'string',
4768
+ default: '',
4769
+ description: 'Forum topic thread ID',
4770
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['telegram', '__manual_platform__'] } },
4771
+ },
4772
+ {
4773
+ displayName: 'Telegram Disable Notification',
4774
+ name: 'telegramDisableNotification',
4775
+ type: 'boolean',
4776
+ default: false,
4777
+ description: 'Whether to send the Telegram message silently',
4778
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['telegram', '__manual_platform__'] } },
4779
+ },
4780
+ {
4781
+ displayName: 'Telegram Protect Content',
4782
+ name: 'telegramProtectContent',
4783
+ type: 'boolean',
4784
+ default: false,
4785
+ description: 'Whether to forbid forwarding and saving of the Telegram message',
4786
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['telegram', '__manual_platform__'] } },
4787
+ },
4788
+ {
4789
+ displayName: 'Telegram Has Spoiler',
4790
+ name: 'telegramHasSpoiler',
4791
+ type: 'boolean',
4792
+ default: false,
4793
+ description: 'Whether to mark Telegram media as a spoiler',
4794
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['telegram', '__manual_platform__'] } },
4795
+ },
4796
+ {
4797
+ displayName: 'Telegram As Document',
4798
+ name: 'telegramAsDocument',
4799
+ type: 'boolean',
4800
+ default: false,
4801
+ description: 'Whether to send the file as a document instead of media',
4802
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['telegram', '__manual_platform__'] } },
4803
+ },
4804
+ {
4805
+ displayName: 'Mastodon Visibility',
4806
+ name: 'mastodonVisibility',
4807
+ type: 'options',
4808
+ options: [
4809
+ { name: 'Account Default', value: '' },
4810
+ { name: 'Direct', value: 'direct' },
4811
+ { name: 'Private', value: 'private' },
4812
+ { name: 'Public', value: 'public' },
4813
+ { name: 'Unlisted', value: 'unlisted' },
4814
+ ],
4815
+ default: '',
4816
+ description: 'Mastodon post visibility',
4817
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4818
+ },
4819
+ {
4820
+ displayName: 'Mastodon Sensitive',
4821
+ name: 'mastodonSensitive',
4822
+ type: 'boolean',
4823
+ default: false,
4824
+ description: 'Whether to mark the Mastodon post as sensitive',
4825
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4826
+ },
4827
+ {
4828
+ displayName: 'Mastodon Spoiler Text',
4829
+ name: 'mastodonSpoilerText',
4830
+ type: 'string',
4831
+ default: '',
4832
+ description: 'Content warning shown before the Mastodon post',
4833
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4834
+ },
4835
+ {
4836
+ displayName: 'Mastodon Language',
4837
+ name: 'mastodonLanguage',
4838
+ type: 'string',
4839
+ default: '',
4840
+ description: 'ISO language code for the Mastodon post',
4841
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4842
+ },
4843
+ {
4844
+ displayName: 'Mastodon Alt Text',
4845
+ name: 'mastodonAltText',
4846
+ type: 'string',
4847
+ default: '',
4848
+ description: 'Alt text for Mastodon media',
4849
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['mastodon', '__manual_platform__'] } },
4850
+ },
4851
+ {
4852
+ displayName: 'Mastodon Poll Options',
4853
+ name: 'mastodonPollOptions',
4854
+ type: 'string',
4855
+ default: '',
4856
+ description: 'Comma-separated poll options for a Mastodon text post',
4857
+ displayOptions: { show: { operation: ['uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4858
+ },
4859
+ {
4860
+ displayName: 'Mastodon Poll Expires In',
4861
+ name: 'mastodonPollExpiresIn',
4862
+ type: 'number',
4863
+ default: 0,
4864
+ description: 'Poll duration in seconds. 0 means no poll expiry override.',
4865
+ displayOptions: { show: { operation: ['uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4866
+ },
4867
+ {
4868
+ displayName: 'Mastodon Poll Multiple',
4869
+ name: 'mastodonPollMultiple',
4870
+ type: 'boolean',
4871
+ default: false,
4872
+ description: 'Whether the Mastodon poll allows multiple choices',
4873
+ displayOptions: { show: { operation: ['uploadText'], platform: ['mastodon', '__manual_platform__'] } },
4874
+ },
4875
+ {
4876
+ displayName: 'WordPress Status',
4877
+ name: 'wordpressStatus',
4878
+ type: 'options',
4879
+ options: [
4880
+ { name: 'Draft', value: 'draft' },
4881
+ { name: 'Not Set', value: '' },
4882
+ { name: 'Pending', value: 'pending' },
4883
+ { name: 'Private', value: 'private' },
4884
+ { name: 'Publish', value: 'publish' },
4885
+ ],
4886
+ default: '',
4887
+ description: 'WordPress post status',
4888
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4889
+ },
4890
+ {
4891
+ displayName: 'WordPress Date',
4892
+ name: 'wordpressDate',
4893
+ type: 'string',
4894
+ default: '',
4895
+ description: 'WordPress publication date (ISO-8601)',
4896
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4897
+ },
4898
+ {
4899
+ displayName: 'WordPress Categories',
4900
+ name: 'wordpressCategories',
4901
+ type: 'string',
4902
+ default: '',
4903
+ description: 'Comma-separated WordPress category IDs or names',
4904
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4905
+ },
4906
+ {
4907
+ displayName: 'WordPress Tags',
4908
+ name: 'wordpressTags',
4909
+ type: 'string',
4910
+ default: '',
4911
+ description: 'Comma-separated WordPress tags',
4912
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4913
+ },
4914
+ {
4915
+ displayName: 'WordPress Excerpt',
4916
+ name: 'wordpressExcerpt',
4917
+ type: 'string',
4918
+ default: '',
4919
+ description: 'Short excerpt shown on WordPress archive pages',
4920
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4921
+ },
4922
+ {
4923
+ displayName: 'WordPress Slug',
4924
+ name: 'wordpressSlug',
4925
+ type: 'string',
4926
+ default: '',
4927
+ description: 'WordPress post slug',
4928
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
4929
+ },
4930
+ {
4931
+ displayName: 'WordPress Alt Text',
4932
+ name: 'wordpressAltText',
4933
+ type: 'string',
4934
+ default: '',
4935
+ description: 'Alt text for WordPress media',
4936
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['wordpress', '__manual_platform__'] } },
4937
+ },
4938
+ {
4939
+ displayName: 'Lemmy Community',
4940
+ name: 'lemmyCommunity',
4941
+ type: 'string',
4942
+ default: '',
4943
+ description: 'Lemmy community name or ID',
4944
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['lemmy', '__manual_platform__'] } },
4945
+ },
4946
+ {
4947
+ displayName: 'Lemmy URL',
4948
+ name: 'lemmyUrl',
4949
+ type: 'string',
4950
+ default: '',
4951
+ description: 'Optional link URL for a Lemmy post',
4952
+ displayOptions: { show: { operation: ['uploadText'], platform: ['lemmy', '__manual_platform__'] } },
4953
+ },
4954
+ {
4955
+ displayName: 'Lemmy NSFW',
4956
+ name: 'lemmyNsfw',
4957
+ type: 'boolean',
4958
+ default: false,
4959
+ description: 'Whether to mark the Lemmy post as NSFW',
4960
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['lemmy', '__manual_platform__'] } },
4961
+ },
4962
+ {
4963
+ displayName: 'Lemmy Alt Text',
4964
+ name: 'lemmyAltText',
4965
+ type: 'string',
4966
+ default: '',
4967
+ description: 'Alt text for Lemmy images',
4968
+ displayOptions: { show: { operation: ['uploadPhotos'], platform: ['lemmy', '__manual_platform__'] } },
4969
+ },
4970
+ {
4971
+ displayName: 'Slack Markdown',
4972
+ name: 'slackMarkdown',
4973
+ type: 'boolean',
4974
+ default: false,
4975
+ description: 'Whether to send the Slack message as markdown',
4976
+ displayOptions: { show: { operation: ['uploadText'], platform: ['slack', '__manual_platform__'] } },
4977
+ },
4978
+ {
4979
+ displayName: 'Slack Blocks',
4980
+ name: 'slackBlocks',
4981
+ type: 'string',
4982
+ default: '',
4983
+ description: 'JSON Slack Block Kit payload',
4984
+ displayOptions: { show: { operation: ['uploadText'], platform: ['slack', '__manual_platform__'] } },
4985
+ },
4986
+ {
4987
+ displayName: 'Slack Mrkdwn',
4988
+ name: 'slackMrkdwn',
4989
+ type: 'boolean',
4990
+ default: false,
4991
+ description: 'Whether to enable Slack mrkdwn formatting',
4992
+ displayOptions: { show: { operation: ['uploadText'], platform: ['slack', '__manual_platform__'] } },
4993
+ },
4994
+ {
4995
+ displayName: 'Nostr Kind',
4996
+ name: 'nostrKind',
4997
+ type: 'string',
4998
+ default: '',
4999
+ description: 'Nostr event kind. Leave empty for a short note.',
5000
+ displayOptions: { show: { operation: ['uploadText'], platform: ['nostr', '__manual_platform__'] } },
5001
+ },
5002
+ {
5003
+ displayName: 'Nostr Long Form',
5004
+ name: 'nostrLongForm',
5005
+ type: 'boolean',
5006
+ default: false,
5007
+ description: 'Whether to publish as a Nostr long-form article',
5008
+ displayOptions: { show: { operation: ['uploadText'], platform: ['nostr', '__manual_platform__'] } },
5009
+ },
5010
+ {
5011
+ displayName: 'Dev.to Tags',
5012
+ name: 'devtoTags',
5013
+ type: 'string',
5014
+ default: '',
5015
+ description: 'Comma-separated Dev.to tags',
5016
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5017
+ },
5018
+ {
5019
+ displayName: 'Dev.to Canonical URL',
5020
+ name: 'devtoCanonicalUrl',
5021
+ type: 'string',
5022
+ default: '',
5023
+ description: 'Canonical URL if the article was originally published elsewhere',
5024
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5025
+ },
5026
+ {
5027
+ displayName: 'Dev.to Description',
5028
+ name: 'devtoDescription',
5029
+ type: 'string',
5030
+ default: '',
5031
+ description: 'Dev.to article description / subtitle',
5032
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5033
+ },
5034
+ {
5035
+ displayName: 'Dev.to Main Image',
5036
+ name: 'devtoMainImage',
5037
+ type: 'string',
5038
+ default: '',
5039
+ description: 'Cover image URL for the Dev.to article',
5040
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5041
+ },
5042
+ {
5043
+ displayName: 'Dev.to Series',
5044
+ name: 'devtoSeries',
5045
+ type: 'string',
5046
+ default: '',
5047
+ description: 'Dev.to series name',
5048
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5049
+ },
5050
+ {
5051
+ displayName: 'Dev.to Published',
5052
+ name: 'devtoPublished',
5053
+ type: 'boolean',
5054
+ default: false,
5055
+ description: 'Whether to publish the Dev.to article immediately instead of saving it as a draft',
5056
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
5057
+ },
5058
+ {
5059
+ displayName: 'Hashnode Tags',
5060
+ name: 'hashnodeTags',
5061
+ type: 'string',
5062
+ default: '',
5063
+ description: 'Comma-separated Hashnode tags',
5064
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
5065
+ },
5066
+ {
5067
+ displayName: 'Hashnode Subtitle',
5068
+ name: 'hashnodeSubtitle',
5069
+ type: 'string',
5070
+ default: '',
5071
+ description: 'Hashnode article subtitle',
5072
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
5073
+ },
5074
+ {
5075
+ displayName: 'Hashnode Cover Image URL',
5076
+ name: 'hashnodeCoverImageUrl',
5077
+ type: 'string',
5078
+ default: '',
5079
+ description: 'Cover image URL for the Hashnode article',
5080
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
5081
+ },
5082
+ {
5083
+ displayName: 'Hashnode Body',
5084
+ name: 'hashnodeBody',
5085
+ type: 'string',
5086
+ default: '',
5087
+ description: 'Markdown body of the Hashnode article. The title field is used as the article title.',
5088
+ typeOptions: { rows: 6 },
5089
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
5090
+ },
5091
+ {
5092
+ displayName: 'Hashnode Draft',
5093
+ name: 'hashnodeDraft',
5094
+ type: 'boolean',
5095
+ default: false,
5096
+ description: 'Whether to save the Hashnode article as a draft',
5097
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
5098
+ },
5099
+ {
5100
+ displayName: 'Whop Body',
5101
+ name: 'whopBody',
5102
+ type: 'string',
5103
+ default: '',
5104
+ description: 'Whop post body',
5105
+ typeOptions: { rows: 4 },
5106
+ displayOptions: { show: { operation: ['uploadText'], platform: ['whop', '__manual_platform__'] } },
5107
+ },
5108
+ {
5109
+ displayName: 'Whop Pinned',
5110
+ name: 'whopPinned',
5111
+ type: 'boolean',
5112
+ default: false,
5113
+ description: 'Whether to pin the Whop post',
5114
+ displayOptions: { show: { operation: ['uploadText'], platform: ['whop', '__manual_platform__'] } },
5115
+ },
5116
+ {
5117
+ displayName: 'Whop Paywall Amount',
5118
+ name: 'whopPaywallAmount',
5119
+ type: 'string',
5120
+ default: '',
5121
+ description: 'Paywall amount for the Whop post',
5122
+ displayOptions: { show: { operation: ['uploadText'], platform: ['whop', '__manual_platform__'] } },
5123
+ },
5124
+ {
5125
+ displayName: 'Whop Paywall Currency',
5126
+ name: 'whopPaywallCurrency',
5127
+ type: 'string',
5128
+ default: '',
5129
+ description: 'Paywall currency code (e.g. USD)',
5130
+ displayOptions: { show: { operation: ['uploadText'], platform: ['whop', '__manual_platform__'] } },
5131
+ },
5132
+ {
5133
+ displayName: 'Listmonk Content Type',
5134
+ name: 'listmonkContentType',
5135
+ type: 'options',
5136
+ options: [
5137
+ { name: 'HTML', value: 'html' },
5138
+ { name: 'Markdown', value: 'markdown' },
5139
+ { name: 'Not Set', value: '' },
5140
+ { name: 'Plain', value: 'plain' },
5141
+ ],
5142
+ default: '',
5143
+ description: 'Listmonk campaign content type',
5144
+ displayOptions: { show: { operation: ['uploadText'], platform: ['listmonk', '__manual_platform__'] } },
5145
+ },
5146
+ {
5147
+ displayName: 'Listmonk Send At',
5148
+ name: 'listmonkSendAt',
5149
+ type: 'string',
5150
+ default: '',
5151
+ description: 'When to send the Listmonk campaign (ISO-8601)',
5152
+ displayOptions: { show: { operation: ['uploadText'], platform: ['listmonk', '__manual_platform__'] } },
5153
+ },
5154
+ {
5155
+ displayName: 'Listmonk Lists',
5156
+ name: 'listmonkLists',
5157
+ type: 'string',
5158
+ default: '',
5159
+ description: 'Comma-separated Listmonk list IDs',
5160
+ displayOptions: { show: { operation: ['uploadText'], platform: ['listmonk', '__manual_platform__'] } },
5161
+ },
5162
+ {
5163
+ displayName: 'Listmonk Template ID',
5164
+ name: 'listmonkTemplateId',
5165
+ type: 'string',
5166
+ default: '',
5167
+ description: 'Template ID used by Listmonk for the campaign',
5168
+ displayOptions: { show: { operation: ['uploadText'], platform: ['listmonk', '__manual_platform__'] } },
5169
+ },
3725
5170
  {
3726
5171
  displayName: 'Reddit Subreddit',
3727
5172
  name: 'redditSubreddit',
@@ -3746,6 +5191,30 @@ class UploadPost {
3746
5191
  description: 'URL for a Reddit link post. Creates a link post with URL preview card instead of a text post.',
3747
5192
  displayOptions: { show: { operation: ['uploadText'], platform: ['reddit', '__manual_platform__'] } },
3748
5193
  },
5194
+ {
5195
+ displayName: 'Reddit NSFW',
5196
+ name: 'redditNsfw',
5197
+ type: 'boolean',
5198
+ default: false,
5199
+ description: 'Whether to mark the Reddit post as NSFW',
5200
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['reddit', '__manual_platform__'] } },
5201
+ },
5202
+ {
5203
+ displayName: 'Reddit Spoiler',
5204
+ name: 'redditSpoiler',
5205
+ type: 'boolean',
5206
+ default: false,
5207
+ description: 'Whether to mark the Reddit post as a spoiler',
5208
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['reddit', '__manual_platform__'] } },
5209
+ },
5210
+ {
5211
+ displayName: 'Reddit Flair Text',
5212
+ name: 'redditFlairText',
5213
+ type: 'string',
5214
+ default: '',
5215
+ description: 'Flair text when a flair ID is not used',
5216
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['reddit', '__manual_platform__'] } },
5217
+ },
3749
5218
  {
3750
5219
  displayName: 'YouTube Tags',
3751
5220
  name: 'youtubeTags',
@@ -4002,6 +5471,32 @@ class UploadPost {
4002
5471
  },
4003
5472
  },
4004
5473
  },
5474
+ {
5475
+ displayName: 'YouTube Notify Subscribers',
5476
+ name: 'youtubeNotifySubscribers',
5477
+ type: 'boolean',
5478
+ default: true,
5479
+ description: 'Whether YouTube should notify subscribers when the video is published',
5480
+ displayOptions: {
5481
+ show: {
5482
+ operation: ['uploadVideo'],
5483
+ platform: ['youtube', '__manual_platform__']
5484
+ },
5485
+ },
5486
+ },
5487
+ {
5488
+ displayName: 'YouTube Publish At',
5489
+ name: 'youtubePublishAt',
5490
+ type: 'string',
5491
+ default: '',
5492
+ description: 'Schedule the YouTube video to go public at this ISO-8601 datetime. Privacy should be private.',
5493
+ displayOptions: {
5494
+ show: {
5495
+ operation: ['uploadVideo'],
5496
+ platform: ['youtube', '__manual_platform__']
5497
+ },
5498
+ },
5499
+ },
4005
5500
  {
4006
5501
  displayName: 'Pinterest Board Name or ID',
4007
5502
  name: 'pinterestBoardId',
@@ -4046,6 +5541,19 @@ class UploadPost {
4046
5541
  }
4047
5542
  },
4048
5543
  },
5544
+ {
5545
+ displayName: 'Pinterest Board Section ID',
5546
+ name: 'pinterestBoardSectionId',
5547
+ type: 'string',
5548
+ default: '',
5549
+ description: 'Optional Pinterest board section ID',
5550
+ displayOptions: {
5551
+ show: {
5552
+ operation: ['uploadPhotos', 'uploadVideo'],
5553
+ platform: ['pinterest', '__manual_platform__']
5554
+ }
5555
+ },
5556
+ },
4049
5557
  {
4050
5558
  displayName: 'Pinterest Cover Image URL (Video)',
4051
5559
  name: 'pinterestCoverImageUrl',
@@ -4338,6 +5846,47 @@ class UploadPost {
4338
5846
  },
4339
5847
  },
4340
5848
  },
5849
+ {
5850
+ displayName: 'X Paid Partnership',
5851
+ name: 'xPaidPartnership',
5852
+ type: 'boolean',
5853
+ default: false,
5854
+ description: 'Whether to mark the X post as a paid partnership',
5855
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['x', '__manual_platform__'] } },
5856
+ },
5857
+ {
5858
+ displayName: 'X Alt Text',
5859
+ name: 'xAltText',
5860
+ type: 'string',
5861
+ default: '',
5862
+ description: 'Alt text for X images',
5863
+ displayOptions: { show: { operation: ['uploadPhotos'], platform: ['x', '__manual_platform__'] } },
5864
+ },
5865
+ {
5866
+ displayName: 'X Subtitles URL',
5867
+ name: 'xSubtitlesUrl',
5868
+ type: 'string',
5869
+ default: '',
5870
+ description: 'URL of a subtitles file for the X video',
5871
+ displayOptions: { show: { operation: ['uploadVideo'], platform: ['x', '__manual_platform__'] } },
5872
+ },
5873
+ {
5874
+ displayName: 'X Article Title',
5875
+ name: 'xArticleTitle',
5876
+ type: 'string',
5877
+ default: '',
5878
+ description: 'Title for an X article post',
5879
+ displayOptions: { show: { operation: ['uploadText'], platform: ['x', '__manual_platform__'] } },
5880
+ },
5881
+ {
5882
+ displayName: 'X Article Body',
5883
+ name: 'xArticleBody',
5884
+ type: 'string',
5885
+ default: '',
5886
+ description: 'Body of an X article post',
5887
+ typeOptions: { rows: 4 },
5888
+ displayOptions: { show: { operation: ['uploadText'], platform: ['x', '__manual_platform__'] } },
5889
+ },
4341
5890
  {
4342
5891
  displayName: 'LinkedIn Page ID',
4343
5892
  name: 'targetLinkedinPageIdManualEntry',