n8n-nodes-upload-post 0.1.48 → 0.1.52
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.
|
@@ -70,6 +70,30 @@ const ensureArrayFromCommaSeparated = (value) => {
|
|
|
70
70
|
.map(item => item.trim())
|
|
71
71
|
.filter(item => item.length > 0);
|
|
72
72
|
};
|
|
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
|
+
};
|
|
89
|
+
const buildIdempotencyKey = (ctx) => {
|
|
90
|
+
var _a;
|
|
91
|
+
const override = String((_a = ctx.node.getNodeParameter('idempotencyKey', ctx.itemIndex, '')) !== null && _a !== void 0 ? _a : '').trim();
|
|
92
|
+
if (override) {
|
|
93
|
+
return override;
|
|
94
|
+
}
|
|
95
|
+
return `n8n:${ctx.node.getExecutionId()}:${ctx.node.getNode().id}:${ctx.itemIndex}`;
|
|
96
|
+
};
|
|
73
97
|
const getBinaryFieldFromItem = async (ctx, propertyName, errorLabel) => {
|
|
74
98
|
var _a, _b;
|
|
75
99
|
const { node, itemIndex, items } = ctx;
|
|
@@ -93,9 +117,9 @@ const getBinaryFieldFromItem = async (ctx, propertyName, errorLabel) => {
|
|
|
93
117
|
}
|
|
94
118
|
};
|
|
95
119
|
const PLATFORM_SUPPORT = {
|
|
96
|
-
uploadPhotos: ['bluesky', 'facebook', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x', 'reddit', 'google_business'],
|
|
97
|
-
uploadVideo: ['bluesky', 'facebook', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x', 'youtube', 'google_business'],
|
|
98
|
-
uploadText: ['bluesky', 'facebook', 'linkedin', 'reddit', 'threads', 'x', 'google_business'],
|
|
120
|
+
uploadPhotos: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit', 'google_business'],
|
|
121
|
+
uploadVideo: ['bluesky', 'discord', 'facebook', 'instagram', 'linkedin', 'pinterest', 'reddit', 'telegram', 'threads', 'tiktok', 'x', 'youtube', 'google_business'],
|
|
122
|
+
uploadText: ['bluesky', 'discord', 'facebook', 'linkedin', 'reddit', 'telegram', 'threads', 'x', 'google_business'],
|
|
99
123
|
uploadDocument: ['linkedin'],
|
|
100
124
|
};
|
|
101
125
|
const DESCRIPTION_ENABLED_PLATFORMS = new Set(['linkedin', 'facebook', 'youtube', 'pinterest', 'tiktok']);
|
|
@@ -217,6 +241,10 @@ const prepareUploadBase = (ctx, operation) => {
|
|
|
217
241
|
}
|
|
218
242
|
const uploadAsync = ctx.node.getNodeParameter('uploadAsync', ctx.itemIndex);
|
|
219
243
|
formData.async_upload = String(uploadAsync);
|
|
244
|
+
const autogenerate = ctx.node.getNodeParameter('autogenerate', ctx.itemIndex, false);
|
|
245
|
+
if (autogenerate) {
|
|
246
|
+
formData.autogenerate = 'true';
|
|
247
|
+
}
|
|
220
248
|
const rawPlatforms = ctx.node.getNodeParameter('platform', ctx.itemIndex);
|
|
221
249
|
const platforms = getFilteredPlatforms(operation, Array.isArray(rawPlatforms) ? rawPlatforms : []);
|
|
222
250
|
formData['platform[]'] = platforms;
|
|
@@ -649,6 +677,49 @@ const applyGoogleBusinessOptions = (ctx, _operation, formData) => {
|
|
|
649
677
|
const locationId = ctx.node.getNodeParameter('gbpLocationId', ctx.itemIndex, '');
|
|
650
678
|
if (locationId)
|
|
651
679
|
formData.gbp_location_id = locationId;
|
|
680
|
+
const topicType = ctx.node.getNodeParameter('gbpTopicType', ctx.itemIndex, '');
|
|
681
|
+
if (topicType)
|
|
682
|
+
formData.gbp_topic_type = topicType;
|
|
683
|
+
const mediaUrl = ctx.node.getNodeParameter('gbpMediaUrl', ctx.itemIndex, '');
|
|
684
|
+
if (mediaUrl)
|
|
685
|
+
formData.gbp_media_url = mediaUrl;
|
|
686
|
+
const mediaFormat = ctx.node.getNodeParameter('gbpMediaFormat', ctx.itemIndex, '');
|
|
687
|
+
if (mediaFormat)
|
|
688
|
+
formData.gbp_media_format = mediaFormat;
|
|
689
|
+
const ctaType = ctx.node.getNodeParameter('gbpCtaType', ctx.itemIndex, '');
|
|
690
|
+
if (ctaType)
|
|
691
|
+
formData.gbp_cta_type = ctaType;
|
|
692
|
+
const ctaUrl = ctx.node.getNodeParameter('gbpCtaUrl', ctx.itemIndex, '');
|
|
693
|
+
if (ctaUrl)
|
|
694
|
+
formData.gbp_cta_url = ctaUrl;
|
|
695
|
+
if (topicType === 'EVENT') {
|
|
696
|
+
const eventTitle = ctx.node.getNodeParameter('gbpEventTitle', ctx.itemIndex, '');
|
|
697
|
+
if (eventTitle)
|
|
698
|
+
formData.gbp_event_title = eventTitle;
|
|
699
|
+
const startDate = ctx.node.getNodeParameter('gbpEventStartDate', ctx.itemIndex, '');
|
|
700
|
+
if (startDate)
|
|
701
|
+
formData.gbp_event_start_date = startDate;
|
|
702
|
+
const startTime = ctx.node.getNodeParameter('gbpEventStartTime', ctx.itemIndex, '');
|
|
703
|
+
if (startTime)
|
|
704
|
+
formData.gbp_event_start_time = startTime;
|
|
705
|
+
const endDate = ctx.node.getNodeParameter('gbpEventEndDate', ctx.itemIndex, '');
|
|
706
|
+
if (endDate)
|
|
707
|
+
formData.gbp_event_end_date = endDate;
|
|
708
|
+
const endTime = ctx.node.getNodeParameter('gbpEventEndTime', ctx.itemIndex, '');
|
|
709
|
+
if (endTime)
|
|
710
|
+
formData.gbp_event_end_time = endTime;
|
|
711
|
+
}
|
|
712
|
+
if (topicType === 'OFFER') {
|
|
713
|
+
const coupon = ctx.node.getNodeParameter('gbpOfferCoupon', ctx.itemIndex, '');
|
|
714
|
+
if (coupon)
|
|
715
|
+
formData.gbp_offer_coupon = coupon;
|
|
716
|
+
const redeemUrl = ctx.node.getNodeParameter('gbpOfferRedeemUrl', ctx.itemIndex, '');
|
|
717
|
+
if (redeemUrl)
|
|
718
|
+
formData.gbp_offer_redeem_url = redeemUrl;
|
|
719
|
+
const terms = ctx.node.getNodeParameter('gbpOfferTerms', ctx.itemIndex, '');
|
|
720
|
+
if (terms)
|
|
721
|
+
formData.gbp_offer_terms = terms;
|
|
722
|
+
}
|
|
652
723
|
};
|
|
653
724
|
const applyRedditOptions = (ctx, operation, formData) => {
|
|
654
725
|
const subreddit = ctx.node.getNodeParameter('redditSubreddit', ctx.itemIndex);
|
|
@@ -835,10 +906,21 @@ const buildMonitoringRequest = (ctx) => {
|
|
|
835
906
|
case 'getAnalytics': {
|
|
836
907
|
const profileUsername = ctx.node.getNodeParameter('analyticsProfileUsername', ctx.itemIndex);
|
|
837
908
|
const analyticsPlatforms = ctx.node.getNodeParameter('analyticsPlatforms', ctx.itemIndex, []);
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
909
|
+
if (!Array.isArray(analyticsPlatforms) || analyticsPlatforms.length === 0) {
|
|
910
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), 'Select at least one platform: the analytics API rejects a request without "platforms".', {
|
|
911
|
+
itemIndex: ctx.itemIndex,
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
const qs = { platforms: analyticsPlatforms.join(',') };
|
|
915
|
+
const analyticsPageId = ctx.node.getNodeParameter('analyticsPageId', ctx.itemIndex, '');
|
|
916
|
+
if (analyticsPlatforms.includes('facebook') && !analyticsPageId) {
|
|
917
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), 'Facebook analytics require a Page ID.', { itemIndex: ctx.itemIndex });
|
|
841
918
|
}
|
|
919
|
+
if (analyticsPageId)
|
|
920
|
+
qs.page_id = analyticsPageId;
|
|
921
|
+
const analyticsPageUrn = ctx.node.getNodeParameter('analyticsPageUrn', ctx.itemIndex, '');
|
|
922
|
+
if (analyticsPageUrn)
|
|
923
|
+
qs.page_urn = analyticsPageUrn;
|
|
842
924
|
return {
|
|
843
925
|
endpoint: `/analytics/${encodeURIComponent(profileUsername)}`,
|
|
844
926
|
method: 'GET',
|
|
@@ -847,6 +929,77 @@ const buildMonitoringRequest = (ctx) => {
|
|
|
847
929
|
waitForCompletion: false,
|
|
848
930
|
};
|
|
849
931
|
}
|
|
932
|
+
case 'getPostAnalytics': {
|
|
933
|
+
const requestId = ctx.node.getNodeParameter('postAnalyticsRequestId', ctx.itemIndex);
|
|
934
|
+
const platform = ctx.node.getNodeParameter('postAnalyticsPlatform', ctx.itemIndex, '');
|
|
935
|
+
const qs = {};
|
|
936
|
+
if (platform) {
|
|
937
|
+
qs.platform = platform;
|
|
938
|
+
}
|
|
939
|
+
return {
|
|
940
|
+
endpoint: `/uploadposts/post-analytics/${encodeURIComponent(requestId)}`,
|
|
941
|
+
method: 'GET',
|
|
942
|
+
qs,
|
|
943
|
+
isUploadOperation: false,
|
|
944
|
+
waitForCompletion: false,
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
case 'getPostAnalyticsByPlatformId': {
|
|
948
|
+
return {
|
|
949
|
+
endpoint: '/uploadposts/post-analytics',
|
|
950
|
+
method: 'GET',
|
|
951
|
+
qs: {
|
|
952
|
+
platform_post_id: ctx.node.getNodeParameter('platformPostId', ctx.itemIndex),
|
|
953
|
+
platform: ctx.node.getNodeParameter('nativePostPlatform', ctx.itemIndex),
|
|
954
|
+
user: ctx.node.getNodeParameter('nativePostProfileUsername', ctx.itemIndex),
|
|
955
|
+
},
|
|
956
|
+
isUploadOperation: false,
|
|
957
|
+
waitForCompletion: false,
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
case 'getPlatformMetrics': {
|
|
961
|
+
return {
|
|
962
|
+
endpoint: '/uploadposts/platform-metrics',
|
|
963
|
+
method: 'GET',
|
|
964
|
+
isUploadOperation: false,
|
|
965
|
+
waitForCompletion: false,
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
case 'getTotalImpressions': {
|
|
969
|
+
const profileUsername = ctx.node.getNodeParameter('impressionsProfileUsername', ctx.itemIndex);
|
|
970
|
+
const qs = {};
|
|
971
|
+
const period = ctx.node.getNodeParameter('impressionsPeriod', ctx.itemIndex, '');
|
|
972
|
+
const startDate = ctx.node.getNodeParameter('impressionsStartDate', ctx.itemIndex, '');
|
|
973
|
+
const endDate = ctx.node.getNodeParameter('impressionsEndDate', ctx.itemIndex, '');
|
|
974
|
+
const platforms = ctx.node.getNodeParameter('impressionsPlatforms', ctx.itemIndex, []);
|
|
975
|
+
const breakdown = ctx.node.getNodeParameter('impressionsBreakdown', ctx.itemIndex, false);
|
|
976
|
+
if (period)
|
|
977
|
+
qs.period = period;
|
|
978
|
+
if (startDate)
|
|
979
|
+
qs.start_date = startDate;
|
|
980
|
+
if (endDate)
|
|
981
|
+
qs.end_date = endDate;
|
|
982
|
+
if (Array.isArray(platforms) && platforms.length > 0)
|
|
983
|
+
qs.platform = platforms.join(',');
|
|
984
|
+
if (breakdown)
|
|
985
|
+
qs.breakdown = 'true';
|
|
986
|
+
return {
|
|
987
|
+
endpoint: `/uploadposts/total-impressions/${encodeURIComponent(profileUsername)}`,
|
|
988
|
+
method: 'GET',
|
|
989
|
+
qs,
|
|
990
|
+
isUploadOperation: false,
|
|
991
|
+
waitForCompletion: false,
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
case 'getRedditDetailedPosts': {
|
|
995
|
+
return {
|
|
996
|
+
endpoint: '/uploadposts/reddit/detailed-posts/',
|
|
997
|
+
method: 'GET',
|
|
998
|
+
qs: { profile_username: ctx.node.getNodeParameter('redditProfileUsername', ctx.itemIndex) },
|
|
999
|
+
isUploadOperation: false,
|
|
1000
|
+
waitForCompletion: false,
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
850
1003
|
case 'listScheduled': {
|
|
851
1004
|
return {
|
|
852
1005
|
endpoint: '/uploadposts/schedule',
|
|
@@ -871,14 +1024,14 @@ const buildMonitoringRequest = (ctx) => {
|
|
|
871
1024
|
const body = {};
|
|
872
1025
|
if (normalizedDate) {
|
|
873
1026
|
body.scheduled_date = normalizedDate;
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
1027
|
+
}
|
|
1028
|
+
const newTimezone = ctx.node.getNodeParameter('newTimezone', ctx.itemIndex, '');
|
|
1029
|
+
if (newTimezone) {
|
|
1030
|
+
body.timezone = newTimezone;
|
|
878
1031
|
}
|
|
879
1032
|
return {
|
|
880
1033
|
endpoint: `/uploadposts/schedule/${jobId}`,
|
|
881
|
-
method: '
|
|
1034
|
+
method: 'PATCH',
|
|
882
1035
|
body,
|
|
883
1036
|
isUploadOperation: false,
|
|
884
1037
|
waitForCompletion: false,
|
|
@@ -890,7 +1043,7 @@ const buildMonitoringRequest = (ctx) => {
|
|
|
890
1043
|
});
|
|
891
1044
|
}
|
|
892
1045
|
};
|
|
893
|
-
const buildUserRequest = (ctx) => {
|
|
1046
|
+
const buildUserRequest = async (ctx) => {
|
|
894
1047
|
switch (ctx.operation) {
|
|
895
1048
|
case 'listUsers':
|
|
896
1049
|
return {
|
|
@@ -929,6 +1082,7 @@ const buildUserRequest = (ctx) => {
|
|
|
929
1082
|
const readonlyCalendar = ctx.node.getNodeParameter('readonlyCalendar', ctx.itemIndex, false);
|
|
930
1083
|
const connectTitle = ctx.node.getNodeParameter('connectTitle', ctx.itemIndex, '');
|
|
931
1084
|
const connectDescription = ctx.node.getNodeParameter('connectDescription', ctx.itemIndex, '');
|
|
1085
|
+
const language = ctx.node.getNodeParameter('language', ctx.itemIndex, '');
|
|
932
1086
|
const body = { username };
|
|
933
1087
|
if (redirectUrl)
|
|
934
1088
|
body.redirect_url = redirectUrl;
|
|
@@ -944,6 +1098,8 @@ const buildUserRequest = (ctx) => {
|
|
|
944
1098
|
body.connect_title = connectTitle;
|
|
945
1099
|
if (connectDescription)
|
|
946
1100
|
body.connect_description = connectDescription;
|
|
1101
|
+
if (language)
|
|
1102
|
+
body.language = language;
|
|
947
1103
|
return {
|
|
948
1104
|
endpoint: '/uploadposts/users/generate-jwt',
|
|
949
1105
|
method: 'POST',
|
|
@@ -956,9 +1112,9 @@ const buildUserRequest = (ctx) => {
|
|
|
956
1112
|
const jwt = ctx.node.getNodeParameter('jwtToken', ctx.itemIndex);
|
|
957
1113
|
return {
|
|
958
1114
|
endpoint: '/uploadposts/users/validate-jwt',
|
|
959
|
-
method: '
|
|
960
|
-
body: { jwt },
|
|
1115
|
+
method: 'GET',
|
|
961
1116
|
headers: { Authorization: `Bearer ${jwt}` },
|
|
1117
|
+
skipCredentialAuth: true,
|
|
962
1118
|
isUploadOperation: false,
|
|
963
1119
|
waitForCompletion: false,
|
|
964
1120
|
};
|
|
@@ -976,13 +1132,15 @@ const buildUserRequest = (ctx) => {
|
|
|
976
1132
|
const webhookUrl = ctx.node.getNodeParameter('webhookUrl', ctx.itemIndex, '');
|
|
977
1133
|
const webhookEnabled = ctx.node.getNodeParameter('webhookEnabled', ctx.itemIndex, false);
|
|
978
1134
|
const webhookEventsRaw = ctx.node.getNodeParameter('webhookEvents', ctx.itemIndex, []);
|
|
1135
|
+
const existingChannels = await fetchNotificationChannels(ctx);
|
|
979
1136
|
const body = {
|
|
980
|
-
channels: { webhook: webhookEnabled },
|
|
1137
|
+
channels: { ...existingChannels, webhook: webhookEnabled },
|
|
981
1138
|
};
|
|
982
1139
|
if (webhookUrl)
|
|
983
1140
|
body.webhook_url = webhookUrl;
|
|
984
|
-
if (webhookEventsRaw.length > 0)
|
|
985
|
-
body.webhook_events = webhookEventsRaw;
|
|
1141
|
+
if (webhookEventsRaw.length > 0) {
|
|
1142
|
+
body.webhook_events = Object.fromEntries(webhookEventsRaw.map(event => [event, true]));
|
|
1143
|
+
}
|
|
986
1144
|
return {
|
|
987
1145
|
endpoint: '/uploadposts/users/notifications',
|
|
988
1146
|
method: 'POST',
|
|
@@ -1003,7 +1161,7 @@ const buildUserRequest = (ctx) => {
|
|
|
1003
1161
|
const weekStartDay = ctx.node.getNodeParameter('weekStartDay', ctx.itemIndex, '');
|
|
1004
1162
|
const body = {};
|
|
1005
1163
|
if (weekStartDay !== '')
|
|
1006
|
-
body.
|
|
1164
|
+
body.weekStartDay = parseInt(weekStartDay, 10);
|
|
1007
1165
|
return {
|
|
1008
1166
|
endpoint: '/uploadposts/users/preferences',
|
|
1009
1167
|
method: 'POST',
|
|
@@ -1089,7 +1247,7 @@ const buildRequestConfig = async (ctx) => {
|
|
|
1089
1247
|
return buildMonitoringRequest(ctx);
|
|
1090
1248
|
}
|
|
1091
1249
|
if (resource === 'users') {
|
|
1092
|
-
return buildUserRequest(ctx);
|
|
1250
|
+
return await buildUserRequest(ctx);
|
|
1093
1251
|
}
|
|
1094
1252
|
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported operation: ${ctx.operation}`, {
|
|
1095
1253
|
itemIndex: ctx.itemIndex,
|
|
@@ -1153,8 +1311,7 @@ const pollUploadStatus = async (node, requestId, pollInterval, pollTimeout) => {
|
|
|
1153
1311
|
const statusData = await node.helpers.httpRequestWithAuthentication.call(node, 'uploadPostApi', statusOptions);
|
|
1154
1312
|
finalData = statusData;
|
|
1155
1313
|
const statusValue = (statusData && statusData.status);
|
|
1156
|
-
if (
|
|
1157
|
-
(typeof statusValue === 'string' && ['success', 'completed', 'failed', 'error', 'scheduled', 'queued', 'pending'].includes(statusValue.toLowerCase()))) {
|
|
1314
|
+
if (typeof statusValue === 'string' && TERMINAL_UPLOAD_STATUSES.includes(statusValue.toLowerCase())) {
|
|
1158
1315
|
break;
|
|
1159
1316
|
}
|
|
1160
1317
|
}
|
|
@@ -1203,9 +1360,9 @@ class UploadPost {
|
|
|
1203
1360
|
noDataExpression: true,
|
|
1204
1361
|
options: [
|
|
1205
1362
|
{ 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)' },
|
|
1206
|
-
{ name: 'Upload Photo(s)', value: 'uploadPhotos', action: 'Upload photos', description: 'Upload one or more photos (Supports: TikTok, Instagram, LinkedIn, Facebook, X, Threads)' },
|
|
1207
|
-
{ name: 'Upload Text', value: 'uploadText', action: 'Upload a text post', description: 'Upload a text-based post (Supports: X, LinkedIn, Facebook, Threads)' },
|
|
1208
|
-
{ name: 'Upload Video', value: 'uploadVideo', action: 'Upload a video', description: 'Upload a single video (Supports: TikTok, Instagram, LinkedIn, YouTube, Facebook, X, Threads)' },
|
|
1363
|
+
{ name: 'Upload Photo(s)', value: 'uploadPhotos', action: 'Upload photos', description: 'Upload one or more photos (Supports: TikTok, Instagram, LinkedIn, Facebook, X, Threads, Discord, Telegram)' },
|
|
1364
|
+
{ name: 'Upload Text', value: 'uploadText', action: 'Upload a text post', description: 'Upload a text-based post (Supports: X, LinkedIn, Facebook, Threads, Discord, Telegram)' },
|
|
1365
|
+
{ name: 'Upload Video', value: 'uploadVideo', action: 'Upload a video', description: 'Upload a single video (Supports: TikTok, Instagram, LinkedIn, YouTube, Facebook, X, Threads, Discord, Telegram)' },
|
|
1209
1366
|
],
|
|
1210
1367
|
default: 'uploadPhotos',
|
|
1211
1368
|
displayOptions: { show: { resource: ['uploads'] } },
|
|
@@ -1220,6 +1377,11 @@ class UploadPost {
|
|
|
1220
1377
|
{ name: 'Edit Scheduled Post', value: 'editScheduled', action: 'Edit scheduled post', description: 'Edit schedule details (like date/time) by job ID' },
|
|
1221
1378
|
{ name: 'Get Analytics', value: 'getAnalytics', action: 'Get analytics', description: 'Retrieve aggregated analytics for uploads' },
|
|
1222
1379
|
{ name: 'Get Job Status', value: 'getJobStatus', action: 'Get job status', description: 'Check the status of a scheduled or queued post using the job_id' },
|
|
1380
|
+
{ name: 'Get Platform Metrics', value: 'getPlatformMetrics', action: 'Get platform metrics', description: 'List the analytics metrics available for each platform' },
|
|
1381
|
+
{ name: 'Get Post Analytics', value: 'getPostAnalytics', action: 'Get post analytics', description: 'Retrieve per-post analytics for an upload using its request_id' },
|
|
1382
|
+
{ 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' },
|
|
1383
|
+
{ name: 'Get Reddit Detailed Posts', value: 'getRedditDetailedPosts', action: 'Get reddit detailed posts', description: 'Retrieve detailed Reddit posts with full media information' },
|
|
1384
|
+
{ name: 'Get Total Impressions', value: 'getTotalImpressions', action: 'Get total impressions', description: 'Retrieve impressions aggregated across connected platforms for a date range' },
|
|
1223
1385
|
{ name: 'Get Upload History', value: 'getHistory', action: 'Get upload history', description: 'List past uploads with optional filters' },
|
|
1224
1386
|
{ name: 'Get Upload Status', value: 'getStatus', action: 'Get upload status', description: 'Check the status of an upload using the request_id' },
|
|
1225
1387
|
{ name: 'List Scheduled Posts', value: 'listScheduled', action: 'List scheduled posts', description: 'List your scheduled (future) posts' },
|
|
@@ -1670,13 +1832,37 @@ class UploadPost {
|
|
|
1670
1832
|
name: 'uploadAsync',
|
|
1671
1833
|
type: 'boolean',
|
|
1672
1834
|
default: true,
|
|
1673
|
-
description: 'Whether to process the upload asynchronously and return immediately.
|
|
1835
|
+
description: 'Whether to process the upload asynchronously and return immediately. Recommended: leaving this off holds the HTTP connection open, and if it exceeds the server\'s synchronous wait window the upload switches to asynchronous processing anyway. In that case, use the request_id with the Upload Status endpoint to check the upload status and result.',
|
|
1674
1836
|
displayOptions: {
|
|
1675
1837
|
show: {
|
|
1676
1838
|
operation: ['uploadPhotos', 'uploadVideo', 'uploadText', 'uploadDocument']
|
|
1677
1839
|
}
|
|
1678
1840
|
},
|
|
1679
1841
|
},
|
|
1842
|
+
{
|
|
1843
|
+
displayName: 'Idempotency Key',
|
|
1844
|
+
name: 'idempotencyKey',
|
|
1845
|
+
type: 'string',
|
|
1846
|
+
default: '',
|
|
1847
|
+
description: 'Key the API uses to collapse duplicate uploads within 24 hours. Leave empty to derive one automatically from the execution, node and item, which is what prevents a retried upload from posting twice. Set it explicitly only when you drive retries yourself.',
|
|
1848
|
+
displayOptions: {
|
|
1849
|
+
show: {
|
|
1850
|
+
operation: ['uploadPhotos', 'uploadVideo', 'uploadText', 'uploadDocument']
|
|
1851
|
+
}
|
|
1852
|
+
},
|
|
1853
|
+
},
|
|
1854
|
+
{
|
|
1855
|
+
displayName: 'Autogenerate Copy With AI',
|
|
1856
|
+
name: 'autogenerate',
|
|
1857
|
+
type: 'boolean',
|
|
1858
|
+
default: false,
|
|
1859
|
+
description: 'Whether the server should use AI to generate native per-platform title/description from the media and fill any platform field left empty',
|
|
1860
|
+
displayOptions: {
|
|
1861
|
+
show: {
|
|
1862
|
+
operation: ['uploadPhotos', 'uploadVideo']
|
|
1863
|
+
}
|
|
1864
|
+
},
|
|
1865
|
+
},
|
|
1680
1866
|
{
|
|
1681
1867
|
displayName: 'Wait for Completion',
|
|
1682
1868
|
name: 'waitForCompletion',
|
|
@@ -1800,19 +1986,187 @@ class UploadPost {
|
|
|
1800
1986
|
displayOptions: { show: { operation: ["editScheduled"] } },
|
|
1801
1987
|
},
|
|
1802
1988
|
{
|
|
1803
|
-
displayName: 'Platforms
|
|
1989
|
+
displayName: 'Platforms',
|
|
1804
1990
|
name: 'analyticsPlatforms',
|
|
1805
1991
|
type: 'multiOptions',
|
|
1992
|
+
required: true,
|
|
1806
1993
|
options: [
|
|
1994
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
1807
1995
|
{ name: 'Instagram', value: 'instagram' },
|
|
1808
1996
|
{ name: 'LinkedIn', value: 'linkedin' },
|
|
1809
|
-
{ name: '
|
|
1997
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
1998
|
+
{ name: 'Reddit', value: 'reddit' },
|
|
1999
|
+
{ name: 'Threads', value: 'threads' },
|
|
2000
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
1810
2001
|
{ name: 'X (Twitter)', value: 'x' },
|
|
2002
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
1811
2003
|
],
|
|
1812
2004
|
default: [],
|
|
1813
|
-
description: 'Platforms to fetch analytics for
|
|
2005
|
+
description: 'Platforms to fetch analytics for. Analytics are not available for Bluesky, Discord, Google Business or Telegram.',
|
|
2006
|
+
displayOptions: { show: { operation: ['getAnalytics'] } },
|
|
2007
|
+
},
|
|
2008
|
+
{
|
|
2009
|
+
displayName: 'Facebook Page ID',
|
|
2010
|
+
name: 'analyticsPageId',
|
|
2011
|
+
type: 'string',
|
|
2012
|
+
default: '',
|
|
2013
|
+
description: 'Required when Facebook is among the selected platforms',
|
|
2014
|
+
displayOptions: { show: { operation: ['getAnalytics'] } },
|
|
2015
|
+
},
|
|
2016
|
+
{
|
|
2017
|
+
displayName: 'LinkedIn Page URN',
|
|
2018
|
+
name: 'analyticsPageUrn',
|
|
2019
|
+
type: 'string',
|
|
2020
|
+
default: '',
|
|
2021
|
+
description: 'LinkedIn organization page to report on. Defaults to the personal profile.',
|
|
1814
2022
|
displayOptions: { show: { operation: ['getAnalytics'] } },
|
|
1815
2023
|
},
|
|
2024
|
+
{
|
|
2025
|
+
displayName: 'Request ID',
|
|
2026
|
+
name: 'postAnalyticsRequestId',
|
|
2027
|
+
type: 'string',
|
|
2028
|
+
required: true,
|
|
2029
|
+
default: '',
|
|
2030
|
+
description: 'The request_id returned by the upload you want metrics for',
|
|
2031
|
+
displayOptions: { show: { operation: ['getPostAnalytics'] } },
|
|
2032
|
+
},
|
|
2033
|
+
{
|
|
2034
|
+
displayName: 'Platform',
|
|
2035
|
+
name: 'postAnalyticsPlatform',
|
|
2036
|
+
type: 'options',
|
|
2037
|
+
options: [
|
|
2038
|
+
{ name: 'All Platforms', value: '' },
|
|
2039
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
2040
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
2041
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
2042
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
2043
|
+
{ name: 'Reddit', value: 'reddit' },
|
|
2044
|
+
{ name: 'Threads', value: 'threads' },
|
|
2045
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
2046
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
2047
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
2048
|
+
],
|
|
2049
|
+
default: '',
|
|
2050
|
+
description: 'Restrict the result to a single platform',
|
|
2051
|
+
displayOptions: { show: { operation: ['getPostAnalytics'] } },
|
|
2052
|
+
},
|
|
2053
|
+
{
|
|
2054
|
+
displayName: 'Platform Post ID',
|
|
2055
|
+
name: 'platformPostId',
|
|
2056
|
+
type: 'string',
|
|
2057
|
+
required: true,
|
|
2058
|
+
default: '',
|
|
2059
|
+
description: 'The post ID as assigned by the social platform itself',
|
|
2060
|
+
displayOptions: { show: { operation: ['getPostAnalyticsByPlatformId'] } },
|
|
2061
|
+
},
|
|
2062
|
+
{
|
|
2063
|
+
displayName: 'Platform',
|
|
2064
|
+
name: 'nativePostPlatform',
|
|
2065
|
+
type: 'options',
|
|
2066
|
+
required: true,
|
|
2067
|
+
options: [
|
|
2068
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
2069
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
2070
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
2071
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
2072
|
+
{ name: 'Reddit', value: 'reddit' },
|
|
2073
|
+
{ name: 'Threads', value: 'threads' },
|
|
2074
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
2075
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
2076
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
2077
|
+
],
|
|
2078
|
+
default: 'instagram',
|
|
2079
|
+
description: 'Platform the post lives on',
|
|
2080
|
+
displayOptions: { show: { operation: ['getPostAnalyticsByPlatformId'] } },
|
|
2081
|
+
},
|
|
2082
|
+
{
|
|
2083
|
+
displayName: 'Profile Username',
|
|
2084
|
+
name: 'nativePostProfileUsername',
|
|
2085
|
+
type: 'string',
|
|
2086
|
+
required: true,
|
|
2087
|
+
default: '',
|
|
2088
|
+
description: 'Upload-Post profile that owns the connected account',
|
|
2089
|
+
displayOptions: { show: { operation: ['getPostAnalyticsByPlatformId'] } },
|
|
2090
|
+
},
|
|
2091
|
+
{
|
|
2092
|
+
displayName: 'Profile Username',
|
|
2093
|
+
name: 'impressionsProfileUsername',
|
|
2094
|
+
type: 'string',
|
|
2095
|
+
required: true,
|
|
2096
|
+
default: '',
|
|
2097
|
+
description: 'Profile username to aggregate impressions for',
|
|
2098
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2099
|
+
},
|
|
2100
|
+
{
|
|
2101
|
+
displayName: 'Period',
|
|
2102
|
+
name: 'impressionsPeriod',
|
|
2103
|
+
type: 'options',
|
|
2104
|
+
options: [
|
|
2105
|
+
{ name: 'Custom Range (Use Start/End Date)', value: '' },
|
|
2106
|
+
{ name: 'Last 3 Months', value: 'last_3months' },
|
|
2107
|
+
{ name: 'Last Day', value: 'last_day' },
|
|
2108
|
+
{ name: 'Last Month', value: 'last_month' },
|
|
2109
|
+
{ name: 'Last Week', value: 'last_week' },
|
|
2110
|
+
{ name: 'Last Year', value: 'last_year' },
|
|
2111
|
+
],
|
|
2112
|
+
default: '',
|
|
2113
|
+
description: 'Preset range. Leave on custom range to use Start and End Date instead. Defaults to the last 30 days when nothing is set.',
|
|
2114
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
displayName: 'Start Date',
|
|
2118
|
+
name: 'impressionsStartDate',
|
|
2119
|
+
type: 'string',
|
|
2120
|
+
default: '',
|
|
2121
|
+
placeholder: 'YYYY-MM-DD',
|
|
2122
|
+
description: 'Start of a custom date range. Ignored when Period is set.',
|
|
2123
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2124
|
+
},
|
|
2125
|
+
{
|
|
2126
|
+
displayName: 'End Date',
|
|
2127
|
+
name: 'impressionsEndDate',
|
|
2128
|
+
type: 'string',
|
|
2129
|
+
default: '',
|
|
2130
|
+
placeholder: 'YYYY-MM-DD',
|
|
2131
|
+
description: 'End of a custom date range. Ignored when Period is set.',
|
|
2132
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
displayName: 'Platforms',
|
|
2136
|
+
name: 'impressionsPlatforms',
|
|
2137
|
+
type: 'multiOptions',
|
|
2138
|
+
options: [
|
|
2139
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
2140
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
2141
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
2142
|
+
{ name: 'Pinterest', value: 'pinterest' },
|
|
2143
|
+
{ name: 'Reddit', value: 'reddit' },
|
|
2144
|
+
{ name: 'Threads', value: 'threads' },
|
|
2145
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
2146
|
+
{ name: 'X (Twitter)', value: 'x' },
|
|
2147
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
2148
|
+
],
|
|
2149
|
+
default: [],
|
|
2150
|
+
description: 'Restrict the aggregate to these platforms. Leave empty for all.',
|
|
2151
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2152
|
+
},
|
|
2153
|
+
{
|
|
2154
|
+
displayName: 'Breakdown',
|
|
2155
|
+
name: 'impressionsBreakdown',
|
|
2156
|
+
type: 'boolean',
|
|
2157
|
+
default: false,
|
|
2158
|
+
description: 'Whether to return impressions broken down per platform instead of a single total',
|
|
2159
|
+
displayOptions: { show: { operation: ['getTotalImpressions'] } },
|
|
2160
|
+
},
|
|
2161
|
+
{
|
|
2162
|
+
displayName: 'Profile Username',
|
|
2163
|
+
name: 'redditProfileUsername',
|
|
2164
|
+
type: 'string',
|
|
2165
|
+
required: true,
|
|
2166
|
+
default: '',
|
|
2167
|
+
description: 'Profile username whose Reddit posts you want',
|
|
2168
|
+
displayOptions: { show: { operation: ['getRedditDetailedPosts'] } },
|
|
2169
|
+
},
|
|
1816
2170
|
{
|
|
1817
2171
|
displayName: 'New User Identifier',
|
|
1818
2172
|
name: 'newUser',
|
|
@@ -1864,9 +2218,11 @@ class UploadPost {
|
|
|
1864
2218
|
name: 'jwtPlatforms',
|
|
1865
2219
|
type: 'multiOptions',
|
|
1866
2220
|
options: [
|
|
2221
|
+
{ name: 'Discord', value: 'discord' },
|
|
1867
2222
|
{ name: 'Facebook', value: 'facebook' },
|
|
1868
2223
|
{ name: 'Instagram', value: 'instagram' },
|
|
1869
2224
|
{ name: 'LinkedIn', value: 'linkedin' },
|
|
2225
|
+
{ name: 'Telegram', value: 'telegram' },
|
|
1870
2226
|
{ name: 'Threads', value: 'threads' },
|
|
1871
2227
|
{ name: 'TikTok', value: 'tiktok' },
|
|
1872
2228
|
{ name: 'X (Twitter)', value: 'x' },
|
|
@@ -1908,6 +2264,22 @@ class UploadPost {
|
|
|
1908
2264
|
description: 'Optional custom description for the connection page',
|
|
1909
2265
|
displayOptions: { show: { operation: ['generateJwt'] } },
|
|
1910
2266
|
},
|
|
2267
|
+
{
|
|
2268
|
+
displayName: 'Language',
|
|
2269
|
+
name: 'language',
|
|
2270
|
+
type: 'options',
|
|
2271
|
+
default: '',
|
|
2272
|
+
description: 'Force the connection page language for this profile. When set to Auto-Detect, the page detects the visitor browser language and falls back to English.',
|
|
2273
|
+
options: [
|
|
2274
|
+
{ name: 'Auto-Detect (Default)', value: '' },
|
|
2275
|
+
{ name: 'English', value: 'en' },
|
|
2276
|
+
{ name: 'French', value: 'fr' },
|
|
2277
|
+
{ name: 'German', value: 'de' },
|
|
2278
|
+
{ name: 'Portuguese', value: 'pt' },
|
|
2279
|
+
{ name: 'Spanish', value: 'es' },
|
|
2280
|
+
],
|
|
2281
|
+
displayOptions: { show: { operation: ['generateJwt'] } },
|
|
2282
|
+
},
|
|
1911
2283
|
{
|
|
1912
2284
|
displayName: 'JWT',
|
|
1913
2285
|
name: 'jwtToken',
|
|
@@ -2521,6 +2893,133 @@ class UploadPost {
|
|
|
2521
2893
|
description: 'Location ID for accounts with multiple Google Business Profile locations (e.g., accounts/123/locations/456). If omitted, uses the default connected location.',
|
|
2522
2894
|
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2523
2895
|
},
|
|
2896
|
+
{
|
|
2897
|
+
displayName: 'Google Business Post Type',
|
|
2898
|
+
name: 'gbpTopicType',
|
|
2899
|
+
type: 'options',
|
|
2900
|
+
options: [
|
|
2901
|
+
{ name: 'Standard', value: 'STANDARD' },
|
|
2902
|
+
{ name: 'Event', value: 'EVENT' },
|
|
2903
|
+
{ name: 'Offer', value: 'OFFER' },
|
|
2904
|
+
],
|
|
2905
|
+
default: 'STANDARD',
|
|
2906
|
+
description: 'Kind of Google Business post to publish',
|
|
2907
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2908
|
+
},
|
|
2909
|
+
{
|
|
2910
|
+
displayName: 'Google Business Media URL',
|
|
2911
|
+
name: 'gbpMediaUrl',
|
|
2912
|
+
type: 'string',
|
|
2913
|
+
default: '',
|
|
2914
|
+
description: 'URL of the media attached to the Google Business post',
|
|
2915
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2916
|
+
},
|
|
2917
|
+
{
|
|
2918
|
+
displayName: 'Google Business Media Format',
|
|
2919
|
+
name: 'gbpMediaFormat',
|
|
2920
|
+
type: 'options',
|
|
2921
|
+
options: [
|
|
2922
|
+
{ name: 'Not Set', value: '' },
|
|
2923
|
+
{ name: 'Photo', value: 'PHOTO' },
|
|
2924
|
+
{ name: 'Video', value: 'VIDEO' },
|
|
2925
|
+
],
|
|
2926
|
+
default: '',
|
|
2927
|
+
description: 'Format of the attached media',
|
|
2928
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2929
|
+
},
|
|
2930
|
+
{
|
|
2931
|
+
displayName: 'Google Business Call to Action',
|
|
2932
|
+
name: 'gbpCtaType',
|
|
2933
|
+
type: 'options',
|
|
2934
|
+
options: [
|
|
2935
|
+
{ name: 'Book', value: 'BOOK' },
|
|
2936
|
+
{ name: 'Call', value: 'CALL' },
|
|
2937
|
+
{ name: 'Learn More', value: 'LEARN_MORE' },
|
|
2938
|
+
{ name: 'None', value: '' },
|
|
2939
|
+
{ name: 'Order', value: 'ORDER' },
|
|
2940
|
+
{ name: 'Shop', value: 'SHOP' },
|
|
2941
|
+
{ name: 'Sign Up', value: 'SIGN_UP' },
|
|
2942
|
+
],
|
|
2943
|
+
default: '',
|
|
2944
|
+
description: 'Button shown under the Google Business post',
|
|
2945
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2946
|
+
},
|
|
2947
|
+
{
|
|
2948
|
+
displayName: 'Google Business Call to Action URL',
|
|
2949
|
+
name: 'gbpCtaUrl',
|
|
2950
|
+
type: 'string',
|
|
2951
|
+
default: '',
|
|
2952
|
+
description: 'URL the call-to-action button opens',
|
|
2953
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'] } },
|
|
2954
|
+
},
|
|
2955
|
+
{
|
|
2956
|
+
displayName: 'Google Business Event Title',
|
|
2957
|
+
name: 'gbpEventTitle',
|
|
2958
|
+
type: 'string',
|
|
2959
|
+
default: '',
|
|
2960
|
+
description: 'Title of the event',
|
|
2961
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
|
|
2962
|
+
},
|
|
2963
|
+
{
|
|
2964
|
+
displayName: 'Google Business Event Start Date',
|
|
2965
|
+
name: 'gbpEventStartDate',
|
|
2966
|
+
type: 'string',
|
|
2967
|
+
default: '',
|
|
2968
|
+
placeholder: 'YYYY-MM-DD',
|
|
2969
|
+
description: 'Date the event starts',
|
|
2970
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
|
|
2971
|
+
},
|
|
2972
|
+
{
|
|
2973
|
+
displayName: 'Google Business Event Start Time',
|
|
2974
|
+
name: 'gbpEventStartTime',
|
|
2975
|
+
type: 'string',
|
|
2976
|
+
default: '',
|
|
2977
|
+
placeholder: 'HH:MM',
|
|
2978
|
+
description: 'Time the event starts',
|
|
2979
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
|
|
2980
|
+
},
|
|
2981
|
+
{
|
|
2982
|
+
displayName: 'Google Business Event End Date',
|
|
2983
|
+
name: 'gbpEventEndDate',
|
|
2984
|
+
type: 'string',
|
|
2985
|
+
default: '',
|
|
2986
|
+
placeholder: 'YYYY-MM-DD',
|
|
2987
|
+
description: 'Date the event ends',
|
|
2988
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
|
|
2989
|
+
},
|
|
2990
|
+
{
|
|
2991
|
+
displayName: 'Google Business Event End Time',
|
|
2992
|
+
name: 'gbpEventEndTime',
|
|
2993
|
+
type: 'string',
|
|
2994
|
+
default: '',
|
|
2995
|
+
placeholder: 'HH:MM',
|
|
2996
|
+
description: 'Time the event ends',
|
|
2997
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['EVENT'] } },
|
|
2998
|
+
},
|
|
2999
|
+
{
|
|
3000
|
+
displayName: 'Google Business Offer Coupon',
|
|
3001
|
+
name: 'gbpOfferCoupon',
|
|
3002
|
+
type: 'string',
|
|
3003
|
+
default: '',
|
|
3004
|
+
description: 'Coupon code for the offer',
|
|
3005
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
|
|
3006
|
+
},
|
|
3007
|
+
{
|
|
3008
|
+
displayName: 'Google Business Offer Redeem URL',
|
|
3009
|
+
name: 'gbpOfferRedeemUrl',
|
|
3010
|
+
type: 'string',
|
|
3011
|
+
default: '',
|
|
3012
|
+
description: 'URL where the offer is redeemed',
|
|
3013
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
|
|
3014
|
+
},
|
|
3015
|
+
{
|
|
3016
|
+
displayName: 'Google Business Offer Terms',
|
|
3017
|
+
name: 'gbpOfferTerms',
|
|
3018
|
+
type: 'string',
|
|
3019
|
+
default: '',
|
|
3020
|
+
description: 'Terms and conditions of the offer',
|
|
3021
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText'], platform: ['google_business', '__manual_platform__'], gbpTopicType: ['OFFER'] } },
|
|
3022
|
+
},
|
|
2524
3023
|
{
|
|
2525
3024
|
displayName: 'Reddit Subreddit',
|
|
2526
3025
|
name: 'redditSubreddit',
|
|
@@ -3171,21 +3670,24 @@ class UploadPost {
|
|
|
3171
3670
|
const operation = this.getCurrentNodeParameter('operation');
|
|
3172
3671
|
const allPlatforms = [
|
|
3173
3672
|
{ name: 'Bluesky', value: 'bluesky' },
|
|
3673
|
+
{ name: 'Discord', value: 'discord' },
|
|
3174
3674
|
{ name: 'Facebook', value: 'facebook' },
|
|
3175
3675
|
{ name: 'Google Business', value: 'google_business' },
|
|
3176
3676
|
{ name: 'Instagram', value: 'instagram' },
|
|
3177
3677
|
{ name: 'LinkedIn', value: 'linkedin' },
|
|
3178
3678
|
{ name: 'Pinterest', value: 'pinterest' },
|
|
3179
3679
|
{ name: 'Reddit', value: 'reddit' },
|
|
3680
|
+
{ name: 'Telegram', value: 'telegram' },
|
|
3180
3681
|
{ name: 'Threads', value: 'threads' },
|
|
3181
3682
|
{ name: 'TikTok', value: 'tiktok' },
|
|
3182
3683
|
{ name: 'X (Twitter)', value: 'x' },
|
|
3183
3684
|
{ name: 'YouTube', value: 'youtube' },
|
|
3184
3685
|
];
|
|
3185
3686
|
const platformSupport = {
|
|
3186
|
-
uploadPhotos: ['bluesky', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x', 'reddit'],
|
|
3187
|
-
uploadVideo: ['bluesky', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'threads', 'tiktok', 'x', 'youtube'],
|
|
3188
|
-
uploadText: ['bluesky', 'facebook', 'google_business', 'linkedin', 'reddit', 'threads', 'x'],
|
|
3687
|
+
uploadPhotos: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'telegram', 'threads', 'tiktok', 'x', 'reddit'],
|
|
3688
|
+
uploadVideo: ['bluesky', 'discord', 'facebook', 'google_business', 'instagram', 'linkedin', 'pinterest', 'reddit', 'telegram', 'threads', 'tiktok', 'x', 'youtube'],
|
|
3689
|
+
uploadText: ['bluesky', 'discord', 'facebook', 'google_business', 'linkedin', 'reddit', 'telegram', 'threads', 'x'],
|
|
3690
|
+
uploadDocument: ['linkedin'],
|
|
3189
3691
|
};
|
|
3190
3692
|
const supportedPlatforms = platformSupport[operation] || [];
|
|
3191
3693
|
const filtered = allPlatforms.filter(platform => supportedPlatforms.includes(platform.value));
|
|
@@ -3308,7 +3810,7 @@ class UploadPost {
|
|
|
3308
3810
|
};
|
|
3309
3811
|
}
|
|
3310
3812
|
async execute() {
|
|
3311
|
-
var _a, _b;
|
|
3813
|
+
var _a, _b, _c;
|
|
3312
3814
|
const items = this.getInputData();
|
|
3313
3815
|
const returnData = [];
|
|
3314
3816
|
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
|
|
@@ -3327,6 +3829,13 @@ class UploadPost {
|
|
|
3327
3829
|
if (config.headers) {
|
|
3328
3830
|
requestOptions.headers = config.headers;
|
|
3329
3831
|
}
|
|
3832
|
+
if (config.isUploadOperation) {
|
|
3833
|
+
requestOptions.headers = {
|
|
3834
|
+
...((_a = requestOptions.headers) !== null && _a !== void 0 ? _a : {}),
|
|
3835
|
+
'Idempotency-Key': buildIdempotencyKey(ctx),
|
|
3836
|
+
'X-Upload-Post-Source': 'n8n',
|
|
3837
|
+
};
|
|
3838
|
+
}
|
|
3330
3839
|
if (config.qs) {
|
|
3331
3840
|
requestOptions.qs = config.qs;
|
|
3332
3841
|
}
|
|
@@ -3343,7 +3852,9 @@ class UploadPost {
|
|
|
3343
3852
|
else {
|
|
3344
3853
|
requestOptions.json = true;
|
|
3345
3854
|
}
|
|
3346
|
-
const rawResponse =
|
|
3855
|
+
const rawResponse = config.skipCredentialAuth
|
|
3856
|
+
? await this.helpers.httpRequest(requestOptions)
|
|
3857
|
+
: await this.helpers.httpRequestWithAuthentication.call(this, 'uploadPostApi', requestOptions);
|
|
3347
3858
|
const responseData = parseJsonIfNeeded(rawResponse);
|
|
3348
3859
|
let finalData = responseData;
|
|
3349
3860
|
if (config.isUploadOperation && config.waitForCompletion) {
|
|
@@ -3351,7 +3862,7 @@ class UploadPost {
|
|
|
3351
3862
|
? responseData.request_id
|
|
3352
3863
|
: undefined;
|
|
3353
3864
|
if (requestId) {
|
|
3354
|
-
finalData = await pollUploadStatus(this, requestId, (
|
|
3865
|
+
finalData = await pollUploadStatus(this, requestId, (_b = config.pollInterval) !== null && _b !== void 0 ? _b : 10, (_c = config.pollTimeout) !== null && _c !== void 0 ? _c : 600);
|
|
3355
3866
|
}
|
|
3356
3867
|
}
|
|
3357
3868
|
returnData.push({
|