Skip to content

README.md

87 lines · 5.3 KB · Markdown
Raw

@kody/linkedin

Official LinkedIn “in” mark in white on LinkedIn Blue #0A66C2 (brand guidelines / Simple Icons letter paths; enclosing square omitted so the mark is not inverted). LinkedIn® is a trademark of LinkedIn Corporation. This package is not affiliated with or endorsed by LinkedIn.

Intent

Give any Kody account reusable, headless LinkedIn helpers for identity (/v2/userinfo and the posting personUrn), a generic authenticated request escape hatch, and guarded personal-profile posting. Author identity is always resolved from the connected member — never hard-coded to a specific profile.

This listing is meant to be forked. After you fork, connect your LinkedIn account and run ./smoke-test on your copy. Do not treat the live @kody/linkedin integration as yours.

What it does

  • Verify the saved linkedin OAuth integration and read the connected member’s identity or person URN
  • Call uncommon LinkedIn REST endpoints with ./request
  • Preview a text, article, image, or video post with dryRun: true, then publish only after confirm: true
  • Upload article thumbnails through the Images API before publishing link-preview cards
  • Delete a post by share or UGC post URN after explicit confirmation
  • Run the native video upload flow: register, upload parts, finalize, then post

Do not use this package as an organization-page poster, a scraping client, or a place to paste access tokens.

Prerequisites / setup

LinkedIn is bring-your-own OAuth. There is no built-in Kody LinkedIn app. Tokens come from the hosted connect page (createAuthenticatedFetch('linkedin')). Never paste a client secret or access token into chat. Agents: see AGENTS.md for import paths, smoke, and dryRun.

  1. Open LinkedIn Developers → Create app.
  2. Auth → Authorized redirect URLs → add exactly https://kody.codes/connect/oauth (the connect page shows the same value with a copy button).
  3. Products → request Sign In with LinkedIn using OpenID Connect and Share on LinkedIn.
  4. Note the app’s Client ID and Client Secret (paste them into Kody, not into chat).
  5. Open this prefilled connect URL while signed in to Kody:
https://kody.codes/connect/oauth?provider=linkedin

First-time setup also needs LinkedIn’s authorize and token URLs. Use this complete prefilled URL when the connection does not exist yet:

https://kody.codes/connect/oauth?provider=linkedin&authorizeUrl=https%3A%2F%2Fwww.linkedin.com%2Foauth%2Fv2%2Fauthorization&tokenUrl=https%3A%2F%2Fwww.linkedin.com%2Foauth%2Fv2%2FaccessToken&apiBaseUrl=https%3A%2F%2Fapi.linkedin.com&flow=confidential&tokenExchangeStyle=form&allowedHosts=api.linkedin.com%2Cwww.linkedin.com&dashboardUrl=https%3A%2F%2Fwww.linkedin.com%2Fdevelopers%2Fapps&scopes=openid%20profile%20email%20w_member_social

Decoded:

  • Redirect / callback: https://kody.codes/connect/oauth
  • Authorize: https://www.linkedin.com/oauth/v2/authorization
  • Token: https://www.linkedin.com/oauth/v2/accessToken
  • API base: https://api.linkedin.com
  • Flow: confidential with tokenExchangeStyle=form
  • Hosts: api.linkedin.com, www.linkedin.com
  • Scopes: openid, profile, email, w_member_social
  1. Paste the Client ID and Client Secret into the Kody form, continue to LinkedIn, and approve.
  2. Run smoke-test on the forked package.

Reconnect the same connection with https://kody.codes/connect/oauth?provider=linkedin. Kody reuses the saved authorize/token endpoints.

LinkedIn does not issue a refresh token unless the app has approved partner access. When the access token expires, reconnect — do not invent a refresh flow.

Scopes
ScopeProductUsed by
openidSign In with LinkedIn using OpenID Connectsmoke-test, get-user-info, get-person-urn
profileSign In with LinkedIn using OpenID Connectget-user-info (name / picture / locale flags)
emailSign In with LinkedIn using OpenID Connectget-user-info (email presence flags only)
w_member_socialShare on LinkedInposting, upload, and delete helpers
Auth / transport

There is no usable public LinkedIn OpenAPI for the full REST surface. Helpers authenticate with createAuthenticatedFetch('linkedin') and inject LinkedIn protocol headers (LinkedIn-Version, X-Restli-Protocol-Version) for Rest.li endpoints. Posting helpers resolve author from /v2/userinfo (urn:li:person:{sub}) unless the caller passes an explicit urn:li:person:…. Do not hard-code a member URN in forks.

Done when

  • Forked copy has a working linkedin OAuth connection with the scopes above
  • Smoke-test returns { ok: true, hasSubject: true, personUrnPresent: true } without names or emails
  • Posting/upload helpers refuse without confirm: true; dryRun: true never mutates LinkedIn

Branding

Keep LICENSE (MIT), ## Intent, and community-icon.svg intact for community listing.

Troubleshooting

  • Connect page asks for authorize/token URLs: use the complete first-time URL above.
  • HTTP 401 / expired token: reconnect at https://kody.codes/connect/oauth?provider=linkedin.
  • HTTP 403 on posting: the LinkedIn app needs Share on LinkedIn and w_member_social. Reconnect after approval.
  • redirect_uri mismatch: the LinkedIn app redirect must be exactly https://kody.codes/connect/oauth.