@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 { InstagramBaseAction } from '../instagram-base.action';
|
|
3
3
|
import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
|
|
4
|
-
import { LogError } from '@memberjunction/
|
|
4
|
+
import { LogError } from '@memberjunction/core';
|
|
5
5
|
import { MediaFile } from '../../../base/base-social.action';
|
|
6
6
|
import { BaseAction } from '@memberjunction/actions';
|
|
7
7
|
|
|
@@ -11,300 +11,320 @@ import { BaseAction } from '@memberjunction/actions';
|
|
|
11
11
|
*/
|
|
12
12
|
@RegisterClass(BaseAction, 'Instagram - Create Post')
|
|
13
13
|
export class InstagramCreatePostAction extends InstagramBaseAction {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
14
|
+
|
|
15
|
+
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
|
|
16
|
+
try {
|
|
17
|
+
const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
|
|
18
|
+
const content = this.getParamValue(params.Params, 'Content');
|
|
19
|
+
const mediaFiles = this.getParamValue(params.Params, 'MediaFiles') as MediaFile[];
|
|
20
|
+
const postType = this.getParamValue(params.Params, 'PostType') || 'FEED';
|
|
21
|
+
const locationId = this.getParamValue(params.Params, 'LocationID');
|
|
22
|
+
const taggedUsers = this.getParamValue(params.Params, 'TaggedUsers') as string[];
|
|
23
|
+
const scheduledTime = this.getParamValue(params.Params, 'ScheduledTime');
|
|
24
|
+
|
|
25
|
+
// Initialize OAuth
|
|
26
|
+
if (!await this.initializeOAuth(companyIntegrationId)) {
|
|
27
|
+
return {
|
|
28
|
+
Success: false,
|
|
29
|
+
Message: 'Failed to initialize Instagram authentication',
|
|
30
|
+
ResultCode: 'AUTH_FAILED'
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Validate inputs
|
|
35
|
+
if (!mediaFiles || mediaFiles.length === 0) {
|
|
36
|
+
return {
|
|
37
|
+
Success: false,
|
|
38
|
+
Message: 'At least one media file is required for Instagram posts',
|
|
39
|
+
ResultCode: 'MISSING_MEDIA'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Instagram has specific requirements for different post types
|
|
44
|
+
if (postType === 'CAROUSEL' && mediaFiles.length < 2) {
|
|
45
|
+
return {
|
|
46
|
+
Success: false,
|
|
47
|
+
Message: 'Carousel posts require at least 2 media files',
|
|
48
|
+
ResultCode: 'INVALID_CAROUSEL'
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (postType === 'REELS' && (!mediaFiles[0].mimeType.startsWith('video/') || mediaFiles.length > 1)) {
|
|
53
|
+
return {
|
|
54
|
+
Success: false,
|
|
55
|
+
Message: 'Reels require exactly one video file',
|
|
56
|
+
ResultCode: 'INVALID_REEL'
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Handle scheduled posts differently
|
|
61
|
+
if (scheduledTime) {
|
|
62
|
+
const scheduleDate = new Date(scheduledTime);
|
|
63
|
+
if (scheduleDate <= new Date()) {
|
|
64
|
+
return {
|
|
65
|
+
Success: false,
|
|
66
|
+
Message: 'Scheduled time must be in the future',
|
|
67
|
+
ResultCode: 'INVALID_SCHEDULE_TIME'
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Instagram requires Facebook Creator Studio for scheduling
|
|
72
|
+
return {
|
|
73
|
+
Success: false,
|
|
74
|
+
Message: 'Instagram post scheduling requires Facebook Creator Studio integration',
|
|
75
|
+
ResultCode: 'SCHEDULING_NOT_SUPPORTED'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let postId: string;
|
|
80
|
+
|
|
81
|
+
if (postType === 'CAROUSEL') {
|
|
82
|
+
postId = await this.createCarouselPost(mediaFiles, content, locationId, taggedUsers);
|
|
83
|
+
} else if (postType === 'REELS') {
|
|
84
|
+
postId = await this.createReelPost(mediaFiles[0], content, locationId, taggedUsers);
|
|
85
|
+
} else {
|
|
86
|
+
postId = await this.createFeedPost(mediaFiles[0], content, locationId, taggedUsers);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Store result in output params
|
|
90
|
+
const outputParams = [...params.Params];
|
|
91
|
+
outputParams.push({
|
|
92
|
+
Name: 'PostID',
|
|
93
|
+
Type: 'Output',
|
|
94
|
+
Value: postId
|
|
95
|
+
});
|
|
96
|
+
outputParams.push({
|
|
97
|
+
Name: 'Permalink',
|
|
98
|
+
Type: 'Output',
|
|
99
|
+
Value: `https://www.instagram.com/p/${postId}/`
|
|
100
|
+
});
|
|
101
|
+
outputParams.push({
|
|
102
|
+
Name: 'PostType',
|
|
103
|
+
Type: 'Output',
|
|
104
|
+
Value: postType
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
Success: true,
|
|
109
|
+
Message: `Instagram ${postType.toLowerCase()} created successfully`,
|
|
110
|
+
ResultCode: 'SUCCESS',
|
|
111
|
+
Params: outputParams
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
} catch (error: any) {
|
|
115
|
+
LogError('Failed to create Instagram post', error);
|
|
116
|
+
|
|
117
|
+
if (error.code === 'RATE_LIMIT') {
|
|
118
|
+
return {
|
|
119
|
+
Success: false,
|
|
120
|
+
Message: 'Instagram API rate limit exceeded. Please try again later.',
|
|
121
|
+
ResultCode: 'RATE_LIMIT'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (error.code === 'INVALID_MEDIA') {
|
|
126
|
+
return {
|
|
127
|
+
Success: false,
|
|
128
|
+
Message: error.message,
|
|
129
|
+
ResultCode: 'INVALID_MEDIA'
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
Success: false,
|
|
135
|
+
Message: `Failed to create Instagram post: ${error.message}`,
|
|
136
|
+
ResultCode: 'ERROR'
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
50
140
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Create a standard feed post (single image or video)
|
|
143
|
+
*/
|
|
144
|
+
private async createFeedPost(
|
|
145
|
+
mediaFile: MediaFile,
|
|
146
|
+
caption: string,
|
|
147
|
+
locationId?: string,
|
|
148
|
+
taggedUsers?: string[]
|
|
149
|
+
): Promise<string> {
|
|
150
|
+
// Add metadata to media file
|
|
151
|
+
(mediaFile as any).metadata = { caption };
|
|
152
|
+
|
|
153
|
+
// Upload media and get container ID
|
|
154
|
+
const containerId = await this.uploadSingleMedia(mediaFile);
|
|
155
|
+
|
|
156
|
+
// Wait for media to be processed
|
|
157
|
+
await this.waitForMediaContainer(containerId);
|
|
158
|
+
|
|
159
|
+
// Add additional parameters if provided
|
|
160
|
+
const publishParams: any = {
|
|
161
|
+
creation_id: containerId,
|
|
162
|
+
access_token: this.getAccessToken()
|
|
56
163
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (scheduledTime) {
|
|
61
|
-
const scheduleDate = new Date(scheduledTime);
|
|
62
|
-
if (scheduleDate <= new Date()) {
|
|
63
|
-
return {
|
|
64
|
-
Success: false,
|
|
65
|
-
Message: 'Scheduled time must be in the future',
|
|
66
|
-
ResultCode: 'INVALID_SCHEDULE_TIME',
|
|
67
|
-
};
|
|
164
|
+
|
|
165
|
+
if (locationId) {
|
|
166
|
+
publishParams.location_id = locationId;
|
|
68
167
|
}
|
|
69
168
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
let postId: string;
|
|
79
|
-
|
|
80
|
-
if (postType === 'CAROUSEL') {
|
|
81
|
-
postId = await this.createCarouselPost(mediaFiles, content, locationId, taggedUsers);
|
|
82
|
-
} else if (postType === 'REELS') {
|
|
83
|
-
postId = await this.createReelPost(mediaFiles[0], content, locationId, taggedUsers);
|
|
84
|
-
} else {
|
|
85
|
-
postId = await this.createFeedPost(mediaFiles[0], content, locationId, taggedUsers);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Store result in output params
|
|
89
|
-
const outputParams = [...params.Params];
|
|
90
|
-
outputParams.push({
|
|
91
|
-
Name: 'PostID',
|
|
92
|
-
Type: 'Output',
|
|
93
|
-
Value: postId,
|
|
94
|
-
});
|
|
95
|
-
outputParams.push({
|
|
96
|
-
Name: 'Permalink',
|
|
97
|
-
Type: 'Output',
|
|
98
|
-
Value: `https://www.instagram.com/p/${postId}/`,
|
|
99
|
-
});
|
|
100
|
-
outputParams.push({
|
|
101
|
-
Name: 'PostType',
|
|
102
|
-
Type: 'Output',
|
|
103
|
-
Value: postType,
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
return {
|
|
107
|
-
Success: true,
|
|
108
|
-
Message: `Instagram ${postType.toLowerCase()} created successfully`,
|
|
109
|
-
ResultCode: 'SUCCESS',
|
|
110
|
-
Params: outputParams,
|
|
111
|
-
};
|
|
112
|
-
} catch (error: any) {
|
|
113
|
-
LogError('Failed to create Instagram post', error);
|
|
114
|
-
|
|
115
|
-
if (error.code === 'RATE_LIMIT') {
|
|
116
|
-
return {
|
|
117
|
-
Success: false,
|
|
118
|
-
Message: 'Instagram API rate limit exceeded. Please try again later.',
|
|
119
|
-
ResultCode: 'RATE_LIMIT',
|
|
120
|
-
};
|
|
121
|
-
}
|
|
169
|
+
if (taggedUsers && taggedUsers.length > 0) {
|
|
170
|
+
publishParams.user_tags = taggedUsers.map(userId => ({
|
|
171
|
+
username: userId,
|
|
172
|
+
x: 0.5, // Center of image
|
|
173
|
+
y: 0.5
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
122
176
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
177
|
+
// Publish the post
|
|
178
|
+
const response = await this.makeInstagramRequest<{ id: string }>(
|
|
179
|
+
`${this.instagramBusinessAccountId}/media_publish`,
|
|
180
|
+
'POST',
|
|
181
|
+
publishParams
|
|
182
|
+
);
|
|
130
183
|
|
|
131
|
-
|
|
132
|
-
Success: false,
|
|
133
|
-
Message: `Failed to create Instagram post: ${error.message}`,
|
|
134
|
-
ResultCode: 'ERROR',
|
|
135
|
-
};
|
|
184
|
+
return response.id;
|
|
136
185
|
}
|
|
137
|
-
}
|
|
138
186
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Create a carousel post (multiple images/videos)
|
|
189
|
+
*/
|
|
190
|
+
private async createCarouselPost(
|
|
191
|
+
mediaFiles: MediaFile[],
|
|
192
|
+
caption: string,
|
|
193
|
+
locationId?: string,
|
|
194
|
+
taggedUsers?: string[]
|
|
195
|
+
): Promise<string> {
|
|
196
|
+
// Upload all media items as carousel items
|
|
197
|
+
const containerIds: string[] = [];
|
|
198
|
+
|
|
199
|
+
for (const file of mediaFiles.slice(0, 10)) { // Instagram allows max 10 items
|
|
200
|
+
file.filename = `carousel_${file.filename}`; // Mark as carousel item
|
|
201
|
+
const containerId = await this.uploadSingleMedia(file);
|
|
202
|
+
containerIds.push(containerId);
|
|
203
|
+
}
|
|
145
204
|
|
|
146
|
-
|
|
147
|
-
|
|
205
|
+
// Wait for all media to be processed
|
|
206
|
+
await Promise.all(containerIds.map(id => this.waitForMediaContainer(id)));
|
|
148
207
|
|
|
149
|
-
|
|
150
|
-
|
|
208
|
+
// Create carousel container
|
|
209
|
+
const carouselParams: any = {
|
|
210
|
+
media_type: 'CAROUSEL',
|
|
211
|
+
children: containerIds,
|
|
212
|
+
caption: caption,
|
|
213
|
+
access_token: this.getAccessToken()
|
|
214
|
+
};
|
|
151
215
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
access_token: this.getAccessToken(),
|
|
156
|
-
};
|
|
216
|
+
if (locationId) {
|
|
217
|
+
carouselParams.location_id = locationId;
|
|
218
|
+
}
|
|
157
219
|
|
|
158
|
-
|
|
159
|
-
|
|
220
|
+
const carouselResponse = await this.makeInstagramRequest<{ id: string }>(
|
|
221
|
+
`${this.instagramBusinessAccountId}/media`,
|
|
222
|
+
'POST',
|
|
223
|
+
carouselParams
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// Wait for carousel container to be ready
|
|
227
|
+
await this.waitForMediaContainer(carouselResponse.id);
|
|
228
|
+
|
|
229
|
+
// Publish the carousel
|
|
230
|
+
const publishResponse = await this.makeInstagramRequest<{ id: string }>(
|
|
231
|
+
`${this.instagramBusinessAccountId}/media_publish`,
|
|
232
|
+
'POST',
|
|
233
|
+
{
|
|
234
|
+
creation_id: carouselResponse.id,
|
|
235
|
+
access_token: this.getAccessToken()
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
return publishResponse.id;
|
|
160
240
|
}
|
|
161
241
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Create a Reel post
|
|
244
|
+
*/
|
|
245
|
+
private async createReelPost(
|
|
246
|
+
videoFile: MediaFile,
|
|
247
|
+
caption: string,
|
|
248
|
+
locationId?: string,
|
|
249
|
+
taggedUsers?: string[]
|
|
250
|
+
): Promise<string> {
|
|
251
|
+
// Validate video duration (Reels must be 90 seconds or less)
|
|
252
|
+
// In production, you'd check the actual video duration
|
|
253
|
+
|
|
254
|
+
// Add metadata
|
|
255
|
+
(videoFile as any).metadata = {
|
|
256
|
+
caption,
|
|
257
|
+
media_type: 'REELS'
|
|
258
|
+
};
|
|
169
259
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`${this.instagramBusinessAccountId}/media_publish`,
|
|
173
|
-
'POST',
|
|
174
|
-
publishParams
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
return response.id;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Create a carousel post (multiple images/videos)
|
|
182
|
-
*/
|
|
183
|
-
private async createCarouselPost(mediaFiles: MediaFile[], caption: string, locationId?: string, taggedUsers?: string[]): Promise<string> {
|
|
184
|
-
// Upload all media items as carousel items
|
|
185
|
-
const containerIds: string[] = [];
|
|
186
|
-
|
|
187
|
-
for (const file of mediaFiles.slice(0, 10)) {
|
|
188
|
-
// Instagram allows max 10 items
|
|
189
|
-
file.filename = `carousel_${file.filename}`; // Mark as carousel item
|
|
190
|
-
const containerId = await this.uploadSingleMedia(file);
|
|
191
|
-
containerIds.push(containerId);
|
|
192
|
-
}
|
|
260
|
+
// Upload video
|
|
261
|
+
const containerId = await this.uploadSingleMedia(videoFile);
|
|
193
262
|
|
|
194
|
-
|
|
195
|
-
|
|
263
|
+
// Wait for video to be processed (videos take longer)
|
|
264
|
+
await this.waitForMediaContainer(containerId, 300000); // 5 minute timeout for videos
|
|
196
265
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
266
|
+
// Publish the reel
|
|
267
|
+
const publishParams: any = {
|
|
268
|
+
creation_id: containerId,
|
|
269
|
+
access_token: this.getAccessToken()
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
if (locationId) {
|
|
273
|
+
publishParams.location_id = locationId;
|
|
274
|
+
}
|
|
204
275
|
|
|
205
|
-
|
|
206
|
-
|
|
276
|
+
const response = await this.makeInstagramRequest<{ id: string }>(
|
|
277
|
+
`${this.instagramBusinessAccountId}/media_publish`,
|
|
278
|
+
'POST',
|
|
279
|
+
publishParams
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
return response.id;
|
|
207
283
|
}
|
|
208
284
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// Publish the reel
|
|
247
|
-
const publishParams: any = {
|
|
248
|
-
creation_id: containerId,
|
|
249
|
-
access_token: this.getAccessToken(),
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
if (locationId) {
|
|
253
|
-
publishParams.location_id = locationId;
|
|
285
|
+
/**
|
|
286
|
+
* Define the parameters for this action
|
|
287
|
+
*/
|
|
288
|
+
public get Params(): ActionParam[] {
|
|
289
|
+
return [
|
|
290
|
+
...this.commonSocialParams,
|
|
291
|
+
{
|
|
292
|
+
Name: 'Content',
|
|
293
|
+
Type: 'Input',
|
|
294
|
+
Value: null,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
Name: 'MediaFiles',
|
|
298
|
+
Type: 'Input',
|
|
299
|
+
Value: null,
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
Name: 'PostType',
|
|
303
|
+
Type: 'Input',
|
|
304
|
+
Value: 'FEED',
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
Name: 'LocationID',
|
|
308
|
+
Type: 'Input',
|
|
309
|
+
Value: null,
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
Name: 'TaggedUsers',
|
|
313
|
+
Type: 'Input',
|
|
314
|
+
Value: null,
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
Name: 'ScheduledTime',
|
|
318
|
+
Type: 'Input',
|
|
319
|
+
Value: null,
|
|
320
|
+
}
|
|
321
|
+
];
|
|
254
322
|
}
|
|
255
323
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Define the parameters for this action
|
|
267
|
-
*/
|
|
268
|
-
public get Params(): ActionParam[] {
|
|
269
|
-
return [
|
|
270
|
-
...this.commonSocialParams,
|
|
271
|
-
{
|
|
272
|
-
Name: 'Content',
|
|
273
|
-
Type: 'Input',
|
|
274
|
-
Value: null,
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
Name: 'MediaFiles',
|
|
278
|
-
Type: 'Input',
|
|
279
|
-
Value: null,
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
Name: 'PostType',
|
|
283
|
-
Type: 'Input',
|
|
284
|
-
Value: 'FEED',
|
|
285
|
-
},
|
|
286
|
-
{
|
|
287
|
-
Name: 'LocationID',
|
|
288
|
-
Type: 'Input',
|
|
289
|
-
Value: null,
|
|
290
|
-
},
|
|
291
|
-
{
|
|
292
|
-
Name: 'TaggedUsers',
|
|
293
|
-
Type: 'Input',
|
|
294
|
-
Value: null,
|
|
295
|
-
},
|
|
296
|
-
{
|
|
297
|
-
Name: 'ScheduledTime',
|
|
298
|
-
Type: 'Input',
|
|
299
|
-
Value: null,
|
|
300
|
-
},
|
|
301
|
-
];
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Get the description for this action
|
|
306
|
-
*/
|
|
307
|
-
public get Description(): string {
|
|
308
|
-
return 'Creates a new Instagram post with images or videos. Supports feed posts, carousels, and reels.';
|
|
309
|
-
}
|
|
310
|
-
}
|
|
324
|
+
/**
|
|
325
|
+
* Get the description for this action
|
|
326
|
+
*/
|
|
327
|
+
public get Description(): string {
|
|
328
|
+
return 'Creates a new Instagram post with images or videos. Supports feed posts, carousels, and reels.';
|
|
329
|
+
}
|
|
330
|
+
}
|