feat(LinkedIn Node): Add support for Community Management API (#7451)

This commit is contained in:
Jon 2024-01-24 09:28:42 +00:00 committed by GitHub
parent 7386f79362
commit 7660d7e735
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 122 additions and 9 deletions

View file

@ -0,0 +1,54 @@
import type { ICredentialType, INodeProperties } from 'n8n-workflow';
const scopes = ['w_member_social', 'w_organization_social', 'r_basicprofile'];
export class LinkedInCommunityManagementOAuth2Api implements ICredentialType {
name = 'linkedInCommunityManagementOAuth2Api';
extends = ['oAuth2Api'];
displayName = 'LinkedIn Community Management OAuth2 API';
documentationUrl = 'linkedIn';
properties: INodeProperties[] = [
{
displayName: 'Grant Type',
name: 'grantType',
type: 'hidden',
default: 'authorizationCode',
},
{
displayName: 'Authorization URL',
name: 'authUrl',
type: 'hidden',
default: 'https://www.linkedin.com/oauth/v2/authorization',
required: true,
},
{
displayName: 'Access Token URL',
name: 'accessTokenUrl',
type: 'hidden',
default: 'https://www.linkedin.com/oauth/v2/accessToken',
required: true,
},
{
displayName: 'Scope',
name: 'scope',
type: 'hidden',
default: scopes.join(' '),
},
{
displayName: 'Auth URI Query Parameters',
name: 'authQueryParameters',
type: 'hidden',
default: '',
},
{
displayName: 'Authentication',
name: 'authentication',
type: 'hidden',
default: 'body',
},
];
}

View file

@ -42,7 +42,7 @@ export class LinkedInOAuth2Api implements ICredentialType {
name: 'scope', name: 'scope',
type: 'hidden', type: 'hidden',
default: default:
'=w_member_social{{$self["organizationSupport"] === true ? ",w_organization_social":",r_liteprofile,r_emailaddress"}}', '=w_member_social{{$self["organizationSupport"] === true ? ",w_organization_social": $self["legacy"] === true ? ",r_liteprofile,r_emailaddress" : ",profile,email,openid"}}',
description: description:
'Standard scopes for posting on behalf of a user or organization. See <a href="https://docs.microsoft.com/en-us/linkedin/marketing/getting-started#available-permissions"> this resource </a>.', 'Standard scopes for posting on behalf of a user or organization. See <a href="https://docs.microsoft.com/en-us/linkedin/marketing/getting-started#available-permissions"> this resource </a>.',
}, },
@ -58,5 +58,12 @@ export class LinkedInOAuth2Api implements ICredentialType {
type: 'hidden', type: 'hidden',
default: 'body', default: 'body',
}, },
{
displayName: 'Legacy',
name: 'legacy',
type: 'boolean',
default: true,
description: 'Whether to use the legacy API',
},
]; ];
} }

View file

@ -25,6 +25,14 @@ export async function linkedInApiRequest(
binary?: boolean, binary?: boolean,
_headers?: object, _headers?: object,
): Promise<any> { ): Promise<any> {
const authenticationMethod = this.getNodeParameter('authentication', 0);
const credentialType =
authenticationMethod === 'standard'
? 'linkedInOAuth2Api'
: 'linkedInCommunityManagementOAuth2Api';
const baseUrl = 'https://api.linkedin.com';
let options: OptionsWithUrl = { let options: OptionsWithUrl = {
headers: { headers: {
Accept: 'application/json', Accept: 'application/json',
@ -33,9 +41,10 @@ export async function linkedInApiRequest(
}, },
method, method,
body, body,
url: binary ? endpoint : `https://api.linkedin.com/rest${endpoint}`, url: binary ? endpoint : `${baseUrl}${endpoint.includes('v2') ? '' : '/rest'}${endpoint}`,
json: true, json: true,
}; };
options = Object.assign({}, options, { options = Object.assign({}, options, {
resolveWithFullResponse: true, resolveWithFullResponse: true,
}); });
@ -51,7 +60,7 @@ export async function linkedInApiRequest(
try { try {
return resolveHeaderData( return resolveHeaderData(
await this.helpers.requestOAuth2.call(this, 'linkedInOAuth2Api', options, { await this.helpers.requestOAuth2.call(this, credentialType, options, {
tokenType: 'Bearer', tokenType: 'Bearer',
}), }),
); );

View file

@ -28,9 +28,39 @@ export class LinkedIn implements INodeType {
{ {
name: 'linkedInOAuth2Api', name: 'linkedInOAuth2Api',
required: true, required: true,
displayOptions: {
show: {
authentication: ['standard'],
},
},
},
{
name: 'linkedInCommunityManagementOAuth2Api',
required: true,
displayOptions: {
show: {
authentication: ['communityManagement'],
},
},
}, },
], ],
properties: [ properties: [
{
displayName: 'Authentication',
name: 'authentication',
type: 'options',
options: [
{
name: 'Standard',
value: 'standard',
},
{
name: 'Community Management',
value: 'communityManagement',
},
],
default: 'standard',
},
{ {
displayName: 'Resource', displayName: 'Resource',
name: 'resource', name: 'resource',
@ -55,12 +85,24 @@ export class LinkedIn implements INodeType {
// Get Person URN which has to be used with other LinkedIn API Requests // Get Person URN which has to be used with other LinkedIn API Requests
// https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin // https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin
async getPersonUrn(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> { async getPersonUrn(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
const returnData: INodePropertyOptions[] = []; const authentication = this.getNodeParameter('authentication', 0);
const person = await linkedInApiRequest.call(this, 'GET', '/me', {}); let endpoint = '/me';
returnData.push({ if (authentication === 'standard') {
name: `${person.localizedFirstName} ${person.localizedLastName}`, const { legacy } = await this.getCredentials('linkedInOAuth2Api');
value: person.id, if (!legacy) {
}); endpoint = '/v2/userinfo';
}
}
const person = await linkedInApiRequest.call(this, 'GET', endpoint, {});
const firstName = person.localizedFirstName ?? person.given_name;
const lastName = person.localizedLastName ?? person.family_name;
const name = `${firstName} ${lastName}`;
const returnData: INodePropertyOptions[] = [
{
name,
value: person.id ?? person.sub,
},
];
return returnData; return returnData;
}, },
}, },

View file

@ -195,6 +195,7 @@
"dist/credentials/LinearOAuth2Api.credentials.js", "dist/credentials/LinearOAuth2Api.credentials.js",
"dist/credentials/LineNotifyOAuth2Api.credentials.js", "dist/credentials/LineNotifyOAuth2Api.credentials.js",
"dist/credentials/LingvaNexApi.credentials.js", "dist/credentials/LingvaNexApi.credentials.js",
"dist/credentials/LinkedInCommunityManagementOAuth2Api.credentials.js",
"dist/credentials/LinkedInOAuth2Api.credentials.js", "dist/credentials/LinkedInOAuth2Api.credentials.js",
"dist/credentials/LoneScaleApi.credentials.js", "dist/credentials/LoneScaleApi.credentials.js",
"dist/credentials/Magento2Api.credentials.js", "dist/credentials/Magento2Api.credentials.js",