@kody/linkedin
Identity, generic requests, and guarded posting through the saved LinkedIn OAuth integration.
README.md
87 lines · 5.3 KB · Markdown@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
linkedinOAuth 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 afterconfirm: 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.
- Open LinkedIn Developers → Create app.
- Auth → Authorized redirect URLs → add exactly
https://kody.codes/connect/oauth(the connect page shows the same value with a copy button). - Products → request Sign In with LinkedIn using OpenID Connect and Share on LinkedIn.
- Note the app’s Client ID and Client Secret (paste them into Kody, not into chat).
- Open this prefilled connect URL while signed in to Kody:
https://kody.codes/connect/oauth?provider=linkedinFirst-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_socialDecoded:
- 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:
confidentialwithtokenExchangeStyle=form - Hosts:
api.linkedin.com,www.linkedin.com - Scopes:
openid,profile,email,w_member_social
- Paste the Client ID and Client Secret into the Kody form, continue to LinkedIn, and approve.
- 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
| Scope | Product | Used by |
|---|---|---|
openid | Sign In with LinkedIn using OpenID Connect | smoke-test, get-user-info, get-person-urn |
profile | Sign In with LinkedIn using OpenID Connect | get-user-info (name / picture / locale flags) |
email | Sign In with LinkedIn using OpenID Connect | get-user-info (email presence flags only) |
w_member_social | Share on LinkedIn | posting, 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
linkedinOAuth 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: truenever 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_urimismatch: the LinkedIn app redirect must be exactlyhttps://kody.codes/connect/oauth.