@memberjunction/actions-bizapps-social 2.111.1 → 2.112.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 +6 -6
  3. package/dist/base/base-social.action.d.ts.map +1 -1
  4. package/dist/base/base-social.action.js +18 -24
  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 +35 -34
  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 +34 -36
  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 +25 -27
  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 +19 -23
  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 +28 -32
  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 +42 -44
  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 +37 -39
  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 +44 -59
  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 +33 -31
  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 +28 -32
  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 +24 -26
  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 +32 -34
  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 +43 -52
  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 +30 -28
  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 +18 -20
  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 +27 -26
  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 +38 -59
  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 +23 -25
  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 +56 -60
  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 +25 -27
  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 +55 -45
  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 +31 -29
  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 +25 -23
  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 +32 -30
  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 +28 -30
  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 +33 -38
  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 +25 -26
  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 +25 -29
  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 +40 -47
  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 +30 -31
  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 +56 -58
  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 +58 -68
  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 +22 -25
  153. package/dist/providers/youtube/youtube-base.action.js.map +1 -1
  154. package/package.json +5 -6
  155. package/src/base/base-social.action.ts +217 -224
  156. package/src/providers/buffer/buffer-base.action.ts +435 -441
  157. package/src/providers/facebook/actions/boost-post.action.ts +350 -386
  158. package/src/providers/facebook/actions/create-album.action.ts +291 -307
  159. package/src/providers/facebook/actions/create-post.action.ts +224 -227
  160. package/src/providers/facebook/actions/get-page-insights.action.ts +383 -403
  161. package/src/providers/facebook/actions/get-page-posts.action.ts +214 -225
  162. package/src/providers/facebook/actions/get-post-insights.action.ts +300 -316
  163. package/src/providers/facebook/actions/respond-to-comments.action.ts +319 -336
  164. package/src/providers/facebook/actions/schedule-post.action.ts +289 -292
  165. package/src/providers/facebook/actions/search-posts.action.ts +399 -413
  166. package/src/providers/facebook/facebook-base.action.ts +653 -670
  167. package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
  168. package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +184 -189
  169. package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +160 -161
  170. package/src/providers/hootsuite/actions/get-analytics.action.ts +249 -254
  171. package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +206 -207
  172. package/src/providers/hootsuite/actions/get-social-profiles.action.ts +206 -205
  173. package/src/providers/hootsuite/actions/search-posts.action.ts +351 -369
  174. package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +211 -209
  175. package/src/providers/hootsuite/hootsuite-base.action.ts +301 -307
  176. package/src/providers/instagram/actions/create-post.action.ts +276 -296
  177. package/src/providers/instagram/actions/create-story.action.ts +378 -394
  178. package/src/providers/instagram/actions/get-account-insights.action.ts +384 -420
  179. package/src/providers/instagram/actions/get-business-posts.action.ts +233 -242
  180. package/src/providers/instagram/actions/get-comments.action.ts +365 -377
  181. package/src/providers/instagram/actions/get-post-insights.action.ts +265 -273
  182. package/src/providers/instagram/actions/schedule-post.action.ts +233 -235
  183. package/src/providers/instagram/actions/search-posts.action.ts +512 -538
  184. package/src/providers/instagram/instagram-base.action.ts +368 -393
  185. package/src/providers/linkedin/actions/create-article.action.ts +275 -266
  186. package/src/providers/linkedin/actions/create-post.action.ts +179 -177
  187. package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
  188. package/src/providers/linkedin/actions/get-organization-posts.action.ts +146 -147
  189. package/src/providers/linkedin/actions/get-personal-posts.action.ts +138 -139
  190. package/src/providers/linkedin/actions/get-post-analytics.action.ts +190 -189
  191. package/src/providers/linkedin/actions/schedule-post.action.ts +191 -189
  192. package/src/providers/linkedin/actions/search-posts.action.ts +275 -283
  193. package/src/providers/linkedin/linkedin-base.action.ts +407 -421
  194. package/src/providers/tiktok/tiktok-base.action.ts +305 -320
  195. package/src/providers/twitter/actions/create-thread.action.ts +203 -207
  196. package/src/providers/twitter/actions/create-tweet.action.ts +187 -188
  197. package/src/providers/twitter/actions/delete-tweet.action.ts +128 -129
  198. package/src/providers/twitter/actions/get-analytics.action.ts +402 -411
  199. package/src/providers/twitter/actions/get-mentions.action.ts +218 -219
  200. package/src/providers/twitter/actions/get-timeline.action.ts +232 -233
  201. package/src/providers/twitter/actions/schedule-tweet.action.ts +221 -222
  202. package/src/providers/twitter/actions/search-tweets.action.ts +540 -543
  203. package/src/providers/twitter/twitter-base.action.ts +541 -560
  204. package/src/providers/youtube/youtube-base.action.ts +320 -333
