upload-post 1.0.3 → 2.0.4

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.
@@ -0,0 +1,67 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ branches: [main]
8
+ paths: ['package.json']
9
+ workflow_dispatch:
10
+ inputs:
11
+ dry_run:
12
+ description: 'Dry run (no publish)'
13
+ required: true
14
+ default: true
15
+ type: boolean
16
+
17
+ jobs:
18
+ publish:
19
+ runs-on: ubuntu-latest
20
+ permissions:
21
+ contents: read
22
+ id-token: write
23
+ steps:
24
+ - name: Checkout
25
+ uses: actions/checkout@v4
26
+
27
+ - name: Setup Node.js
28
+ uses: actions/setup-node@v4
29
+ with:
30
+ node-version: '22'
31
+ registry-url: 'https://registry.npmjs.org'
32
+
33
+ - name: Check if version is new
34
+ id: version_check
35
+ run: |
36
+ LOCAL=$(node -p "require('./package.json').version")
37
+ PKG_NAME=$(node -p "require('./package.json').name")
38
+ REMOTE=$(npm view "$PKG_NAME" version 2>/dev/null || echo "0.0.0")
39
+ echo "local=$LOCAL" >> $GITHUB_OUTPUT
40
+ echo "remote=$REMOTE" >> $GITHUB_OUTPUT
41
+ if [ "$LOCAL" = "$REMOTE" ]; then
42
+ echo "new=false" >> $GITHUB_OUTPUT
43
+ echo "⏭️ Version $LOCAL already published, skipping."
44
+ else
45
+ echo "new=true" >> $GITHUB_OUTPUT
46
+ echo "🚀 New version detected: $REMOTE → $LOCAL"
47
+ fi
48
+
49
+ - name: Update npm to latest
50
+ if: steps.version_check.outputs.new == 'true' || github.event_name == 'workflow_dispatch'
51
+ run: npm install -g npm@latest && npm --version
52
+
53
+ - name: Install dependencies
54
+ if: steps.version_check.outputs.new == 'true' || github.event_name == 'workflow_dispatch'
55
+ run: npm ci
56
+
57
+ - name: Build (if needed)
58
+ if: steps.version_check.outputs.new == 'true' || github.event_name == 'workflow_dispatch'
59
+ run: npm run build --if-present
60
+
61
+ - name: Publish to npm (dry-run)
62
+ if: ${{ inputs.dry_run == true }}
63
+ run: npm publish --access public --dry-run
64
+
65
+ - name: Publish to npm
66
+ if: (steps.version_check.outputs.new == 'true' && inputs.dry_run != true) || github.event_name == 'release'
67
+ run: npm publish --access public --provenance
package/README.md CHANGED
@@ -1,13 +1,8 @@
1
- # Upload-Post Node.js Client
1
+ # Upload-Post SDK for Node.js
2
2
 
