upload-post 2.1.0 → 2.1.2

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.
@@ -46,10 +46,6 @@ jobs:
46
46
  echo "🚀 New version detected: $REMOTE → $LOCAL"
47
47
  fi
48
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
49
  - name: Install dependencies
54
50
  if: steps.version_check.outputs.new == 'true' || github.event_name == 'workflow_dispatch'
55
51
  run: npm ci
@@ -61,7 +57,11 @@ jobs:
61
57
  - name: Publish to npm (dry-run)
62
58
  if: ${{ inputs.dry_run == true }}
63
59
  run: npm publish --access public --dry-run
60
+ env:
61
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
64
62
 
65
63
  - name: Publish to npm
66
64
  if: (steps.version_check.outputs.new == 'true' && inputs.dry_run != true) || github.event_name == 'release'
67
- run: npm publish --access public --provenance
65
+ run: npm publish --access public
66
+ env:
67
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/index.d.ts CHANGED
@@ -136,8 +136,8 @@ declare module 'upload-post' {
136
136
  instagramShareToFeed?: boolean;
137
137
  /** Comma-separated collaborator usernames */
138
138
  instagramCollaborators?: string;
139
- /** Custom cover URL */
140
- instagramCoverUrl?: string;
139
+ /** Custom cover: URL string, file path, Buffer, or ReadableStream */
140
+ instagramCoverUrl?: string | Buffer | NodeJS.ReadableStream;
141
141
  /** Audio track name */
142
142
  instagramAudioName?: string;
143
143
  /** Comma-separated user tags */
@@ -648,6 +648,68 @@ declare module 'upload-post' {
648
648
  */
649
649
  validateJwt(jwt: string): Promise<{ success: boolean; valid?: boolean }>;
650
650
 
651
+ /**
652
+ * Get user preferences (including calendar settings)
653
+ */
654
+ getUserPreferences(): Promise<{ success: boolean; preferences?: { week_start_day?: number; [key: string]: any } }>;
655
+
656
+ /**
657
+ * Update user preferences (including calendar settings)
658
+ * @param options - Preferences options
659
+ */
660
+ updateUserPreferences(options?: { weekStartDay?: number }): Promise<{ success: boolean; preferences?: { week_start_day?: number; [key: string]: any } }>;
661
+
662
+ /**
663
+ * Get notification configuration (including webhook settings)
664
+ */
665
+ getNotificationConfig(): Promise<{ success: boolean; config?: { webhook_events?: string[]; webhook_url?: string; [key: string]: any } }>;
666
+
667
+ /**
668
+ * Update notification configuration (including webhook settings)
669
+ * @param options - Notification config options
670
+ */
671
+ updateNotificationConfig(options?: { webhookEvents?: string[]; webhookUrl?: string }): Promise<{ success: boolean; config?: { webhook_events?: string[]; webhook_url?: string; [key: string]: any } }>;
672
+
673
+ // Instagram Comments
674
+
675
+ /**
676
+ * Get comments on an Instagram post
677
+ * @param user - Profile username
678
+ * @param options - Query options
679
+ */
680
+ getPostComments(user: string, options?: { postId?: string; postUrl?: string }): Promise<{
681
+ success: boolean;
682
+ comments?: Array<{
683
+ id: string;
684
+ text: string;
685
+ timestamp: string;
686
+ user: { id: string; username: string };
687
+ }>;
688
+ }>;
689
+
690
+ /**
691
+ * Send a private reply (DM) to the author of an Instagram comment
692
+ * @param options - Reply options
693
+ */
694
+ replyToComment(options: { user: string; commentId: string; message: string }): Promise<{
695
+ success: boolean;
696
+ recipient_id?: string;
697
+ message_id?: string;
698
+ message?: string;
699
+ error?: string;
700
+ }>;
701
+
702
+ /**
703
+ * Post a public reply to an Instagram comment (visible under the original comment)
704
+ * @param options - Reply options
705
+ */
706
+ publicReplyToComment(options: { user: string; commentId: string; message: string }): Promise<{
707
+ success: boolean;
708
+ id?: string;
709
+ message?: string;
710
+ error?: string;
711
+ }>;
712
+
651
713
  // Helper Endpoints
652
714
  /**
653
715
  * Get Facebook pages for a profile
package/index.js CHANGED
@@ -160,7 +160,16 @@ export class UploadPost {
160
160
 
161
161
  if (isVideo) {
162
162
  if (options.instagramShareToFeed !== undefined) form.append('share_to_feed', String(options.instagramShareToFeed));
163
- if (options.instagramCoverUrl) form.append('cover_url', options.instagramCoverUrl);
163
+ if (options.instagramCoverUrl) {
164
+ const coverVal = options.instagramCoverUrl;
165
+ if (typeof coverVal === 'string' && (coverVal.toLowerCase().startsWith('http://') || coverVal.toLowerCase().startsWith('https://'))) {
166
+ form.append('cover_url', coverVal);
167
+ } else if (typeof coverVal === 'string') {
168
+ form.append('cover_image', createReadStream(coverVal));
169
+ } else {
170
+ form.append('cover_image', coverVal);
171
+ }
172
+ }
164
173
  if (options.instagramAudioName) form.append('audio_name', options.instagramAudioName);
165
174
  if (options.instagramThumbOffset) form.append('thumb_offset', options.instagramThumbOffset);
166
175
  }
@@ -326,7 +335,7 @@ export class UploadPost {
326
335
  * @param {string} [options.instagramMediaType] - REELS or STORIES
327
336
  * @param {boolean} [options.instagramShareToFeed] - Share to feed
328
337
  * @param {string} [options.instagramCollaborators] - Comma-separated collaborator usernames
329
- * @param {string} [options.instagramCoverUrl] - Custom cover URL
338
+ * @param {string|Buffer|ReadableStream} [options.instagramCoverUrl] - Custom cover: URL string, file path, Buffer, or ReadableStream
330
339
  * @param {string} [options.instagramAudioName] - Audio track name
331
340
  * @param {string} [options.instagramUserTags] - Comma-separated user tags
332
341
  * @param {string} [options.instagramLocationId] - Location ID
@@ -710,6 +719,22 @@ export class UploadPost {
710
719
  return this._request(`/uploadposts/post-analytics/${encodeURIComponent(requestId)}`, 'GET');
711
720
  }
712
721
 
722
+ /**
723
+ * Get analytics for any post (including organic posts) using its native platform ID
724
+ *
725
+ * @param {string} platformPostId - The native post ID on the platform (e.g., Instagram media ID)
726
+ * @param {string} platform - The platform to query (instagram, youtube, tiktok, facebook, linkedin, x, threads, pinterest, reddit)
727
+ * @param {string} user - The profile_username that owns the social account
728
+ * @returns {Promise<Object>} Post analytics with live per-post metrics from the platform API
729
+ */
730
+ async getPostAnalyticsByPlatformId(platformPostId, platform, user) {
731
+ return this._request('/uploadposts/post-analytics', 'GET', {
732
+ platform_post_id: platformPostId,
733
+ platform,
734
+ user,
735
+ });
736
+ }
737
+
713
738
  /**
714
739
  * Get available metrics configuration for all supported platforms
715
740
  *
@@ -826,6 +851,106 @@ export class UploadPost {
826
851
  return this._request('/uploadposts/users/validate-jwt', 'POST', { jwt });
827
852
  }
828
853
 
854
+ /**
855
+ * Get user preferences (including calendar settings)
856
+ *
857
+ * @returns {Promise<Object>} User preferences
858
+ */
859
+ async getUserPreferences() {
860
+ return this._request('/uploadposts/users/preferences', 'GET');
861
+ }
862
+
863
+ /**
864
+ * Update user preferences (including calendar settings)
865
+ *
866
+ * @param {Object} options - Preferences options
867
+ * @param {number} [options.weekStartDay] - Week start day (0=Sunday, 1=Monday)
868
+ * @returns {Promise<Object>} Updated preferences
869
+ */
870
+ async updateUserPreferences(options = {}) {
871
+ const body = {};
872
+ if (options.weekStartDay !== undefined) body.week_start_day = options.weekStartDay;
873
+ return this._request('/uploadposts/users/preferences', 'POST', body);
874
+ }
875
+
876
+ /**
877
+ * Get notification configuration (including webhook settings)
878
+ *
879
+ * @returns {Promise<Object>} Notification config
880
+ */
881
+ async getNotificationConfig() {
882
+ return this._request('/uploadposts/notification-config', 'GET');
883
+ }
884
+
885
+ /**
886
+ * Update notification configuration (including webhook settings)
887
+ *
888
+ * @param {Object} options - Notification config options
889
+ * @param {string[]} [options.webhookEvents] - Webhook event types to subscribe to (upload_completed, social_account_connected, social_account_disconnected, social_account_reauth_required)
890
+ * @param {string} [options.webhookUrl] - Webhook URL for notifications
891
+ * @returns {Promise<Object>} Updated notification config
892
+ */
893
+ async updateNotificationConfig(options = {}) {
894
+ const body = {};
895
+ if (options.webhookEvents) body.webhook_events = options.webhookEvents;
896
+ if (options.webhookUrl) body.webhook_url = options.webhookUrl;
897
+ return this._request('/uploadposts/notification-config', 'POST', body);
898
+ }
899
+
900
+ // ==================== Instagram Comments ====================
901
+
902
+ /**
903
+ * Get comments on an Instagram post
904
+ *
905
+ * @param {string} user - Profile username
906
+ * @param {Object} options - Query options
907
+ * @param {string} [options.postId] - Numeric media ID (provide postId or postUrl)
908
+ * @param {string} [options.postUrl] - Full Instagram post URL (provide postId or postUrl)
909
+ * @returns {Promise<Object>} Comments data
910
+ */
911
+ async getPostComments(user, options = {}) {
912
+ const params = { platform: 'instagram', user };
913
+ if (options.postId) params.post_id = options.postId;
914
+ if (options.postUrl) params.post_url = options.postUrl;
915
+ return this._request('/uploadposts/comments', 'GET', params);
916
+ }
917
+
918
+ /**
919
+ * Send a private reply (DM) to the author of an Instagram comment
920
+ *
921
+ * @param {Object} options - Reply options
922
+ * @param {string} options.user - Profile username
923
+ * @param {string} options.commentId - Comment ID from getPostComments
924
+ * @param {string} options.message - Reply message text
925
+ * @returns {Promise<Object>} Reply result
926
+ */
927
+ async replyToComment(options) {
928
+ return this._request('/uploadposts/comments/reply', 'POST', {
929
+ platform: 'instagram',
930
+ user: options.user,
931
+ comment_id: options.commentId,
932
+ message: options.message
933
+ });
934
+ }
935
+
936
+ /**
937
+ * Post a public reply to an Instagram comment (visible under the original comment)
938
+ *
939
+ * @param {Object} options - Reply options
940
+ * @param {string} options.user - Profile username
941
+ * @param {string} options.commentId - Comment ID from getPostComments
942
+ * @param {string} options.message - Reply message text
943
+ * @returns {Promise<Object>} Reply result with the new comment ID
944
+ */
945
+ async publicReplyToComment(options) {
946
+ return this._request('/uploadposts/comments/public-reply', 'POST', {
947
+ platform: 'instagram',
948
+ user: options.user,
949
+ comment_id: options.commentId,
950
+ message: options.message
951
+ });
952
+ }
953
+
829
954
  // ==================== Helper Endpoints ====================
830
955
 
831
956
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "upload-post",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
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",