@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 { TwitterBaseAction, CreateTweetData } from '../twitter-base.action';
3
3
  import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
4
- import { LogStatus, LogError } from '@memberjunction/core';
4
+ import { LogStatus, LogError } from '@memberjunction/global';
5
5
  import { MediaFile } from '../../../base/base-social.action';
6
6
  import { BaseAction } from '@memberjunction/actions';
7
7
 
@@ -12,249 +12,248 @@ 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;
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
- }
15
+ /**
16
+ * Schedule a tweet for future posting
17
+ */
18
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
19
+ const { Params, ContextUser } = params;
27
20
 
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
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
+ }
36
27
 
37
- // Validate required parameters
38
- if (!content) {
39
- throw new Error('Content is required');
40
- }
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
41
36
 
42
- if (!scheduledTime) {
43
- throw new Error('ScheduledTime is required');
44
- }
37
+ // Validate required parameters
38
+ if (!content) {
39
+ throw new Error('Content is required');
40
+ }
45
41
 
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
- }
42
+ if (!scheduledTime) {
43
+ throw new Error('ScheduledTime is required');
44
+ }
53
45
 
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
- }
46
+ // Validate scheduled time is in the future
47
+ const scheduleDate = new Date(scheduledTime);
48
+ const now = new Date();
61
49
 
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
- }
50
+ if (scheduleDate <= now) {
51
+ throw new Error('ScheduledTime must be in the future');
52
+ }
66
53
 
67
- // Build tweet data structure
68
- const tweetData: CreateTweetData = {
69
- text: content
70
- };
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);
71
57
 
72
- // Add reply if specified
73
- if (replyToTweetId) {
74
- tweetData.reply = {
75
- in_reply_to_tweet_id: replyToTweetId
76
- };
77
- }
58
+ if (scheduleDate > maxFutureDate) {
59
+ throw new Error('ScheduledTime cannot be more than 1 year in the future');
60
+ }
78
61
 
79
- // Add quote tweet if specified
80
- if (quoteTweetId) {
81
- tweetData.quote_tweet_id = quoteTweetId;
82
- }
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
+ }
83
66
 
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
- }
67
+ // Build tweet data structure
68
+ const tweetData: CreateTweetData = {
69
+ text: content,
70
+ };
96
71
 
97
- tweetData.poll = {
98
- options: pollOptions,
99
- duration_minutes: Math.min(Math.max(pollDurationMinutes, 5), 10080)
100
- };
101
- }
72
+ // Add reply if specified
73
+ if (replyToTweetId) {
74
+ tweetData.reply = {
75
+ in_reply_to_tweet_id: replyToTweetId,
76
+ };
77
+ }
102
78
 
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
- }
79
+ // Add quote tweet if specified
80
+ if (quoteTweetId) {
81
+ tweetData.quote_tweet_id = quoteTweetId;
82
+ }
109
83
 
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
- }
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
- };
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
+ }
139
89
 
140
- // Simulate saving to a scheduling service
141
- LogStatus(`Tweet scheduled for ${scheduleDate.toLocaleString()}`);
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
+ }
142
96
 
143
- // Get user info for context
144
- const user = await this.getCurrentUser();
97
+ tweetData.poll = {
98
+ options: pollOptions,
99
+ duration_minutes: Math.min(Math.max(pollDurationMinutes, 5), 10080),
100
+ };
101
+ }
145
102
 
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]`;
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
+ }
154
109
 
155
- return {
156
- Success: true,
157
- ResultCode: 'SUCCESS',
158
- Message: `Successfully scheduled tweet for ${scheduleDate.toLocaleString()}`,
159
- Params: outputParams
160
- };
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);
161
113
 
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
- };
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");
171
125
  }
172
- }
126
+ }
173
127
 
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
- }
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
+ };
180
139
 
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';
193
- }
140
+ // Simulate saving to a scheduling service
141
+ LogStatus(`Tweet scheduled for ${scheduleDate.toLocaleString()}`);
142
+
143
+ // Get user info for context
144
+ const user = await this.getCurrentUser();
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]`;
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';
194
163
 
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
- ];
164
+ return {
165
+ Success: false,
166
+ ResultCode: this.getErrorCode(error),
167
+ Message: `Failed to schedule tweet: ${errorMessage}`,
168
+ Params,
169
+ };
252
170
  }
171
+ }
253
172
 
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';
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
+ }
179
+
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';
259
190
  }
260
- }
191
+ return 'ERROR';
192
+ }
193
+
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
+ }
252
+
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
+ }