@memberjunction/actions-bizapps-social 2.111.0 → 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, Tweet } 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, SocialPost } from '../../../base/base-social.action';
6
6
  import { BaseAction } from '@memberjunction/actions';
7
7
 
@@ -10,219 +10,215 @@ import { BaseAction } from '@memberjunction/actions';
10
10
  */
11
11
  @RegisterClass(BaseAction, 'TwitterCreateThreadAction')
12
12
  export class TwitterCreateThreadAction extends TwitterBaseAction {
13
- /**
14
- * Create a thread on Twitter
15
- */
16
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
17
- const { Params, ContextUser } = params;
18
-
19
- try {
20
- // Initialize OAuth
21
- const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
22
- if (!await this.initializeOAuth(companyIntegrationId)) {
23
- throw new Error('Failed to initialize OAuth connection');
24
- }
25
-
26
- // Extract parameters
27
- const tweets = this.getParamValue(Params, 'Tweets');
28
- const mediaFilesByTweet = this.getParamValue(Params, 'MediaFilesByTweet');
29
- const includeNumbers = this.getParamValue(Params, 'IncludeNumbers') !== false; // Default true
30
- const numberFormat = this.getParamValue(Params, 'NumberFormat') || '{n}/{total}'; // Default format
31
-
32
- // Validate required parameters
33
- if (!tweets || !Array.isArray(tweets) || tweets.length === 0) {
34
- throw new Error('Tweets array is required and must not be empty');
35
- }
36
-
37
- if (tweets.length < 2) {
38
- throw new Error('A thread must contain at least 2 tweets');
39
- }
13
+ /**
14
+ * Create a thread on Twitter
15
+ */
16
+ protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
17
+ const { Params, ContextUser } = params;
18
+
19
+ try {
20
+ // Initialize OAuth
21
+ const companyIntegrationId = this.getParamValue(Params, 'CompanyIntegrationID');
22
+ if (!(await this.initializeOAuth(companyIntegrationId))) {
23
+ throw new Error('Failed to initialize OAuth connection');
24
+ }
25
+
26
+ // Extract parameters
27
+ const tweets = this.getParamValue(Params, 'Tweets');
28
+ const mediaFilesByTweet = this.getParamValue(Params, 'MediaFilesByTweet');
29
+ const includeNumbers = this.getParamValue(Params, 'IncludeNumbers') !== false; // Default true
30
+ const numberFormat = this.getParamValue(Params, 'NumberFormat') || '{n}/{total}'; // Default format
31
+
32
+ // Validate required parameters
33
+ if (!tweets || !Array.isArray(tweets) || tweets.length === 0) {
34
+ throw new Error('Tweets array is required and must not be empty');
35
+ }
36
+
37
+ if (tweets.length < 2) {
38
+ throw new Error('A thread must contain at least 2 tweets');
39
+ }
40
+
41
+ if (tweets.length > 25) {
42
+ throw new Error('Twitter threads are limited to 25 tweets');
43
+ }
44
+
45
+ // Prepare tweets with numbering if requested
46
+ const preparedTweets = includeNumbers ? this.addThreadNumbers(tweets, numberFormat) : tweets;
47
+
48
+ // Validate all tweet lengths
49
+ for (let i = 0; i < preparedTweets.length; i++) {
50
+ if (preparedTweets[i].length > 280) {
51
+ throw new Error(`Tweet ${i + 1} exceeds Twitter's 280 character limit (current: ${preparedTweets[i].length} characters)`);
52
+ }
53
+ }
40
54
 
41
- if (tweets.length > 25) {
42
- throw new Error('Twitter threads are limited to 25 tweets');
43
- }
55
+ const createdTweets: Tweet[] = [];
56
+ const createdPosts: SocialPost[] = [];
57
+ let previousTweetId: string | undefined;
44
58
 
45
- // Prepare tweets with numbering if requested
46
- const preparedTweets = includeNumbers
47
- ? this.addThreadNumbers(tweets, numberFormat)
48
- : tweets;
59
+ try {
60
+ // Create tweets in sequence
61
+ for (let i = 0; i < preparedTweets.length; i++) {
62
+ LogStatus(`Creating tweet ${i + 1} of ${preparedTweets.length}...`);
49
63
 
50
- // Validate all tweet lengths
51
- for (let i = 0; i < preparedTweets.length; i++) {
52
- if (preparedTweets[i].length > 280) {
53
- throw new Error(`Tweet ${i + 1} exceeds Twitter's 280 character limit (current: ${preparedTweets[i].length} characters)`);
54
- }
55
- }
64
+ const tweetData: CreateTweetData = {
65
+ text: preparedTweets[i],
66
+ };
56
67
 
57
- const createdTweets: Tweet[] = [];
58
- const createdPosts: SocialPost[] = [];
59
- let previousTweetId: string | undefined;
60
-
61
- try {
62
- // Create tweets in sequence
63
- for (let i = 0; i < preparedTweets.length; i++) {
64
- LogStatus(`Creating tweet ${i + 1} of ${preparedTweets.length}...`);
65
-
66
- const tweetData: CreateTweetData = {
67
- text: preparedTweets[i]
68
- };
69
-
70
- // Reply to previous tweet in thread
71
- if (previousTweetId) {
72
- tweetData.reply = {
73
- in_reply_to_tweet_id: previousTweetId
74
- };
75
- }
76
-
77
- // Add media if provided for this tweet
78
- if (mediaFilesByTweet && mediaFilesByTweet[i]) {
79
- const mediaFiles = mediaFilesByTweet[i];
80
- if (Array.isArray(mediaFiles) && mediaFiles.length > 0) {
81
- if (mediaFiles.length > 4) {
82
- throw new Error(`Tweet ${i + 1}: Twitter supports a maximum of 4 media items per tweet`);
83
- }
84
-
85
- LogStatus(`Uploading ${mediaFiles.length} media files for tweet ${i + 1}...`);
86
- const mediaIds = await this.uploadMedia(mediaFiles as MediaFile[]);
87
-
88
- tweetData.media = {
89
- media_ids: mediaIds
90
- };
91
- }
92
- }
93
-
94
- // Create the tweet
95
- const tweet = await this.createTweet(tweetData);
96
- createdTweets.push(tweet);
97
- createdPosts.push(this.normalizePost(tweet));
98
- previousTweetId = tweet.id;
99
-
100
- // Small delay between tweets to avoid rate limiting
101
- if (i < preparedTweets.length - 1) {
102
- await new Promise(resolve => setTimeout(resolve, 1000)); // 1 second delay
103
- }
104
- }
105
-
106
- // Get user info for URLs
107
- const user = await this.getCurrentUser();
108
-
109
- // Build thread URL (link to first tweet)
110
- const threadUrl = `https://twitter.com/${user.username}/status/${createdTweets[0].id}`;
111
-
112
- // Update output parameters
113
- const outputParams = [...Params];
114
- const postsParam = outputParams.find(p => p.Name === 'CreatedPosts');
115
- if (postsParam) postsParam.Value = createdPosts;
116
- const tweetIdsParam = outputParams.find(p => p.Name === 'TweetIDs');
117
- if (tweetIdsParam) tweetIdsParam.Value = createdTweets.map(t => t.id);
118
- const threadUrlParam = outputParams.find(p => p.Name === 'ThreadURL');
119
- if (threadUrlParam) threadUrlParam.Value = threadUrl;
120
-
121
- return {
122
- Success: true,
123
- ResultCode: 'SUCCESS',
124
- Message: `Successfully created thread with ${createdTweets.length} tweets`,
125
- Params: outputParams
126
- };
127
-
128
- } catch (error) {
129
- // If thread creation fails partway through, note which tweets were created
130
- if (createdTweets.length > 0) {
131
- LogError(`Thread creation failed after creating ${createdTweets.length} tweets. Tweet IDs: ${createdTweets.map(t => t.id).join(', ')}`);
132
- }
133
- throw error;
134
- }
135
-
136
- } catch (error) {
137
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
138
-
139
- return {
140
- Success: false,
141
- ResultCode: this.getErrorCode(error),
142
- Message: `Failed to create thread: ${errorMessage}`,
143
- Params
68
+ // Reply to previous tweet in thread
69
+ if (previousTweetId) {
70
+ tweetData.reply = {
71
+ in_reply_to_tweet_id: previousTweetId,
144
72
  };
73
+ }
74
+
75
+ // Add media if provided for this tweet
76
+ if (mediaFilesByTweet && mediaFilesByTweet[i]) {
77
+ const mediaFiles = mediaFilesByTweet[i];
78
+ if (Array.isArray(mediaFiles) && mediaFiles.length > 0) {
79
+ if (mediaFiles.length > 4) {
80
+ throw new Error(`Tweet ${i + 1}: Twitter supports a maximum of 4 media items per tweet`);
81
+ }
82
+
83
+ LogStatus(`Uploading ${mediaFiles.length} media files for tweet ${i + 1}...`);
84
+ const mediaIds = await this.uploadMedia(mediaFiles as MediaFile[]);
85
+
86
+ tweetData.media = {
87
+ media_ids: mediaIds,
88
+ };
89
+ }
90
+ }
91
+
92
+ // Create the tweet
93
+ const tweet = await this.createTweet(tweetData);
94
+ createdTweets.push(tweet);
95
+ createdPosts.push(this.normalizePost(tweet));
96
+ previousTweetId = tweet.id;
97
+
98
+ // Small delay between tweets to avoid rate limiting
99
+ if (i < preparedTweets.length - 1) {
100
+ await new Promise((resolve) => setTimeout(resolve, 1000)); // 1 second delay
101
+ }
145
102
  }
146
- }
147
-
148
- /**
149
- * Add thread numbers to tweets
150
- */
151
- private addThreadNumbers(tweets: string[], format: string): string[] {
152
- const total = tweets.length;
153
-
154
- return tweets.map((tweet, index) => {
155
- const number = index + 1;
156
- const threadNumber = format
157
- .replace('{n}', number.toString())
158
- .replace('{total}', total.toString());
159
-
160
- // Add number to beginning of tweet with a space
161
- return `${threadNumber} ${tweet}`;
162
- });
163
- }
164
103
 
165
- /**
166
- * Get error code based on error type
167
- */
168
- private getErrorCode(error: any): string {
169
- if (error instanceof Error) {
170
- if (error.message.includes('Rate Limit')) return 'RATE_LIMIT';
171
- if (error.message.includes('Unauthorized')) return 'INVALID_TOKEN';
172
- if (error.message.includes('character limit')) return 'CONTENT_TOO_LONG';
173
- if (error.message.includes('media')) return 'INVALID_MEDIA';
104
+ // Get user info for URLs
105
+ const user = await this.getCurrentUser();
106
+
107
+ // Build thread URL (link to first tweet)
108
+ const threadUrl = `https://twitter.com/${user.username}/status/${createdTweets[0].id}`;
109
+
110
+ // Update output parameters
111
+ const outputParams = [...Params];
112
+ const postsParam = outputParams.find((p) => p.Name === 'CreatedPosts');
113
+ if (postsParam) postsParam.Value = createdPosts;
114
+ const tweetIdsParam = outputParams.find((p) => p.Name === 'TweetIDs');
115
+ if (tweetIdsParam) tweetIdsParam.Value = createdTweets.map((t) => t.id);
116
+ const threadUrlParam = outputParams.find((p) => p.Name === 'ThreadURL');
117
+ if (threadUrlParam) threadUrlParam.Value = threadUrl;
118
+
119
+ return {
120
+ Success: true,
121
+ ResultCode: 'SUCCESS',
122
+ Message: `Successfully created thread with ${createdTweets.length} tweets`,
123
+ Params: outputParams,
124
+ };
125
+ } catch (error) {
126
+ // If thread creation fails partway through, note which tweets were created
127
+ if (createdTweets.length > 0) {
128
+ LogError(
129
+ `Thread creation failed after creating ${createdTweets.length} tweets. Tweet IDs: ${createdTweets.map((t) => t.id).join(', ')}`
130
+ );
174
131
  }
175
- return 'ERROR';
132
+ throw error;
133
+ }
134
+ } catch (error) {
135
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
136
+
137
+ return {
138
+ Success: false,
139
+ ResultCode: this.getErrorCode(error),
140
+ Message: `Failed to create thread: ${errorMessage}`,
141
+ Params,
142
+ };
176
143
  }
177
-
178
- /**
179
- * Define the parameters this action expects
180
- */
181
- public get Params(): ActionParam[] {
182
- return [
183
- ...this.commonSocialParams,
184
- {
185
- Name: 'Tweets',
186
- Type: 'Input',
187
- Value: null
188
- },
189
- {
190
- Name: 'MediaFilesByTweet',
191
- Type: 'Input',
192
- Value: null
193
- },
194
- {
195
- Name: 'IncludeNumbers',
196
- Type: 'Input',
197
- Value: true
198
- },
199
- {
200
- Name: 'NumberFormat',
201
- Type: 'Input',
202
- Value: '{n}/{total}'
203
- },
204
- {
205
- Name: 'CreatedPosts',
206
- Type: 'Output',
207
- Value: null
208
- },
209
- {
210
- Name: 'TweetIDs',
211
- Type: 'Output',
212
- Value: null
213
- },
214
- {
215
- Name: 'ThreadURL',
216
- Type: 'Output',
217
- Value: null
218
- }
219
- ];
220
- }
221
-
222
- /**
223
- * Get action description
224
- */
225
- public get Description(): string {
226
- return 'Creates a thread (series of connected tweets) on Twitter/X with optional media attachments and automatic numbering';
144
+ }
145
+
146
+ /**
147
+ * Add thread numbers to tweets
148
+ */
149
+ private addThreadNumbers(tweets: string[], format: string): string[] {
150
+ const total = tweets.length;
151
+
152
+ return tweets.map((tweet, index) => {
153
+ const number = index + 1;
154
+ const threadNumber = format.replace('{n}', number.toString()).replace('{total}', total.toString());
155
+
156
+ // Add number to beginning of tweet with a space
157
+ return `${threadNumber} ${tweet}`;
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Get error code based on error type
163
+ */
164
+ private getErrorCode(error: any): string {
165
+ if (error instanceof Error) {
166
+ if (error.message.includes('Rate Limit')) return 'RATE_LIMIT';
167
+ if (error.message.includes('Unauthorized')) return 'INVALID_TOKEN';
168
+ if (error.message.includes('character limit')) return 'CONTENT_TOO_LONG';
169
+ if (error.message.includes('media')) return 'INVALID_MEDIA';
227
170
  }
228
- }
171
+ return 'ERROR';
172
+ }
173
+
174
+ /**
175
+ * Define the parameters this action expects
176
+ */
177
+ public get Params(): ActionParam[] {
178
+ return [
179
+ ...this.commonSocialParams,
180
+ {
181
+ Name: 'Tweets',
182
+ Type: 'Input',
183
+ Value: null,
184
+ },
185
+ {
186
+ Name: 'MediaFilesByTweet',
187
+ Type: 'Input',
188
+ Value: null,
189
+ },
190
+ {
191
+ Name: 'IncludeNumbers',
192
+ Type: 'Input',
193
+ Value: true,
194
+ },
195
+ {
196
+ Name: 'NumberFormat',
197
+ Type: 'Input',
198
+ Value: '{n}/{total}',
199
+ },
200
+ {
201
+ Name: 'CreatedPosts',
202
+ Type: 'Output',
203
+ Value: null,
204
+ },
205
+ {
206
+ Name: 'TweetIDs',
207
+ Type: 'Output',
208
+ Value: null,
209
+ },
210
+ {
211
+ Name: 'ThreadURL',
212
+ Type: 'Output',
213
+ Value: null,
214
+ },
215
+ ];
216
+ }
217
+
218
+ /**
219
+ * Get action description
220
+ */
221
+ public get Description(): string {
222
+ return 'Creates a thread (series of connected tweets) on Twitter/X with optional media attachments and automatic numbering';
223
+ }
224
+ }