DEV Community

Cover image for Stop Writing LinkedIn Posts by Hand - Here's the n8n Workflow I Built
Mateo Ruiz
Mateo Ruiz

Posted on

Stop Writing LinkedIn Posts by Hand - Here's the n8n Workflow I Built

If you're building automations with n8n, LinkedIn content is one of the more satisfying workflows to tackle because the manual version is genuinely painful at scale, and the automated version is actually possible to get right.

This post covers the full technical architecture of a LinkedIn post automation workflow using n8n + Google Gemini + DALL·E, including the parts most write-ups skip: prompt design, error handling, approval gates, and what the workflow can't do reliably.

There's also a free downloadable JSON at the end.

The Problem This Solves

Posting consistently on LinkedIn requires repeating the same cycle every few days:

  1. Come up with a topic
  2. Write a caption (with hook, body, hashtags)
  3. Find or create a matching image
  4. Review it
  5. Publish it

Each step is small. Together, they're a significant time sink especially for agencies managing multiple company pages, or small B2B teams where one person owns this alongside ten other priorities.

The workflow below automates steps 1–3 entirely, adds an optional review gate before step 5, and logs every run so you have a content record without any extra effort.

Architecture Overview

┌─────────────────────────────────────────────────┐
│              n8n Workflow                        │
│                                                 │
│  [Schedule Trigger]                             │
│       ↓                                         │
│  [Google Sheets] ← Topic list (optional)        │
│       ↓                                         │
│  [Gemini API] → caption + hashtags              │
│       ↓                                         │
│  [Prompt Builder] → constructs image prompt     │
│       ↓                                         │
│  [DALL·E API] → image URL                       │
│       ↓                                         │
│  [IF node] → publish directly OR send for review│
│       ↓                   ↓                     │
│  [LinkedIn API]     [Slack / Email]             │
│       ↓                                         │
│  [Google Sheets] → log post                     │
└─────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Tools Used

Tool Purpose
n8n Workflow orchestration
Google Gemini API Caption and hashtag generation
OpenAI DALL·E API Image generation
LinkedIn API (OAuth) Publishing to company page
Google Sheets Topic input + post logging
Slack / Email Approval gate (optional)

Node-by-Node Breakdown

1. Schedule Trigger

Standard n8n Cron node. Set your posting frequency here - Monday/Wednesday/Friday at 9am is a reasonable starting cadence.

Important: LinkedIn has API rate limits on automated publishing via the Organisation Share endpoint. Don't set this to run more aggressively than you actually need. Check LinkedIn's current API documentation before going live.

2. Topic Input

This is where most workflows underperform. Feeding Gemini nothing but a bare topic produces generic output.

Option A: Static prompt template inside n8n

Include these elements in your prompt:

  • Industry and target audience
  • Tone (conversational, thought-leadership, technical)
  • Post format (hook → 3-5 lines → CTA)
  • Hashtag strategy (count, categories to use or avoid)
  • 2–3 example posts for style reference

Option B: Google Sheets topic list (recommended for production)

Set up a Sheet with columns: Topic, Status, Posted Date. The workflow reads the next row where Status = pending, uses that topic, and marks it published after a successful run.

This lets you plan content without touching the workflow configuration.

3. Gemini Caption Generation

The Gemini node receives the topic and your prompt template and returns a complete LinkedIn caption.

Example prompt structure:

You are writing a LinkedIn post for [Company Name], a [industry] company.
Target audience: [description]
Tone: [conversational / thought-leadership / technical]
Post structure:
- Hook (first line, max 15 words, must make the reader stop scrolling)
- Body (3–4 lines, one key insight or perspective)
- CTA (1 line, low friction)
- Hashtags: 4–5, mix of broad and niche

Topic: {{topic}}

Return only the post text. No labels, no preamble.
Enter fullscreen mode Exit fullscreen mode

The output from this node is stored as {{ $json.caption }} and also used to build the image prompt in the next step.

4. Image Prompt Builder (Function Node)

Don't pass the raw caption directly to DALL·E. Extract the core concept and frame it as a visual description.

// Function node
const caption = $input.first().json.caption;

// Extract first sentence as the concept anchor
const concept = caption.split('.')[0].replace(/[^a-zA-Z0-9 ]/g, '').trim();

const imagePrompt = `Clean flat-design illustration representing: ${concept}. 
Professional color palette (blues and grays), minimal background, 
no text in image, modern B2B tech aesthetic.`;

