@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.
Files changed (204) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +13 -0
  3. package/dist/base/base-social.action.d.ts.map +1 -1
  4. package/dist/base/base-social.action.js +24 -18
  5. package/dist/base/base-social.action.js.map +1 -1
  6. package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
  7. package/dist/providers/buffer/buffer-base.action.js +34 -35
  8. package/dist/providers/buffer/buffer-base.action.js.map +1 -1
  9. package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
  10. package/dist/providers/facebook/actions/boost-post.action.js +33 -33
  11. package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
  12. package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
  13. package/dist/providers/facebook/actions/create-album.action.js +36 -34
  14. package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
  15. package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
  16. package/dist/providers/facebook/actions/create-post.action.js +20 -20
  17. package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
  18. package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
  19. package/dist/providers/facebook/actions/get-page-insights.action.js +27 -25
  20. package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
  21. package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
  22. package/dist/providers/facebook/actions/get-page-posts.action.js +23 -19
  23. package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
  24. package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
  25. package/dist/providers/facebook/actions/get-post-insights.action.js +32 -28
  26. package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
  27. package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
  28. package/dist/providers/facebook/actions/respond-to-comments.action.js +44 -42
  29. package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
  30. package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
  31. package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
  32. package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
  33. package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
  34. package/dist/providers/facebook/actions/search-posts.action.js +39 -37
  35. package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
  36. package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
  37. package/dist/providers/facebook/facebook-base.action.js +59 -44
  38. package/dist/providers/facebook/facebook-base.action.js.map +1 -1
  39. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
  40. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +31 -33
  41. package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
  42. package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
  43. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +32 -28
  44. package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
  45. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
  46. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
  47. package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
  48. package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
  49. package/dist/providers/hootsuite/actions/get-analytics.action.js +26 -24
  50. package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
  51. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
  52. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
  53. package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
  54. package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
  55. package/dist/providers/hootsuite/actions/get-social-profiles.action.js +34 -32
  56. package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
  57. package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
  58. package/dist/providers/hootsuite/actions/search-posts.action.js +52 -43
  59. package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
  60. package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
  61. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +28 -30
  62. package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
  63. package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
  64. package/dist/providers/hootsuite/hootsuite-base.action.js +20 -18
  65. package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
  66. package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
  67. package/dist/providers/instagram/actions/create-post.action.js +26 -27
  68. package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
  69. package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
  70. package/dist/providers/instagram/actions/create-story.action.js +35 -35
  71. package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
  72. package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
  73. package/dist/providers/instagram/actions/get-account-insights.action.js +59 -38
  74. package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
  75. package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
  76. package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
  77. package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
  78. package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
  79. package/dist/providers/instagram/actions/get-comments.action.js +36 -36
  80. package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
  81. package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
  82. package/dist/providers/instagram/actions/get-post-insights.action.js +25 -23
  83. package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
  84. package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
  85. package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
  86. package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
  87. package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
  88. package/dist/providers/instagram/actions/search-posts.action.js +60 -56
  89. package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
  90. package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
  91. package/dist/providers/instagram/instagram-base.action.js +27 -25
  92. package/dist/providers/instagram/instagram-base.action.js.map +1 -1
  93. package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
  94. package/dist/providers/linkedin/actions/create-article.action.js +45 -55
  95. package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
  96. package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
  97. package/dist/providers/linkedin/actions/create-post.action.js +29 -31
  98. package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
  99. package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
  100. package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
  101. package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
  102. package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
  103. package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
  104. package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
  105. package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
  106. package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
  107. package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
  108. package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
  109. package/dist/providers/linkedin/actions/get-post-analytics.action.js +23 -25
  110. package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
  111. package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
  112. package/dist/providers/linkedin/actions/schedule-post.action.js +30 -32
  113. package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
  114. package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
  115. package/dist/providers/linkedin/actions/search-posts.action.js +30 -28
  116. package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
  117. package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
  118. package/dist/providers/linkedin/linkedin-base.action.js +38 -33
  119. package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
  120. package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
  121. package/dist/providers/tiktok/tiktok-base.action.js +26 -25
  122. package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
  123. package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
  124. package/dist/providers/twitter/actions/create-thread.action.js +29 -25
  125. package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
  126. package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
  127. package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
  128. package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
  129. package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
  130. package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
  131. package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
  132. package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
  133. package/dist/providers/twitter/actions/get-analytics.action.js +47 -40
  134. package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
  135. package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
  136. package/dist/providers/twitter/actions/get-mentions.action.js +31 -30
  137. package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
  138. package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
  139. package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
  140. package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
  141. package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
  142. package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
  143. package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
  144. package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
  145. package/dist/providers/twitter/actions/search-tweets.action.js +58 -56
  146. package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
  147. package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
  148. package/dist/providers/twitter/twitter-base.action.js +68 -58
  149. package/dist/providers/twitter/twitter-base.action.js.map +1 -1
  150. package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
  151. package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
  152. package/dist/providers/youtube/youtube-base.action.js +25 -22
  153. package/dist/providers/youtube/youtube-base.action.js.map +1 -1
  154. package/package.json +6 -5
  155. package/src/base/base-social.action.ts +224 -217
  156. package/src/providers/buffer/buffer-base.action.ts +441 -435
  157. package/src/providers/facebook/actions/boost-post.action.ts +386 -350
  158. package/src/providers/facebook/actions/create-album.action.ts +307 -291
  159. package/src/providers/facebook/actions/create-post.action.ts +227 -224
  160. package/src/providers/facebook/actions/get-page-insights.action.ts +403 -383
  161. package/src/providers/facebook/actions/get-page-posts.action.ts +225 -214
  162. package/src/providers/facebook/actions/get-post-insights.action.ts +316 -300
  163. package/src/providers/facebook/actions/respond-to-comments.action.ts +336 -319
  164. package/src/providers/facebook/actions/schedule-post.action.ts +292 -289
  165. package/src/providers/facebook/actions/search-posts.action.ts +413 -399
  166. package/src/providers/facebook/facebook-base.action.ts +670 -653
  167. package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
  168. package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +189 -184
  169. package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +161 -160
  170. package/src/providers/hootsuite/actions/get-analytics.action.ts +254 -249
  171. package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +207 -206
  172. package/src/providers/hootsuite/actions/get-social-profiles.action.ts +205 -206
  173. package/src/providers/hootsuite/actions/search-posts.action.ts +369 -351
  174. package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +209 -211
  175. package/src/providers/hootsuite/hootsuite-base.action.ts +307 -301
  176. package/src/providers/instagram/actions/create-post.action.ts +296 -276
  177. package/src/providers/instagram/actions/create-story.action.ts +394 -378
  178. package/src/providers/instagram/actions/get-account-insights.action.ts +420 -384
  179. package/src/providers/instagram/actions/get-business-posts.action.ts +242 -233
  180. package/src/providers/instagram/actions/get-comments.action.ts +377 -365
  181. package/src/providers/instagram/actions/get-post-insights.action.ts +273 -265
  182. package/src/providers/instagram/actions/schedule-post.action.ts +235 -233
  183. package/src/providers/instagram/actions/search-posts.action.ts +538 -512
  184. package/src/providers/instagram/instagram-base.action.ts +393 -368
  185. package/src/providers/linkedin/actions/create-article.action.ts +266 -275
  186. package/src/providers/linkedin/actions/create-post.action.ts +177 -179
  187. package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
  188. package/src/providers/linkedin/actions/get-organization-posts.action.ts +147 -146
  189. package/src/providers/linkedin/actions/get-personal-posts.action.ts +139 -138
  190. package/src/providers/linkedin/actions/get-post-analytics.action.ts +189 -190
  191. package/src/providers/linkedin/actions/schedule-post.action.ts +189 -191
  192. package/src/providers/linkedin/actions/search-posts.action.ts +283 -275
  193. package/src/providers/linkedin/linkedin-base.action.ts +421 -407
  194. package/src/providers/tiktok/tiktok-base.action.ts +320 -305
  195. package/src/providers/twitter/actions/create-thread.action.ts +207 -203
  196. package/src/providers/twitter/actions/create-tweet.action.ts +188 -187
  197. package/src/providers/twitter/actions/delete-tweet.action.ts +129 -128
  198. package/src/providers/twitter/actions/get-analytics.action.ts +411 -402
  199. package/src/providers/twitter/actions/get-mentions.action.ts +219 -218
  200. package/src/providers/twitter/actions/get-timeline.action.ts +233 -232
  201. package/src/providers/twitter/actions/schedule-tweet.action.ts +222 -221
  202. package/src/providers/twitter/actions/search-tweets.action.ts +543 -540
  203. package/src/providers/twitter/twitter-base.action.ts +560 -541
  204. package/src/providers/youtube/youtube-base.action.ts +333 -320
