- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Hi there,
While looking for ways to be more efficient in my content creation, I caught myself thinking:
"If only I could automatically post on LinkedIn..."
LinkedIn is an important channel for sharing my articles, blogs, Share projects, YouTube videos, or just posting random. Usually, I prepare my content in my Personal Developer Instance and then manually schedule it on both the ServiceNow Community and LinkedIn.
So the obvious question became:
"Is it possible to automatically post on LinkedIn?"
Yes, it is! LinkedIn provides a solid set of APIs that allow exactly that.
Let's take a closer look.
What this series will cover
In the coming weeks, I'll be sharing a short series of articles:
- Scripted LinkedIn Posts API Using RESTMessageV2
- Extending a Scripted LinkedIn Posts API with the Images API
- Extending a Scripted LinkedIn Posts API with the Documents API
- Refactoring a Scripted LinkedIn Posts API into an Integration Hub Spoke
This first article focuses on the foundation: posting text-only content to LinkedIn using a scripted approach.
LinkedIn APIs
When I first started searching for LinkedIn APIs about a year ago, I quickly noticed that many others had already written articles or created videos about this topic. So rather than reinventing the wheel, I decided to rebuild and adapt what I found.
Getting a basic LinkedIn post working turned out to be fairly straightforward - within an hour, I had my first post live.
Nice!
But then came the next realization:
"A post without an image, document, or video doesn’t really attract much attention."
All of the existing examples online are just about posting text-only. That's where the search becomes a bit more challenging 😀.
LinkedIn API Overview
There is a very solid LinkedIn API overview available here:
https://learn.microsoft.com/en-us/linkedin/
Going through the documentation, I quickly identified the APIs that mattered for this use case:
- Posts API
- Images API
- Documents API
- ...and more
From legacy to modern APIs
I initially had the ugcPosts API working, though reviewing the LinkedIn API Overview, I came across something interesting...
According to the documentation, the ugcPosts API is legacy and has been replaced by the newer content APIs - a change announced back on June 30, 2023.
Why are there still several people creating new content, on the legacy ugcPosts API?
Anyway, time to refactor everything to use the newer Posts API instead. The Posts API is also needed to get the Images API or Documents API combined (hence why I'm sharing this knowledge with you). While I'm not an integration expert, properly wiring everything together took me about half a day.
LinkedIn App
Before doing any development in ServiceNow, we first need to obtain credentials from LinkedIn. This starts with creating an application in LinkedIn Developers:
https://developer.linkedin.com/
Create a LinkedIn app
- Sign-in using your regular LinkedIn credentials
- Click Create app
- Fill in all required information:
- App name
- LinkedIn Page (If you don't have one, click Create a new LinkedIn Page)
- App logo
- Agree to the API Terms of Use
- Click Create app
Authentication
After creating the app, navigate to the Auth section of your LinkedIn application. Here you will find the Application credentials required later in ServiceNow:
- Client ID
- Primary Client Secret
Authorized redirect URLs
Next, configure the Authorized redirect URLs for your app. This should look like:
OAuth 2.0 scopes
At the bottom of the Auth page, you will find the available OAuth 2.0 scopes. These scopes will be required when configuring OAuth within ServiceNow. I'll cover the exact scopes needed in the next section.
Products
Finally, in the Products section on LinkedIn Developers, request access to:
- Sign In with LinkedIn using OpenID Connect
Posts API
Time to do some ServiceNow magic 😀.
To work with the LinkedIn API in ServiceNow, you would need the following components:
- REST Message
- OAuth Entity Profile
- Application Registries
- HTTP Method
All required information for these components can be found in the LinkedIn Overview API and LinkedIn Developer.
Application Registries
For practical reasons, we will start with the Application Registries, as this forms the basis for the OAuth authentication.
- Navigate to System OAuth > Application Registry
- Click New
- For "What kind of OAuth application?", select:
Connect to a third party OAuth Provider - Outbound - Populate the following fields using the values from the LinkedIn App - Auth section:
- Client ID
- Client Secret
- Set the Authorization URL to:
https://www.linkedin.com/oauth/v2/authorization - Set the Token URL to:
https://www.linkedin.com/oauth/v2/accessToken
Within the OAuth Entity Scopes section, define the required scopes exactly as specified in the LinkedIn App - Auth section.
OAuth Entity Profile
Next, we configure the OAuth Entity Profile.
- Navigate to the OAuth Entity Profile table [oauth_entity_profile]
- Create New
- For OAuth provider, select the Application Registry created in the previous step
- Select as Grand type:
Authorization Code
In the OAuth Entity Profile Scopes section, define the required scopes exactly as specified in the LinkedIn App - Auth section.
REST Message
Almost there! The next step is creating the REST Message in ServiceNow.
- Navigate to:
System Web Services > Outbound > REST Message - Click New
- Populate the Endpoint field.
The exact value is not critical here, as the endpoint will be defined on the HTTP Method, but it is a mandatory field. For example:
https://api.linkedin.com/rest
In the Authorization section of the REST Message:
- Set Authentication type to:
OAuth 2.0 - Select the OAuth Entity Profile created in the previous step
In the HTTP Request section, add the following HTTP Headers as specified in the LinkedIn API Overview:
- Name: LinkedIn-Version
Value: 202601 - Name: X-Restli-Protocol-Version
Value: 2.0.0
HTTP Method
The final step is adding the POST HTTP Method to the REST Message we just created.
At the bottom of the REST Message form, you will find the HTTP Methods related list. From here, we can define the method that will call the LinkedIn Posts API.
- On the REST Message record, scroll down to the HTTP Methods related list
- Click New
- Set HTTP Method to:
POST - Set the Endpoint to:
https://api.linkedin.com/rest/posts
In the Authentication section, leave the Authentication type set to:
Inherit from parent
This ensures the HTTP Method uses the OAuth configuration defined on the REST Message.
In the HTTP Request section, add the following HTTP header:
- Name: Content-Type
- Value: application/json
In the Content field under HTTP Query Parameters, add the following JSON payload:
{
"author": "${personUrn}",
"commentary": ${content},
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}
This payload is almost identical to the example provided in the LinkedIn API Overview, the only difference I introduced variable substitutions for dynamic values. To support the variable substitutions, we need to define them.
- On the HTTP Method, scroll down to the Variable Substitutions related list
- Click New
- Create a record with:
Name: content - Click New again
- Create a second record with:
Name: personUrn
Script
After applying Get OAuth Token on the REST Message, you can technically trigger the Posts API using a simple script like this:
var rm = new sn_ws.RESTMessageV2('LinkedIn', 'Posts API');
rm.setStringParameterNoEscape('personUrn', 'urn:li:person:**********');
rm.setStringParameterNoEscape('content', JSON.stringify('Your LinkedIn post goes here.'));
var response = rm.execute();
Person URN
O wait... The above code uses a variable substitution for personUrn. LinkedIn APIs don't use usernames. Instead, they rely on a URN (Uniform Resource Name). This is what the Posts API, Images API, and Documents API expect.
After OAuth authentication, call LinkedIn's userinfo endpoint:
GET https://api.linkedin.com/v2/userinfo
In the response, the sub attribute contains the LinkedIn person identifier. E.g.:
{
"sub": "6EossiXPyn",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"picture": "https://media.licdn.com/...",
"locale": {
"country": "US",
"language": "en"
}
}
You can convert this value into a Person URN by prefixing it:
urn:li:person:6EossiXPyn
This Person URN can then be reused in your REST Messages for posting content, uploading images, or attaching documents.
Scheduled posts
With all of the above, we can now schedule LinkedIn posts directly from ServiceNow. That was the goal of this article right 😀.
In my Personal Developer Instance I use a custom application that stores all my contributions, amongst them the LinkedIn posts, which are stored in a dedicated table. Each record contains the post content, a Scheduled date field, and optionally you can add attachments (images, documents, etcetera).
To publish posts automatically, I use a Scheduled Script Execution that runs daily at 07:30 AM. The scheduled job queries all records where the Scheduled field is set to today and then triggers the LinkedIn Posts API for each matching record.
Next...
In a follow-up article, I’ll extend this scripted LinkedIn Posts API by adding support for the Images API.
---
| C |
If this content helped you, I would appreciate it if you hit bookmark or mark it as helpful.
Interested in more Articles, Blogs, Videos, Podcasts, Share projects I shared/participated in? |
Kind regards,
Mark Roethof
Independent ServiceNow Consultant
10x ServiceNow MVP
---
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
