arizuko › components › linkd
linkd is the LinkedIn channel adapter. It targets the LinkedIn v2 community-management API for the bot account’s own shares and comments — UGC posts, likes, reshares, comments, deletes. JID prefix is linkedin:.
LinkedIn DMs and company-page posting are gated behind partner-only OAuth scopes that arizuko deployments cannot get. linkd carves out the subset that works under w_member_social — the agent’s own UGC posts and the social actions on them — and returns structured hints for the rest so the agent has a concrete alternative instead of a silent failure.
LinkedIn (api.linkedin.com)
| poll: own UGC shares + comments, every LINKEDIN_POLL_INTERVAL
v
linkd (LISTEN_ADDR=:8080)
| POST /v1/messages (signed by CHANNEL_SECRET)
v
gated
| POST /v1/send (callback to linkd)
v
linkd (REST: /v2/ugcPosts | /v2/socialActions/{urn}/...)
|
v
LinkedIn
Wired verbs (linkd/client.go): send / reply as comments on a post URN (POST /v2/socialActions/{urn}/comments); when LINKEDIN_AUTO_PUBLISH=true, send with a non-comment JID falls back to publishing a ugcPost. post (/v2/ugcPosts), like (/v2/socialActions/{urn}/likes), delete (DELETE /v2/ugcPosts/{urn} for own posts), repost (/v2/ugcPosts with referenceUgcPost), fetch_history (comments on a post URN). send_file, forward, quote, dislike, edit are 501-with-hint.
The edit hint exists because UGC edit requires the versioned /rest/posts PARTIAL_UPDATE flow, which is not wired. send_file needs the /assets registerUpload + binary PUT dance; same story.
linkd is a plain Go binary. It needs a reachable gated and a LinkedIn application with member-social scopes. linkd refreshes the access token automatically on 401 via the refresh token.
export ROUTER_URL=http://gated:8080
export CHANNEL_SECRET=$(grep ^CHANNEL_SECRET .env | cut -d= -f2)
export LISTEN_ADDR=:8080
export LINKEDIN_CLIENT_ID=...
export LINKEDIN_CLIENT_SECRET=...
export LINKEDIN_ACCESS_TOKEN=...
export LINKEDIN_REFRESH_TOKEN=...
export LINKEDIN_POLL_INTERVAL=300s
export LINKEDIN_AUTO_PUBLISH=false
./linkd
LinkedIn-side setup: register an app at linkedin.com/developers. Required scopes: r_liteprofile, w_member_social. Walk through the OAuth code flow once to mint the initial access + refresh tokens; copy them into env. Company-page posting and DM messaging both need partner approval and are intentionally out of scope.
GET /health returns 503 when the access token is expired and refresh fails.
linkd/README.md — verb table, scopes, file map.