n8n-nodes-upload-post 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ The node provides the following operations grouped for clarity:
|
|
|
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).
|
|
78
|
+
- On TikTok, `post_metrics` also carries `retention`, `impression_sources`, `audience_types`, `new_followers`, `reach` and the watch times.
|
|
78
79
|
- **Get Post Analytics by Platform ID**: Per-post metrics for a post published outside Upload-Post.
|
|
79
80
|
- Parameters: Platform Post ID, Platform, Profile Username.
|
|
80
81
|
- **Get Cached Post Analytics**: Replays per-post metrics already fetched, 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 a live per-post endpoint; there is no background refresh, so captured_at is the last time that post was read live.
|
|
@@ -114,6 +115,31 @@ The node provides the following operations grouped for clarity:
|
|
|
114
115
|
- Parameters: JWT token (password field).
|
|
115
116
|
- The API response is returned as-is; its `profile` object also carries the `ui_labels` map configured for that profile.
|
|
116
117
|
|
|
118
|
+
### Comment Actions
|
|
119
|
+
The comment endpoints are shaped like the rest of the API: **one endpoint per question, with a `platform` parameter** that says which connected network is being asked. There is no endpoint per social network.
|
|
120
|
+
- **Get Post Comments**: Comments on a post from the network given by `Platform` (Instagram, Facebook, YouTube, LinkedIn or TikTok).
|
|
121
|
+
- Parameters: User Identifier, Platform, Post ID or URL, Comment ID (optional).
|
|
122
|
+
- Instagram and Facebook accept the media ID or the post URL, YouTube the video ID, LinkedIn the post URN, TikTok the video ID. TikTok has no URL lookup, so pasting a URL fails with a descriptive error instead of an upstream one.
|
|
123
|
+
- Fill **Comment ID** to get the replies to that comment instead of the top-level comments of the post. It is the same question with one parameter more, not a separate operation.
|
|
124
|
+
- **Comment Action**: Moderate one comment — hide, unhide, like, unlike, pin or unpin it.
|
|
125
|
+
- Parameters: User Identifier, Platform, Comment ID, Action, Post ID (shown only when it is needed).
|
|
126
|
+
- Each action carries its own inverse, so there is no separate toggle: `hide`/`unhide`, `like`/`unlike`, `pin`/`unpin`.
|
|
127
|
+
- **Post ID** is required for `hide`, `unhide`, `pin` and `unpin`, and is never sent for `like`/`unlike` — the API rejects a like that carries a post. The node checks it before the request leaves n8n.
|
|
128
|
+
- TikTok is the network that answers this today, and its profile needs the `comments` capability (see the `capabilities` array returned by **List Users**); an account connected before that capability existed has to reconnect TikTok.
|
|
129
|
+
- **Private Reply to Comment**: DM the author of a comment. Instagram only.
|
|
130
|
+
- **Public Reply to Comment**: Public reply under the comment. Instagram only.
|
|
131
|
+
|
|
132
|
+
### Insight Actions
|
|
133
|
+
Two more questions with a `platform` parameter, not two TikTok endpoints. A network that cannot answer a question replies with `platform_not_supported` and the list of the ones that can; today that network is TikTok, whose profile needs the `profile_analytics` capability (see the `capabilities` array returned by **List Users**).
|
|
134
|
+
- **Get Audience**: Who follows the profile and when they are around — audience countries, cities, age brackets and genders, followers online per hour, daily followers gained and lost, profile actions and the bio.
|
|
135
|
+
- Parameters: User Identifier, Platform, Start Date, End Date, Benchmark Category (all optional except the first two).
|
|
136
|
+
- Dates are `YYYY-MM-DD`. The window is clamped **by the server**: 60 days at most, and End Date always below today. A wider range is trimmed, not rejected, so the node sends it as typed.
|
|
137
|
+
- Filling **Benchmark Category** adds a `benchmark` object with that niche's averages (comments, engagement rate, follower count and growth, likes, shares, video count and views) next to the account's own numbers. The 25 accepted values come back in `benchmark_categories` on every response, so filling a picker needs no extra call.
|
|
138
|
+
- Use this to know *who* the audience is and *when* to post; use **Get Post Analytics** for how a given post did.
|
|
139
|
+
- **Get Suggestions**: What to write about — hashtags or the searches people run around a seed word.
|
|
140
|
+
- Parameters: User Identifier, Platform, Type (`hashtags` / `keywords`), Query, Country Code, Language.
|
|
141
|
+
- `Type = hashtags` answers with `hashtags: [{ name, view_count }]`; `Type = keywords` answers with `keywords: [...]`. One endpoint, told apart by `type`, not by operation.
|
|
142
|
+
|
|
117
143
|
Refer to the [Upload Post API Documentation](https://docs.upload-post.com) for detailed information on parameters and platform requirements.
|
|
118
144
|
|
|
119
145
|
### Waiting for asynchronous uploads
|
|
@@ -268,6 +294,10 @@ If you saw duplicate posts on an older version of this node, upgrade: versions b
|
|
|
268
294
|
- **`Description (Optional)`**: Generic description used for LinkedIn, Facebook, YouTube, Pinterest, TikTok when supported.
|
|
269
295
|
- **Platform Description Overrides**: `[platform]_description` (e.g., `youtube_description`, `linkedin_description`).
|
|
270
296
|
- Available for: facebook, tiktok, linkedin, youtube, pinterest
|
|
297
|
+
- **`First Comment`**: Generic first comment posted right after publishing.
|
|
298
|
+
- **Platform First Comment Overrides**: `[platform]_first_comment` (e.g., `instagram_first_comment`, `tiktok_first_comment`).
|
|
299
|
+
- Available for: instagram, facebook, x, threads, youtube (video only), reddit, bluesky, linkedin, tiktok (media only).
|
|
300
|
+
- TikTok needs the `comments` capability on the profile's TikTok account.
|
|
271
301
|
|
|
272
302
|
**⚠️ Runtime Validations**: The node performs automatic validations at runtime including poll constraints, mutually exclusive field checks, and platform-specific requirements. Invalid configurations will throw descriptive error messages.
|
|
273
303
|
|
|
@@ -159,6 +159,7 @@ const FIRST_COMMENT_OVERRIDES = [
|
|
|
159
159
|
{ platform: 'reddit', param: 'redditFirstComment', field: 'reddit_first_comment' },
|
|
160
160
|
{ platform: 'bluesky', param: 'blueskyFirstComment', field: 'bluesky_first_comment' },
|
|
161
161
|
{ platform: 'linkedin', param: 'linkedinFirstComment', field: 'linkedin_first_comment' },
|
|
162
|
+
{ platform: 'tiktok', param: 'tiktokFirstComment', field: 'tiktok_first_comment', operations: ['uploadPhotos', 'uploadVideo'] },
|
|
162
163
|
];
|
|
163
164
|
const getFilteredPlatforms = (operation, platforms) => {
|
|
164
165
|
var _a;
|
|
@@ -1266,18 +1267,28 @@ const buildUserRequest = async (ctx) => {
|
|
|
1266
1267
|
});
|
|
1267
1268
|
}
|
|
1268
1269
|
};
|
|
1270
|
+
const COMMENT_ACTIONS_WITHOUT_POST = new Set(['like', 'unlike']);
|
|
1269
1271
|
const buildInstagramRequest = (ctx) => {
|
|
1270
1272
|
switch (ctx.operation) {
|
|
1271
1273
|
case 'getPostComments': {
|
|
1272
1274
|
const user = ctx.node.getNodeParameter('instagramUser', ctx.itemIndex);
|
|
1275
|
+
const platform = ctx.node.getNodeParameter('commentPlatform', ctx.itemIndex, 'instagram');
|
|
1273
1276
|
const postId = ctx.node.getNodeParameter('instagramPostId', ctx.itemIndex);
|
|
1274
|
-
const qs = { platform
|
|
1277
|
+
const qs = { platform, user };
|
|
1275
1278
|
if (postId.startsWith('http://') || postId.startsWith('https://')) {
|
|
1279
|
+
if (platform === 'tiktok') {
|
|
1280
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), 'TikTok comments are looked up by video ID, not by URL. Paste the numeric video ID instead.', {
|
|
1281
|
+
itemIndex: ctx.itemIndex,
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1276
1284
|
qs.post_url = postId;
|
|
1277
1285
|
}
|
|
1278
1286
|
else {
|
|
1279
1287
|
qs.post_id = postId;
|
|
1280
1288
|
}
|
|
1289
|
+
const commentId = ctx.node.getNodeParameter('commentsCommentId', ctx.itemIndex, '');
|
|
1290
|
+
if (commentId)
|
|
1291
|
+
qs.comment_id = commentId;
|
|
1281
1292
|
return {
|
|
1282
1293
|
endpoint: '/uploadposts/comments',
|
|
1283
1294
|
method: 'GET',
|
|
@@ -1310,12 +1321,91 @@ const buildInstagramRequest = (ctx) => {
|
|
|
1310
1321
|
waitForCompletion: false,
|
|
1311
1322
|
};
|
|
1312
1323
|
}
|
|
1324
|
+
case 'commentAction': {
|
|
1325
|
+
const user = ctx.node.getNodeParameter('instagramUser', ctx.itemIndex);
|
|
1326
|
+
const platform = ctx.node.getNodeParameter('commentActionPlatform', ctx.itemIndex, 'tiktok');
|
|
1327
|
+
const action = ctx.node.getNodeParameter('commentModerationAction', ctx.itemIndex);
|
|
1328
|
+
const body = {
|
|
1329
|
+
platform,
|
|
1330
|
+
user,
|
|
1331
|
+
comment_id: ctx.node.getNodeParameter('instagramCommentId', ctx.itemIndex),
|
|
1332
|
+
action,
|
|
1333
|
+
};
|
|
1334
|
+
if (!COMMENT_ACTIONS_WITHOUT_POST.has(action)) {
|
|
1335
|
+
const postId = ctx.node.getNodeParameter('commentActionPostId', ctx.itemIndex, '');
|
|
1336
|
+
if (!postId) {
|
|
1337
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `A Post ID is required to ${action} a comment.`, {
|
|
1338
|
+
itemIndex: ctx.itemIndex,
|
|
1339
|
+
});
|
|
1340
|
+
}
|
|
1341
|
+
body.post_id = postId;
|
|
1342
|
+
}
|
|
1343
|
+
return {
|
|
1344
|
+
endpoint: '/uploadposts/comments/action',
|
|
1345
|
+
method: 'POST',
|
|
1346
|
+
body,
|
|
1347
|
+
isUploadOperation: false,
|
|
1348
|
+
waitForCompletion: false,
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1313
1351
|
default:
|
|
1314
1352
|
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported Instagram operation: ${ctx.operation}`, {
|
|
1315
1353
|
itemIndex: ctx.itemIndex,
|
|
1316
1354
|
});
|
|
1317
1355
|
}
|
|
1318
1356
|
};
|
|
1357
|
+
const buildInsightsRequest = (ctx) => {
|
|
1358
|
+
const user = ctx.node.getNodeParameter('insightsUser', ctx.itemIndex);
|
|
1359
|
+
const platform = ctx.node.getNodeParameter('insightsPlatform', ctx.itemIndex, 'tiktok');
|
|
1360
|
+
switch (ctx.operation) {
|
|
1361
|
+
case 'getAudience': {
|
|
1362
|
+
const qs = { user, platform };
|
|
1363
|
+
const startDate = ctx.node.getNodeParameter('audienceStartDate', ctx.itemIndex, '');
|
|
1364
|
+
if (startDate)
|
|
1365
|
+
qs.start_date = startDate.slice(0, 10);
|
|
1366
|
+
const endDate = ctx.node.getNodeParameter('audienceEndDate', ctx.itemIndex, '');
|
|
1367
|
+
if (endDate)
|
|
1368
|
+
qs.end_date = endDate.slice(0, 10);
|
|
1369
|
+
const benchmarkCategory = ctx.node.getNodeParameter('audienceBenchmarkCategory', ctx.itemIndex, '');
|
|
1370
|
+
if (benchmarkCategory)
|
|
1371
|
+
qs.benchmark_category = benchmarkCategory;
|
|
1372
|
+
return {
|
|
1373
|
+
endpoint: '/uploadposts/audience',
|
|
1374
|
+
method: 'GET',
|
|
1375
|
+
qs,
|
|
1376
|
+
isUploadOperation: false,
|
|
1377
|
+
waitForCompletion: false,
|
|
1378
|
+
};
|
|
1379
|
+
}
|
|
1380
|
+
case 'getSuggestions': {
|
|
1381
|
+
const qs = {
|
|
1382
|
+
user,
|
|
1383
|
+
platform,
|
|
1384
|
+
type: ctx.node.getNodeParameter('suggestionsType', ctx.itemIndex),
|
|
1385
|
+
};
|
|
1386
|
+
const query = ctx.node.getNodeParameter('suggestionsQuery', ctx.itemIndex, '');
|
|
1387
|
+
if (query)
|
|
1388
|
+
qs.q = query;
|
|
1389
|
+
const countryCode = ctx.node.getNodeParameter('suggestionsCountryCode', ctx.itemIndex, '');
|
|
1390
|
+
if (countryCode)
|
|
1391
|
+
qs.country_code = countryCode;
|
|
1392
|
+
const language = ctx.node.getNodeParameter('suggestionsLanguage', ctx.itemIndex, '');
|
|
1393
|
+
if (language)
|
|
1394
|
+
qs.language = language;
|
|
1395
|
+
return {
|
|
1396
|
+
endpoint: '/uploadposts/suggestions',
|
|
1397
|
+
method: 'GET',
|
|
1398
|
+
qs,
|
|
1399
|
+
isUploadOperation: false,
|
|
1400
|
+
waitForCompletion: false,
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
default:
|
|
1404
|
+
throw new n8n_workflow_1.NodeOperationError(ctx.node.getNode(), `Unsupported insights operation: ${ctx.operation}`, {
|
|
1405
|
+
itemIndex: ctx.itemIndex,
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1319
1409
|
const buildRequestConfig = async (ctx) => {
|
|
1320
1410
|
if (ctx.operation === 'uploadPhotos') {
|
|
1321
1411
|
return buildUploadPhotosRequest(ctx);
|
|
@@ -1333,6 +1423,9 @@ const buildRequestConfig = async (ctx) => {
|
|
|
1333
1423
|
if (resource === 'instagram') {
|
|
1334
1424
|
return buildInstagramRequest(ctx);
|
|
1335
1425
|
}
|
|
1426
|
+
if (resource === 'insights') {
|
|
1427
|
+
return buildInsightsRequest(ctx);
|
|
1428
|
+
}
|
|
1336
1429
|
if (resource === 'monitoring') {
|
|
1337
1430
|
return buildMonitoringRequest(ctx);
|
|
1338
1431
|
}
|
|
@@ -1436,9 +1529,10 @@ class UploadPost {
|
|
|
1436
1529
|
type: 'options',
|
|
1437
1530
|
noDataExpression: true,
|
|
1438
1531
|
options: [
|
|
1439
|
-
{ name: '
|
|
1440
|
-
{ name: '
|
|
1532
|
+
{ name: 'Comment', value: 'instagram' },
|
|
1533
|
+
{ name: 'Insight', value: 'insights' },
|
|
1441
1534
|
{ name: 'Status & History', value: 'monitoring' },
|
|
1535
|
+
{ name: 'Upload', value: 'uploads' },
|
|
1442
1536
|
{ name: 'User', value: 'users' },
|
|
1443
1537
|
],
|
|
1444
1538
|
default: 'uploads',
|
|
@@ -1469,7 +1563,7 @@ class UploadPost {
|
|
|
1469
1563
|
{ 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.' },
|
|
1470
1564
|
{ name: 'Get Job Status', value: 'getJobStatus', action: 'Get job status', description: 'Check the status of a scheduled or queued post using the job_id' },
|
|
1471
1565
|
{ name: 'Get Platform Metrics', value: 'getPlatformMetrics', action: 'Get platform metrics', description: 'List the analytics metrics available for each platform' },
|
|
1472
|
-
{ name: 'Get Post Analytics', value: 'getPostAnalytics', action: 'Get post analytics', description: 'Retrieve per-post analytics for an upload using its request_id' },
|
|
1566
|
+
{ 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.' },
|
|
1473
1567
|
{ 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' },
|
|
1474
1568
|
{ name: 'Get Reddit Detailed Posts', value: 'getRedditDetailedPosts', action: 'Get reddit detailed posts', description: 'Retrieve detailed Reddit posts with full media information' },
|
|
1475
1569
|
{ name: 'Get Total Impressions', value: 'getTotalImpressions', action: 'Get total impressions', description: 'Retrieve impressions aggregated across connected platforms for a date range' },
|
|
@@ -1505,9 +1599,10 @@ class UploadPost {
|
|
|
1505
1599
|
type: 'options',
|
|
1506
1600
|
noDataExpression: true,
|
|
1507
1601
|
options: [
|
|
1508
|
-
{ name: '
|
|
1509
|
-
{ name: '
|
|
1510
|
-
{ name: '
|
|
1602
|
+
{ 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.' },
|
|
1603
|
+
{ 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
|
+
{ 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
|
+
{ name: 'Public Reply to Comment', value: 'publicReplyToComment', action: 'Public reply to comment', description: 'Post a public reply visible under the original comment. Instagram only.' },
|
|
1511
1606
|
],
|
|
1512
1607
|
default: 'getPostComments',
|
|
1513
1608
|
displayOptions: { show: { resource: ['instagram'] } },
|
|
@@ -1524,7 +1619,40 @@ class UploadPost {
|
|
|
1524
1619
|
displayOptions: {
|
|
1525
1620
|
show: {
|
|
1526
1621
|
resource: ['instagram'],
|
|
1527
|
-
operation: ['getPostComments', 'privateReplyToComment', 'publicReplyToComment'],
|
|
1622
|
+
operation: ['getPostComments', 'privateReplyToComment', 'publicReplyToComment', 'commentAction'],
|
|
1623
|
+
},
|
|
1624
|
+
},
|
|
1625
|
+
},
|
|
1626
|
+
{
|
|
1627
|
+
displayName: 'Platform',
|
|
1628
|
+
name: 'commentPlatform',
|
|
1629
|
+
type: 'options',
|
|
1630
|
+
options: [
|
|
1631
|
+
{ name: 'Facebook', value: 'facebook' },
|
|
1632
|
+
{ name: 'Instagram', value: 'instagram' },
|
|
1633
|
+
{ name: 'LinkedIn', value: 'linkedin' },
|
|
1634
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
1635
|
+
{ name: 'YouTube', value: 'youtube' },
|
|
1636
|
+
],
|
|
1637
|
+
default: 'instagram',
|
|
1638
|
+
description: 'Network the post lives on. TikTok needs the "comments" capability on the profile (see the capabilities array returned by List Users); an account connected before that capability existed has to reconnect TikTok.',
|
|
1639
|
+
displayOptions: {
|
|
1640
|
+
show: {
|
|
1641
|
+
resource: ['instagram'],
|
|
1642
|
+
operation: ['getPostComments'],
|
|
1643
|
+
},
|
|
1644
|
+
},
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
displayName: 'Comment ID',
|
|
1648
|
+
name: 'commentsCommentId',
|
|
1649
|
+
type: 'string',
|
|
1650
|
+
default: '',
|
|
1651
|
+
description: 'Leave empty for the top-level comments of the post. Set it to a comment ID to get the replies to that comment instead: it is the same question with one parameter more.',
|
|
1652
|
+
displayOptions: {
|
|
1653
|
+
show: {
|
|
1654
|
+
resource: ['instagram'],
|
|
1655
|
+
operation: ['getPostComments'],
|
|
1528
1656
|
},
|
|
1529
1657
|
},
|
|
1530
1658
|
},
|
|
@@ -1534,7 +1662,7 @@ class UploadPost {
|
|
|
1534
1662
|
type: 'string',
|
|
1535
1663
|
required: true,
|
|
1536
1664
|
default: '',
|
|
1537
|
-
description: '
|
|
1665
|
+
description: 'Post identifier. Instagram and Facebook accept the numeric media ID or the post URL, YouTube the video ID, LinkedIn the post URN, TikTok the video ID (TikTok has no URL lookup).',
|
|
1538
1666
|
displayOptions: {
|
|
1539
1667
|
show: {
|
|
1540
1668
|
resource: ['instagram'],
|
|
@@ -1548,11 +1676,55 @@ class UploadPost {
|
|
|
1548
1676
|
type: 'string',
|
|
1549
1677
|
required: true,
|
|
1550
1678
|
default: '',
|
|
1551
|
-
description: 'The ID of the comment to reply to (from Get Post Comments)',
|
|
1679
|
+
description: 'The ID of the comment to reply to or act on (from Get Post Comments)',
|
|
1552
1680
|
displayOptions: {
|
|
1553
1681
|
show: {
|
|
1554
1682
|
resource: ['instagram'],
|
|
1555
|
-
operation: ['privateReplyToComment', 'publicReplyToComment'],
|
|
1683
|
+
operation: ['privateReplyToComment', 'publicReplyToComment', 'commentAction'],
|
|
1684
|
+
},
|
|
1685
|
+
},
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
displayName: 'Platform',
|
|
1689
|
+
name: 'commentActionPlatform',
|
|
1690
|
+
type: 'options',
|
|
1691
|
+
required: true,
|
|
1692
|
+
options: [
|
|
1693
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
1694
|
+
],
|
|
1695
|
+
default: 'tiktok',
|
|
1696
|
+
description: 'Network the comment lives on. 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 "comments" capability (see the capabilities array returned by List Users); an account connected before that capability existed has to reconnect TikTok.',
|
|
1697
|
+
displayOptions: { show: { resource: ['instagram'], operation: ['commentAction'] } },
|
|
1698
|
+
},
|
|
1699
|
+
{
|
|
1700
|
+
displayName: 'Action',
|
|
1701
|
+
name: 'commentModerationAction',
|
|
1702
|
+
type: 'options',
|
|
1703
|
+
required: true,
|
|
1704
|
+
options: [
|
|
1705
|
+
{ name: 'Hide', value: 'hide' },
|
|
1706
|
+
{ name: 'Like', value: 'like' },
|
|
1707
|
+
{ name: 'Pin', value: 'pin' },
|
|
1708
|
+
{ name: 'Unhide', value: 'unhide' },
|
|
1709
|
+
{ name: 'Unlike', value: 'unlike' },
|
|
1710
|
+
{ name: 'Unpin', value: 'unpin' },
|
|
1711
|
+
],
|
|
1712
|
+
default: 'hide',
|
|
1713
|
+
description: 'What to do with the comment. Each action carries its own inverse, so there is no separate toggle: hide/unhide change its visibility, like/unlike react to it as the account, pin/unpin move it to the top of the thread.',
|
|
1714
|
+
displayOptions: { show: { resource: ['instagram'], operation: ['commentAction'] } },
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
displayName: 'Post ID',
|
|
1718
|
+
name: 'commentActionPostId',
|
|
1719
|
+
type: 'string',
|
|
1720
|
+
required: true,
|
|
1721
|
+
default: '',
|
|
1722
|
+
description: 'Native ID of the post the comment hangs from, as the platform assigns it (on TikTok, the video ID). Required to hide, unhide, pin or unpin; it is not sent for like or unlike, which the API rejects when it carries a post.',
|
|
1723
|
+
displayOptions: {
|
|
1724
|
+
show: {
|
|
1725
|
+
resource: ['instagram'],
|
|
1726
|
+
operation: ['commentAction'],
|
|
1727
|
+
commentModerationAction: ['hide', 'unhide', 'pin', 'unpin'],
|
|
1556
1728
|
},
|
|
1557
1729
|
},
|
|
1558
1730
|
},
|
|
@@ -1571,6 +1743,107 @@ class UploadPost {
|
|
|
1571
1743
|
},
|
|
1572
1744
|
},
|
|
1573
1745
|
},
|
|
1746
|
+
{
|
|
1747
|
+
displayName: 'Operation',
|
|
1748
|
+
name: 'operation',
|
|
1749
|
+
type: 'options',
|
|
1750
|
+
noDataExpression: true,
|
|
1751
|
+
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.' },
|
|
1754
|
+
],
|
|
1755
|
+
default: 'getAudience',
|
|
1756
|
+
displayOptions: { show: { resource: ['insights'] } },
|
|
1757
|
+
},
|
|
1758
|
+
{
|
|
1759
|
+
displayName: 'User Identifier Name or ID',
|
|
1760
|
+
name: 'insightsUser',
|
|
1761
|
+
type: 'options',
|
|
1762
|
+
noDataExpression: true,
|
|
1763
|
+
required: true,
|
|
1764
|
+
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>.',
|
|
1766
|
+
typeOptions: { loadOptionsMethod: 'getUserProfiles' },
|
|
1767
|
+
displayOptions: { show: { resource: ['insights'] } },
|
|
1768
|
+
},
|
|
1769
|
+
{
|
|
1770
|
+
displayName: 'Platform',
|
|
1771
|
+
name: 'insightsPlatform',
|
|
1772
|
+
type: 'options',
|
|
1773
|
+
required: true,
|
|
1774
|
+
options: [
|
|
1775
|
+
{ name: 'TikTok', value: 'tiktok' },
|
|
1776
|
+
],
|
|
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'] } },
|
|
1780
|
+
},
|
|
1781
|
+
{
|
|
1782
|
+
displayName: 'Start Date',
|
|
1783
|
+
name: 'audienceStartDate',
|
|
1784
|
+
type: 'string',
|
|
1785
|
+
default: '',
|
|
1786
|
+
placeholder: 'YYYY-MM-DD',
|
|
1787
|
+
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.',
|
|
1788
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getAudience'] } },
|
|
1789
|
+
},
|
|
1790
|
+
{
|
|
1791
|
+
displayName: 'End Date',
|
|
1792
|
+
name: 'audienceEndDate',
|
|
1793
|
+
type: 'string',
|
|
1794
|
+
default: '',
|
|
1795
|
+
placeholder: 'YYYY-MM-DD',
|
|
1796
|
+
description: 'Last day of the window. The server moves it below today, because there are no audience numbers for the current day yet.',
|
|
1797
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getAudience'] } },
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
displayName: 'Benchmark Category',
|
|
1801
|
+
name: 'audienceBenchmarkCategory',
|
|
1802
|
+
type: 'string',
|
|
1803
|
+
default: '',
|
|
1804
|
+
placeholder: 'SOFTWARE_AND_APPS',
|
|
1805
|
+
description: 'Niche to compare the account against, which adds a benchmark object to the response. Leave empty to skip the comparison: the accepted values come back in benchmark_categories on every response anyway, so no extra call is needed to fill a picker.',
|
|
1806
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getAudience'] } },
|
|
1807
|
+
},
|
|
1808
|
+
{
|
|
1809
|
+
displayName: 'Type',
|
|
1810
|
+
name: 'suggestionsType',
|
|
1811
|
+
type: 'options',
|
|
1812
|
+
required: true,
|
|
1813
|
+
options: [
|
|
1814
|
+
{ name: 'Hashtags', value: 'hashtags' },
|
|
1815
|
+
{ name: 'Keywords', value: 'keywords' },
|
|
1816
|
+
],
|
|
1817
|
+
default: 'hashtags',
|
|
1818
|
+
description: 'Which suggestions you want. Hashtags answers with a list of name and view_count; keywords answers with the searches people run around the word.',
|
|
1819
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getSuggestions'] } },
|
|
1820
|
+
},
|
|
1821
|
+
{
|
|
1822
|
+
displayName: 'Query',
|
|
1823
|
+
name: 'suggestionsQuery',
|
|
1824
|
+
type: 'string',
|
|
1825
|
+
default: '',
|
|
1826
|
+
description: 'Seed word to get suggestions around, written without the "#"',
|
|
1827
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getSuggestions'] } },
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
displayName: 'Country Code',
|
|
1831
|
+
name: 'suggestionsCountryCode',
|
|
1832
|
+
type: 'string',
|
|
1833
|
+
default: '',
|
|
1834
|
+
placeholder: 'ES',
|
|
1835
|
+
description: 'ISO 3166-1 alpha-2 country to bias the suggestions towards, e.g. ES or US',
|
|
1836
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getSuggestions'] } },
|
|
1837
|
+
},
|
|
1838
|
+
{
|
|
1839
|
+
displayName: 'Language',
|
|
1840
|
+
name: 'suggestionsLanguage',
|
|
1841
|
+
type: 'string',
|
|
1842
|
+
default: '',
|
|
1843
|
+
placeholder: 'es',
|
|
1844
|
+
description: 'Language code to bias the suggestions towards, e.g. es or en',
|
|
1845
|
+
displayOptions: { show: { resource: ['insights'], operation: ['getSuggestions'] } },
|
|
1846
|
+
},
|
|
1574
1847
|
{
|
|
1575
1848
|
displayName: 'User Identifier Name or ID',
|
|
1576
1849
|
name: 'user',
|
|
@@ -1625,7 +1898,7 @@ class UploadPost {
|
|
|
1625
1898
|
name: 'firstComment',
|
|
1626
1899
|
type: 'string',
|
|
1627
1900
|
default: '',
|
|
1628
|
-
description: 'Text to post as the first comment (or reply) immediately after publishing. Supported on Instagram, Facebook, X, Threads, YouTube, Reddit, Bluesky.',
|
|
1901
|
+
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).',
|
|
1629
1902
|
displayOptions: { show: { resource: ['uploads'], operation: ['uploadPhotos', 'uploadVideo', 'uploadText'] } },
|
|
1630
1903
|
},
|
|
1631
1904
|
{
|
|
@@ -1905,6 +2178,14 @@ class UploadPost {
|
|
|
1905
2178
|
description: 'Optional override for LinkedIn first comment. If provided, overrides the generic First Comment for LinkedIn.',
|
|
1906
2179
|
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo', 'uploadText', 'uploadDocument'], platform: ['linkedin', '__manual_platform__'] } },
|
|
1907
2180
|
},
|
|
2181
|
+
{
|
|
2182
|
+
displayName: 'TikTok First Comment (Override)',
|
|
2183
|
+
name: 'tiktokFirstComment',
|
|
2184
|
+
type: 'string',
|
|
2185
|
+
default: '',
|
|
2186
|
+
description: 'Optional override for the TikTok first comment. If provided, overrides the generic First Comment for TikTok. The profile needs the "comments" capability (see the capabilities array returned by List Users); an account connected before that capability existed has to reconnect TikTok.',
|
|
2187
|
+
displayOptions: { show: { operation: ['uploadPhotos', 'uploadVideo'], platform: ['tiktok', '__manual_platform__'] } },
|
|
2188
|
+
},
|
|
1908
2189
|
{
|
|
1909
2190
|
displayName: 'Photos (Files or URLs)',
|
|
1910
2191
|
name: 'photos',
|