@memberjunction/actions-bizapps-social 2.112.0 → 2.113.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.
Files changed (204) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +13 -0
  3. package/dist/base/base-social.action.d.ts.map +1 -1
  4. package/dist/base/base-social.action.js +24 -18
  5. package/dist/base/base-social.action.js.map +1 -1
  6. package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
  7. package/dist/providers/buffer/buffer-base.action.js +34 -35
  8. package/dist/providers/buffer/buffer-base.action.js.map +1 -1
  9. package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
  10. package/dist/providers/facebook/actions/boost-post.action.js +33 -33
  11. package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
  12. package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
  13. package/dist/providers/facebook/actions/create-album.action.js +36 -34
  14. package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
  15. package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
  16. package/dist/providers/facebook/actions/create-post.action.js +20 -20
  17. package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
  18. package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
  19. package/dist/providers/facebook/actions/get-page-insights.action.js +27 -25
  20. package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
  21. package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
  22. package/dist/providers/facebook/actions/get-page-posts.action.js +23 -19
  23. package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
  24. package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
  25. package/dist/providers/facebook/actions/get-post-insights.action.js +32 -28
  26. package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
  27. package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
  28. package/dist/providers/facebook/actions/respond-to-comments.action.js +44 -42
  29. package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
  30. package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
  31. package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
  32. package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
  33. package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
  34. package/dist/providers/facebook/actions/search-posts.action.js +39 -37
  35. package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
  36. package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
  37. package/dist/providers/facebook/facebook-base.action.js +59 -44
  38. package/dist/providers/facebook/facebook-base.action.js.map +1 -1
  39. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
  40. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +31 -33
  41. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
  42. package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
  43. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +32 -28
  44. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
  45. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
  46. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
  47. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
  48. package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
  49. package/dist/providers/hootsuite/actions/get-analytics.action.js +26 -24
  50. package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
  51. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
  52. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
  53. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
  54. package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
  55. package/dist/providers/hootsuite/actions/get-social-profiles.action.js +34 -32
  56. package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
  57. package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
  58. package/dist/providers/hootsuite/actions/search-posts.action.js +52 -43
  59. package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
  60. package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
  61. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +28 -30
  62. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
  63. package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
  64. package/dist/providers/hootsuite/hootsuite-base.action.js +20 -18
  65. package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
  66. package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
  67. package/dist/providers/instagram/actions/create-post.action.js +26 -27
  68. package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
  69. package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
  70. package/dist/providers/instagram/actions/create-story.action.js +35 -35
  71. package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
  72. package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
  73. package/dist/providers/instagram/actions/get-account-insights.action.js +59 -38
  74. package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
  75. package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
  76. package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
  77. package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
  78. package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
  79. package/dist/providers/instagram/actions/get-comments.action.js +36 -36
  80. package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
  81. package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
  82. package/dist/providers/instagram/actions/get-post-insights.action.js +25 -23
  83. package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
  84. package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
  85. package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
  86. package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
  87. package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
  88. package/dist/providers/instagram/actions/search-posts.action.js +60 -56
  89. package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
  90. package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
  91. package/dist/providers/instagram/instagram-base.action.js +27 -25
  92. package/dist/providers/instagram/instagram-base.action.js.map +1 -1
  93. package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
  94. package/dist/providers/linkedin/actions/create-article.action.js +45 -55
  95. package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
  96. package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
  97. package/dist/providers/linkedin/actions/create-post.action.js +29 -31
  98. package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
  99. package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
  100. package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
  101. package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
  102. package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
  103. package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
  104. package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
  105. package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
  106. package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
  107. package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
  108. package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
  109. package/dist/providers/linkedin/actions/get-post-analytics.action.js +23 -25
  110. package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
  111. package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
  112. package/dist/providers/linkedin/actions/schedule-post.action.js +30 -32
  113. package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
  114. package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
  115. package/dist/providers/linkedin/actions/search-posts.action.js +30 -28
  116. package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
  117. package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
  118. package/dist/providers/linkedin/linkedin-base.action.js +38 -33
  119. package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
  120. package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
  121. package/dist/providers/tiktok/tiktok-base.action.js +26 -25
  122. package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
  123. package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
  124. package/dist/providers/twitter/actions/create-thread.action.js +29 -25
  125. package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
  126. package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
  127. package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
  128. package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
  129. package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
  130. package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
  131. package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
  132. package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
  133. package/dist/providers/twitter/actions/get-analytics.action.js +47 -40
  134. package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
  135. package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
  136. package/dist/providers/twitter/actions/get-mentions.action.js +31 -30
  137. package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
  138. package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
  139. package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
  140. package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
  141. package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
  142. package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
  143. package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
  144. package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
  145. package/dist/providers/twitter/actions/search-tweets.action.js +58 -56
  146. package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
  147. package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
  148. package/dist/providers/twitter/twitter-base.action.js +68 -58
  149. package/dist/providers/twitter/twitter-base.action.js.map +1 -1
  150. package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
  151. package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
  152. package/dist/providers/youtube/youtube-base.action.js +25 -22
  153. package/dist/providers/youtube/youtube-base.action.js.map +1 -1
  154. package/package.json +6 -5
  155. package/src/base/base-social.action.ts +224 -217
  156. package/src/providers/buffer/buffer-base.action.ts +441 -435
  157. package/src/providers/facebook/actions/boost-post.action.ts +386 -350
  158. package/src/providers/facebook/actions/create-album.action.ts +307 -291
  159. package/src/providers/facebook/actions/create-post.action.ts +227 -224
  160. package/src/providers/facebook/actions/get-page-insights.action.ts +403 -383
  161. package/src/providers/facebook/actions/get-page-posts.action.ts +225 -214
  162. package/src/providers/facebook/actions/get-post-insights.action.ts +316 -300
  163. package/src/providers/facebook/actions/respond-to-comments.action.ts +336 -319
  164. package/src/providers/facebook/actions/schedule-post.action.ts +292 -289
  165. package/src/providers/facebook/actions/search-posts.action.ts +413 -399
  166. package/src/providers/facebook/facebook-base.action.ts +670 -653
  167. package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
  168. package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +189 -184
  169. package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +161 -160
  170. package/src/providers/hootsuite/actions/get-analytics.action.ts +254 -249
  171. package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +207 -206
  172. package/src/providers/hootsuite/actions/get-social-profiles.action.ts +205 -206
  173. package/src/providers/hootsuite/actions/search-posts.action.ts +369 -351
  174. package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +209 -211
  175. package/src/providers/hootsuite/hootsuite-base.action.ts +307 -301
  176. package/src/providers/instagram/actions/create-post.action.ts +296 -276
  177. package/src/providers/instagram/actions/create-story.action.ts +394 -378
  178. package/src/providers/instagram/actions/get-account-insights.action.ts +420 -384
  179. package/src/providers/instagram/actions/get-business-posts.action.ts +242 -233
  180. package/src/providers/instagram/actions/get-comments.action.ts +377 -365
  181. package/src/providers/instagram/actions/get-post-insights.action.ts +273 -265
  182. package/src/providers/instagram/actions/schedule-post.action.ts +235 -233
  183. package/src/providers/instagram/actions/search-posts.action.ts +538 -512
  184. package/src/providers/instagram/instagram-base.action.ts +393 -368
  185. package/src/providers/linkedin/actions/create-article.action.ts +266 -275
  186. package/src/providers/linkedin/actions/create-post.action.ts +177 -179
  187. package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
  188. package/src/providers/linkedin/actions/get-organization-posts.action.ts +147 -146
  189. package/src/providers/linkedin/actions/get-personal-posts.action.ts +139 -138
  190. package/src/providers/linkedin/actions/get-post-analytics.action.ts +189 -190
  191. package/src/providers/linkedin/actions/schedule-post.action.ts +189 -191
  192. package/src/providers/linkedin/actions/search-posts.action.ts +283 -275
  193. package/src/providers/linkedin/linkedin-base.action.ts +421 -407
  194. package/src/providers/tiktok/tiktok-base.action.ts +320 -305
  195. package/src/providers/twitter/actions/create-thread.action.ts +207 -203
  196. package/src/providers/twitter/actions/create-tweet.action.ts +188 -187
  197. package/src/providers/twitter/actions/delete-tweet.action.ts +129 -128
  198. package/src/providers/twitter/actions/get-analytics.action.ts +411 -402
  199. package/src/providers/twitter/actions/get-mentions.action.ts +219 -218
  200. package/src/providers/twitter/actions/get-timeline.action.ts +233 -232
  201. package/src/providers/twitter/actions/schedule-tweet.action.ts +222 -221
  202. package/src/providers/twitter/actions/search-tweets.action.ts +543 -540
  203. package/src/providers/twitter/twitter-base.action.ts +560 -541
  204. package/src/providers/youtube/youtube-base.action.ts +333 -320
