@memberjunction/actions-bizapps-social 2.112.0 → 2.113.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +13 -0
- package/dist/base/base-social.action.d.ts.map +1 -1
- package/dist/base/base-social.action.js +24 -18
- package/dist/base/base-social.action.js.map +1 -1
- package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
- package/dist/providers/buffer/buffer-base.action.js +34 -35
- package/dist/providers/buffer/buffer-base.action.js.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.js +33 -33
- package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.js +36 -34
- package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.js +20 -20
- package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.js +27 -25
- package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.js +23 -19
- package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.js +32 -28
- package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.js +44 -42
- package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
- package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.js +39 -37
- package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
- package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
- package/dist/providers/facebook/facebook-base.action.js +59 -44
- package/dist/providers/facebook/facebook-base.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +31 -33
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +32 -28
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.js +26 -24
- package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js +34 -32
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.js +52 -43
- package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +28 -30
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.js +20 -18
- package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.js +26 -27
- package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.js +35 -35
- package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.js +59 -38
- package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
- package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.js +36 -36
- package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.js +25 -23
- package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
- package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.js +60 -56
- package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
- package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
- package/dist/providers/instagram/instagram-base.action.js +27 -25
- package/dist/providers/instagram/instagram-base.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.js +45 -55
- package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.js +29 -31
- package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
- package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
- package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
- package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.js +23 -25
- package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.js +30 -32
- package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.js +30 -28
- package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.js +38 -33
- package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.js +26 -25
- package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.js +29 -25
- package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
- package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
- package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.js +47 -40
- package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.js +31 -30
- package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
- package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
- package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.js +58 -56
- package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
- package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
- package/dist/providers/twitter/twitter-base.action.js +68 -58
- package/dist/providers/twitter/twitter-base.action.js.map +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
- package/dist/providers/youtube/youtube-base.action.js +25 -22
- package/dist/providers/youtube/youtube-base.action.js.map +1 -1
- package/package.json +6 -5
- package/src/base/base-social.action.ts +224 -217
- package/src/providers/buffer/buffer-base.action.ts +441 -435
- package/src/providers/facebook/actions/boost-post.action.ts +386 -350
- package/src/providers/facebook/actions/create-album.action.ts +307 -291
- package/src/providers/facebook/actions/create-post.action.ts +227 -224
- package/src/providers/facebook/actions/get-page-insights.action.ts +403 -383
- package/src/providers/facebook/actions/get-page-posts.action.ts +225 -214
- package/src/providers/facebook/actions/get-post-insights.action.ts +316 -300
- package/src/providers/facebook/actions/respond-to-comments.action.ts +336 -319
- package/src/providers/facebook/actions/schedule-post.action.ts +292 -289
- package/src/providers/facebook/actions/search-posts.action.ts +413 -399
- package/src/providers/facebook/facebook-base.action.ts +670 -653
- package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
- package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +189 -184
- package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +161 -160
- package/src/providers/hootsuite/actions/get-analytics.action.ts +254 -249
- package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +207 -206
- package/src/providers/hootsuite/actions/get-social-profiles.action.ts +205 -206
- package/src/providers/hootsuite/actions/search-posts.action.ts +369 -351
- package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +209 -211
- package/src/providers/hootsuite/hootsuite-base.action.ts +307 -301
- package/src/providers/instagram/actions/create-post.action.ts +296 -276
- package/src/providers/instagram/actions/create-story.action.ts +394 -378
- package/src/providers/instagram/actions/get-account-insights.action.ts +420 -384
- package/src/providers/instagram/actions/get-business-posts.action.ts +242 -233
- package/src/providers/instagram/actions/get-comments.action.ts +377 -365
- package/src/providers/instagram/actions/get-post-insights.action.ts +273 -265
- package/src/providers/instagram/actions/schedule-post.action.ts +235 -233
- package/src/providers/instagram/actions/search-posts.action.ts +538 -512
- package/src/providers/instagram/instagram-base.action.ts +393 -368
- package/src/providers/linkedin/actions/create-article.action.ts +266 -275
- package/src/providers/linkedin/actions/create-post.action.ts +177 -179
- package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
- package/src/providers/linkedin/actions/get-organization-posts.action.ts +147 -146
- package/src/providers/linkedin/actions/get-personal-posts.action.ts +139 -138
- package/src/providers/linkedin/actions/get-post-analytics.action.ts +189 -190
- package/src/providers/linkedin/actions/schedule-post.action.ts +189 -191
- package/src/providers/linkedin/actions/search-posts.action.ts +283 -275
- package/src/providers/linkedin/linkedin-base.action.ts +421 -407
- package/src/providers/tiktok/tiktok-base.action.ts +320 -305
- package/src/providers/twitter/actions/create-thread.action.ts +207 -203
- package/src/providers/twitter/actions/create-tweet.action.ts +188 -187
- package/src/providers/twitter/actions/delete-tweet.action.ts +129 -128
- package/src/providers/twitter/actions/get-analytics.action.ts +411 -402
- package/src/providers/twitter/actions/get-mentions.action.ts +219 -218
- package/src/providers/twitter/actions/get-timeline.action.ts +233 -232
- package/src/providers/twitter/actions/schedule-tweet.action.ts +222 -221
- package/src/providers/twitter/actions/search-tweets.action.ts +543 -540
- package/src/providers/twitter/twitter-base.action.ts +560 -541
- 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/
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
154
|
-
throw new Error(`
|
|
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
|
-
|
|
159
|
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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
|
-
|
|
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
|
-
|
|
224
|
-
|
|
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
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
+
}
|