n8n-nodes-upload-post 0.1.51 → 0.1.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,7 +71,7 @@ The node provides the following operations grouped for clarity:
71
71
  - **Get Upload History**: List past uploads.
72
72
  - Parameters: Page (default 1), Limit (default 20). Limit can be 20, 50, or 100.
73
73
  - **Get Analytics**: Retrieve aggregated profile analytics.
74
- - Parameters: Profile Username, Platforms (required — at least one).
74
+ - Parameters: Profile Username, Platforms (required — at least one), Facebook Page ID (required when Facebook is selected), LinkedIn Page URN (optional).
75
75
  - Supported: Facebook, Instagram, LinkedIn, Pinterest, Reddit, Threads, TikTok, X, YouTube. Analytics are not available for Bluesky, Discord, Google Business or Telegram.
76
76
  - **Get Post Analytics**: Per-post metrics for an upload, by `request_id`.
77
77
  - Parameters: Request ID, Platform (optional filter).
@@ -71,6 +71,21 @@ const ensureArrayFromCommaSeparated = (value) => {
71
71
  .filter(item => item.length > 0);
72
72
  };
73
73
  const TERMINAL_UPLOAD_STATUSES = ['completed', 'failed', 'error', 'retryable', 'scheduled', 'not_found'];
74
+ const fetchNotificationChannels = async (ctx) => {
75
+ var _a, _b;
76
+ try {
77
+ const current = await ctx.node.helpers.httpRequestWithAuthentication.call(ctx.node, 'uploadPostApi', {
78
+ url: `${API_BASE_URL}/uploadposts/users/notifications`,
79
+ method: 'GET',
80
+ json: true,
81
+ });
82
+ const channels = (_a = current === null || current === void 0 ? void 0 : current.notifications) === null || _a === void 0 ? void 0 : _a.channels;
83
+ return (_b = channels) !== null && _b !== void 0 ? _b : {};
84
+ }
85
+ catch {
86
+ return {};
87
+ }
88
+ };
74
89
  const buildIdempotencyKey = (ctx) => {
75
90
  var _a;
76
91
  const override = String((_a = ctx.node.getNodeParameter('idempotencyKey', ctx.itemIndex, '')) !== null && _a !== void 0 ? _a : '').trim();
@@ -102,9 +117,9 @@ const getBinaryFieldFromItem = async (ctx, propertyName, errorLabel) => {
102
117
  }
103
118
  };
104
119
  const PLATFORM_SUPPORT = {
105
- uploadPhotos: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit', 'google_business'],
106
- uploadVideo: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'youtube', 'google_business'],
107
- uploadText: ['bluesky', 'discord', 'facebook', 'linkedin', 'reddit', 'telegram', 'threads', 'x', 'google_business'],
120
+ uploadPhotos: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit', 'google_business', 'mastodon', 'lemmy', 'wordpress'],
121
+ uploadVideo: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'reddit', 'telegram', 'threads', 'tiktok', 'x', 'youtube', 'google_business', 'mastodon', 'wordpress'],
122
+ uploadText: ['bluesky', 'discord', 'facebook', 'linkedin', 'reddit', 'telegram', 'threads', 'x', 'google_business', 'slack', 'mastodon', 'nostr', 'lemmy', 'devto', 'hashnode', 'wordpress', 'whop', 'listmonk'],
108
123
  uploadDocument: ['linkedin'],
109
124
  };
110
125
  const DESCRIPTION_ENABLED_PLATFORMS = new Set(['linkedin', 'facebook', 'youtube', 'pinterest', 'tiktok']);
@@ -118,6 +133,15 @@ const TITLE_OVERRIDES = [
118
133
  { platform: 'youtube', param: 'youtubeTitle', field: 'youtube_title', operations: ['uploadVideo'] },
119
134
  { platform: 'pinterest', param: 'pinterestTitle', field: 'pinterest_title' },
120
135
  { platform: 'threads', param: 'threadsTitle', field: 'threads_title' },
136
+ { platform: 'slack', param: 'slackTitle', field: 'slack_title' },
137
+ { platform: 'mastodon', param: 'mastodonTitle', field: 'mastodon_title' },
138
+ { platform: 'nostr', param: 'nostrTitle', field: 'nostr_title' },
139
+ { platform: 'lemmy', param: 'lemmyTitle', field: 'lemmy_title' },
140
+ { platform: 'devto', param: 'devtoTitle', field: 'devto_title' },
141
+ { platform: 'hashnode', param: 'hashnodeTitle', field: 'hashnode_title' },
142
+ { platform: 'wordpress', param: 'wordpressTitle', field: 'wordpress_title' },
143
+ { platform: 'whop', param: 'whopTitle', field: 'whop_title' },
144
+ { platform: 'listmonk', param: 'listmonkTitle', field: 'listmonk_title' },
121
145
  ];
