26ph19
26ph19

Reputation: 393

How to automate post on linkedin using nextjs and linkedin API

I am trying to automate posts to my linkedin page using nextjs. I have a web application built using next js. When I make a new post on my web application then it should automatically be posted to my linkedin page. I already created linkedin app and already have the Client ID and Client Secret. I googled about this and I found following resources and among many other but none of them seem to answer my requirements above.

https://www.highnitin.com/how-to-automate-post-on-linkedin-with-javascript-without-using-any-tools/

https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin?context=linkedin%2Fconsumer%2Fcontext

https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin?context=linkedin%2Fconsumer%2Fcontext#creating-a-share-on-linkedin

As these links will require access token and that does not fit my use case above as these links gives information when making a post on behalf of other users whereas I want to make a post to linked using my linkedin application and web application to my linkedin page where OAuth shouldn't be a requirement.

I will appreciate any help with code sample.

Update

I followed @dave answer and make below post.

const linkedinPost = await fetch(`https://api.linkedin.com/v2/ugcPosts`, {
        method: "post",
        headers: {
          "Authorization": `Bearer ${process.env.NEXT_PUBLIC_LINKEDIN_ACCESS_TOKEN_DRJ_2}`,
          "Content-Type": "application/json"
        }, 
        body: JSON.stringify({
          "author": "urn:li:person:8675309",
          "lifecycleState": "PUBLISHED",
          "specificContent": {
              "com.linkedin.ugc.ShareContent": {
                  "shareCommentary": {
                      "text": "This text is to be posted",
                  },
                  "shareMediaCategory": "NONE"
              }
          },
          "visibility": {
              "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
          }
        })
      });

When I try this I get below log.

Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 422,
    timingInfo: {
      startTime: 492846.5113720894,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 492846.5113720894,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 0,
      decodedBodySize: 0,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'Unprocessable Entity',
    headersList: HeadersList {
      cookies: [Array],
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ URL {} ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: [
      'bcookie="v=2&07f3a4fc-656e-4486-8277-7f8de8a53e92"; domain=.linkedin.com; Path=/; Secure; Expires=Thu, 05-Dec-2024 10:13:09 GMT; SameSite=None',
      'lidc="b=OB72:s=O:r=O:a=O:p=O:g=3281:u=14:x=1:i=1701857588:t=1701859352:v=2:sig=AQFr_d1F9snHikizALVmxzSowEosPeV0"'
    ],
    [Symbol(headers map)]: Map(14) {
      'x-li-responseorigin' => [Object],
      'content-type' => [Object],
      'x-linkedin-error-response' => [Object],
      'x-restli-gateway-error' => [Object],
      'x-restli-protocol-version' => [Object],
      'content-length' => [Object],
      'date' => [Object],
      'connection' => [Object],
      'x-li-fabric' => [Object],
      'x-li-pop' => [Object],
      'x-li-proto' => [Object],
      'x-li-uuid' => [Object],
      'set-cookie' => [Object],
      'x-li-route-key' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}

As it can be seem that statusText='Unprocessable Entity'.

Any idea what could be the issue here?

Upvotes: 1

Views: 1837

Answers (3)

I found there are two tokens which LinkedIn provide.

  1. access_token
  2. provider_token

For me provider_token worked.

Upvotes: 0

karim arbia
karim arbia

Reputation: 21

At last i accomplished it.

As They already told you you need the access token (pretty simple to get it) and the URN (your Linkedin personID) to get your URN the endpoint is :

GET https://api.linkedin.com/v2/userInfo

And use the token as Authorization.

the old way is to use /me as endpoint you should change it to /userInfo

and :

  author: `urn:li:person:${process.env.LINKEDIN_URN}`,

change the env variable for the sub (Subject Identifier) in the response.

more info : https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2

Upvotes: 1

Dave
Dave

Reputation: 2049

You have to authorize your application to post on behalf of your user. Even if your app only ever posts for your user, even if you're the only one who uses it, you must authorize your app to post for you. The way this authorization works, is that you authenticate yourself to the oauth server, using your client ID and secret, and the server sends you back a token. You then use this token when you call the Linkedin API to share a post.

If this app is used only by yourself, you can make the authentication call manually, using, curl or the Linkedin developer portal and then store the token for use by your app. You should only do this if your app is used locally (not online.) Storing credentials or a token in an app that people can access over the internet would compromise your Linkedin account.

Step 1: Get a token by manually authenticating against the Linkedin developer portal: https://www.linkedin.com/developers/tools/oauth/token-generator

Step 2: Store the token in your Nextjs app

LINKEDIN_TOKEN=<your token>

Step 3: Use the token to hit the Linkedin API

axios({
  method: "post",
  url: "https://api.linkedin.com/v2/ugcPosts",
  headers: {"Authorization": `Bearer ${process.env.LINKEDIN_TOKEN}`}, 
  data: {
    "author": "urn:li:person:<your Linkedin personID>",
    "lifecycleState": "PUBLISHED",
    "specificContent": {
        "com.linkedin.ugc.ShareContent": {
            "shareCommentary": {
                "text": "Hello World! This is my first Share on LinkedIn!"
            },
            "shareMediaCategory": "NONE"
        }
    },
    "visibility": {
        "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
    }
  }
});

In this sample code, urn:li:person:<your Linkedin personID> is the URN of the person posting (i.e. you.) Use curl to call the retrieve current member profile route with your token to get your personID:

curl -X GET -H "Authorization: Bearer <your token>" https://api.linkedin.com/v2/me

Your personID is the field "id" in the response. See the docs here: https://learn.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api#retrieve-current-members-profile

API request docs: https://learn.microsoft.com/en-us/linkedin/shared/authentication/client-credentials-flow#step-3-make-api-requests

Sharing docs: https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/share-on-linkedin

Upvotes: 1

Related Questions