@@ -1,7 +1,7 @@
1
1
  import { RegisterClass } from '@memberjunction/global';
2
2
  import { TwitterBaseAction, CreateTweetData } from '../twitter-base.action';
3
3
  import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
4
- import { LogStatus, LogError } from '@memberjunction/global';
4
+ import { LogStatus, LogError } from '@memberjunction/core';
5
5
  import { MediaFile } from '../../../base/base-social.action';
6
6
  import { BaseAction } from '@memberjunction/actions';
7
7
 
@@ -12,248 +12,249 @@ import { BaseAction } from '@memberjunction/actions';
12
12
  */
13
13
  @RegisterClass(BaseAction, 'TwitterScheduleTweetAction')
14
14
  export class TwitterScheduleTweetAction extends TwitterBaseAction {
15
- /**
16
- * Schedule a tweet for future posting
17
- */
18
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
19
- const { Params, ContextUser } = params;
15
+ /**
16
+ * Schedule a tweet for future posting
17
+ */
18
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
19
+ const { Params, ContextUser } = params;
20
+
21
+ try {
22
+ // Initialize OAuth
23
+ const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
24
+ if (!await this.initializeOAuth(companyIntegrationId)) {
25
+ throw new Error('Failed to initialize OAuth connection');
26
+ }
20
27
 
21
- try {
22
- // Initialize OAuth
23
- const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
24
- if (!(await this.initializeOAuth(companyIntegrationId))) {
25
- throw new Error('Failed to initialize OAuth connection');
26
- }
28
+ // Extract parameters
29
+ const content = this.getParamValue(Params, 'Content');
30
+ const scheduledTime = this.getParamValue(Params, 'ScheduledTime');
31
+ const mediaFiles = this.getParamValue(Params, 'MediaFiles');
32
+ const replyToTweetId = this.getParamValue(Params, 'ReplyToTweetID');
33
+ const quoteTweetId = this.getParamValue(Params, 'QuoteTweetID');
34
+ const pollOptions = this.getParamValue(Params, 'PollOptions');
35
+ const pollDurationMinutes = this.getParamValue(Params, 'PollDurationMinutes') || 1440; // Default 24 hours
27
36
 
28
- // Extract parameters
29
- const content = this.getParamValue(Params, 'Content');
30
- const scheduledTime = this.getParamValue(Params, 'ScheduledTime');
31
- const mediaFiles = this.getParamValue(Params, 'MediaFiles');
32
- const replyToTweetId = this.getParamValue(Params, 'ReplyToTweetID');
33
- const quoteTweetId = this.getParamValue(Params, 'QuoteTweetID');
34
- const pollOptions = this.getParamValue(Params, 'PollOptions');
35
- const pollDurationMinutes = this.getParamValue(Params, 'PollDurationMinutes') || 1440; // Default 24 hours
37
+ // Validate required parameters
38
+ if (!content) {
39
+ throw new Error('Content is required');
40
+ }
36
41
 
37
- // Validate required parameters
38
- if (!content) {
39
- throw new Error('Content is required');
40
- }
42
+ if (!scheduledTime) {
43
+ throw new Error('ScheduledTime is required');
44
+ }
41
45
 
42
- if (!scheduledTime) {
43
- throw new Error('ScheduledTime is required');
44
- }
46
+ // Validate scheduled time is in the future
47
+ const scheduleDate = new Date(scheduledTime);
48
+ const now = new Date();
49
+
50
+ if (scheduleDate <= now) {
51
+ throw new Error('ScheduledTime must be in the future');
52
+ }
45
53
 
46
- // Validate scheduled time is in the future
47
- const scheduleDate = new Date(scheduledTime);
48
- const now = new Date();
54
+ // Validate scheduled time is not too far in the future (e.g., 1 year)
55
+ const maxFutureDate = new Date();
56
+ maxFutureDate.setFullYear(maxFutureDate.getFullYear() + 1);
57
+
58
+ if (scheduleDate > maxFutureDate) {
59
+ throw new Error('ScheduledTime cannot be more than 1 year in the future');
60
+ }
49
61
 
50
- if (scheduleDate <= now) {
51
- throw new Error('ScheduledTime must be in the future');
52
- }
62
+ // Validate content length
63
+ if (content.length > 280) {
64
+ throw new Error(`Content exceeds Twitter's 280 character limit (current: ${content.length} characters)`);
65
+ }
53
66
 
54
- // Validate scheduled time is not too far in the future (e.g., 1 year)
55
- const maxFutureDate = new Date();
56
- maxFutureDate.setFullYear(maxFutureDate.getFullYear() + 1);
67
+ // Build tweet data structure
68
+ const tweetData: CreateTweetData = {
69
+ text: content
70
+ };
57
71
 
58
- if (scheduleDate > maxFutureDate) {
59
- throw new Error('ScheduledTime cannot be more than 1 year in the future');
60
- }
72
+ // Add reply if specified
73
+ if (replyToTweetId) {
74
+ tweetData.reply = {
75
+ in_reply_to_tweet_id: replyToTweetId
76
+ };
77
+ }
61
78
 
62
- // Validate content length
63
- if (content.length > 280) {
64
- throw new Error(`Content exceeds Twitter's 280 character limit (current: ${content.length} characters)`);
65
- }
79
+ // Add quote tweet if specified
80
+ if (quoteTweetId) {
81
+ tweetData.quote_tweet_id = quoteTweetId;
82
+ }
66
83
 
67
- // Build tweet data structure
68
- const tweetData: CreateTweetData = {
69
- text: content,
70
- };
84
+ // Add poll if specified
85
+ if (pollOptions && Array.isArray(pollOptions) && pollOptions.length >= 2) {
86
+ if (pollOptions.length > 4) {
87
+ throw new Error('Twitter polls support a maximum of 4 options');
88
+ }
89
+
90
+ // Validate poll option lengths
91
+ for (const option of pollOptions) {
92
+ if (option.length > 25) {
93
+ throw new Error(`Poll option "${option}" exceeds 25 character limit`);
94
+ }
95
+ }
71
96
 
72
- // Add reply if specified
73
- if (replyToTweetId) {
74
- tweetData.reply = {
75
- in_reply_to_tweet_id: replyToTweetId,
76
- };
77
- }
97
+ tweetData.poll = {
98
+ options: pollOptions,
99
+ duration_minutes: Math.min(Math.max(pollDurationMinutes, 5), 10080)
100
+ };
101
+ }
78
102
 
79
- // Add quote tweet if specified
80
- if (quoteTweetId) {
81
- tweetData.quote_tweet_id = quoteTweetId;
82
- }
103
+ // Handle media files
104
+ let uploadedMediaIds: string[] = [];
105
+ if (mediaFiles && Array.isArray(mediaFiles) && mediaFiles.length > 0) {
106
+ if (mediaFiles.length > 4) {
107
+ throw new Error('Twitter supports a maximum of 4 media items per tweet');
108
+ }
83
109
 
84
- // Add poll if specified
85
- if (pollOptions && Array.isArray(pollOptions) && pollOptions.length >= 2) {
86
- if (pollOptions.length > 4) {
87
- throw new Error('Twitter polls support a maximum of 4 options');
88
- }
89
-
90
- // Validate poll option lengths
91
- for (const option of pollOptions) {
92
- if (option.length > 25) {
93
- throw new Error(`Poll option "${option}" exceeds 25 character limit`);
94
- }
95
- }
96
-
97
- tweetData.poll = {
98
- options: pollOptions,
99
- duration_minutes: Math.min(Math.max(pollDurationMinutes, 5), 10080),
100
- };
101
- }
102
-
103
- // Handle media files
104
- let uploadedMediaIds: string[] = [];
105
- if (mediaFiles && Array.isArray(mediaFiles) && mediaFiles.length > 0) {
106
- if (mediaFiles.length > 4) {
107
- throw new Error('Twitter supports a maximum of 4 media items per tweet');
108
- }
109
-
110
- // For scheduling, we'll upload the media now and store the IDs
111
- // Note: Twitter media IDs expire after 24 hours if not used
112
- const hoursUntilScheduled = (scheduleDate.getTime() - now.getTime()) / (1000 * 60 * 60);
110
+ // For scheduling, we'll upload the media now and store the IDs
111
+ // Note: Twitter media IDs expire after 24 hours if not used
112
+ const hoursUntilScheduled = (scheduleDate.getTime() - now.getTime()) / (1000 * 60 * 60);
113
+
114
+ if (hoursUntilScheduled <= 24) {
115
+ // Upload now if scheduling within 24 hours
116
+ LogStatus(`Uploading ${mediaFiles.length} media files...`);
117
+ uploadedMediaIds = await this.uploadMedia(mediaFiles as MediaFile[]);
118
+ tweetData.media = {
119
+ media_ids: uploadedMediaIds
120
+ };
121
+ } else {
122
+ // For tweets scheduled beyond 24 hours, we'll need to store media
123
+ // data and upload closer to the scheduled time
124
+ LogStatus('Media will be uploaded closer to scheduled time due to Twitter\'s 24-hour media expiration');
125
+ }
126
+ }
113
127
 
114
- if (hoursUntilScheduled <= 24) {
115
- // Upload now if scheduling within 24 hours
116
- LogStatus(`Uploading ${mediaFiles.length} media files...`);
117
- uploadedMediaIds = await this.uploadMedia(mediaFiles as MediaFile[]);
118
- tweetData.media = {
119
- media_ids: uploadedMediaIds,
120
- };
121
- } else {
122
- // For tweets scheduled beyond 24 hours, we'll need to store media
123
- // data and upload closer to the scheduled time
124
- LogStatus("Media will be uploaded closer to scheduled time due to Twitter's 24-hour media expiration");
125
- }
126
- }
127
-
128
- // Create scheduled tweet record
129
- // In a real implementation, this would save to a database or queue service
130
- const scheduledTweet = {
131
- id: this.generateScheduledTweetId(),
132
- scheduledFor: scheduleDate.toISOString(),
133
- tweetData: tweetData,
134
- mediaFiles: mediaFiles, // Store for later upload if needed
135
- companyIntegrationId: companyIntegrationId,
136
- createdAt: new Date().toISOString(),
137
- status: 'scheduled',
138
- };
128
+ // Create scheduled tweet record
129
+ // In a real implementation, this would save to a database or queue service
130
+ const scheduledTweet = {
131
+ id: this.generateScheduledTweetId(),
132
+ scheduledFor: scheduleDate.toISOString(),
133
+ tweetData: tweetData,
134
+ mediaFiles: mediaFiles, // Store for later upload if needed
135
+ companyIntegrationId: companyIntegrationId,
136
+ createdAt: new Date().toISOString(),
137
+ status: 'scheduled'
138
+ };
139
139
 
140
- // Simulate saving to a scheduling service
141
- LogStatus(`Tweet scheduled for ${scheduleDate.toLocaleString()}`);
140
+ // Simulate saving to a scheduling service
141
+ LogStatus(`Tweet scheduled for ${scheduleDate.toLocaleString()}`);
142
142
 
143
- // Get user info for context
144
- const user = await this.getCurrentUser();
143
+ // Get user info for context
144
+ const user = await this.getCurrentUser();
145
145
 
146
- // Update output parameters
147
- const outputParams = [...Params];
148
- const scheduledIdParam = outputParams.find((p) => p.Name === 'ScheduledTweetID');
149
- if (scheduledIdParam) scheduledIdParam.Value = scheduledTweet.id;
150
- const scheduledDataParam = outputParams.find((p) => p.Name === 'ScheduledTweetData');
151
- if (scheduledDataParam) scheduledDataParam.Value = scheduledTweet;
152
- const estimatedUrlParam = outputParams.find((p) => p.Name === 'EstimatedURL');
153
- if (estimatedUrlParam) estimatedUrlParam.Value = `https://twitter.com/${user.username}/status/[pending]`;
146
+ // Update output parameters
147
+ const outputParams = [...Params];
148
+ const scheduledIdParam = outputParams.find(p => p.Name === 'ScheduledTweetID');
149
+ if (scheduledIdParam) scheduledIdParam.Value = scheduledTweet.id;
150
+ const scheduledDataParam = outputParams.find(p => p.Name === 'ScheduledTweetData');
151
+ if (scheduledDataParam) scheduledDataParam.Value = scheduledTweet;
152
+ const estimatedUrlParam = outputParams.find(p => p.Name === 'EstimatedURL');
153
+ if (estimatedUrlParam) estimatedUrlParam.Value = `https://twitter.com/${user.username}/status/[pending]`;
154
154
 
155
- return {
156
- Success: true,
157
- ResultCode: 'SUCCESS',
158
- Message: `Successfully scheduled tweet for ${scheduleDate.toLocaleString()}`,
159
- Params: outputParams,
160
- };
161
- } catch (error) {
162
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
155
+ return {
156
+ Success: true,
157
+ ResultCode: 'SUCCESS',
158
+ Message: `Successfully scheduled tweet for ${scheduleDate.toLocaleString()}`,
159
+ Params: outputParams
160
+ };
163
161
 
164
- return {
165
- Success: false,
166
- ResultCode: this.getErrorCode(error),
167
- Message: `Failed to schedule tweet: ${errorMessage}`,
168
- Params,
169
- };
162
+ } catch (error) {
163
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
164
+
165
+ return {
166
+ Success: false,
167
+ ResultCode: this.getErrorCode(error),
168
+ Message: `Failed to schedule tweet: ${errorMessage}`,
169
+ Params
170
+ };
171
+ }
170
172
  }
171
- }
172
173
 
