@memberjunction/actions-bizapps-social 2.112.0 → 2.113.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 +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 { LinkedInBaseAction, LinkedInShareData, LinkedInArticle } from '../linkedin-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
 
@@ -10,302 +10,293 @@ import { BaseAction } from '@memberjunction/actions';
10
10
  */
11
11
  @RegisterClass(BaseAction, 'LinkedInCreateArticleAction')
12
12
  export class LinkedInCreateArticleAction extends LinkedInBaseAction {
13
- /**
14
- * Create a LinkedIn article
15
- */
16
- protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
17
- const { Params, ContextUser } = params;
13
+ /**
14
+ * Create a LinkedIn article
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
+ }
18
25
 
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
- }
26
+ // Extract parameters
27
+ const title = this.getParamValue(Params, 'Title');
28
+ const content = this.getParamValue(Params, 'Content');
29
+ const description = this.getParamValue(Params, 'Description');
30
+ const coverImage = this.getParamValue(Params, 'CoverImage');
31
+ const authorType = this.getParamValue(Params, 'AuthorType') || 'personal'; // 'personal' or 'organization'
32
+ const organizationId = this.getParamValue(Params, 'OrganizationID');
33
+ const visibility = this.getParamValue(Params, 'Visibility') || 'PUBLIC';
34
+ const publishImmediately = this.getParamValue(Params, 'PublishImmediately') !== false; // Default true
25
35
 
26
- // Extract parameters
27
- const title = this.getParamValue(Params, 'Title');
28
- const content = this.getParamValue(Params, 'Content');
29
- const description = this.getParamValue(Params, 'Description');
30
- const coverImage = this.getParamValue(Params, 'CoverImage');
31
- const authorType = this.getParamValue(Params, 'AuthorType') || 'personal'; // 'personal' or 'organization'
32
- const organizationId = this.getParamValue(Params, 'OrganizationID');
33
- const visibility = this.getParamValue(Params, 'Visibility') || 'PUBLIC';
34
- const publishImmediately = this.getParamValue(Params, 'PublishImmediately') !== false; // Default true
36
+ // Validate required parameters
37
+ if (!title) {
38
+ throw new Error('Title is required');
39
+ }
40
+ if (!content) {
41
+ throw new Error('Content is required');
42
+ }
35
43
 
36
- // Validate required parameters
37
- if (!title) {
38
- throw new Error('Title is required');
39
- }
40
- if (!content) {
41
- throw new Error('Content is required');
42
- }
43
-
44
- // Determine author URN
45
- let authorUrn: string;
46
- if (authorType === 'organization') {
47
- if (!organizationId) {
48
- // Get first admin organization if not specified
49
- const orgs = await this.getAdminOrganizations();
50
- if (orgs.length === 0) {
51
- throw new Error('No organizations found. Please specify OrganizationID.');
52
- }
53
- authorUrn = orgs[0].urn;
54
- LogStatus(`Using organization: ${orgs[0].name}`);
55
- } else {
56
- authorUrn = `urn:li:organization:${organizationId}`;
57
- }
58
- } else {
59
- // Personal article
60
- authorUrn = await this.getCurrentUserUrn();
61
- }
62
-
63
- // Upload cover image if provided
64
- let coverImageUrn: string | undefined;
65
- if (coverImage) {
66
- LogStatus('Uploading cover image...');
67
- const coverImageFile = coverImage as MediaFile;
68
- const uploadedUrns = await this.uploadMedia([coverImageFile]);
69
- coverImageUrn = uploadedUrns[0];
70
- }
71
-
72
- // Create article share data
73
- const articleShareData: LinkedInShareData = {
74
- author: authorUrn,
75
- lifecycleState: publishImmediately ? 'PUBLISHED' : 'DRAFT',
76
- specificContent: {
77
- 'com.linkedin.ugc.ShareContent': {
78
- shareCommentary: {
79
- text: description || `Check out my new article: ${title}`,
80
- },
81
- shareMediaCategory: 'ARTICLE',
82
- media: [
83
- {
84
- status: 'READY' as const,
85
- media: '', // Article URL will be filled after creation
86
- title: {
87
- text: title,
88
- },
89
- description: description
90
- ? {
91
- text: description,
44
+ // Determine author URN
45
+ let authorUrn: string;
46
+ if (authorType === 'organization') {
47
+ if (!organizationId) {
48
+ // Get first admin organization if not specified
49
+ const orgs = await this.getAdminOrganizations();
50
+ if (orgs.length === 0) {
51
+ throw new Error('No organizations found. Please specify OrganizationID.');
92
52
  }
93
- : undefined,
94
- },
95
- ],
96
- },
97
- },
98
- visibility: {
99
- 'com.linkedin.ugc.MemberNetworkVisibility': visibility as any,
100
- },
101
- };
53
+ authorUrn = orgs[0].urn;
54
+ LogStatus(`Using organization: ${orgs[0].name}`);
55
+ } else {
56
+ authorUrn = `urn:li:organization:${organizationId}`;
57
+ }
58
+ } else {
59
+ // Personal article
60
+ authorUrn = await this.getCurrentUserUrn();
61
+ }
102
62
 
103
- // Format content for LinkedIn article
104
- const formattedContent = this.formatArticleContent(content);
63
+ // Upload cover image if provided
64
+ let coverImageUrn: string | undefined;
65
+ if (coverImage) {
66
+ LogStatus('Uploading cover image...');
67
+ const coverImageFile = coverImage as MediaFile;
68
+ const uploadedUrns = await this.uploadMedia([coverImageFile]);
69
+ coverImageUrn = uploadedUrns[0];
70
+ }
105
71
 
106
- // Create the article
107
- LogStatus('Creating LinkedIn article...');
72
+ // Create article share data
73
+ const articleShareData: LinkedInShareData = {
74
+ author: authorUrn,
75
+ lifecycleState: publishImmediately ? 'PUBLISHED' : 'DRAFT',
76
+ specificContent: {
77
+ 'com.linkedin.ugc.ShareContent': {
78
+ shareCommentary: {
79
+ text: description || `Check out my new article: ${title}`
80
+ },
81
+ shareMediaCategory: 'ARTICLE',
82
+ media: [{
83
+ status: 'READY' as const,
84
+ media: '', // Article URL will be filled after creation
85
+ title: {
86
+ text: title
87
+ },
88
+ description: description ? {
89
+ text: description
90
+ } : undefined
91
+ }]
92
+ }
93
+ },
94
+ visibility: {
95
+ 'com.linkedin.ugc.MemberNetworkVisibility': visibility as any
96
+ }
97
+ };
108
98
 
109
- // Note: LinkedIn's v2 API has limited article creation support
110
- // Full article creation typically requires using the Publishing Platform API
111
- // This implementation creates an article-style share with rich content
99
+ // Format content for LinkedIn article
100
+ const formattedContent = this.formatArticleContent(content);
112
101
 
113
- // For now, we'll create a rich media share that looks like an article
114
- const articlePost = await this.createRichMediaShare(
115
- authorUrn,
116
- title,
117
- formattedContent,
118
- description,
119
- coverImageUrn,
120
- visibility,
121
- publishImmediately
122
- );
102
+ // Create the article
103
+ LogStatus('Creating LinkedIn article...');
104
+
105
+ // Note: LinkedIn's v2 API has limited article creation support
106
+ // Full article creation typically requires using the Publishing Platform API
107
+ // This implementation creates an article-style share with rich content
108
+
109
+ // For now, we'll create a rich media share that looks like an article
110
+ const articlePost = await this.createRichMediaShare(
111
+ authorUrn,
112
+ title,
113
+ formattedContent,
114
+ description,
115
+ coverImageUrn,
116
+ visibility,
117
+ publishImmediately
118
+ );
123
119
 
124
- // Update output parameters
125
- const outputParams = [...Params];
126
- const articleParam = outputParams.find((p) => p.Name === 'Article');
127
- if (articleParam) articleParam.Value = articlePost;
128
- const articleIdParam = outputParams.find((p) => p.Name === 'ArticleID');
129
- if (articleIdParam) articleIdParam.Value = articlePost.id;
120
+ // Update output parameters
121
+ const outputParams = [...Params];
122
+ const articleParam = outputParams.find(p => p.Name === 'Article');
123
+ if (articleParam) articleParam.Value = articlePost;
124
+ const articleIdParam = outputParams.find(p => p.Name === 'ArticleID');
125
+ if (articleIdParam) articleIdParam.Value = articlePost.id;
130
126
 
131
- return {
132
- Success: true,
133
- ResultCode: 'SUCCESS',
134
- Message: `Successfully created LinkedIn article: ${title}`,
135
- Params: outputParams,
136
- };
137
- } catch (error) {
138
- const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
127
+ return {
128
+ Success: true,
129
+ ResultCode: 'SUCCESS',
130
+ Message: `Successfully created LinkedIn article: ${title}`,
131
+ Params: outputParams
132
+ };
139
133
 
140
- return {
141
- Success: false,
142
- ResultCode: 'ERROR',
143
- Message: `Failed to create LinkedIn article: ${errorMessage}`,
144
- Params,
145
- };
134
+ } catch (error) {
135
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
136
+
137
+ return {
138
+ Success: false,
139
+ ResultCode: 'ERROR',
140
+ Message: `Failed to create LinkedIn article: ${errorMessage}`,
141
+ Params
142
+ };
143
+ }
146
144
  }
147
- }
148
145
 
149
- /**
150
- * Format article content for LinkedIn
151
- */
152
- private formatArticleContent(content: string): string {
153
- // LinkedIn articles support basic HTML formatting
154
- // Convert markdown-style formatting to LinkedIn-compatible format
155
- let formatted = content;
146
+ /**
147
+ * Format article content for LinkedIn
148
+ */
149
+ private formatArticleContent(content: string): string {
150
+ // LinkedIn articles support basic HTML formatting
151
+ // Convert markdown-style formatting to LinkedIn-compatible format
152
+ let formatted = content;
156
153
 
157
- // Convert markdown headers to bold text
158
- formatted = formatted.replace(/^### (.+)$/gm, '\n**$1**\n');
159
- formatted = formatted.replace(/^## (.+)$/gm, '\n**$1**\n');
160
- formatted = formatted.replace(/^# (.+)$/gm, '\n**$1**\n');
154
+ // Convert markdown headers to bold text
155
+ formatted = formatted.replace(/^### (.+)$/gm, '\n**$1**\n');
156
+ formatted = formatted.replace(/^## (.+)$/gm, '\n**$1**\n');
157
+ formatted = formatted.replace(/^# (.+)$/gm, '\n**$1**\n');
161
158
 
162
- // Convert markdown bold
163
- formatted = formatted.replace(/\*\*(.+?)\*\*/g, '**$1**');
159
+ // Convert markdown bold
160
+ formatted = formatted.replace(/\*\*(.+?)\*\*/g, '**$1**');
164
161
 
165
- // Convert markdown italic
166
- formatted = formatted.replace(/\*(.+?)\*/g, '_$1_');
162
+ // Convert markdown italic
163
+ formatted = formatted.replace(/\*(.+?)\*/g, '_$1_');
167
164
 
168
- // Add line breaks for paragraphs
169
- formatted = formatted.replace(/\n\n/g, '\n\n');
165
+ // Add line breaks for paragraphs
166
+ formatted = formatted.replace(/\n\n/g, '\n\n');
170
167
 
171
- // Truncate if too long (LinkedIn has character limits)
172
- const maxLength = 3000; // LinkedIn's limit for share commentary
173
- if (formatted.length > maxLength) {
174
- formatted = formatted.substring(0, maxLength - 3) + '...';
175
- }
168
+ // Truncate if too long (LinkedIn has character limits)
169
+ const maxLength = 3000; // LinkedIn's limit for share commentary
170
+ if (formatted.length > maxLength) {
171
+ formatted = formatted.substring(0, maxLength - 3) + '...';
172
+ }
176
173
 
177
- return formatted;
178
- }
174
+ return formatted;
175
+ }
179
176
 
180
- /**
181
- * Create a rich media share that resembles an article
182
- */
183
- private async createRichMediaShare(
184
- authorUrn: string,
185
- title: string,
186
- content: string,
187
- description?: string,
188
- coverImageUrn?: string,
189
- visibility: string = 'PUBLIC',
190
- publishImmediately: boolean = true
191
- ): Promise<any> {
192
- try {
193
- // Create a rich share with article-like formatting
194
- const shareData: LinkedInShareData = {
195
- author: authorUrn,
196
- lifecycleState: publishImmediately ? 'PUBLISHED' : 'DRAFT',
197
- specificContent: {
198
- 'com.linkedin.ugc.ShareContent': {
199
- shareCommentary: {
200
- text: `📝 ${title}\n\n${content}`,
201
- },
202
- shareMediaCategory: coverImageUrn ? 'IMAGE' : 'NONE',
203
- media: coverImageUrn
204
- ? [
205
- {
206
- status: 'READY' as const,
207
- media: coverImageUrn,
208
- title: {
209
- text: title,
210
- },
211
- description: description
212
- ? {
213
- text: description,
214
- }
215
- : undefined,
216
- },
217
- ]
218
- : undefined,
219
- },
220
- },
221
- visibility: {
222
- 'com.linkedin.ugc.MemberNetworkVisibility': visibility as any,
223
- },
224
- };
177
+ /**
178
+ * Create a rich media share that resembles an article
179
+ */
180
+ private async createRichMediaShare(
181
+ authorUrn: string,
182
+ title: string,
183
+ content: string,
184
+ description?: string,
185
+ coverImageUrn?: string,
186
+ visibility: string = 'PUBLIC',
187
+ publishImmediately: boolean = true
188
+ ): Promise<any> {
189
+ try {
190
+ // Create a rich share with article-like formatting
191
+ const shareData: LinkedInShareData = {
192
+ author: authorUrn,
193
+ lifecycleState: publishImmediately ? 'PUBLISHED' : 'DRAFT',
194
+ specificContent: {
195
+ 'com.linkedin.ugc.ShareContent': {
196
+ shareCommentary: {
197
+ text: `📝 ${title}\n\n${content}`
198
+ },
199
+ shareMediaCategory: coverImageUrn ? 'IMAGE' : 'NONE',
200
+ media: coverImageUrn ? [{
201
+ status: 'READY' as const,
202
+ media: coverImageUrn,
203
+ title: {
204
+ text: title
205
+ },
206
+ description: description ? {
207
+ text: description
208
+ } : undefined
209
+ }] : undefined
210
+ }
211
+ },
212
+ visibility: {
213
+ 'com.linkedin.ugc.MemberNetworkVisibility': visibility as any
214
+ }
215
+ };
225
216
 
226
- const postId = await this.createShare(shareData);
217
+ const postId = await this.createShare(shareData);
227
218
 
228
- // Return article-like object
229
- return {
230
- id: postId,
231
- title: title,
232
- content: content,
233
- description: description,
234
- coverImage: coverImageUrn,
235
- author: authorUrn,
236
- publishedAt: publishImmediately ? new Date().toISOString() : null,
237
- visibility: visibility,
238
- url: `https://www.linkedin.com/feed/update/${postId}/`,
239
- };
240
- } catch (error) {
241
- LogError(`Failed to create rich media share: ${error instanceof Error ? error.message : 'Unknown error'}`);
242
- throw error;
219
+ // Return article-like object
220
+ return {
221
+ id: postId,
222
+ title: title,
223
+ content: content,
224
+ description: description,
225
+ coverImage: coverImageUrn,
226
+ author: authorUrn,
227
+ publishedAt: publishImmediately ? new Date().toISOString() : null,
228
+ visibility: visibility,
229
+ url: `https://www.linkedin.com/feed/update/${postId}/`
230
+ };
231
+ } catch (error) {
232
+ LogError(`Failed to create rich media share: ${error instanceof Error ? error.message : 'Unknown error'}`);
233
+ throw error;
234
+ }
243
235
  }
244
- }
245
236
 
246
- /**
247
- * Define the parameters this action expects
248
- */
249
- public get Params(): ActionParam[] {
250
- return [
251
- ...this.commonSocialParams,
252
- {
253
- Name: 'Title',
254
- Type: 'Input',
255
- Value: null,
256
- },
257
- {
258
- Name: 'Content',
259
- Type: 'Input',
260
- Value: null,
261
- },
262
- {
263
- Name: 'Description',
264
- Type: 'Input',
265
- Value: null,
266
- },
267
- {
268
- Name: 'CoverImage',
269
- Type: 'Input',
270
- Value: null,
271
- },
272
- {
273
- Name: 'AuthorType',
274
- Type: 'Input',
275
- Value: 'personal', // 'personal' or 'organization'
276
- },
277
- {
278
- Name: 'OrganizationID',
279
- Type: 'Input',
280
- Value: null,
281
- },
282
- {
283
- Name: 'Visibility',
284
- Type: 'Input',
285
- Value: 'PUBLIC', // 'PUBLIC', 'CONNECTIONS', 'LOGGED_IN', 'CONTAINER'
286
- },
287
- {
288
- Name: 'PublishImmediately',
289
- Type: 'Input',
290
- Value: true,
291
- },
292
- {
293
- Name: 'Article',
294
- Type: 'Output',
295
- Value: null,
296
- },
297
- {
298
- Name: 'ArticleID',
299
- Type: 'Output',
300
- Value: null,
301
- },
302
- ];
303
- }
237
+ /**
238
+ * Define the parameters this action expects
239
+ */
240
+ public get Params(): ActionParam[] {
241
+ return [
242
+ ...this.commonSocialParams,
243
+ {
244
+ Name: 'Title',
245
+ Type: 'Input',
246
+ Value: null
247
+ },
248
+ {
249
+ Name: 'Content',
250
+ Type: 'Input',
251
+ Value: null
252
+ },
253
+ {
254
+ Name: 'Description',
255
+ Type: 'Input',
256
+ Value: null
257
+ },
258
+ {
259
+ Name: 'CoverImage',
260
+ Type: 'Input',
261
+ Value: null
262
+ },
263
+ {
264
+ Name: 'AuthorType',
265
+ Type: 'Input',
266
+ Value: 'personal' // 'personal' or 'organization'
267
+ },
268
+ {
269
+ Name: 'OrganizationID',
270
+ Type: 'Input',
271
+ Value: null
272
+ },
273
+ {
274
+ Name: 'Visibility',
275
+ Type: 'Input',
276
+ Value: 'PUBLIC' // 'PUBLIC', 'CONNECTIONS', 'LOGGED_IN', 'CONTAINER'
277
+ },
278
+ {
279
+ Name: 'PublishImmediately',
280
+ Type: 'Input',
281
+ Value: true
282
+ },
283
+ {
284
+ Name: 'Article',
285
+ Type: 'Output',
286
+ Value: null
287
+ },
288
+ {
289
+ Name: 'ArticleID',
290
+ Type: 'Output',
291
+ Value: null
292
+ }
293
+ ];
294
+ }
304
295
 
305
- /**
306
- * Get action description
307
- */
308
- public get Description(): string {
309
- return 'Creates a LinkedIn article (long-form content) with title, content, and optional cover image. Note: Uses rich media shares to simulate article functionality due to API limitations.';
310
- }
311
- }
296
+ /**
297
+ * Get action description
298
+ */
299
+ public get Description(): string {
300
+ return 'Creates a LinkedIn article (long-form content) with title, content, and optional cover image. Note: Uses rich media shares to simulate article functionality due to API limitations.';
301
+ }
302
+ }