upload-post 2.0.4 → 2.1.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 +11 -0
- package/index.d.ts +82 -7
- package/index.js +145 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,6 +123,13 @@ const status = await client.getStatus('request_id_from_upload');
|
|
|
123
123
|
console.log(status);
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
+
For scheduled or queued posts, check the status using the job_id:
|
|
127
|
+
|
|
128
|
+
```javascript
|
|
129
|
+
const status = await client.getJobStatus('job_id_from_scheduled_post');
|
|
130
|
+
console.log(status);
|
|
131
|
+
```
|
|
132
|
+
|
|
126
133
|
### Get Upload History
|
|
127
134
|
|
|
128
135
|
```javascript
|
|
@@ -267,6 +274,7 @@ const boards = await client.getPinterestBoards('my-profile');
|
|
|
267
274
|
### Threads
|
|
268
275
|
- `threadsLongTextAsPost` - Post long text as single post (vs thread)
|
|
269
276
|
- `threadsThreadMediaLayout` - Comma-separated list of how many media items to include in each Threads post. Each value must be 1-10, and the total must equal the number of files. Example: '5,5' splits 10 items into 2 posts with 5 each. If omitted and more than 10 items are provided, auto-chunks into groups of 10.
|
|
277
|
+
- `threadsTopicTag` - Topic tag for the Threads post (1-50 characters, no periods or ampersands). One tag per post. Helps increase reach.
|
|
270
278
|
|
|
271
279
|
### Reddit
|
|
272
280
|
- `redditSubreddit` - Subreddit name (without r/)
|
|
@@ -286,6 +294,7 @@ These options work across all upload methods:
|
|
|
286
294
|
| `scheduledDate` | ISO date for scheduling |
|
|
287
295
|
| `timezone` | Timezone for scheduled date |
|
|
288
296
|
| `addToQueue` | Add to posting queue |
|
|
297
|
+
| `maxPostsPerSlot` | Max posts per queue slot (overrides profile setting) |
|
|
289
298
|
| `asyncUpload` | Process asynchronously (default: true) |
|
|
290
299
|
|
|
291
300
|
## TypeScript Support
|
|
@@ -327,3 +336,5 @@ try {
|
|
|
327
336
|
## License
|
|
328
337
|
|
|
329
338
|
MIT
|
|
339
|
+
|
|
340
|
+
<!-- deployed 2026-03-16 17:49 UTC -->
|
package/index.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ declare module 'upload-post' {
|
|
|
2
2
|
// ==================== Common Types ====================
|
|
3
3
|
|
|
4
4
|
/** Supported platforms for video upload */
|
|
5
|
-
export type VideoPlatform = 'tiktok' | 'instagram' | 'youtube' | 'linkedin' | 'facebook' | 'pinterest' | 'threads' | 'bluesky' | 'x';
|
|
5
|
+
export type VideoPlatform = 'tiktok' | 'instagram' | 'youtube' | 'linkedin' | 'facebook' | 'pinterest' | 'threads' | 'bluesky' | 'x' | 'google_business';
|
|
6
6
|
|
|
7
7
|
/** Supported platforms for photo upload */
|
|
8
|
-
export type PhotoPlatform = 'tiktok' | 'instagram' | 'linkedin' | 'facebook' | 'pinterest' | 'threads' | 'reddit' | 'bluesky' | 'x';
|
|
8
|
+
export type PhotoPlatform = 'tiktok' | 'instagram' | 'linkedin' | 'facebook' | 'pinterest' | 'threads' | 'reddit' | 'bluesky' | 'x' | 'google_business';
|
|
9
9
|
|
|
10
10
|
/** Supported platforms for text upload */
|
|
11
|
-
export type TextPlatform = 'x' | 'linkedin' | 'facebook' | 'threads' | 'reddit' | 'bluesky';
|
|
11
|
+
export type TextPlatform = 'x' | 'linkedin' | 'facebook' | 'threads' | 'reddit' | 'bluesky' | 'google_business';
|
|
12
12
|
|
|
13
13
|
/** TikTok privacy levels */
|
|
14
14
|
export type TikTokPrivacyLevel = 'PUBLIC_TO_EVERYONE' | 'MUTUAL_FOLLOW_FRIENDS' | 'FOLLOWER_OF_CREATOR' | 'SELF_ONLY';
|
|
@@ -43,8 +43,8 @@ declare module 'upload-post' {
|
|
|
43
43
|
// ==================== Common Options ====================
|
|
44
44
|
|
|
45
45
|
export interface CommonUploadOptions {
|
|
46
|
-
/** Post title/caption */
|
|
47
|
-
title
|
|
46
|
+
/** Post title/caption. Required for YouTube, Reddit, and text posts. Optional for TikTok, Instagram, Facebook, LinkedIn, X, Threads, Bluesky, Pinterest. */
|
|
47
|
+
title?: string;
|
|
48
48
|
/** User identifier (profile name) */
|
|
49
49
|
user: string;
|
|
50
50
|
/** First comment to post after publishing */
|
|
@@ -57,6 +57,8 @@ declare module 'upload-post' {
|
|
|
57
57
|
timezone?: string;
|
|
58
58
|
/** Add to posting queue instead of immediate post */
|
|
59
59
|
addToQueue?: boolean;
|
|
60
|
+
/** Maximum number of posts allowed per queue slot (overrides profile setting). Only used when addToQueue is true. */
|
|
61
|
+
maxPostsPerSlot?: number;
|
|
60
62
|
/** Process upload asynchronously (default: true) */
|
|
61
63
|
asyncUpload?: boolean;
|
|
62
64
|
|
|
@@ -343,12 +345,22 @@ declare module 'upload-post' {
|
|
|
343
345
|
platforms: PhotoPlatform[];
|
|
344
346
|
}
|
|
345
347
|
|
|
348
|
+
export interface LinkPreviewOptions {
|
|
349
|
+
/** Generic URL for link preview card (works for LinkedIn, Bluesky, Facebook). Platform-specific params take priority. */
|
|
350
|
+
linkUrl?: string;
|
|
351
|
+
/** URL for link preview card on LinkedIn */
|
|
352
|
+
linkedinLinkUrl?: string;
|
|
353
|
+
/** URL for external embed link preview on Bluesky */
|
|
354
|
+
blueskyLinkUrl?: string;
|
|
355
|
+
}
|
|
356
|
+
|
|
346
357
|
export interface UploadTextOptions extends CommonUploadOptions,
|
|
347
358
|
LinkedInOptions,
|
|
348
359
|
FacebookTextOptions,
|
|
349
360
|
XTextOptions,
|
|
350
361
|
ThreadsOptions,
|
|
351
|
-
RedditOptions
|
|
362
|
+
RedditOptions,
|
|
363
|
+
LinkPreviewOptions {
|
|
352
364
|
/** Target platforms */
|
|
353
365
|
platforms: TextPlatform[];
|
|
354
366
|
}
|
|
@@ -370,6 +382,8 @@ declare module 'upload-post' {
|
|
|
370
382
|
timezone?: string;
|
|
371
383
|
/** Add to posting queue */
|
|
372
384
|
addToQueue?: boolean;
|
|
385
|
+
/** Maximum number of posts allowed per queue slot (overrides profile setting). Only used when addToQueue is true. */
|
|
386
|
+
maxPostsPerSlot?: number;
|
|
373
387
|
/** Process upload asynchronously */
|
|
374
388
|
asyncUpload?: boolean;
|
|
375
389
|
}
|
|
@@ -501,6 +515,12 @@ declare module 'upload-post' {
|
|
|
501
515
|
*/
|
|
502
516
|
getStatus(requestId: string): Promise<StatusResponse>;
|
|
503
517
|
|
|
518
|
+
/**
|
|
519
|
+
* Get the status of a scheduled or queued upload by job ID
|
|
520
|
+
* @param jobId - The job_id from a scheduled or queued upload
|
|
521
|
+
*/
|
|
522
|
+
getJobStatus(jobId: string): Promise<StatusResponse>;
|
|
523
|
+
|
|
504
524
|
/**
|
|
505
525
|
* Get upload history
|
|
506
526
|
* @param options - Query options
|
|
@@ -512,7 +532,62 @@ declare module 'upload-post' {
|
|
|
512
532
|
* @param profileUsername - Profile username
|
|
513
533
|
* @param options - Query options
|
|
514
534
|
*/
|
|
515
|
-
getAnalytics(profileUsername: string, options?: { platforms?: string[] }): Promise<AnalyticsResponse>;
|
|
535
|
+
getAnalytics(profileUsername: string, options?: { platforms?: string[]; pageId?: string; pageUrn?: string }): Promise<AnalyticsResponse>;
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Get total impressions for a profile from daily snapshots
|
|
539
|
+
* @param profileUsername - Profile username
|
|
540
|
+
* @param options - Query options
|
|
541
|
+
*/
|
|
542
|
+
getTotalImpressions(profileUsername: string, options?: {
|
|
543
|
+
period?: 'last_day' | 'last_week' | 'last_month' | 'last_3months' | 'last_year';
|
|
544
|
+
startDate?: string;
|
|
545
|
+
endDate?: string;
|
|
546
|
+
date?: string;
|
|
547
|
+
platforms?: string[];
|
|
548
|
+
breakdown?: boolean;
|
|
549
|
+
metrics?: string[];
|
|
550
|
+
}): Promise<{
|
|
551
|
+
success: boolean;
|
|
552
|
+
profile_username: string;
|
|
553
|
+
start_date: string;
|
|
554
|
+
end_date: string;
|
|
555
|
+
total_impressions?: number;
|
|
556
|
+
metrics?: Record<string, number>;
|
|
557
|
+
per_platform?: Record<string, number | Record<string, number>>;
|
|
558
|
+
per_day?: Record<string, number | Record<string, number>>;
|
|
559
|
+
platforms_filter?: string[];
|
|
560
|
+
}>;
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Get analytics for a specific post across all platforms
|
|
564
|
+
* @param requestId - The request_id from the upload
|
|
565
|
+
*/
|
|
566
|
+
getPostAnalytics(requestId: string): Promise<{
|
|
567
|
+
success: boolean;
|
|
568
|
+
post: { request_id: string; profile_username: string; post_title: string; post_caption: string; media_type: string; upload_timestamp: string };
|
|
569
|
+
platforms: Record<string, {
|
|
570
|
+
success: boolean;
|
|
571
|
+
platform_post_id?: string;
|
|
572
|
+
post_url?: string;
|
|
573
|
+
post_metrics?: Record<string, number>;
|
|
574
|
+
post_metrics_source?: string;
|
|
575
|
+
post_metrics_error?: string;
|
|
576
|
+
profile_snapshot_at_post_date?: Record<string, number>;
|
|
577
|
+
profile_snapshot_latest?: Record<string, number>;
|
|
578
|
+
profile_snapshot_latest_date?: string;
|
|
579
|
+
error_message?: string;
|
|
580
|
+
}>;
|
|
581
|
+
}>;
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Get available metrics configuration for all supported platforms
|
|
585
|
+
*/
|
|
586
|
+
getPlatformMetrics(): Promise<Record<string, {
|
|
587
|
+
primary_impressions_field: string;
|
|
588
|
+
available_metrics: string[];
|
|
589
|
+
metric_labels: Record<string, string>;
|
|
590
|
+
}>>;
|
|
516
591
|
|
|
517
592
|
// Scheduled Posts
|
|
518
593
|
/**
|
package/index.js
CHANGED
|
@@ -29,7 +29,8 @@ export class UploadPost {
|
|
|
29
29
|
method,
|
|
30
30
|
url: `${this.baseUrl}${endpoint}`,
|
|
31
31
|
headers: {
|
|
32
|
-
'Authorization': `Apikey ${this.apiKey}
|
|
32
|
+
'Authorization': `Apikey ${this.apiKey}`,
|
|
33
|
+
'X-Upload-Post-Source': 'npm',
|
|
33
34
|
},
|
|
34
35
|
maxContentLength: Infinity,
|
|
35
36
|
maxBodyLength: Infinity
|
|
@@ -62,7 +63,7 @@ export class UploadPost {
|
|
|
62
63
|
*/
|
|
63
64
|
_addCommonParams(form, options) {
|
|
64
65
|
form.append('user', options.user);
|
|
65
|
-
form.append('title', options.title);
|
|
66
|
+
if (options.title) form.append('title', options.title);
|
|
66
67
|
|
|
67
68
|
// Platforms
|
|
68
69
|
const platforms = Array.isArray(options.platforms) ? options.platforms : [options.platforms];
|
|
@@ -74,6 +75,7 @@ export class UploadPost {
|
|
|
74
75
|
if (options.scheduledDate) form.append('scheduled_date', options.scheduledDate);
|
|
75
76
|
if (options.timezone) form.append('timezone', options.timezone);
|
|
76
77
|
if (options.addToQueue !== undefined) form.append('add_to_queue', String(options.addToQueue));
|
|
78
|
+
if (options.maxPostsPerSlot !== undefined) form.append('max_posts_per_slot', String(options.maxPostsPerSlot));
|
|
77
79
|
if (options.asyncUpload !== undefined) form.append('async_upload', String(options.asyncUpload));
|
|
78
80
|
|
|
79
81
|
// Platform-specific title overrides
|
|
@@ -103,6 +105,24 @@ export class UploadPost {
|
|
|
103
105
|
if (options.youtubeFirstComment) form.append('youtube_first_comment', options.youtubeFirstComment);
|
|
104
106
|
if (options.redditFirstComment) form.append('reddit_first_comment', options.redditFirstComment);
|
|
105
107
|
if (options.blueskyFirstComment) form.append('bluesky_first_comment', options.blueskyFirstComment);
|
|
108
|
+
if (options.linkedinFirstComment) form.append('linkedin_first_comment', options.linkedinFirstComment);
|
|
109
|
+
|
|
110
|
+
if (options.firstCommentMedia) {
|
|
111
|
+
const mediaItems = Array.isArray(options.firstCommentMedia) ? options.firstCommentMedia : [options.firstCommentMedia];
|
|
112
|
+
for (const mediaItem of mediaItems) {
|
|
113
|
+
if (typeof mediaItem === 'string') {
|
|
114
|
+
if (mediaItem.toLowerCase().startsWith('http://') || mediaItem.toLowerCase().startsWith('https://')) {
|
|
115
|
+
form.append('first_comment_media[]', mediaItem);
|
|
116
|
+
} else {
|
|
117
|
+
if (fs.existsSync(mediaItem)) {
|
|
118
|
+
form.append('first_comment_media[]', createReadStream(mediaItem));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
form.append('first_comment_media[]', mediaItem);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
106
126
|
}
|
|
107
127
|
|
|
108
128
|
/**
|
|
@@ -175,9 +195,12 @@ export class UploadPost {
|
|
|
175
195
|
* Add LinkedIn-specific parameters
|
|
176
196
|
* @private
|
|
177
197
|
*/
|
|
178
|
-
_addLinkedinParams(form, options) {
|
|
198
|
+
_addLinkedinParams(form, options, isText = false) {
|
|
179
199
|
if (options.linkedinVisibility) form.append('visibility', options.linkedinVisibility);
|
|
180
200
|
if (options.targetLinkedinPageId) form.append('target_linkedin_page_id', options.targetLinkedinPageId);
|
|
201
|
+
if (isText && (options.linkedinLinkUrl || options.linkUrl)) {
|
|
202
|
+
form.append('linkedin_link_url', options.linkedinLinkUrl || options.linkUrl);
|
|
203
|
+
}
|
|
181
204
|
}
|
|
182
205
|
|
|
183
206
|
/**
|
|
@@ -258,15 +281,19 @@ export class UploadPost {
|
|
|
258
281
|
_addThreadsParams(form, options) {
|
|
259
282
|
if (options.threadsLongTextAsPost !== undefined) form.append('threads_long_text_as_post', String(options.threadsLongTextAsPost));
|
|
260
283
|
if (options.threadsThreadMediaLayout) form.append('threads_thread_media_layout', options.threadsThreadMediaLayout);
|
|
284
|
+
if (options.threadsTopicTag) form.append('threads_topic_tag', options.threadsTopicTag);
|
|
261
285
|
}
|
|
262
286
|
|
|
263
287
|
/**
|
|
264
288
|
* Add Reddit-specific parameters
|
|
265
289
|
* @private
|
|
266
290
|
*/
|
|
267
|
-
_addRedditParams(form, options) {
|
|
291
|
+
_addRedditParams(form, options, isText = false) {
|
|
268
292
|
if (options.redditSubreddit) form.append('subreddit', options.redditSubreddit);
|
|
269
293
|
if (options.redditFlairId) form.append('flair_id', options.redditFlairId);
|
|
294
|
+
if (isText && (options.redditLinkUrl || options.linkUrl)) {
|
|
295
|
+
form.append('reddit_link_url', options.redditLinkUrl || options.linkUrl);
|
|
296
|
+
}
|
|
270
297
|
}
|
|
271
298
|
|
|
272
299
|
/**
|
|
@@ -352,6 +379,7 @@ export class UploadPost {
|
|
|
352
379
|
* Threads options:
|
|
353
380
|
* @param {boolean} [options.threadsLongTextAsPost] - Post long text as single post (vs thread)
|
|
354
381
|
* @param {string} [options.threadsThreadMediaLayout] - Comma-separated list of how many media items per Threads post (e.g. "5,5")
|
|
382
|
+
* @param {string} [options.threadsTopicTag] - Topic tag for the Threads post (1-50 chars, no periods or ampersands)
|
|
355
383
|
*
|
|
356
384
|
* @returns {Promise<Object>} API response with request_id for async uploads
|
|
357
385
|
*/
|
|
@@ -359,7 +387,7 @@ export class UploadPost {
|
|
|
359
387
|
const form = new FormData();
|
|
360
388
|
|
|
361
389
|
// Handle video (file path or URL)
|
|
362
|
-
if (videoPathOrUrl.toLowerCase().startsWith('http://') || videoPathOrUrl.toLowerCase().startsWith('https://')) {
|
|
390
|
+
if (typeof videoPathOrUrl === 'string' && (videoPathOrUrl.toLowerCase().startsWith('http://') || videoPathOrUrl.toLowerCase().startsWith('https://'))) {
|
|
363
391
|
form.append('video', videoPathOrUrl);
|
|
364
392
|
} else {
|
|
365
393
|
if (!fs.existsSync(videoPathOrUrl)) {
|
|
@@ -433,6 +461,7 @@ export class UploadPost {
|
|
|
433
461
|
* Threads options:
|
|
434
462
|
* @param {boolean} [options.threadsLongTextAsPost] - Post long text as single post
|
|
435
463
|
* @param {string} [options.threadsThreadMediaLayout] - Comma-separated list of how many media items per Threads post (e.g. "5,5")
|
|
464
|
+
* @param {string} [options.threadsTopicTag] - Topic tag for the Threads post (1-50 chars, no periods or ampersands)
|
|
436
465
|
*
|
|
437
466
|
* Reddit options:
|
|
438
467
|
* @param {string} [options.redditSubreddit] - Subreddit name (without r/)
|
|
@@ -482,13 +511,18 @@ export class UploadPost {
|
|
|
482
511
|
* @param {string} [options.timezone] - Timezone for scheduled date
|
|
483
512
|
* @param {boolean} [options.addToQueue] - Add to posting queue
|
|
484
513
|
* @param {boolean} [options.asyncUpload=true] - Process upload asynchronously
|
|
485
|
-
*
|
|
514
|
+
* @param {string} [options.linkUrl] - Generic URL for link preview card (works for LinkedIn, Bluesky, Facebook). Platform-specific params take priority.
|
|
515
|
+
*
|
|
486
516
|
* LinkedIn options:
|
|
487
517
|
* @param {string} [options.targetLinkedinPageId] - Page ID for organization posts
|
|
488
|
-
*
|
|
518
|
+
* @param {string} [options.linkedinLinkUrl] - URL to attach as link preview on LinkedIn
|
|
519
|
+
*
|
|
520
|
+
* Bluesky options:
|
|
521
|
+
* @param {string} [options.blueskyLinkUrl] - URL to attach as external embed link preview on Bluesky
|
|
522
|
+
*
|
|
489
523
|
* Facebook options:
|
|
490
524
|
* @param {string} [options.facebookPageId] - Facebook Page ID
|
|
491
|
-
* @param {string} [options.facebookLinkUrl] - URL to attach as link preview
|
|
525
|
+
* @param {string} [options.facebookLinkUrl] - URL to attach as link preview on Facebook
|
|
492
526
|
*
|
|
493
527
|
* X (Twitter) options:
|
|
494
528
|
* @param {string} [options.xReplySettings] - Who can reply
|
|
@@ -503,6 +537,7 @@ export class UploadPost {
|
|
|
503
537
|
* Threads options:
|
|
504
538
|
* @param {boolean} [options.threadsLongTextAsPost] - Post long text as single post
|
|
505
539
|
* @param {string} [options.threadsThreadMediaLayout] - Comma-separated list of how many media items per Threads post (e.g. "5,5")
|
|
540
|
+
* @param {string} [options.threadsTopicTag] - Topic tag for the Threads post (1-50 chars, no periods or ampersands)
|
|
506
541
|
*
|
|
507
542
|
* Reddit options:
|
|
508
543
|
* @param {string} [options.redditSubreddit] - Subreddit name (without r/)
|
|
@@ -512,15 +547,21 @@ export class UploadPost {
|
|
|
512
547
|
*/
|
|
513
548
|
async uploadText(options) {
|
|
514
549
|
const form = new FormData();
|
|
515
|
-
|
|
550
|
+
|
|
516
551
|
this._addCommonParams(form, options);
|
|
517
|
-
|
|
552
|
+
|
|
553
|
+
// Generic link_url support
|
|
554
|
+
if (options.linkUrl) form.append('link_url', options.linkUrl);
|
|
555
|
+
|
|
518
556
|
const platforms = Array.isArray(options.platforms) ? options.platforms : [options.platforms];
|
|
519
|
-
if (platforms.includes('linkedin')) this._addLinkedinParams(form, options);
|
|
557
|
+
if (platforms.includes('linkedin')) this._addLinkedinParams(form, options, true);
|
|
520
558
|
if (platforms.includes('facebook')) this._addFacebookParams(form, options, false, true);
|
|
521
559
|
if (platforms.includes('x')) this._addXParams(form, options, true);
|
|
522
560
|
if (platforms.includes('threads')) this._addThreadsParams(form, options);
|
|
523
|
-
if (platforms.includes('reddit')) this._addRedditParams(form, options);
|
|
561
|
+
if (platforms.includes('reddit')) this._addRedditParams(form, options, true);
|
|
562
|
+
if (platforms.includes('bluesky') && (options.blueskyLinkUrl || options.linkUrl)) {
|
|
563
|
+
form.append('bluesky_link_url', options.blueskyLinkUrl || options.linkUrl);
|
|
564
|
+
}
|
|
524
565
|
|
|
525
566
|
return this._request('/upload_text', 'POST', form, true);
|
|
526
567
|
}
|
|
@@ -546,7 +587,7 @@ export class UploadPost {
|
|
|
546
587
|
const form = new FormData();
|
|
547
588
|
|
|
548
589
|
// Handle document (file path or URL)
|
|
549
|
-
if (documentPathOrUrl.toLowerCase().startsWith('http://') || documentPathOrUrl.toLowerCase().startsWith('https://')) {
|
|
590
|
+
if (typeof documentPathOrUrl === 'string' && (documentPathOrUrl.toLowerCase().startsWith('http://') || documentPathOrUrl.toLowerCase().startsWith('https://'))) {
|
|
550
591
|
form.append('document', documentPathOrUrl);
|
|
551
592
|
} else {
|
|
552
593
|
if (!fs.existsSync(documentPathOrUrl)) {
|
|
@@ -564,6 +605,7 @@ export class UploadPost {
|
|
|
564
605
|
if (options.scheduledDate) form.append('scheduled_date', options.scheduledDate);
|
|
565
606
|
if (options.timezone) form.append('timezone', options.timezone);
|
|
566
607
|
if (options.addToQueue !== undefined) form.append('add_to_queue', String(options.addToQueue));
|
|
608
|
+
if (options.maxPostsPerSlot !== undefined) form.append('max_posts_per_slot', String(options.maxPostsPerSlot));
|
|
567
609
|
if (options.asyncUpload !== undefined) form.append('async_upload', String(options.asyncUpload));
|
|
568
610
|
|
|
569
611
|
this._addLinkedinParams(form, options);
|
|
@@ -583,6 +625,16 @@ export class UploadPost {
|
|
|
583
625
|
return this._request('/uploadposts/status', 'GET', { request_id: requestId });
|
|
584
626
|
}
|
|
585
627
|
|
|
628
|
+
/**
|
|
629
|
+
* Get the status of a scheduled or queued upload by job ID
|
|
630
|
+
*
|
|
631
|
+
* @param {string} jobId - The job_id from a scheduled or queued upload
|
|
632
|
+
* @returns {Promise<Object>} Upload status
|
|
633
|
+
*/
|
|
634
|
+
async getJobStatus(jobId) {
|
|
635
|
+
return this._request('/uploadposts/status', 'GET', { job_id: jobId });
|
|
636
|
+
}
|
|
637
|
+
|
|
586
638
|
/**
|
|
587
639
|
* Get upload history
|
|
588
640
|
*
|
|
@@ -600,20 +652,73 @@ export class UploadPost {
|
|
|
600
652
|
|
|
601
653
|
/**
|
|
602
654
|
* Get analytics for a profile
|
|
603
|
-
*
|
|
655
|
+
*
|
|
604
656
|
* @param {string} profileUsername - Profile username
|
|
605
657
|
* @param {Object} [options] - Query options
|
|
606
|
-
* @param {string[]} [options.platforms] - Filter by platforms (instagram, linkedin, facebook, x)
|
|
607
|
-
* @
|
|
658
|
+
* @param {string[]} [options.platforms] - Filter by platforms (instagram, linkedin, facebook, x, youtube, tiktok, threads, pinterest, reddit)
|
|
659
|
+
* @param {string} [options.pageId] - Facebook Page ID (required for Facebook analytics)
|
|
660
|
+
* @param {string} [options.pageUrn] - LinkedIn page URN (defaults to "me" for personal profile)
|
|
661
|
+
* @returns {Promise<Object>} Analytics data per platform
|
|
608
662
|
*/
|
|
609
663
|
async getAnalytics(profileUsername, options = {}) {
|
|
610
664
|
const params = {};
|
|
611
665
|
if (options.platforms && options.platforms.length > 0) {
|
|
612
666
|
params.platforms = options.platforms.join(',');
|
|
613
667
|
}
|
|
668
|
+
if (options.pageId) params.page_id = options.pageId;
|
|
669
|
+
if (options.pageUrn) params.page_urn = options.pageUrn;
|
|
614
670
|
return this._request(`/analytics/${encodeURIComponent(profileUsername)}`, 'GET', params);
|
|
615
671
|
}
|
|
616
672
|
|
|
673
|
+
/**
|
|
674
|
+
* Get total impressions for a profile from daily snapshots
|
|
675
|
+
*
|
|
676
|
+
* @param {string} profileUsername - Profile username
|
|
677
|
+
* @param {Object} [options] - Query options
|
|
678
|
+
* @param {string} [options.period] - Period shortcut: last_day, last_week, last_month, last_3months, last_year
|
|
679
|
+
* @param {string} [options.startDate] - Start date in YYYY-MM-DD format
|
|
680
|
+
* @param {string} [options.endDate] - End date in YYYY-MM-DD format
|
|
681
|
+
* @param {string} [options.date] - Single date in YYYY-MM-DD format
|
|
682
|
+
* @param {string[]} [options.platforms] - Filter by platforms
|
|
683
|
+
* @param {boolean} [options.breakdown] - Include per-platform and per-day breakdown
|
|
684
|
+
* @param {string[]} [options.metrics] - Specific metrics to aggregate (e.g., ['likes', 'comments', 'shares'])
|
|
685
|
+
* @returns {Promise<Object>} Total impressions data
|
|
686
|
+
*/
|
|
687
|
+
async getTotalImpressions(profileUsername, options = {}) {
|
|
688
|
+
const params = {};
|
|
689
|
+
if (options.period) params.period = options.period;
|
|
690
|
+
if (options.startDate) params.start_date = options.startDate;
|
|
691
|
+
if (options.endDate) params.end_date = options.endDate;
|
|
692
|
+
if (options.date) params.date = options.date;
|
|
693
|
+
if (options.platforms && options.platforms.length > 0) {
|
|
694
|
+
params.platform = options.platforms.join(',');
|
|
695
|
+
}
|
|
696
|
+
if (options.breakdown) params.breakdown = 'true';
|
|
697
|
+
if (options.metrics && options.metrics.length > 0) {
|
|
698
|
+
params.metrics = options.metrics.join(',');
|
|
699
|
+
}
|
|
700
|
+
return this._request(`/uploadposts/total-impressions/${encodeURIComponent(profileUsername)}`, 'GET', params);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Get analytics for a specific post across all platforms it was published to
|
|
705
|
+
*
|
|
706
|
+
* @param {string} requestId - The request_id from the upload
|
|
707
|
+
* @returns {Promise<Object>} Post analytics with per-platform metrics
|
|
708
|
+
*/
|
|
709
|
+
async getPostAnalytics(requestId) {
|
|
710
|
+
return this._request(`/uploadposts/post-analytics/${encodeURIComponent(requestId)}`, 'GET');
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Get available metrics configuration for all supported platforms
|
|
715
|
+
*
|
|
716
|
+
* @returns {Promise<Object>} Platform metrics config (primary fields, available metrics, labels)
|
|
717
|
+
*/
|
|
718
|
+
async getPlatformMetrics() {
|
|
719
|
+
return this._request('/uploadposts/platform-metrics', 'GET');
|
|
720
|
+
}
|
|
721
|
+
|
|
617
722
|
// ==================== Scheduled Posts ====================
|
|
618
723
|
|
|
619
724
|
/**
|
|
@@ -755,6 +860,30 @@ export class UploadPost {
|
|
|
755
860
|
const params = profile ? { profile } : {};
|
|
756
861
|
return this._request('/uploadposts/pinterest/boards', 'GET', params);
|
|
757
862
|
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Get Google Business Profile locations for a connected account
|
|
866
|
+
*
|
|
867
|
+
* @param {string} [profile] - Profile username
|
|
868
|
+
* @returns {Promise<Object>} List of Google Business locations
|
|
869
|
+
*/
|
|
870
|
+
async getGoogleBusinessLocations(profile) {
|
|
871
|
+
const params = profile ? { profile } : {};
|
|
872
|
+
return this._request('/uploadposts/google-business/locations', 'GET', params);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Select a specific Google Business Profile location for a profile
|
|
877
|
+
*
|
|
878
|
+
* @param {string} locationId - The location ID to select (e.g. "accounts/123/locations/456")
|
|
879
|
+
* @param {string} [profile] - Profile username
|
|
880
|
+
* @returns {Promise<Object>} Selection result with google_business_id and display_name
|
|
881
|
+
*/
|
|
882
|
+
async selectGoogleBusinessLocation(locationId, profile) {
|
|
883
|
+
const data = { location_id: locationId };
|
|
884
|
+
if (profile) data.profile = profile;
|
|
885
|
+
return this._request('/uploadposts/google-business/locations/select', 'POST', data);
|
|
886
|
+
}
|
|
758
887
|
}
|
|
759
888
|
|
|
760
889
|
// Default export for CommonJS compatibility
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "upload-post",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Official client library for Upload-Post API - Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, and X (Twitter)",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|