@@ -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/core';
4
+ import { LogError } from '@memberjunction/global';
5
5
  import { MediaFile } from '../../../base/base-social.action';
6
6
  import { BaseAction } from '@memberjunction/actions';
7
7
 
@@ -11,320 +11,300 @@ import { BaseAction } from '@memberjunction/actions';
11
11
  */
12
12
  @RegisterClass(BaseAction, 'Instagram - Create Post')
13
13
  export class InstagramCreatePostAction extends InstagramBaseAction {
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
- }
140
-
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()
14
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
15
+ try {
16
+ const companyIntegrationId = this.getParamValue(params.Params, 'CompanyIntegrationID');
17
+ const content = this.getParamValue(params.Params, 'Content');
18
+ const mediaFiles = this.getParamValue(params.Params, 'MediaFiles') as MediaFile[];
19
+ const postType = this.getParamValue(params.Params, 'PostType') || 'FEED';
20
+ const locationId = this.getParamValue(params.Params, 'LocationID');
21
+ const taggedUsers = this.getParamValue(params.Params, 'TaggedUsers') as string[];
22
+ const scheduledTime = this.getParamValue(params.Params, 'ScheduledTime');
23
+
24
+ // Initialize OAuth
25
+ if (!(await this.initializeOAuth(companyIntegrationId))) {
26
+ return {
27
+ Success: false,
28
+ Message: 'Failed to initialize Instagram authentication',
29
+ ResultCode: 'AUTH_FAILED',
163
30
  };
31
+ }
32
+
33
+ // Validate inputs
34
+ if (!mediaFiles || mediaFiles.length === 0) {
35
+ return {
36
+ Success: false,
37
+ Message: 'At least one media file is required for Instagram posts',
38
+ ResultCode: 'MISSING_MEDIA',
39
+ };
40
+ }
41
+
42
+ // Instagram has specific requirements for different post types
43
+ if (postType === 'CAROUSEL' && mediaFiles.length < 2) {
44
+ return {
45
+ Success: false,
46
+ Message: 'Carousel posts require at least 2 media files',
47
+ ResultCode: 'INVALID_CAROUSEL',
48
+ };
49
+ }
164
50
 
165
- if (locationId) {
166
- publishParams.location_id = locationId;
51
+ if (postType === 'REELS' && (!mediaFiles[0].mimeType.startsWith('video/') || mediaFiles.length > 1)) {
52
+ return {
53
+ Success: false,
54
+ Message: 'Reels require exactly one video file',
55
+ ResultCode: 'INVALID_REEL',
56
+ };
57
+ }
58
+
59
+ // Handle scheduled posts differently
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
+ };
167
68
  }
168
69
 
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
- }
70
+ // Instagram requires Facebook Creator Studio for scheduling
71
+ return {
72
+ Success: false,
73
+ Message: 'Instagram post scheduling requires Facebook Creator Studio integration',
74
+ ResultCode: 'SCHEDULING_NOT_SUPPORTED',
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
+ }
176
122
 
177
- // Publish the post
178
- const response = await this.makeInstagramRequest<{ id: string }>(
179
- `${this.instagramBusinessAccountId}/media_publish`,
180
- 'POST',
181
- publishParams
182
- );
123
+ if (error.code === 'INVALID_MEDIA') {
124
+ return {
125
+ Success: false,
126
+ Message: error.message,
127
+ ResultCode: 'INVALID_MEDIA',
128
+ };
129
+ }
183
130
 
184
- return response.id;
131
+ return {
132
+ Success: false,
133
+ Message: `Failed to create Instagram post: ${error.message}`,
134
+ ResultCode: 'ERROR',
135
+ };
185
136
  }