@@ -1,7 +1,7 @@
1
1
  import { RegisterClass } from '@memberjunction/global';
2
2
  import { HootSuiteBaseAction, HootSuitePost } from '../hootsuite-base.action';
3
3
  import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
4
- import { LogStatus, LogError } from '@memberjunction/global';
4
+ import { LogStatus, LogError } from '@memberjunction/core';
5
5
  import { MediaFile } from '../../../base/base-social.action';
6
6
  import { BaseAction } from '@memberjunction/actions';
7
7
 
@@ -9,12 +9,12 @@ import { BaseAction } from '@memberjunction/actions';
9
9
  * Interface for bulk post data
10
10
  */
11
11
  interface BulkPostData {
12
- content: string;
13
- scheduledTime?: string;
14
- profileIds?: string[];
15
- mediaFiles?: MediaFile[];
16
- tags?: string[];
17
- location?: { latitude: number; longitude: number };
12
+ content: string;
13
+ scheduledTime?: string;
14
+ profileIds?: string[];
15
+ mediaFiles?: MediaFile[];
16
+ tags?: string[];
17
+ location?: { latitude: number; longitude: number; };
18
18
  }
19
19
 
20
20
  /**
@@ -22,273 +22,273 @@ interface BulkPostData {
22
22
  */
23
23
  @RegisterClass(BaseAction, 'HootSuiteBulkSchedulePostsAction')