122
146
  const DESCRIPTION_OVERRIDES = [
123
147
  { platform: 'linkedin', param: 'linkedinDescription', field: 'linkedin_description', operations: ['uploadPhotos', 'uploadVideo'] },
@@ -662,6 +686,49 @@ const applyGoogleBusinessOptions = (ctx, _operation, formData) => {
662
686
  const locationId = ctx.node.getNodeParameter('gbpLocationId', ctx.itemIndex, '');
663
687
  if (locationId)
664
688
  formData.gbp_location_id = locationId;
689
+ const topicType = ctx.node.getNodeParameter('gbpTopicType', ctx.itemIndex, '');
690
+ if (topicType)
691
+ formData.gbp_topic_type = topicType;
692
+ const mediaUrl = ctx.node.getNodeParameter('gbpMediaUrl', ctx.itemIndex, '');
693
+ if (mediaUrl)
694
+ formData.gbp_media_url = mediaUrl;
695
+ const mediaFormat = ctx.node.getNodeParameter('gbpMediaFormat', ctx.itemIndex, '');
696
+ if (mediaFormat)
697
+ formData.gbp_media_format = mediaFormat;
698
+ const ctaType = ctx.node.getNodeParameter('gbpCtaType', ctx.itemIndex, '');
699
+ if (ctaType)
700
+ formData.gbp_cta_type = ctaType;
701
+ const ctaUrl = ctx.node.getNodeParameter('gbpCtaUrl', ctx.itemIndex, '');
702
+ if (ctaUrl)
703
+ formData.gbp_cta_url = ctaUrl;
704
+ if (topicType === 'EVENT') {
705
+ const eventTitle = ctx.node.getNodeParameter('gbpEventTitle', ctx.itemIndex, '');
706
+ if (eventTitle)
707
+ formData.gbp_event_title = eventTitle;
708
+ const startDate = ctx.node.getNodeParameter('gbpEventStartDate', ctx.itemIndex, '');
709
+ if (startDate)
710
+ formData.gbp_event_start_date = startDate;
711
+ const startTime = ctx.node.getNodeParameter('gbpEventStartTime', ctx.itemIndex, '');
712
+ if (startTime)
713
+ formData.gbp_event_start_time = startTime;
714
+ const endDate = ctx.node.getNodeParameter('gbpEventEndDate', ctx.itemIndex, '');
715
+ if (endDate)
716
+ formData.gbp_event_end_date = endDate;
717
+ const endTime = ctx.node.getNodeParameter('gbpEventEndTime', ctx.itemIndex, '');
718
+ if (endTime)
719
+ formData.gbp_event_end_time = endTime;
720
+ }
721
+ if (topicType === 'OFFER') {
722
+ const coupon = ctx.node.getNodeParameter('gbpOfferCoupon', ctx.itemIndex, '');
723
+ if (coupon)
724
+ formData.gbp_offer_coupon = coupon;
725
+ const redeemUrl = ctx.node.getNodeParameter('gbpOfferRedeemUrl', ctx.itemIndex, '');
726
+ if (redeemUrl)
727
+ formData.gbp_offer_redeem_url = redeemUrl;
728
+ const terms = ctx.node.getNodeParameter('gbpOfferTerms', ctx.itemIndex, '');
729
+ if (terms)
730
+ formData.gbp_offer_terms = terms;
731
+ }
665
732
  };
666
733
  const applyRedditOptions = (ctx, operation, formData) => {
667
734
  const subreddit = ctx.node.getNodeParameter('redditSubreddit', ctx.itemIndex);
@@ -854,6 +921,15 @@ const buildMonitoringRequest = (ctx) => {
854
921
  });
855
922
  }
856
923
  const qs = { platforms: analyticsPlatforms.join(',') };
