- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
a week ago
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 second article focuses on extending the scripted approach for posting text-only content by adding support for one or multiple images using the LinkedIn Images API.
Images API
Following the first article in this series, the Images API is an addition to the Posts API. All the steps outlined in the first article are prerequisites for getting the Images API working.
- REST Message
- OAuth Entity Profile
- Application Registries
- HTTP Method (Posts API)
We left off with a working REST Message that uses OAuth 2.0 authentication that contains a HTTP Method for the Posts API. The HTTP Method we need to expand a tiny bit for the Images API, though the challenging part is adding an HTTP Method for the Images API.
Registering an image
Reading through the API documentation, the "Managing Images asset" mentions two important steps:
- Registering an image
- Uploading an image
- Create image content
To register an image, you need to use the initializeUpload action to register the upload.
HTTP Method
On the REST Message created in the first article, we need to add an HTTP Method for the Images API.
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 Images 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/images?action=initializeUpload
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: image/png
Good to know, while specifying image/png here, this will also work for jpeg for example. I am not sure how this part works, though it works 😀.
In the Content field under HTTP Query Parameters, add the following JSON payload:
{
"initializeUploadRequest": {
"owner": "${personUrn}"
}
}
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: personUrn
When running this HTTP method, you would get a sample response like:
{
"value": {
"uploadUrlExpiresAt": 1650567510704,
"uploadUrl": "https://www.linkedin.com/dms-uploads/C3E12BQFoyyAjHPMQuQ/uploaded-image/0?ca=vector_ads&cn=uploads&sync=0&v=beta&ut=07zHRjMiAOLqc1",
"image": "urn:li:image:C4B09AQFoyyAjHPMQuQ"
}
}
Upload an image
The response from the Images API contains vital information for being able to actually upload an image like the Image URN and the uploadUrl.
HTTP Method
On the REST Message created in the first article, we need to add the HTTP Method for the uploadUrl retrieved in the previous step.
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 Images API.
- On the REST Message record, scroll down to the HTTP Methods related list
- Click New
- Set HTTP Method to:
PUT - Set the Endpoint to:
${endpoint}
To support the variable substitution for endpoint, we need to define it.
- On the HTTP Method, scroll down to the Variable Substitutions related list
- Click New
- Create a record with:
Name: endpoint
Posts API
After having the image registered and uploaded, the Image URN needs to be appended to the Content of the Posts API HTTP Method.
In the Content field under HTTP Query Parameters, expand the JSON object with the "content" object:
{
"author": "${personUrn}",
"commentary": ${content},
"visibility": "PUBLIC",
"distribution": {
"feedDistribution": "MAIN_FEED",
"targetEntities": [],
"thirdPartyDistributionChannels": []
},
"content": {
"media": {
"altText": "Testing",
"id": "${imageUrn}"
}
},
"lifecycleState": "PUBLISHED",
"isReshareDisabledByAuthor": false
}
The id (Image Urn), is what we obtained from the response when uploading the image.
Script
You can technically trigger the Posts API using a simple script like this:
var rm = new sn_ws.RESTMessageV2('LinkedIn', 'Images API');
rm.setStringParameterNoEscape('personUrn', 'urn:li:person:**********');
var response = rm.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
var uploadUrl = JSON.parse(responseBody).value.uploadUrl;
var imageUrn = JSON.parse(responseBody).value.image;
var rm = new sn_ws.RESTMessageV2('LinkedIn', 'uploadUrl');
rm.setStringParameterNoEscape('endpoint', uploadUrl);
rm.setRequestBodyFromAttachment('<image_sys_id>');
var response = rm.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
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.'));
rm.setStringParameterNoEscape('imageUrn', imageUrn);
var response = rm.execute();
var responseBody = response.getBody();
var httpStatus = response.getStatusCode();
Of course this isn't the greatest artwork of scripting 😀 In a later article I'll share how I applied all scripting from a Script Include with re-usable functions.
Also not included in the above scripting:
- What if the image is optional? Now the script will fail, meaning the content object in the Content field under HTTP Query Parameters in the Posts API needs to become dynamic.
- What if there are multiple images? There is a Multiimage API! Be aware, the Multiimage API only works with multiple images, if you have only one image it will fail!
I like to leave you all with a tiny bit of work to do yourself, instead of just copy/pasting everything 😀.
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 the scripted LinkedIn Posts API by adding support for the Documents 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
---
- 389 Views
