@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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +13 -0
- package/dist/base/base-social.action.d.ts.map +1 -1
- package/dist/base/base-social.action.js +24 -18
- package/dist/base/base-social.action.js.map +1 -1
- package/dist/providers/buffer/buffer-base.action.d.ts.map +1 -1
- package/dist/providers/buffer/buffer-base.action.js +34 -35
- package/dist/providers/buffer/buffer-base.action.js.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/boost-post.action.js +33 -33
- package/dist/providers/facebook/actions/boost-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-album.action.js +36 -34
- package/dist/providers/facebook/actions/create-album.action.js.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/create-post.action.js +20 -20
- package/dist/providers/facebook/actions/create-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-insights.action.js +27 -25
- package/dist/providers/facebook/actions/get-page-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-page-posts.action.js +23 -19
- package/dist/providers/facebook/actions/get-page-posts.action.js.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/get-post-insights.action.js +32 -28
- package/dist/providers/facebook/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/respond-to-comments.action.js +44 -42
- package/dist/providers/facebook/actions/respond-to-comments.action.js.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/schedule-post.action.js +29 -29
- package/dist/providers/facebook/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/facebook/actions/search-posts.action.js +39 -37
- package/dist/providers/facebook/actions/search-posts.action.js.map +1 -1
- package/dist/providers/facebook/facebook-base.action.d.ts.map +1 -1
- package/dist/providers/facebook/facebook-base.action.js +59 -44
- package/dist/providers/facebook/facebook-base.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js +31 -33
- package/dist/providers/hootsuite/actions/bulk-schedule-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js +32 -28
- package/dist/providers/hootsuite/actions/create-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js +19 -19
- package/dist/providers/hootsuite/actions/delete-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-analytics.action.js +26 -24
- package/dist/providers/hootsuite/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js +22 -22
- package/dist/providers/hootsuite/actions/get-scheduled-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js +34 -32
- package/dist/providers/hootsuite/actions/get-social-profiles.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/search-posts.action.js +52 -43
- package/dist/providers/hootsuite/actions/search-posts.action.js.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js +28 -30
- package/dist/providers/hootsuite/actions/update-scheduled-post.action.js.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.d.ts.map +1 -1
- package/dist/providers/hootsuite/hootsuite-base.action.js +20 -18
- package/dist/providers/hootsuite/hootsuite-base.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-post.action.js +26 -27
- package/dist/providers/instagram/actions/create-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/create-story.action.js +35 -35
- package/dist/providers/instagram/actions/create-story.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-account-insights.action.js +59 -38
- package/dist/providers/instagram/actions/get-account-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-business-posts.action.js +29 -29
- package/dist/providers/instagram/actions/get-business-posts.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-comments.action.js +36 -36
- package/dist/providers/instagram/actions/get-comments.action.js.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/get-post-insights.action.js +25 -23
- package/dist/providers/instagram/actions/get-post-insights.action.js.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/schedule-post.action.js +25 -25
- package/dist/providers/instagram/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/instagram/actions/search-posts.action.js +60 -56
- package/dist/providers/instagram/actions/search-posts.action.js.map +1 -1
- package/dist/providers/instagram/instagram-base.action.d.ts.map +1 -1
- package/dist/providers/instagram/instagram-base.action.js +27 -25
- package/dist/providers/instagram/instagram-base.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-article.action.js +45 -55
- package/dist/providers/linkedin/actions/create-article.action.js.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/create-post.action.js +29 -31
- package/dist/providers/linkedin/actions/create-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-followers.action.js +28 -28
- package/dist/providers/linkedin/actions/get-followers.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-organization-posts.action.js +20 -20
- package/dist/providers/linkedin/actions/get-organization-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-personal-posts.action.js +19 -19
- package/dist/providers/linkedin/actions/get-personal-posts.action.js.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/get-post-analytics.action.js +23 -25
- package/dist/providers/linkedin/actions/get-post-analytics.action.js.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/schedule-post.action.js +30 -32
- package/dist/providers/linkedin/actions/schedule-post.action.js.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.d.ts.map +1 -1
- package/dist/providers/linkedin/actions/search-posts.action.js +30 -28
- package/dist/providers/linkedin/actions/search-posts.action.js.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.d.ts.map +1 -1
- package/dist/providers/linkedin/linkedin-base.action.js +38 -33
- package/dist/providers/linkedin/linkedin-base.action.js.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.d.ts.map +1 -1
- package/dist/providers/tiktok/tiktok-base.action.js +26 -25
- package/dist/providers/tiktok/tiktok-base.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-thread.action.js +29 -25
- package/dist/providers/twitter/actions/create-thread.action.js.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/create-tweet.action.js +23 -23
- package/dist/providers/twitter/actions/create-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/delete-tweet.action.js +19 -19
- package/dist/providers/twitter/actions/delete-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-analytics.action.js +47 -40
- package/dist/providers/twitter/actions/get-analytics.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-mentions.action.js +31 -30
- package/dist/providers/twitter/actions/get-mentions.action.js.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/get-timeline.action.js +29 -29
- package/dist/providers/twitter/actions/get-timeline.action.js.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/schedule-tweet.action.js +26 -26
- package/dist/providers/twitter/actions/schedule-tweet.action.js.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.d.ts.map +1 -1
- package/dist/providers/twitter/actions/search-tweets.action.js +58 -56
- package/dist/providers/twitter/actions/search-tweets.action.js.map +1 -1
- package/dist/providers/twitter/twitter-base.action.d.ts.map +1 -1
- package/dist/providers/twitter/twitter-base.action.js +68 -58
- package/dist/providers/twitter/twitter-base.action.js.map +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts +1 -1
- package/dist/providers/youtube/youtube-base.action.d.ts.map +1 -1
- package/dist/providers/youtube/youtube-base.action.js +25 -22
- package/dist/providers/youtube/youtube-base.action.js.map +1 -1
- package/package.json +6 -5
- package/src/base/base-social.action.ts +224 -217
- package/src/providers/buffer/buffer-base.action.ts +441 -435
- package/src/providers/facebook/actions/boost-post.action.ts +386 -350
- package/src/providers/facebook/actions/create-album.action.ts +307 -291
- package/src/providers/facebook/actions/create-post.action.ts +227 -224
- package/src/providers/facebook/actions/get-page-insights.action.ts +403 -383
- package/src/providers/facebook/actions/get-page-posts.action.ts +225 -214
- package/src/providers/facebook/actions/get-post-insights.action.ts +316 -300
- package/src/providers/facebook/actions/respond-to-comments.action.ts +336 -319
- package/src/providers/facebook/actions/schedule-post.action.ts +292 -289
- package/src/providers/facebook/actions/search-posts.action.ts +413 -399
- package/src/providers/facebook/facebook-base.action.ts +670 -653
- package/src/providers/hootsuite/actions/bulk-schedule-posts.action.ts +257 -257
- package/src/providers/hootsuite/actions/create-scheduled-post.action.ts +189 -184
- package/src/providers/hootsuite/actions/delete-scheduled-post.action.ts +161 -160
- package/src/providers/hootsuite/actions/get-analytics.action.ts +254 -249
- package/src/providers/hootsuite/actions/get-scheduled-posts.action.ts +207 -206
- package/src/providers/hootsuite/actions/get-social-profiles.action.ts +205 -206
- package/src/providers/hootsuite/actions/search-posts.action.ts +369 -351
- package/src/providers/hootsuite/actions/update-scheduled-post.action.ts +209 -211
- package/src/providers/hootsuite/hootsuite-base.action.ts +307 -301
- package/src/providers/instagram/actions/create-post.action.ts +296 -276
- package/src/providers/instagram/actions/create-story.action.ts +394 -378
- package/src/providers/instagram/actions/get-account-insights.action.ts +420 -384
- package/src/providers/instagram/actions/get-business-posts.action.ts +242 -233
- package/src/providers/instagram/actions/get-comments.action.ts +377 -365
- package/src/providers/instagram/actions/get-post-insights.action.ts +273 -265
- package/src/providers/instagram/actions/schedule-post.action.ts +235 -233
- package/src/providers/instagram/actions/search-posts.action.ts +538 -512
- package/src/providers/instagram/instagram-base.action.ts +393 -368
- package/src/providers/linkedin/actions/create-article.action.ts +266 -275
- package/src/providers/linkedin/actions/create-post.action.ts +177 -179
- package/src/providers/linkedin/actions/get-followers.action.ts +211 -211
- package/src/providers/linkedin/actions/get-organization-posts.action.ts +147 -146
- package/src/providers/linkedin/actions/get-personal-posts.action.ts +139 -138
- package/src/providers/linkedin/actions/get-post-analytics.action.ts +189 -190
- package/src/providers/linkedin/actions/schedule-post.action.ts +189 -191
- package/src/providers/linkedin/actions/search-posts.action.ts +283 -275
- package/src/providers/linkedin/linkedin-base.action.ts +421 -407
- package/src/providers/tiktok/tiktok-base.action.ts +320 -305
- package/src/providers/twitter/actions/create-thread.action.ts +207 -203
- package/src/providers/twitter/actions/create-tweet.action.ts +188 -187
- package/src/providers/twitter/actions/delete-tweet.action.ts +129 -128
- package/src/providers/twitter/actions/get-analytics.action.ts +411 -402
- package/src/providers/twitter/actions/get-mentions.action.ts +219 -218
- package/src/providers/twitter/actions/get-timeline.action.ts +233 -232
- package/src/providers/twitter/actions/schedule-tweet.action.ts +222 -221
- package/src/providers/twitter/actions/search-tweets.action.ts +543 -540
- package/src/providers/twitter/twitter-base.action.ts +560 -541
- 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/
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
104
|
-
|
|
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
|
-
|
|
107
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
|
|
163
|
-
|
|
159
|
+
// Convert markdown bold
|
|
160
|
+
formatted = formatted.replace(/\*\*(.+?)\*\*/g, '**$1**');
|
|
164
161
|
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
// Convert markdown italic
|
|
163
|
+
formatted = formatted.replace(/\*(.+?)\*/g, '_$1_');
|
|
167
164
|
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
// Add line breaks for paragraphs
|
|
166
|
+
formatted = formatted.replace(/\n\n/g, '\n\n');
|
|
170
167
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
178
|
-
|
|
174
|
+
return formatted;
|
|
175
|
+
}
|
|
179
176
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
|
|
217
|
+
const postId = await this.createShare(shareData);
|
|
227
218
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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
|
+
}
|