173
- /**
174
- * Generate a unique ID for scheduled tweet
175
- */
176
- private generateScheduledTweetId(): string {
177
- return `scheduled_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
178
- }
174
+ /**
175
+ * Generate a unique ID for scheduled tweet
176
+ */
177
+ private generateScheduledTweetId(): string {
178
+ return `scheduled_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
179
+ }
179
180
 
180
- /**
181
- * Get error code based on error type
182
- */
183
- private getErrorCode(error: any): string {
184
- if (error instanceof Error) {
185
- if (error.message.includes('Rate Limit')) return 'RATE_LIMIT';
186
- if (error.message.includes('Unauthorized')) return 'INVALID_TOKEN';
187
- if (error.message.includes('character limit')) return 'CONTENT_TOO_LONG';
188
- if (error.message.includes('media')) return 'INVALID_MEDIA';
189
- if (error.message.includes('future')) return 'INVALID_SCHEDULE_TIME';
181
+ /**
182
+ * Get error code based on error type
183
+ */
184
+ private getErrorCode(error: any): string {
185
+ if (error instanceof Error) {
186
+ if (error.message.includes('Rate Limit')) return 'RATE_LIMIT';
187
+ if (error.message.includes('Unauthorized')) return 'INVALID_TOKEN';
188
+ if (error.message.includes('character limit')) return 'CONTENT_TOO_LONG';
189
+ if (error.message.includes('media')) return 'INVALID_MEDIA';
190
+ if (error.message.includes('future')) return 'INVALID_SCHEDULE_TIME';
191
+ }
192
+ return 'ERROR';
190
193
  }
191
- return 'ERROR';
192
- }
193
194
 
194
- /**
195
- * Define the parameters this action expects
196
- */
197
- public get Params(): ActionParam[] {
198
- return [
199
- ...this.commonSocialParams,
200
- {
201
- Name: 'Content',
202
- Type: 'Input',
203
- Value: null,
204
- },
205
- {
206
- Name: 'ScheduledTime',
207
- Type: 'Input',
208
- Value: null,
209
- },
210
- {
211
- Name: 'MediaFiles',
212
- Type: 'Input',
213
- Value: null,
214
- },
215
- {
216
- Name: 'ReplyToTweetID',
217
- Type: 'Input',
218
- Value: null,
219
- },
220
- {
221
- Name: 'QuoteTweetID',
222
- Type: 'Input',
223
- Value: null,
224
- },
225
- {
226
- Name: 'PollOptions',
227
- Type: 'Input',
228
- Value: null,
229
- },
230
- {
231
- Name: 'PollDurationMinutes',
232
- Type: 'Input',
233
- Value: 1440, // Default 24 hours
234
- },
235
- {
236
- Name: 'ScheduledTweetID',
237
- Type: 'Output',
238
- Value: null,
239
- },
240
- {
241
- Name: 'ScheduledTweetData',
242
- Type: 'Output',
243
- Value: null,
244
- },
245
- {
246
- Name: 'EstimatedURL',
247
- Type: 'Output',
248
- Value: null,
249
- },
250
- ];
251
- }
195
+ /**
196
+ * Define the parameters this action expects
197
+ */
198
+ public get Params(): ActionParam[] {
199
+ return [
200
+ ...this.commonSocialParams,
201
+ {
202
+ Name: 'Content',
203
+ Type: 'Input',
204
+ Value: null
205
+ },
206
+ {
207
+ Name: 'ScheduledTime',
208
+ Type: 'Input',
209
+ Value: null
210
+ },
211
+ {
212
+ Name: 'MediaFiles',
213
+ Type: 'Input',
214
+ Value: null
215
+ },
216
+ {
217
+ Name: 'ReplyToTweetID',
218
+ Type: 'Input',
219
+ Value: null
220
+ },
221
+ {
222
+ Name: 'QuoteTweetID',
223
+ Type: 'Input',
224
+ Value: null
225
+ },
226
+ {
227
+ Name: 'PollOptions',
228
+ Type: 'Input',
229
+ Value: null
230
+ },
231
+ {
232
+ Name: 'PollDurationMinutes',
233
+ Type: 'Input',
234
+ Value: 1440 // Default 24 hours
235
+ },
236
+ {
237
+ Name: 'ScheduledTweetID',
238
+ Type: 'Output',
239
+ Value: null
240
+ },
241
+ {
242
+ Name: 'ScheduledTweetData',
243
+ Type: 'Output',
244
+ Value: null
245
+ },
246
+ {
247
+ Name: 'EstimatedURL',
248
+ Type: 'Output',
249
+ Value: null
250
+ }
251
+ ];
252
+ }
252
253
 
253
- /**
254
- * Get action description
255
- */
256
- public get Description(): string {
257
- return 'Schedules a tweet for future posting on Twitter/X with optional media attachments, polls, replies, or quote tweets';
258
- }
259
- }
254
+ /**
255
+ * Get action description
256
+ */
257
+ public get Description(): string {
258
+ return 'Schedules a tweet for future posting on Twitter/X with optional media attachments, polls, replies, or quote tweets';
259
+ }
260
+ }