924
+ const analyticsPageId = ctx.node.getNodeParameter('analyticsPageId', ctx.itemIndex, '');
925
+ if (analyticsPlatforms.includes('facebook') && !analyticsPageId) {
926
+ throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), 'Facebook analytics require a Page ID.', { itemIndex: ctx.itemIndex });
927
+ }
928
+ if (analyticsPageId)
929
+ qs.page_id = analyticsPageId;
930
+ const analyticsPageUrn = ctx.node.getNodeParameter('analyticsPageUrn', ctx.itemIndex, '');
931
+ if (analyticsPageUrn)
932
+ qs.page_urn = analyticsPageUrn;
857
933
  return {
858
934
  endpoint: `/analytics/${encodeURIComponent(profileUsername)}`,
859
935
  method: 'GET',
@@ -957,14 +1033,14 @@ const buildMonitoringRequest = (ctx) => {
957
1033
  const body = {};
958
1034
  if (normalizedDate) {
959
1035
  body.scheduled_date = normalizedDate;
960
- const newTimezone = ctx.node.getNodeParameter("newTimezone", ctx.itemIndex, "");
961
- if (newTimezone) {
962
- body.timezone = newTimezone;
963
- }
1036
+ }
1037
+ const newTimezone = ctx.node.getNodeParameter('newTimezone', ctx.itemIndex, '');
1038
+ if (newTimezone) {
1039
+ body.timezone = newTimezone;
964
1040
  }
965
1041
  return {
966
1042
  endpoint: `/uploadposts/schedule/${jobId}`,
967
- method: 'POST',
1043
+ method: 'PATCH',
968
1044
  body,
969
1045
  isUploadOperation: false,
970
1046
  waitForCompletion: false,
@@ -976,7 +1052,7 @@ const buildMonitoringRequest = (ctx) => {
976
1052
  });
977
1053
  }
978
1054
  };
