n8n Multi-Channel Social Publisher cover art
← downloads · 2026-04-20 · workflow

n8n Multi-Channel Social Publisher

One webhook call publishes a post to X, Bluesky, Threads, and LinkedIn, formatted per channel. The publish half of my content pipeline.

This is the publish side of my content pipeline. One webhook call fans a post out to whichever social channels you list in the request, formatting each one to that channel's own rules before it goes out.

How it works

A POST to /webhook/content-publish triggers it. A Set node pulls slug, channels, posts, and image_url off the request body, then IF branches check whether channels contains x, threads, bluesky, or linkedin and skip whichever aren't listed. Each enabled branch posts on its own:

  • X: goes through n8n's built-in Twitter node with a single text field. No image parameter is wired in this version, so an X post is text-only regardless of image_url.
  • Threads: a Code node that calls the Graph API directly: creates a media container, polls it for readiness (up to 6 attempts), then publishes.
  • Bluesky: a Code node that logs in, uploads an image blob if one's provided, and posts a full reply chain from posts.bluesky.thread, an array of strings rather than one block of text.
  • LinkedIn: a Code node that posts through the UGC Posts API using a personal access token and author URN. LinkedIn gates API posting access, so you need an approved app with the w_member_social scope.

A Merge node waits for all enabled branches, then Respond to Webhook returns { slug, results }, one result object per channel that ran.

The template wires four channels end-to-end: X, Bluesky, Threads, and LinkedIn. In my own running pipeline I post to LinkedIn by hand and keep Threads off, the setup the pipeline guide describes; the public template leaves all four wired so you can turn on whichever you have access to.

What you'll need

  • X (Twitter): an n8n credential, type OAuth2, created through the X Developer Portal with read and write access.
  • Threads: no n8n credential. The Code node reads THREADS_USER_ID and THREADS_ACCESS_TOKEN from n8n's instance Variables (Settings → Variables), sourced from the Meta Developer Portal.
  • Bluesky: same pattern, different variables: BSKY_HANDLE and BSKY_APP_PASSWORD, from an app password you generate at bsky.app → Settings → App passwords.
  • LinkedIn: variables again, LINKEDIN_ACCESS_TOKEN and LINKEDIN_AUTHOR_URN (e.g. urn:li:person:xxxx), from a LinkedIn Developer app with the w_member_social scope. LinkedIn gates posting access, so approval isn't instant.

The one credential placeholder in the imported JSON is REPLACE_WITH_TWITTEROAUTH2API_CREDENTIAL_ID on the X node. Swap it for your own credential, then set the Threads, Bluesky, and LinkedIn variables above before you activate the workflow.

Request shape

{
  "slug": "2026-05-22-eval-rubric",
  "channels": ["x", "threads", "bluesky", "linkedin"],
  "posts": {
    "x": { "text": "post text, 280 characters or under" },
    "threads": { "text": "post text" },
    "bluesky": { "thread": ["first post", "reply to the first post"] },
    "linkedin": { "text": "post text" }
  },
  "image_url": "https://example.com/cover.png"
}

image_url is shared across channels rather than per-post: Threads attaches it to the post, Bluesky attaches it to the first post in the thread. Leave a channel out of channels[] and its branch skips without an error.

How it fits

This is the publish half of the content pipeline behind this site; podcast intake is the companion workflow that fills the queue it empties.

> esc
$ keyboard_shortcuts.md esc

// navigation

  • ⌘K or ctrl+K — open command palette
  • ? — toggle this overlay
  • esc — close any overlay
  • / — jump to command palette input

// command palette

  • ↑ ↓ — navigate results
  • ↵ — select / navigate
  • type a tag like #agents — search by tag
  • type a service like workshop — find related pages

// 404 page

  • cd <path> — navigate
  • ls — list pages
  • help — show commands
  • clear — clear history

// agent swarm

  • click anywhere — spawn a task
  • drag a rectangle — dispatch a team
  • hover over a worker — see its model
based on conventions from cmd+k, vercel, linear, and most claude code workflows