3
- Official client library for [Upload-Post](https://www.upload-post.com) API - cross-platform social media video upload.
3
+ Official Node.js client for the [Upload-Post API](https://www.upload-post.com) - Cross-platform social media upload.
4
4
 
5
- ## Features
6
-
7
- - 🚀 Simple video upload to multiple platforms
8
- - 🔒 Secure API key authentication
9
- - 📁 Supports all major video formats
10
- - 📝 Automatic form data handling
5
+ Upload videos, photos, text posts, and documents to **TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, and X (Twitter)** with a single API.
11
6
 
12
7
  ## Installation
13
8
 
@@ -15,246 +10,320 @@ Official client library for [Upload-Post](https://www.upload-post.com) API - cro
15
10
  npm install upload-post
16
11
  ```
17
12
 
18
- ## Usage
13
+ ## Quick Start
19
14
 
20
15
  ```javascript
21
16
  import { UploadPost } from 'upload-post';
22
17
 
23
- const uploader = new UploadPost('your-api-key-here');
18
+ const client = new UploadPost('YOUR_API_KEY');
24
19
 
25
- // Upload video with options
26
- try {
27
- const result = await uploader.upload(
28
- '/path/to/your/local/video.mp4', // or "https://example.com/remote/video.mp4"
29
- {
30
- title: 'My Awesome Video',
31
- user: 'test-user',
32
- platforms: ['tiktok', 'youtube'],
33
- // TikTok specific
34
- privacy_level: 'PUBLIC_TO_EVERYONE',
35
- disable_comment: false,
36
- // YouTube specific
37
- description: 'This is a great video about coding.',
38
- tags: ['coding', 'nodejs', 'api'],
39
- privacyStatus: 'public'
40
- }
41
- );
42
- console.log('Upload successful:', result);
43
- } catch (error) {
44
- console.error('Upload failed:', error.message);
45
- }
20
+ // Upload a video to multiple platforms
21
+ const response = await client.upload('./video.mp4', {
22
+ title: 'Check out this awesome video! 🎬',
23
+ user: 'my-profile',
24
+ platforms: ['tiktok', 'instagram', 'youtube']
25
+ });
46
26
 
47
- // Example: Upload video from a URL
48
- try {
49
- const resultFromUrl = await uploader.upload(
50
- null, // videoPath can be null or undefined if options.video is a URL
51
- {
52
- video: "https://example.com/remote/another_video.mp4",
53
- title: 'Remote Video Fun',
54
- user: 'test-user-url',
55
- platforms: ['instagram'],
56
- media_type: 'REELS',
57
- share_to_feed: true
58
- }
59
- );
60
- console.log('Upload from URL successful:', resultFromUrl);
61
- } catch (error) {
62
- console.error('Upload from URL failed:', error.message);
63
- }
27
+ console.log(response);
64
28
  ```
65
29
 
66
- ## API Documentation
67
-
68
- ### Constructor
69
- `new UploadPost(apiKey: string)`
70
-
71
- ### upload()
72
- `upload(videoPath: string, options: UploadOptions): Promise<object>`
73
-
74
- #### Video Upload Options (`UploadOptions`)
75
- **Common Parameters:**
76
- - `videoPath`: (Required) Path to your local video file (e.g., MP4, MOV) OR a public URL to a video file. If providing a URL, you can also use the `options.video` field.
77
- - `options.title`: (Required) Title of the video.
78
- - `options.user`: (Required) User identifier.
79
- - `options.platforms`: (Required) Array of target platforms (e.g., `['tiktok', 'youtube', 'instagram']`). Supported: `tiktok`, `instagram`, `linkedin`, `youtube`, `facebook`, `x` (Twitter), `threads`, `pinterest`.
80
- - `options.video`: (Optional) Public URL of the video file. Use this if `videoPath` is not a local file.
81
-
82
- **Platform-Specific Parameters (all optional):**
83
-
84
- - **TikTok:**
85
- - `options.privacy_level`: `'PUBLIC_TO_EVERYONE'`, `'MUTUAL_FOLLOW_FRIENDS'`, `'FOLLOWER_OF_CREATOR'`, or `'SELF_ONLY'`.
86
- - `options.disable_duet`: `boolean`.
87
- - `options.disable_comment`: `boolean`.
88
- - `options.disable_stitch`: `boolean`.
89
- - `options.cover_timestamp`: `number` (milliseconds for video cover).
90
- - `options.brand_content_toggle`: `boolean`.
91
- - `options.brand_organic`: `boolean`.
92
- - `options.branded_content`: `boolean`.
93
- - `options.brand_organic_toggle`: `boolean`.
94
- - `options.is_aigc`: `boolean` (AI-generated content).
95
- - **Instagram:**
96
- - `options.media_type`: `'REELS'` or `'STORIES'`. Default: `'REELS'`.
97
- - `options.share_to_feed`: `boolean`.
98
- - `options.collaborators`: `string` (comma-separated usernames).
99
- - `options.cover_url`: `string` (URL for custom video cover).
100
- - `options.audio_name`: `string`.
101
- - `options.user_tags`: `string` (comma-separated user tags).
102
- - `options.location_id`: `string`.
103
- - `options.thumb_offset`: `string` (timestamp offset for thumbnail).
104
- - **LinkedIn:**
105
- - `options.description`: `string` (post commentary, defaults to `title`).
106
- - `options.visibility`: `'CONNECTIONS'`, `'PUBLIC'`, `'LOGGED_IN'`, or `'CONTAINER'`. Default: `'PUBLIC'`.
107
- - `options.target_linkedin_page_id`: `string` (LinkedIn page ID for organization uploads).
108
- - **YouTube:**
109
- - `options.description`: `string` (video description, defaults to `title`).
110
- - `options.tags`: `string[]` (array of tags).
111
- - `options.categoryId`: `string` (video category ID, default: `"22"`).
112
- - `options.privacyStatus`: `'public'`, `'unlisted'`, or `'private'`. Default: `'public'`.
113
- - `options.embeddable`: `boolean`.
114
- - `options.license`: `'youtube'` or `'creativeCommon'`.
115
- - `options.publicStatsViewable`: `boolean`.
116
- - `options.madeForKids`: `boolean`.
117
- - **Facebook:**
118
- - `options.facebook_page_id`: (Required if `facebook` in `platforms`) Facebook Page ID.
119
- - `options.description`: `string` (video description, defaults to `title`).
120
- - `options.video_state`: `'DRAFT'`, `'PUBLISHED'`, or `'SCHEDULED'`. Default: `'PUBLISHED'`.
121
- - **Threads:**
122
- - `options.description`: `string` (post commentary, defaults to `title`).
123
- - **X (Twitter):**
124
- - `options.tagged_user_ids`: `string[]` (array of user IDs to tag).
125
- - `options.reply_settings`: `'following'`, `'mentionedUsers'`, or `'everyone'`.
126
- - `options.nullcast`: `boolean` (publish without broadcasting).
127
- - `options.place_id`: `string` (location place ID).
128
- - `options.poll_duration`: `number` (poll duration in minutes).
129
- - `options.poll_options`: `string[]` (array of poll options).
130
- - `options.poll_reply_settings`: `'following'`, `'mentionedUsers'`, or `'everyone'` (for poll replies).
131
- - **Pinterest:**
132
- - `options.pinterest_board_id`: (Required if `pinterest` in `platforms`) Pinterest board ID.
133
- - `options.pinterest_link`: `string` (destination link for the Pin).
134
- - `options.pinterest_cover_image_url`: `string` (URL for cover image).
135
- - `options.pinterest_cover_image_content_type`: `string` (e.g., `image/jpeg`).
136
- - `options.pinterest_cover_image_data`: `string` (Base64 encoded cover image).
137
- - `options.pinterest_cover_image_key_frame_time`: `number` (milliseconds for video frame to use as cover).
138
-
139
- ### uploadPhotos()
140
- `uploadPhotos(photos: string[], options: UploadPhotosOptions): Promise<object>`
141
-
142
- Uploads photos to various social media platforms.
143
-
144
- #### Photo Upload Options (`UploadPhotosOptions`)
145
- - `photos`: Array of strings, where each string is a local file path to a photo or a public URL of a photo.
146
- - `options.user`: (Required) User identifier.
147
- - `options.platforms`: (Required) Array of target platforms. Supported: `tiktok`, `instagram`, `linkedin`, `facebook`, `x`, `threads`, `pinterest`.
148
- - `options.title`: (Required) Title of the post.
149
- - `options.caption`: (Optional) Caption/description for the photos. This will be used as the post commentary.
150
-
151
- ##### Platform-Specific Parameters (Optional unless stated otherwise):
152
-
153
- - **LinkedIn:**
154
- - `options.visibility`: `'PUBLIC'` - Visibility setting for the post.
155
- - `options.target_linkedin_page_id`: LinkedIn page ID to upload photos to an organization.
156
- - **Facebook:**
157
- - `options.facebook_page_id`: (Required if `facebook` in `platforms`) Facebook Page ID.
158
- - **TikTok:**
159
- - `options.auto_add_music`: `boolean` - Automatically add background music.
160
- - `options.disable_comment`: `boolean` - Disable comments.
161
- - `options.branded_content`: `boolean` - Indicate branded content (requires `disclose_commercial` to be `true`).
162
- - `options.disclose_commercial`: `boolean` - Disclose commercial nature.
163
- - `options.photo_cover_index`: `number` - Index (0-based) of the photo to use as cover.
164
- - `options.description`: `string` - Description for TikTok (defaults to `title`).
165
- - **Instagram:**
166
- - `options.media_type`: `'IMAGE'` or `'STORIES'` - Type of media. Defaults to `'IMAGE'`.
167
- - **Pinterest:**
168
- - `options.pinterest_board_id`: (Required if `pinterest` in `platforms`) Pinterest board ID.
169
- - `options.pinterest_alt_text`: `string` - Alt text for the image.
170
- - `options.pinterest_link`: `string` - Destination link for the Pin.
171
-
172
- **X (Twitter) and Threads** do not require additional parameters.
173
-
174
- #### Example: Uploading Photos
30
+ ## Features
31
+
32
+ - ✅ **Video Upload** - TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Bluesky, X
33
+ - ✅ **Photo Upload** - TikTok, Instagram, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, X
34
+ - ✅ **Text Posts** - X, LinkedIn, Facebook, Threads, Reddit, Bluesky
35
+ - ✅ **Document Upload** - LinkedIn (PDF, PPT, PPTX, DOC, DOCX)
36
+ - ✅ **Scheduling** - Schedule posts for later
37
+ - ✅ **Posting Queue** - Add posts to your configured queue
38
+ - ✅ **First Comments** - Auto-post first comment after publishing
39
+ - ✅ **Analytics** - Get engagement metrics
40
+ - ✅ **Full TypeScript Support**
41
+
42
+ ## API Reference
43
+
44
+ ### Upload Video
175
45
 
176
46
  ```javascript
177
- import { UploadPost } from 'upload-post';
47
+ const response = await client.upload('./video.mp4', {
48
+ title: 'My awesome video',
49
+ user: 'my-profile',
50
+ platforms: ['tiktok', 'instagram', 'youtube'],
51
+
52
+ // Optional: Schedule for later
53
+ scheduledDate: '2024-12-25T10:00:00Z',
54
+ timezone: 'Europe/Madrid',
55
+
56
+ // Optional: Add first comment
57
+ firstComment: 'Thanks for watching! 🙏',
58
+
59
+ // Optional: Platform-specific settings
60
+ tiktokPrivacyLevel: 'PUBLIC_TO_EVERYONE',
61
+ instagramMediaType: 'REELS',
62
+ youtubePrivacyStatus: 'public',
63
+ youtubeTags: ['tutorial', 'coding'],
64
+ });
65
+ ```
178
66
 
179
- const uploader = new UploadPost('your-api-key-here');
67
+ ### Upload Photos
180
68
 
181
- // Example: Upload photos to Instagram and Facebook
182
- try {
183
- const photoResult = await uploader.uploadPhotos(
184
- ['/path/to/your/image1.jpg', 'https://example.com/images/photo2.jpg'],
185
- {
186
- user: 'test-user',
187
- platforms: ['instagram', 'facebook'],
188
- title: 'My Beautiful Photos',
189
- caption: 'Check out these amazing shots!',
190
- facebook_page_id: 'your-facebook-page-id', // Required for Facebook
191
- media_type: 'IMAGE' // Optional for Instagram
192
- }
193
- );
194
- console.log('Photo upload successful:', photoResult);
195
- } catch (error) {
196
- console.error('Photo upload failed:', error.message);
197
- }
69
+ ```javascript
70
+ // Upload single or multiple photos
71
+ const response = await client.uploadPhotos(
72
+ ['./photo1.jpg', './photo2.jpg', 'https://example.com/photo3.jpg'],
73
+ {
74
+ title: 'Check out these photos! 📸',
75
+ user: 'my-profile',
76
+ platforms: ['instagram', 'facebook', 'x'],
77
+
78
+ // Optional: Add to queue instead of posting immediately
79
+ addToQueue: true,
80
+
81
+ // Platform-specific
82
+ instagramMediaType: 'IMAGE', // or 'STORIES'
83
+ facebookPageId: 'your-page-id',
84
+ }
85
+ );
198
86
  ```
199
87
 
200
- ### uploadText()
201
- `uploadText(options: UploadTextOptions): Promise<object>`
88
+ ### Upload Text Posts
202
89
 
203
- Uploads text-only posts to supported social media platforms.
90
+ ```javascript
91
+ const response = await client.uploadText({
92
+ title: 'Just shipped a new feature! 🚀 Check it out at example.com',
93
+ user: 'my-profile',
94
+ platforms: ['x', 'linkedin', 'threads'],
95
+
96
+ // Optional: Create a poll on X
97
+ xPollOptions: ['Option A', 'Option B', 'Option C'],
98
+ xPollDuration: 1440, // 24 hours in minutes
99
+
100
+ // Optional: Post to a LinkedIn company page
101
+ targetLinkedinPageId: 'company-page-id',
102
+ });
103
+ ```
204
104
 
205
- #### Text Upload Options (`UploadTextOptions`)
206
- - `options.user`: (Required) User identifier.
207
- - `options.platforms`: (Required) Array of target platforms. Supported: `'linkedin'`, `'x'` (Twitter), `'facebook'`, `'threads'`.
208
- - `options.title`: (Required) The text content for the post. This field is used as the main content for all specified platforms.
105
+ ### Upload Documents (LinkedIn)
209
106
 
210
- ##### Platform-Specific Parameters:
211
- - **LinkedIn:**
212
- - `options.target_linkedin_page_id`: (Optional) LinkedIn page ID to upload text to an organization's page. If not provided, posts to the user's personal profile.
213
- - **Facebook:**
214
- - `options.facebook_page_id`: (Required if `'facebook'` is in `platforms`) Facebook Page ID where the text will be posted.
107
+ ```javascript
108
+ const response = await client.uploadDocument('./presentation.pdf', {
109
+ title: 'Q4 2024 Report',
110
+ user: 'my-profile',
111
+ description: 'Check out our latest quarterly results!',
112
+ linkedinVisibility: 'PUBLIC',
113
+ targetLinkedinPageId: 'company-page-id', // Optional: post to company page
114
+ });
115
+ ```
215
116
 
216
- **X (Twitter) and Threads** use the common `options.title` for the text content and do not require additional specific parameters for text posts.
117
+ ### Check Upload Status
217
118
 
218
- #### Example: Uploading a Text Post
119
+ For async uploads, check the status using the request_id:
219
120
 
220
121
  ```javascript
221
- import { UploadPost } from 'upload-post';
122
+ const status = await client.getStatus('request_id_from_upload');
123
+ console.log(status);
124
+ ```
222
125
 
223
- const uploader = new UploadPost('your-api-key-here');
126
+ ### Get Upload History
224
127
 
225
- // Example: Upload a text post to X (Twitter) and LinkedIn
226
- try {
227
- const textResult = await uploader.uploadText({
228
- user: 'test-user',
229
- platforms: ['x', 'linkedin'],
230
- title: 'This is my awesome text post for X and LinkedIn!',
231
- target_linkedin_page_id: 'your-linkedin-org-page-id' // Optional: for LinkedIn organization page
232
- });
233
- console.log('Text post successful:', textResult);
234
- } catch (error) {
235
- console.error('Text post failed:', error.message);
236
- }
128
+ ```javascript
129
+ const history = await client.getHistory({ page: 1, limit: 20 });
130
+ console.log(history.uploads);
131
+ ```
132
+
133
+ ### Scheduled Posts
237
134
 
238
- // Example: Upload a text post to a Facebook Page
135
+ ```javascript
136
+ // List all scheduled posts
137
+ const scheduled = await client.listScheduled();
138
+
139
+ // Edit a scheduled post
140
+ await client.editScheduled('job-id', {
141
+ scheduledDate: '2024-12-26T15:00:00Z',
142
+ timezone: 'America/New_York',
143
+ });
144
+
145
+ // Cancel a scheduled post
146
+ await client.cancelScheduled('job-id');
147
+ ```
148
+
149
+ ### User Management
150
+
151
+ ```javascript
152
+ // List all profiles
153
+ const users = await client.listUsers();
154
+
155
+ // Create a new profile
156
+ await client.createUser('new-profile');
157
+
158
+ // Delete a profile
159
+ await client.deleteUser('old-profile');
160
+
161
+ // Generate JWT for platform integration (white-label)
162
+ const jwt = await client.generateJwt('my-profile', {
163
+ redirectUrl: 'https://yourapp.com/callback',
164
+ platforms: ['tiktok', 'instagram'],
165
+ });
166
+ ```
167
+
168
+ ### Get Analytics
169
+
170
+ ```javascript
171
+ const analytics = await client.getAnalytics('my-profile', {
172
+ platforms: ['instagram', 'tiktok'],
173
+ });
174
+ console.log(analytics);
175
+ ```
176
+
177
+ ### Helper Methods
178
+
179
+ ```javascript
180
+ // Get Facebook pages for a profile
181
+ const fbPages = await client.getFacebookPages('my-profile');
182
+
183
+ // Get LinkedIn pages for a profile
184
+ const liPages = await client.getLinkedinPages('my-profile');
185
+
186
+ // Get Pinterest boards for a profile
187
+ const boards = await client.getPinterestBoards('my-profile');
188
+ ```
189
+
190
+ ## Platform-Specific Options
191
+
192
+ ### TikTok (Video)
193
+ - `tiktokPrivacyLevel` - PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY
194
+ - `tiktokDisableDuet` - Disable duet
195
+ - `tiktokDisableComment` - Disable comments
196
+ - `tiktokDisableStitch` - Disable stitch
197
+ - `tiktokCoverTimestamp` - Timestamp in ms for cover
198
+ - `tiktokIsAigc` - AI-generated content flag
199
+ - `tiktokPostMode` - DIRECT_POST or MEDIA_UPLOAD
200
+ - `brandContentToggle` - Branded content toggle
201
+ - `brandOrganicToggle` - Brand organic toggle
202
+
203
+ ### TikTok (Photos)
204
+ - `tiktokAutoAddMusic` - Auto add music
205
+ - `tiktokPhotoCoverIndex` - Index of photo for cover (0-based)
206
+ - `tiktokDisableComment` - Disable comments
207
+
208
+ ### Instagram
209
+ - `instagramMediaType` - REELS, STORIES, IMAGE
210
+ - `instagramShareToFeed` - Share to feed (for Reels/Stories)
211
+ - `instagramCollaborators` - Comma-separated collaborator usernames
212
+ - `instagramCoverUrl` - Custom cover URL
213
+ - `instagramAudioName` - Audio track name
214
+ - `instagramUserTags` - Comma-separated user tags
215
+ - `instagramLocationId` - Location ID
216
+ - `instagramThumbOffset` - Thumbnail offset
217
+
218
+ ### YouTube
219
+ - `youtubeTags` - Array or comma-separated tags
220
+ - `youtubeCategoryId` - Category ID (default: "22" People & Blogs)
221
+ - `youtubePrivacyStatus` - public, unlisted, private
222
+ - `youtubeEmbeddable` - Allow embedding
223
+ - `youtubeLicense` - youtube, creativeCommon
224
+ - `youtubePublicStatsViewable` - Show public stats
225
+ - `youtubeThumbnailUrl` - Custom thumbnail URL
226
+ - `youtubeSelfDeclaredMadeForKids` - Made for kids (COPPA)
227
+ - `youtubeContainsSyntheticMedia` - AI/synthetic content flag
228
+ - `youtubeDefaultLanguage` - Title/description language (BCP-47)
229
+ - `youtubeDefaultAudioLanguage` - Audio language (BCP-47)
230
+ - `youtubeAllowedCountries` / `youtubeBlockedCountries` - Country restrictions
231
+ - `youtubeHasPaidProductPlacement` - Paid placement flag
232
+ - `youtubeRecordingDate` - Recording date (ISO 8601)
233
+
234
+ ### LinkedIn
235
+ - `linkedinVisibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
236
+ - `targetLinkedinPageId` - Page ID for organization posts
237
+
238
+ ### Facebook
239
+ - `facebookPageId` - Facebook Page ID (required)
240
+ - `facebookVideoState` - PUBLISHED, DRAFT
241
+ - `facebookMediaType` - REELS, STORIES, VIDEO (VIDEO for normal page videos with no 9:16 restriction)
242
+ - `thumbnailUrl` - URL for custom video thumbnail (only when facebookMediaType is VIDEO)
243
+ - `facebookLinkUrl` - URL for text posts
244
+
245
+ ### Pinterest
246
+ - `pinterestBoardId` - Board ID
247
+ - `pinterestLink` - Destination link
248
+ - `pinterestAltText` - Alt text for photos
249
+ - `pinterestCoverImageUrl` - Cover image URL (video)
250
+ - `pinterestCoverImageKeyFrameTime` - Key frame time in ms
251
+
252
+ ### X (Twitter)
253
+ - `xReplySettings` - everyone, following, mentionedUsers, subscribers, verified
254
+ - `xNullcast` - Promoted-only post
255
+ - `xTaggedUserIds` - User IDs to tag
256
+ - `xPlaceId` / `xGeoPlaceId` - Location place ID
257
+ - `xQuoteTweetId` - Tweet ID to quote
258
+ - `xPollOptions` - Poll options (2-4)
259
+ - `xPollDuration` - Poll duration in minutes (5-10080)
260
+ - `xForSuperFollowersOnly` - Exclusive for super followers
261
+ - `xCommunityId` - Community ID
262
+ - `xShareWithFollowers` - Share community post with followers
263
+ - `xCardUri` - Card URI for Twitter Cards
264
+ - `xLongTextAsPost` - Post long text as single post
265
+ - `xThreadImageLayout` - Comma-separated image layout for thread (e.g. "4,4" or "2,3,1")
266
+
267
+ ### Threads
268
+ - `threadsLongTextAsPost` - Post long text as single post (vs thread)
269
+ - `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.
270
+
271
+ ### Reddit
272
+ - `redditSubreddit` - Subreddit name (without r/)
273
+ - `redditFlairId` - Flair template ID
274
+
275
+ ## Common Options
276
+
277
+ These options work across all upload methods:
278
+
279
+ | Option | Description |
280
+ |--------|-------------|
281
+ | `title` | Post title/caption (required) |
282
+ | `user` | Profile name (required) |
283
+ | `platforms` | Target platforms array (required) |
284
+ | `firstComment` | First comment to post |
285
+ | `altText` | Alt text for accessibility |
286
+ | `scheduledDate` | ISO date for scheduling |
287
+ | `timezone` | Timezone for scheduled date |
288
+ | `addToQueue` | Add to posting queue |
289
+ | `asyncUpload` | Process asynchronously (default: true) |
290
+
291
+ ## TypeScript Support
292
+
293
+ Full TypeScript support with comprehensive type definitions:
294
+
295
+ ```typescript
296
+ import { UploadPost, UploadVideoOptions, UploadResponse } from 'upload-post';
297
+
298
+ const client = new UploadPost('YOUR_API_KEY');
299
+
300
+ const options: UploadVideoOptions = {
301
+ title: 'My video',
302
+ user: 'my-profile',
303
+ platforms: ['tiktok', 'instagram'],
304
+ tiktokPrivacyLevel: 'PUBLIC_TO_EVERYONE',
305
+ };
306
+
307
+ const response: UploadResponse = await client.upload('./video.mp4', options);
308
+ ```
309
+
310
+ ## Error Handling
311
+
312
+ ```javascript
239
313
  try {
240
- const fbTextResult = await uploader.uploadText({
241
- user: 'test-user-fb',
242
- platforms: ['facebook'],
243
- title: 'Hello Facebook Page!',
244
- facebook_page_id: 'your-facebook-page-id' // Required for Facebook
245
- });
246
- console.log('Facebook text post successful:', fbTextResult);
314
+ const response = await client.upload('./video.mp4', options);
315
+ console.log('Upload successful:', response);
247
316
  } catch (error) {
248
- console.error('Facebook text post failed:', error.message);
317
+ console.error('Upload failed:', error.message);
249
318
  }
250
319
  ```
251
320
 
252
- ## Error Handling
253
- The library throws errors for:
254
- - Missing required parameters
255
- - File not found
256
- - API request failures
257
- - Invalid platform specifications
321
+ ## Links
322
+
323
+ - [Upload-Post Website](https://www.upload-post.com)
324
+ - [API Documentation](https://docs.upload-post.com)
325
+ - [Dashboard](https://app.upload-post.com)
258
326
 
259
327
  ## License
328
+
260
329
  MIT