979
- const buildUserRequest = (ctx) => {
1055
+ const buildUserRequest = async (ctx) => {
980
1056
  switch (ctx.operation) {
981
1057
  case 'listUsers':
982
1058
  return {
@@ -1045,9 +1121,9 @@ const buildUserRequest = (ctx) => {
1045
1121
  const jwt = ctx.node.getNodeParameter('jwtToken', ctx.itemIndex);
1046
1122
  return {
1047
1123
  endpoint: '/uploadposts/users/validate-jwt',
1048
- method: 'POST',
1049
- body: { jwt },
1124
+ method: 'GET',
1050
1125
  headers: { Authorization: `Bearer ${jwt}` },
1126
+ skipCredentialAuth: true,
1051
1127
  isUploadOperation: false,
1052
1128
  waitForCompletion: false,
1053
1129
  };
@@ -1065,13 +1141,15 @@ const buildUserRequest = (ctx) => {
1065
1141
  const webhookUrl = ctx.node.getNodeParameter('webhookUrl', ctx.itemIndex, '');
1066
1142
  const webhookEnabled = ctx.node.getNodeParameter('webhookEnabled', ctx.itemIndex, false);
1067
1143
  const webhookEventsRaw = ctx.node.getNodeParameter('webhookEvents', ctx.itemIndex, []);
1144
+ const existingChannels = await fetchNotificationChannels(ctx);
1068
1145
  const body = {
1069
- channels: { webhook: webhookEnabled },
1146
+ channels: { ...existingChannels, webhook: webhookEnabled },
1070
1147
  };
1071
1148
  if (webhookUrl)
1072
1149
  body.webhook_url = webhookUrl;
1073
- if (webhookEventsRaw.length > 0)
1074
- body.webhook_events = webhookEventsRaw;
1150
+ if (webhookEventsRaw.length > 0) {
1151
+ body.webhook_events = Object.fromEntries(webhookEventsRaw.map(event => [event, true]));
1152
+ }
1075
1153
  return {
1076
1154
  endpoint: '/uploadposts/users/notifications',
1077
1155
  method: 'POST',
@@ -1092,7 +1170,7 @@ const buildUserRequest = (ctx) => {
1092
1170
  const weekStartDay = ctx.node.getNodeParameter('weekStartDay', ctx.itemIndex, '');
1093
1171
  const body = {};
1094
1172
  if (weekStartDay !== '')
1095
- body.week_start_day = parseInt(weekStartDay, 10);
1173
+ body.weekStartDay = parseInt(weekStartDay, 10);
1096
1174
  return {
1097
1175
  endpoint: '/uploadposts/users/preferences',
1098
1176
  method: 'POST',
@@ -1178,7 +1256,7 @@ const buildRequestConfig = async (ctx) => {
1178
1256
  return buildMonitoringRequest(ctx);
1179
1257
  }
1180
1258
  if (resource === 'users') {
1181
- return buildUserRequest(ctx);
1259
+ return await buildUserRequest(ctx);
1182
1260
  }
1183
1261
  throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported operation: ${ctx.operation}`, {
1184
1262
  itemIndex: ctx.itemIndex,
@@ -1548,6 +1626,78 @@ class UploadPost {
1548
1626
  description: 'Optional override for Threads title',
1549
1627
  displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['threads', '__manual_platform__'] } },
1550
1628
  },
1629
+ {
1630
+ displayName: 'Slack Title (Override)',
1631
+ name: 'slackTitle',
1632
+ type: 'string',
1633
+ default: '',
1634
+ description: 'Optional override for Slack title',
1635
+ displayOptions: { show: { operation: ['uploadText'], platform: ['slack', '__manual_platform__'] } },
1636
+ },
1637
+ {
1638
+ displayName: 'Mastodon Title (Override)',
1639
+ name: 'mastodonTitle',
1640
+ type: 'string',
1641
+ default: '',
1642
+ description: 'Optional override for Mastodon title',
1643
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['mastodon', '__manual_platform__'] } },
1644
+ },
1645
+ {
1646
+ displayName: 'Nostr Title (Override)',
1647
+ name: 'nostrTitle',
1648
+ type: 'string',
1649
+ default: '',
1650
+ description: 'Optional override for Nostr title',
1651
+ displayOptions: { show: { operation: ['uploadText'], platform: ['nostr', '__manual_platform__'] } },
1652
+ },
1653
+ {
1654
+ displayName: 'Lemmy Title (Override)',
1655
+ name: 'lemmyTitle',
1656
+ type: 'string',
1657
+ default: '',
1658
+ description: 'Optional override for Lemmy title',
1659
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadText'], platform: ['lemmy', '__manual_platform__'] } },
1660
+ },
1661
+ {
1662
+ displayName: 'Dev.to Title (Override)',
1663
+ name: 'devtoTitle',
1664
+ type: 'string',
1665
+ default: '',
1666
+ description: 'Optional override for Dev.to title',
1667
+ displayOptions: { show: { operation: ['uploadText'], platform: ['devto', '__manual_platform__'] } },
1668
+ },
1669
+ {
1670
+ displayName: 'Hashnode Title (Override)',
1671
+ name: 'hashnodeTitle',
1672
+ type: 'string',
1673
+ default: '',
1674
+ description: 'Optional override for Hashnode title',
1675
+ displayOptions: { show: { operation: ['uploadText'], platform: ['hashnode', '__manual_platform__'] } },
1676
+ },
1677
+ {
1678
+ displayName: 'WordPress Title (Override)',
1679
+ name: 'wordpressTitle',
1680
+ type: 'string',
1681
+ default: '',
1682
+ description: 'Optional override for WordPress title',
1683
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['wordpress', '__manual_platform__'] } },
1684
+ },
1685
+ {
1686
+ displayName: 'Whop Title (Override)',
1687
+ name: 'whopTitle',
1688
+ type: 'string',
1689
+ default: '',
1690
+ description: 'Optional override for Whop title',
1691
+ displayOptions: { show: { operation: ['uploadText'], platform: ['whop', '__manual_platform__'] } },
1692
+ },
1693
+ {
1694
+ displayName: 'Listmonk Title (Override)',
1695
+ name: 'listmonkTitle',
1696
+ type: 'string',
1697
+ default: '',
1698
+ description: 'Optional override for Listmonk title',
1699
+ displayOptions: { show: { operation: ['uploadText'], platform: ['listmonk', '__manual_platform__'] } },
1700
+ },
1551
1701
  {
1552
1702
  displayName: 'Description (Optional)',
1553
1703
  name: 'description',
@@ -1936,6 +2086,22 @@ class UploadPost {
1936
2086
  description: 'Platforms to fetch analytics for. Analytics are not available for Bluesky, Discord, Google Business or Telegram.',
1937
2087
  displayOptions: { show: { operation: ['getAnalytics'] } },
1938
2088
  },
2089
+ {
2090
+ displayName: 'Facebook Page ID',
2091
+ name: 'analyticsPageId',
2092
+ type: 'string',
2093
+ default: '',
2094
+ description: 'Required when Facebook is among the selected platforms',
2095
+ displayOptions: { show: { operation: ['getAnalytics'] } },
2096
+ },
2097
+ {
2098
+ displayName: 'LinkedIn Page URN',
2099
+ name: 'analyticsPageUrn',
2100
+ type: 'string',
2101
+ default: '',
2102
+ description: 'LinkedIn organization page to report on. Defaults to the personal profile.',
2103
+ displayOptions: { show: { operation: ['getAnalytics'] } },
2104
+ },
1939
2105
  {
1940
2106
  displayName: 'Request ID',
1941
2107
  name: 'postAnalyticsRequestId',
@@ -2808,6 +2974,133 @@ class UploadPost {
2808
2974
  description: 'Location ID for accounts with multiple Google Business Profile locations (e.g., accounts/123/locations/456). If omitted, uses the default connected location.',
2809
2975
  displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
2810
2976
  },
2977
+ {
2978
+ displayName: 'Google Business Post Type',
2979
+ name: 'gbpTopicType',
2980
+ type: 'options',
2981
+ options: [
2982
+ { name: 'Standard', value: 'STANDARD' },
2983
+ { name: 'Event', value: 'EVENT' },
2984
+ { name: 'Offer', value: 'OFFER' },
2985
+ ],
2986
+ default: 'STANDARD',
2987
+ description: 'Kind of Google Business post to publish',
2988
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
2989
+ },
2990
+ {
2991
+ displayName: 'Google Business Media URL',
2992
+ name: 'gbpMediaUrl',
2993
+ type: 'string',
2994
+ default: '',
2995
+ description: 'URL of the media attached to the Google Business post',
2996
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
2997
+ },
2998
+ {
2999
+ displayName: 'Google Business Media Format',
3000
+ name: 'gbpMediaFormat',
3001
+ type: 'options',
3002
+ options: [
3003
+ { name: 'Not Set', value: '' },
3004
+ { name: 'Photo', value: 'PHOTO' },
3005
+ { name: 'Video', value: 'VIDEO' },
3006
+ ],
3007
+ default: '',
3008
+ description: 'Format of the attached media',
3009
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
3010
+ },
3011
+ {
3012
+ displayName: 'Google Business Call to Action',
3013
+ name: 'gbpCtaType',
3014
+ type: 'options',
3015
+ options: [
3016
+ { name: 'Book', value: 'BOOK' },
3017
+ { name: 'Call', value: 'CALL' },
3018
+ { name: 'Learn More', value: 'LEARN_MORE' },
3019
+ { name: 'None', value: '' },
3020
+ { name: 'Order', value: 'ORDER' },
3021
+ { name: 'Shop', value: 'SHOP' },
3022
+ { name: 'Sign Up', value: 'SIGN_UP' },
3023
+ ],
3024
+ default: '',
3025
+ description: 'Button shown under the Google Business post',
3026
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
3027
+ },
3028
+ {
3029
+ displayName: 'Google Business Call to Action URL',
3030
+ name: 'gbpCtaUrl',
3031
+ type: 'string',
3032
+ default: '',
3033
+ description: 'URL the call-to-action button opens',
3034
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
3035
+ },
3036
+ {
3037
+ displayName: 'Google Business Event Title',
3038
+ name: 'gbpEventTitle',
3039
+ type: 'string',
3040
+ default: '',
3041
+ description: 'Title of the event',
3042
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
3043
+ },
3044
+ {
3045
+ displayName: 'Google Business Event Start Date',
3046
+ name: 'gbpEventStartDate',
3047
+ type: 'string',
3048
+ default: '',
3049
+ placeholder: 'YYYY-MM-DD',
3050
+ description: 'Date the event starts',
3051
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
3052
+ },
3053
+ {
3054
+ displayName: 'Google Business Event Start Time',
3055
+ name: 'gbpEventStartTime',
3056
+ type: 'string',
3057
+ default: '',
3058
+ placeholder: 'HH:MM',
3059
+ description: 'Time the event starts',
3060
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
3061
+ },
3062
+ {
3063
+ displayName: 'Google Business Event End Date',
3064
+ name: 'gbpEventEndDate',
3065
+ type: 'string',
3066
+ default: '',
3067
+ placeholder: 'YYYY-MM-DD',
3068
+ description: 'Date the event ends',
3069
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
3070
+ },
3071
+ {
3072
+ displayName: 'Google Business Event End Time',
3073
+ name: 'gbpEventEndTime',
3074
+ type: 'string',
3075
+ default: '',
3076
+ placeholder: 'HH:MM',
3077
+ description: 'Time the event ends',
3078
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
3079
+ },
3080
+ {
3081
+ displayName: 'Google Business Offer Coupon',
3082
+ name: 'gbpOfferCoupon',
3083
+ type: 'string',
3084
+ default: '',
3085
+ description: 'Coupon code for the offer',
3086
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
3087
+ },
3088
+ {
3089
+ displayName: 'Google Business Offer Redeem URL',
3090
+ name: 'gbpOfferRedeemUrl',
3091
+ type: 'string',
3092
+ default: '',
3093
+ description: 'URL where the offer is redeemed',
3094
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
3095
+ },
3096
+ {
3097
+ displayName: 'Google Business Offer Terms',
3098
+ name: 'gbpOfferTerms',
3099
+ type: 'string',
3100
+ default: '',
3101
+ description: 'Terms and conditions of the offer',
3102
+ displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
3103
+ },
2811
3104
  {
2812
3105
  displayName: 'Reddit Subreddit',
2813
3106
  name: 'redditSubreddit',
@@ -3470,11 +3763,21 @@ class UploadPost {
3470
3763
  { name: 'TikTok', value: 'tiktok' },
3471
3764
  { name: 'X (Twitter)', value: 'x' },
3472
3765
  { name: 'YouTube', value: 'youtube' },
3766
+ { name: 'Slack', value: 'slack' },
3767
+ { name: 'Mastodon', value: 'mastodon' },
3768
+ { name: 'Nostr', value: 'nostr' },
3769
+ { name: 'Lemmy', value: 'lemmy' },
3770
+ { name: 'Dev.to', value: 'devto' },
3771
+ { name: 'Hashnode', value: 'hashnode' },
3772
+ { name: 'WordPress', value: 'wordpress' },
3773
+ { name: 'Whop', value: 'whop' },
3774
+ { name: 'Listmonk', value: 'listmonk' },
3473
3775
  ];
3474
3776
  const platformSupport = {
3475
- uploadPhotos: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit'],
3476
- uploadVideo: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'youtube'],
3477
- uploadText: ['bluesky', 'discord', 'facebook', 'google_business', 'linkedin', 'reddit', 'telegram', 'threads', 'x'],
3777
+ uploadPhotos: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit', 'mastodon', 'lemmy', 'wordpress'],
3778
+ uploadVideo: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'reddit', 'telegram', 'threads', 'tiktok', 'x', 'youtube', 'mastodon', 'wordpress'],
3779
+ uploadText: ['bluesky', 'discord', 'facebook', 'google_business', 'linkedin', 'reddit', 'telegram', 'threads', 'x', 'slack', 'mastodon', 'nostr', 'lemmy', 'devto', 'hashnode', 'wordpress', 'whop', 'listmonk'],
3780
+ uploadDocument: ['linkedin'],
3478
3781
  };
3479
3782
  const supportedPlatforms = platformSupport[operation] || [];
3480
3783
  const filtered = allPlatforms.filter(platform => supportedPlatforms.includes(platform.value));
@@ -3639,7 +3942,9 @@ class UploadPost {
3639
3942
  else {
3640
3943
  requestOptions.json = true;
3641
3944
  }
3642
- const rawResponse = await this.helpers.httpRequestWithAuthentication.call(this, 'uploadPostApi', requestOptions);
3945
+ const rawResponse = config.skipCredentialAuth
3946
+ ? await this.helpers.httpRequest(requestOptions)
3947
+ : await this.helpers.httpRequestWithAuthentication.call(this, 'uploadPostApi', requestOptions);
3643
3948
  const responseData = parseJsonIfNeeded(rawResponse);
3644
3949
  let finalData = responseData;
3645
3950
  if (config.isUploadOperation && config.waitForCompletion) {