24
24
  export class HootSuiteBulkSchedulePostsAction extends HootSuiteBaseAction {
25
- /**
26
- * Bulk schedule posts in HootSuite
27
- */
28
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
29
- const { Params, ContextUser } = params;
30
-
31
- try {
32
- // Initialize OAuth
33
- const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
34
- if (!(await this.initializeOAuth(companyIntegrationId))) {
35
- throw new Error('Failed to initialize OAuth connection');
36
- }
37
-
38
- // Extract parameters
39
- const posts = this.getParamValue(Params, 'Posts') as BulkPostData[];
40
- const defaultProfileIds = this.getParamValue(Params, 'DefaultProfileIDs');
41
- const scheduleInterval = this.getParamValue(Params, 'ScheduleInterval');
42
- const startTime = this.getParamValue(Params, 'StartTime');
43
- const skipOnError = this.getParamValue(Params, 'SkipOnError') || true;
44
- const validateOnly = this.getParamValue(Params, 'ValidateOnly') || false;
45
-
46
- // Validate required parameters
47
- if (!posts || !Array.isArray(posts) || posts.length === 0) {
48
- throw new Error('Posts array is required and must not be empty');
49
- }
50
-
51
- // Get default profiles if not specified
52
- let defaultProfiles: string[] = [];
53
- if (defaultProfileIds && Array.isArray(defaultProfileIds)) {
54
- defaultProfiles = defaultProfileIds;
55
- } else if (defaultProfileIds && typeof defaultProfileIds === 'string') {
56
- defaultProfiles = [defaultProfileIds];
57
- } else {
58
- // Get all available profiles as default
59
- const profiles = await this.getSocialProfiles();
60
- if (profiles.length === 0) {
61
- throw new Error('No social profiles found. Please specify DefaultProfileIDs.');
62
- }
63
- defaultProfiles = profiles.map((p) => p.id);
64
- LogStatus(`Using ${defaultProfiles.length} default profiles`);
65
- }
66
-
67
- // Calculate schedule times if interval is specified
68
- let baseScheduleTime: Date | null = null;
69
- if (scheduleInterval && startTime) {
70
- baseScheduleTime = new Date(startTime);
71
- }
72
-
73
- // Process posts
74
- const results: any[] = [];
75
- const errors: any[] = [];
76
- let successCount = 0;
77
- let failureCount = 0;
78
-
79
- LogStatus(`Processing ${posts.length} posts for bulk scheduling...`);
80
-
81
- for (let i = 0; i < posts.length; i++) {
82
- const post = posts[i];
83
- const postIndex = i + 1;
84
-
25
+ /**
26
+ * Bulk schedule posts in HootSuite
27
+ */
28
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
29
+ const { Params, ContextUser } = params;
30
+
85
31
  try {
86
- // Validate post data
87
- this.validateBulkPost(post, postIndex);
88
-
89
- // Calculate scheduled time for this post
90
- let scheduledTime = post.scheduledTime;
91
- if (!scheduledTime && baseScheduleTime && scheduleInterval) {
92
- const offsetMinutes = i * scheduleInterval;
93
- const postScheduleTime = new Date(baseScheduleTime);
94
- postScheduleTime.setMinutes(postScheduleTime.getMinutes() + offsetMinutes);
95
- scheduledTime = postScheduleTime.toISOString();
96
- }
32
+ // Initialize OAuth
33
+ const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
34
+ if (!await this.initializeOAuth(companyIntegrationId)) {
35
+ throw new Error('Failed to initialize OAuth connection');
36
+ }
97
37
 
98
- // Prepare profile IDs
99
- const profileIds = post.profileIds || defaultProfiles;
38
+ // Extract parameters
39
+ const posts = this.getParamValue(Params, 'Posts') as BulkPostData[];
40
+ const defaultProfileIds = this.getParamValue(Params, 'DefaultProfileIDs');
41
+ const scheduleInterval = this.getParamValue(Params, 'ScheduleInterval');
42
+ const startTime = this.getParamValue(Params, 'StartTime');
43
+ const skipOnError = this.getParamValue(Params, 'SkipOnError') || true;
44
+ const validateOnly = this.getParamValue(Params, 'ValidateOnly') || false;
45
+
46
+ // Validate required parameters
47
+ if (!posts || !Array.isArray(posts) || posts.length === 0) {
48
+ throw new Error('Posts array is required and must not be empty');
49
+ }
100
50
 
101
- // If validate only, just check the data
102
- if (validateOnly) {
103
- results.push({
104
- index: postIndex,
105
- status: 'VALIDATED',
106
- content: post.content.substring(0, 50) + '...',
107
- scheduledTime: scheduledTime,
108
- profileCount: profileIds.length,
109
- });
110
- successCount++;
111
- continue;
112
- }
51
+ // Get default profiles if not specified
52
+ let defaultProfiles: string[] = [];
53
+ if (defaultProfileIds && Array.isArray(defaultProfileIds)) {
54
+ defaultProfiles = defaultProfileIds;
55
+ } else if (defaultProfileIds && typeof defaultProfileIds === 'string') {
56
+ defaultProfiles = [defaultProfileIds];
57
+ } else {
58
+ // Get all available profiles as default
59
+ const profiles = await this.getSocialProfiles();
60
+ if (profiles.length === 0) {
61
+ throw new Error('No social profiles found. Please specify DefaultProfileIDs.');
62
+ }
63
+ defaultProfiles = profiles.map(p => p.id);
64
+ LogStatus(`Using ${defaultProfiles.length} default profiles`);
65
+ }
113
66
 
114
- // Upload media if provided
115
- let mediaIds: string[] = [];
116
- if (post.mediaFiles && Array.isArray(post.mediaFiles)) {
117
- LogStatus(`Uploading ${post.mediaFiles.length} media files for post ${postIndex}...`);
118
- mediaIds = await this.uploadMedia(post.mediaFiles);
119
- }
67
+ // Calculate schedule times if interval is specified
68
+ let baseScheduleTime: Date | null = null;
69
+ if (scheduleInterval && startTime) {
70
+ baseScheduleTime = new Date(startTime);
71
+ }
120
72
 
121
- // Create the post
122
- const postData: any = {
123
- text: post.content,
124
- socialProfileIds: profileIds,
125
- scheduledTime: scheduledTime ? this.formatHootSuiteDate(scheduledTime) : undefined,
126
- mediaIds: mediaIds.length > 0 ? mediaIds : undefined,
127
- tags: post.tags,
128
- location: post.location,
129
- };
73
+ // Process posts
74
+ const results: any[] = [];
75
+ const errors: any[] = [];
76
+ let successCount = 0;
77
+ let failureCount = 0;
78
+
79
+ LogStatus(`Processing ${posts.length} posts for bulk scheduling...`);
80
+
81
+ for (let i = 0; i < posts.length; i++) {
82
+ const post = posts[i];
83
+ const postIndex = i + 1;
84
+
85
+ try {
86
+ // Validate post data
87
+ this.validateBulkPost(post, postIndex);
88
+
89
+ // Calculate scheduled time for this post
90
+ let scheduledTime = post.scheduledTime;
91
+ if (!scheduledTime && baseScheduleTime && scheduleInterval) {
92
+ const offsetMinutes = i * scheduleInterval;
93
+ const postScheduleTime = new Date(baseScheduleTime);
94
+ postScheduleTime.setMinutes(postScheduleTime.getMinutes() + offsetMinutes);
95
+ scheduledTime = postScheduleTime.toISOString();
96
+ }
97
+
98
+ // Prepare profile IDs
99
+ const profileIds = post.profileIds || defaultProfiles;
100
+
101
+ // If validate only, just check the data
102
+ if (validateOnly) {
103
+ results.push({
104
+ index: postIndex,
105
+ status: 'VALIDATED',
106
+ content: post.content.substring(0, 50) + '...',
107
+ scheduledTime: scheduledTime,
108
+ profileCount: profileIds.length
109
+ });
110
+ successCount++;
111
+ continue;
112
+ }
113
+
114
+ // Upload media if provided
115
+ let mediaIds: string[] = [];
116
+ if (post.mediaFiles && Array.isArray(post.mediaFiles)) {
117
+ LogStatus(`Uploading ${post.mediaFiles.length} media files for post ${postIndex}...`);
118
+ mediaIds = await this.uploadMedia(post.mediaFiles);
119
+ }
120
+
121
+ // Create the post
122
+ const postData: any = {
123
+ text: post.content,
124
+ socialProfileIds: profileIds,
125
+ scheduledTime: scheduledTime ? this.formatHootSuiteDate(scheduledTime) : undefined,
126
+ mediaIds: mediaIds.length > 0 ? mediaIds : undefined,
127
+ tags: post.tags,
128
+ location: post.location
129
+ };
130
+
131
+ const response = await this.axiosInstance.post('/messages', postData);
132
+ const createdPost = response.data;
133
+
134
+ results.push({
135
+ index: postIndex,
136
+ status: 'SUCCESS',
137
+ postId: createdPost.id,
138
+ content: post.content.substring(0, 50) + '...',
139
+ scheduledTime: createdPost.scheduledTime,
140
+ profileCount: profileIds.length
141
+ });
142
+ successCount++;
143
+
144
+ } catch (error) {
145
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
146
+
147
+ errors.push({
148
+ index: postIndex,
149
+ content: post.content.substring(0, 50) + '...',
150
+ error: errorMessage
151
+ });
152
+ failureCount++;
153
+
154
+ if (!skipOnError) {
155
+ throw new Error(`Failed at post ${postIndex}: ${errorMessage}`);
156
+ }
157
+ }
158
+
159
+ // Log progress every 10 posts
160
+ if (i > 0 && (i + 1) % 10 === 0) {
161
+ LogStatus(`Processed ${i + 1}/${posts.length} posts...`);
162
+ }
163
+ }
130
164
 
131
- const response = await this.axiosInstance.post('/messages', postData);
132
- const createdPost = response.data;
165
+ // Create summary
166
+ const summary = {
167
+ totalPosts: posts.length,
168
+ successCount: successCount,
169
+ failureCount: failureCount,
170
+ validationOnly: validateOnly,
171
+ processingTime: new Date().toISOString(),
172
+ scheduleRange: baseScheduleTime ? {
173
+ start: baseScheduleTime.toISOString(),
174
+ end: new Date(baseScheduleTime.getTime() + (posts.length - 1) * (scheduleInterval || 0) * 60000).toISOString()
175
+ } : null
176
+ };
177
+
178
+ // Update output parameters
179
+ const outputParams = [...Params];
180
+ const resultsParam = outputParams.find(p => p.Name === 'Results');
181
+ if (resultsParam) resultsParam.Value = results;
182
+ const errorsParam = outputParams.find(p => p.Name === 'Errors');
183
+ if (errorsParam) errorsParam.Value = errors;
184
+ const summaryParam = outputParams.find(p => p.Name === 'Summary');
185
+ if (summaryParam) summaryParam.Value = summary;
186
+
187
+ const resultCode = failureCount === 0 ? 'SUCCESS' : (successCount > 0 ? 'PARTIAL_SUCCESS' : 'FAILED');
188
+ const message = validateOnly
189
+ ? `Validated ${successCount} posts, ${failureCount} failed validation`
190
+ : `Successfully scheduled ${successCount} posts, ${failureCount} failed`;
191
+
192
+ return {
193
+ Success: failureCount === 0 || (skipOnError && successCount > 0),
194
+ ResultCode: resultCode,
195
+ Message: message,
196
+ Params: outputParams
197
+ };
133
198
 
134
- results.push({
135
- index: postIndex,
136
- status: 'SUCCESS',
137
- postId: createdPost.id,
138
- content: post.content.substring(0, 50) + '...',
139
- scheduledTime: createdPost.scheduledTime,
140
- profileCount: profileIds.length,
141
- });
142
- successCount++;
143
199
  } catch (error) {
144
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
200
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
201
+
202
+ return {
203
+ Success: false,
204
+ ResultCode: 'ERROR',
205
+ Message: `Failed to bulk schedule posts: ${errorMessage}`,
206
+ Params
207
+ };
208
+ }
209
+ }
145
210
 
146
- errors.push({
147
- index: postIndex,
148
- content: post.content.substring(0, 50) + '...',
149
- error: errorMessage,
150
- });
151
- failureCount++;
211
+ /**
212
+ * Validate bulk post data
213
+ */
214
+ private validateBulkPost(post: BulkPostData, index: number): void {
215
+ if (!post.content || typeof post.content !== 'string' || post.content.trim().length === 0) {
216
+ throw new Error(`Post ${index}: Content is required and must not be empty`);
217
+ }
152
218
 
153
- if (!skipOnError) {
154
- throw new Error(`Failed at post ${postIndex}: ${errorMessage}`);
155
- }
219
+ if (post.content.length > 10000) {
220
+ throw new Error(`Post ${index}: Content exceeds maximum length of 10000 characters`);
156
221
  }
157
222
 
158
- // Log progress every 10 posts
159
- if (i > 0 && (i + 1) % 10 === 0) {
160
- LogStatus(`Processed ${i + 1}/${posts.length} posts...`);
223
+ if (post.scheduledTime && isNaN(Date.parse(post.scheduledTime))) {
224
+ throw new Error(`Post ${index}: Invalid scheduled time format`);
161
225
  }
162
- }
163
226
 
164
- // Create summary
165
- const summary = {
166
- totalPosts: posts.length,
167
- successCount: successCount,
168
- failureCount: failureCount,
169
- validationOnly: validateOnly,
170
- processingTime: new Date().toISOString(),
171
- scheduleRange: baseScheduleTime
172
- ? {
173
- start: baseScheduleTime.toISOString(),
174
- end: new Date(baseScheduleTime.getTime() + (posts.length - 1) * (scheduleInterval || 0) * 60000).toISOString(),
227
+ if (post.location) {
228
+ if (typeof post.location.latitude !== 'number' || typeof post.location.longitude !== 'number') {
229
+ throw new Error(`Post ${index}: Location must have numeric latitude and longitude`);
175
230
  }
176
- : null,
177
- };
178
-
179
- // Update output parameters
180
- const outputParams = [...Params];
181
- const resultsParam = outputParams.find((p) => p.Name === 'Results');
182
- if (resultsParam) resultsParam.Value = results;
183
- const errorsParam = outputParams.find((p) => p.Name === 'Errors');
184
- if (errorsParam) errorsParam.Value = errors;
185
- const summaryParam = outputParams.find((p) => p.Name === 'Summary');
186
- if (summaryParam) summaryParam.Value = summary;
187
-
188
- const resultCode = failureCount === 0 ? 'SUCCESS' : successCount > 0 ? 'PARTIAL_SUCCESS' : 'FAILED';
189
- const message = validateOnly
190
- ? `Validated ${successCount} posts, ${failureCount} failed validation`
191
- : `Successfully scheduled ${successCount} posts, ${failureCount} failed`;
192
-
193
- return {
194
- Success: failureCount === 0 || (skipOnError && successCount > 0),
195
- ResultCode: resultCode,
196
- Message: message,
197
- Params: outputParams,
198
- };
199
- } catch (error) {
200
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
201
-
202
- return {
203
- Success: false,
204
- ResultCode: 'ERROR',
205
- Message: `Failed to bulk schedule posts: ${errorMessage}`,
206
- Params,
207
- };
208
- }
209
- }
210
-
211
- /**
212
- * Validate bulk post data
213
- */
214
- private validateBulkPost(post: BulkPostData, index: number): void {
215
- if (!post.content || typeof post.content !== 'string' || post.content.trim().length === 0) {
216
- throw new Error(`Post ${index}: Content is required and must not be empty`);
217
- }
218
-
219
- if (post.content.length > 10000) {
220
- throw new Error(`Post ${index}: Content exceeds maximum length of 10000 characters`);
231
+ }
221
232
  }
222
233
 
223
- if (post.scheduledTime && isNaN(Date.parse(post.scheduledTime))) {
224
- throw new Error(`Post ${index}: Invalid scheduled time format`);
234
+ /**
235
+ * Define the parameters this action expects
236
+ */
237
+ public get Params(): ActionParam[] {
238
+ return [
239
+ ...this.oauthParams,
240
+ {
241
+ Name: 'Posts',
242
+ Type: 'Input',
243
+ Value: null
244
+ },
245
+ {
246
+ Name: 'DefaultProfileIDs',
247
+ Type: 'Input',
248
+ Value: null
249
+ },
250
+ {
251
+ Name: 'ScheduleInterval',
252
+ Type: 'Input',
253
+ Value: null
254
+ },
255
+ {
256
+ Name: 'StartTime',
257
+ Type: 'Input',
258
+ Value: null
259
+ },
260
+ {
261
+ Name: 'SkipOnError',
262
+ Type: 'Input',
263
+ Value: null
264
+ },
265
+ {
266
+ Name: 'ValidateOnly',
267
+ Type: 'Input',
268
+ Value: null
269
+ },
270
+ {
271
+ Name: 'Results',
272
+ Type: 'Output',
273
+ Value: null
274
+ },
275
+ {
276
+ Name: 'Errors',
277
+ Type: 'Output',
278
+ Value: null
279
+ },
280
+ {
281
+ Name: 'Summary',
282
+ Type: 'Output',
283
+ Value: null
284
+ }
285
+ ];
225
286
  }
226
287
 
227
- if (post.location) {
228
- if (typeof post.location.latitude !== 'number' || typeof post.location.longitude !== 'number') {
229
- throw new Error(`Post ${index}: Location must have numeric latitude and longitude`);
230
- }
288
+ /**
289
+ * Get action description
290
+ */
291
+ public get Description(): string {
292
+ return 'Bulk schedules multiple posts to HootSuite with support for auto-scheduling intervals and validation';
231
293
  }
232
- }
233
-
234
- /**
235
- * Define the parameters this action expects
236
- */
237
- public get Params(): ActionParam[] {
238
- return [
239
- ...this.oauthParams,
240
- {
241
- Name: 'Posts',
242
- Type: 'Input',
243
- Value: null,
244
- },
245
- {
246
- Name: 'DefaultProfileIDs',
247
- Type: 'Input',
248
- Value: null,
249
- },
250
- {
251
- Name: 'ScheduleInterval',
252
- Type: 'Input',
253
- Value: null,
254
- },
255
- {
256
- Name: 'StartTime',
257
- Type: 'Input',
258
- Value: null,
259
- },
260
- {
261
- Name: 'SkipOnError',
262
- Type: 'Input',
263
- Value: null,
264
- },
265
- {
266
- Name: 'ValidateOnly',
267
- Type: 'Input',
268
- Value: null,
269
- },
270
- {
271
- Name: 'Results',
272
- Type: 'Output',
273
- Value: null,
274
- },
275
- {
276
- Name: 'Errors',
277
- Type: 'Output',
278
- Value: null,
279
- },
280
- {
281
- Name: 'Summary',
282
- Type: 'Output',
283
- Value: null,
284
- },
285
- ];
286
- }
287
-
288
- /**
289
- * Get action description
290
- */
291
- public get Description(): string {
292
- return 'Bulk schedules multiple posts to HootSuite with support for auto-scheduling intervals and validation';
293
- }
294
- }
294
+ }