return [{ json: { imagePrompt } }];
Enter fullscreen mode Exit fullscreen mode

Tweak the style descriptor to match your brand. If you use a specific color palette, reference it here.

5. DALL·E Image Generation

Pass {{ $json.imagePrompt }} to the OpenAI node configured for DALL·E. Use dall-e-3 for better quality. 1024x1024 works well for LinkedIn.

Store the returned image URL as {{ $json.imageUrl }}.

6. Approval Gate (IF Node + Slack/Email)

This is the step most tutorials skip. Don't skip it.

Add an IF node after image generation. The condition can be:

  • Always route to review (safest default)
  • Route to review if a keyword appears in the caption
  • Route directly to publish if confidence score meets threshold (advanced)

For the Slack path, the notification should include:

  • The full caption text
  • The generated image (as an attachment or URL)
  • An Approve / Reject button (using Slack's Block Kit)

A rejected post should either flag for manual editing or trigger a regeneration with a modified prompt.

For regulated industries (healthcare, fintech, legal): the approval gate is non-negotiable. Log the approver name, timestamp, and decision to your compliance record Google Sheets or a connected CRM works fine for this.

7. LinkedIn Publishing

Use the LinkedIn node in n8n configured for the ugcPosts or shares endpoint (check which your account type supports).

You'll need:

  • An OAuth connection to the company page
  • The caption text
  • The image URL (or upload the image via the LinkedIn media upload endpoint first)

Token expiry is the most common production issue. LinkedIn OAuth tokens expire periodically. Build an alert into your error-handling branch that fires when a 401 is returned, so someone refreshes the token before the next scheduled run fails silently.

8. Error Handling Branch

Every n8n workflow that runs on a schedule needs an error branch. Minimum viable error handling:

On Error:
  → Log error details to Google Sheets (timestamp, node, error message)
  → Send Slack/email alert to the team
  → Set post status to "failed" in topic tracker
Enter fullscreen mode Exit fullscreen mode

Specific failures to handle:

  • Gemini returns empty response → retry once, then alert
  • DALL·E timeout or content policy rejection → flag for manual image
  • LinkedIn 401 → alert team to refresh OAuth token
  • LinkedIn 429 (rate limit) → pause workflow, retry after delay

What This Workflow Can't Do

Be honest with yourself about these limitations:

It can't fact-check. Gemini will write confidently about things that may be inaccurate. If your industry involves claims that carry legal or compliance weight, the review gate isn't optional.

It can't evaluate brand nuance. It doesn't know you published a similar post last week, or that a particular phrase doesn't fit your voice, or that a topic is currently sensitive for your company.

It can't guarantee image relevance. DALL·E will always produce something, but something and the right image aren't the same thing. Budget for some review and occasional manual replacement.

The workflow removes the mechanical parts of content production. The judgment still belongs to a person.

Getting the Free Workflow JSON

IT Path Solutions has published the complete n8n workflow as a free download includes the Gemini node, DALL·E node, LinkedIn publish node, approval branch, and error-handling branch, all pre-connected.

Import it into any n8n instance (self-hosted or Cloud), add your API credentials, and you're running.

👉 Download the free n8n workflow JSON here

The full guide on that page also covers:

  • API credential setup (Gemini, DALL·E, LinkedIn OAuth)
  • Prompt customisation for different brand voices
  • Adding the Google Sheets topic and logging layer
  • Multi-page setup for agencies

When You Need a Custom Build

The template handles one brand, simple publishing, straightforward approval. It gets complicated when you need:

  • Multiple LinkedIn pages with separate prompts, topic pools, and approval chains
  • CRM integration — pulling content triggers from pipeline events, product launches, or customer milestones
  • Compliance logging — full audit trail with approver identity and timestamps
  • Performance feedback loop — pulling LinkedIn analytics and using engagement data to influence future prompts

For those cases, IT Path Solutions builds custom n8n workflows for B2B teams — including the API setup, prompt engineering, testing, and documentation.

Summary

The workflow is genuinely useful once the prompts are tuned and the approval gate is in place. The parts that make it reliable error handling, token refresh alerts, human review are also the parts that take the most setup time, which is why most implementations either skip them or struggle in production.

If you're building this yourself, start with the free template, add an approval gate before going live, and don't skip the error handling branch.

If you want a production-ready version without the setup overhead, the full guide and a contact form are both at itpathsolutions.com.

Have you built a similar workflow? What broke first in production? Drop it in the comments.

Top comments (0)