137
+ }
186
138
 
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
- }
139
+ /**
140
+ * Create a standard feed post (single image or video)
141
+ */
142
+ private async createFeedPost(mediaFile: MediaFile, caption: string, locationId?: string, taggedUsers?: string[]): Promise<string> {
143
+ // Add metadata to media file
144
+ (mediaFile as any).metadata = { caption };
204
145
 
205
- // Wait for all media to be processed
206
- await Promise.all(containerIds.map(id => this.waitForMediaContainer(id)));
146
+ // Upload media and get container ID
147
+ const containerId = await this.uploadSingleMedia(mediaFile);
207
148
 
208
- // Create carousel container
209
- const carouselParams: any = {
210
- media_type: 'CAROUSEL',
211
- children: containerIds,
212
- caption: caption,
213
- access_token: this.getAccessToken()
214
- };
149
+ // Wait for media to be processed
150
+ await this.waitForMediaContainer(containerId);
215
151
 
216
- if (locationId) {
217
- carouselParams.location_id = locationId;
218
- }
152
+ // Add additional parameters if provided
153
+ const publishParams: any = {
154
+ creation_id: containerId,
155
+ access_token: this.getAccessToken(),
156
+ };
219
157
 
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;
158
+ if (locationId) {
159
+ publishParams.location_id = locationId;
240
160
  }
241
161
 
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
- };
259
-
260
- // Upload video
261
- const containerId = await this.uploadSingleMedia(videoFile);
262
-
263
- // Wait for video to be processed (videos take longer)
264
- await this.waitForMediaContainer(containerId, 300000); // 5 minute timeout for videos
162
+ if (taggedUsers && taggedUsers.length > 0) {
163
+ publishParams.user_tags = taggedUsers.map((userId) => ({
164
+ username: userId,
165
+ x: 0.5, // Center of image
166
+ y: 0.5,
167
+ }));
168
+ }
265
169
 
266
- // Publish the reel
267
- const publishParams: any = {
268
- creation_id: containerId,
269
- access_token: this.getAccessToken()
270
- };
170
+ // Publish the post
171
+ const response = await this.makeInstagramRequest<{ id: string }>(
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
+ }
271
193
 
272
- if (locationId) {
273
- publishParams.location_id = locationId;
274
- }
194
+ // Wait for all media to be processed
195
+ await Promise.all(containerIds.map((id) => this.waitForMediaContainer(id)));
275
196
 
276
- const response = await this.makeInstagramRequest<{ id: string }>(
277
- `${this.instagramBusinessAccountId}/media_publish`,
278
- 'POST',
279
- publishParams
280
- );
197
+ // Create carousel container
198
+ const carouselParams: any = {
199
+ media_type: 'CAROUSEL',
200
+ children: containerIds,
201
+ caption: caption,
202
+ access_token: this.getAccessToken(),
203
+ };
281
204
 
282
- return response.id;
205
+ if (locationId) {
206
+ carouselParams.location_id = locationId;
283
207
  }
284
208
 
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
- ];
209
+ const carouselResponse = await this.makeInstagramRequest<{ id: string }>(
210
+ `${this.instagramBusinessAccountId}/media`,
211
+ 'POST',
212
+ carouselParams
213
+ );
214
+
215
+ // Wait for carousel container to be ready
216
+ await this.waitForMediaContainer(carouselResponse.id);
217
+
218
+ // Publish the carousel
219
+ const publishResponse = await this.makeInstagramRequest<{ id: string }>(`${this.instagramBusinessAccountId}/media_publish`, 'POST', {
220
+ creation_id: carouselResponse.id,
221
+ access_token: this.getAccessToken(),
222
+ });
223
+
224
+ return publishResponse.id;
225
+ }
226
+
227
+ /**
228
+ * Create a Reel post
229
+ */
230
+ private async createReelPost(videoFile: MediaFile, caption: string, locationId?: string, taggedUsers?: string[]): Promise<string> {
231
+ // Validate video duration (Reels must be 90 seconds or less)
232
+ // In production, you'd check the actual video duration
233
+
234
+ // Add metadata
235
+ (videoFile as any).metadata = {
236
+ caption,
237
+ media_type: 'REELS',
238
+ };
239
+
240
+ // Upload video
241
+ const containerId = await this.uploadSingleMedia(videoFile);
242
+
243
+ // Wait for video to be processed (videos take longer)
244
+ await this.waitForMediaContainer(containerId, 300000); // 5 minute timeout for videos
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;
322
254
  }
323
255
 
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
- }
256
+ const response = await this.makeInstagramRequest<{ id: string }>(
257
+ `${this.instagramBusinessAccountId}/media_publish`,
258
+ 'POST',
259
+ publishParams
260
+ );
261
+
262
+ return response.id;
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
+ }