{"slug": "stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built", "title": "Stop Writing LinkedIn Posts by Hand - Here's the n8n Workflow I Built", "summary": "A developer built an n8n workflow that automates LinkedIn post creation using Google Gemini for caption and hashtag generation and DALL·E for image creation. The workflow includes a schedule trigger, optional topic input from Google Sheets, an approval gate via Slack or email, and logging of all posts. The developer warns about LinkedIn API rate limits and provides a free downloadable JSON of the workflow.", "body_md": "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.\n\nThis 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.\n\nThere's also a free downloadable JSON at the end.\n\nPosting consistently on LinkedIn requires repeating the same cycle every few days:\n\nEach 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.\n\nThe 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.\n\n```\n┌─────────────────────────────────────────────────┐\n│              n8n Workflow                        │\n│                                                 │\n│  [Schedule Trigger]                             │\n│       ↓                                         │\n│  [Google Sheets] ← Topic list (optional)        │\n│       ↓                                         │\n│  [Gemini API] → caption + hashtags              │\n│       ↓                                         │\n│  [Prompt Builder] → constructs image prompt     │\n│       ↓                                         │\n│  [DALL·E API] → image URL                       │\n│       ↓                                         │\n│  [IF node] → publish directly OR send for review│\n│       ↓                   ↓                     │\n│  [LinkedIn API]     [Slack / Email]             │\n│       ↓                                         │\n│  [Google Sheets] → log post                     │\n└─────────────────────────────────────────────────┘\n```\n\n| Tool | Purpose |\n|---|---|\n| n8n | Workflow orchestration |\n| Google Gemini API | Caption and hashtag generation |\n| OpenAI DALL·E API | Image generation |\n| LinkedIn API (OAuth) | Publishing to company page |\n| Google Sheets | Topic input + post logging |\n| Slack / Email | Approval gate (optional) |\n\nStandard n8n Cron node. Set your posting frequency here - Monday/Wednesday/Friday at 9am is a reasonable starting cadence.\n\n**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.\n\nThis is where most workflows underperform. Feeding Gemini nothing but a bare topic produces generic output.\n\n**Option A: Static prompt template inside n8n**\n\nInclude these elements in your prompt:\n\n**Option B: Google Sheets topic list (recommended for production)**\n\nSet up a Sheet with columns: `Topic`\n\n, `Status`\n\n, `Posted Date`\n\n. The workflow reads the next row where `Status = pending`\n\n, uses that topic, and marks it `published`\n\nafter a successful run.\n\nThis lets you plan content without touching the workflow configuration.\n\nThe Gemini node receives the topic and your prompt template and returns a complete LinkedIn caption.\n\n**Example prompt structure:**\n\n```\nYou are writing a LinkedIn post for [Company Name], a [industry] company.\nTarget audience: [description]\nTone: [conversational / thought-leadership / technical]\nPost structure:\n- Hook (first line, max 15 words, must make the reader stop scrolling)\n- Body (3–4 lines, one key insight or perspective)\n- CTA (1 line, low friction)\n- Hashtags: 4–5, mix of broad and niche\n\nTopic: {{topic}}\n\nReturn only the post text. No labels, no preamble.\n```\n\nThe output from this node is stored as `{{ $json.caption }}`\n\nand also used to build the image prompt in the next step.\n\nDon't pass the raw caption directly to DALL·E. Extract the core concept and frame it as a visual description.\n\n``` js\n// Function node\nconst caption = $input.first().json.caption;\n\n// Extract first sentence as the concept anchor\nconst concept = caption.split('.')[0].replace(/[^a-zA-Z0-9 ]/g, '').trim();\n\nconst imagePrompt = `Clean flat-design illustration representing: ${concept}. \nProfessional color palette (blues and grays), minimal background, \nno text in image, modern B2B tech aesthetic.`;\n\nreturn [{ json: { imagePrompt } }];\n```\n\nTweak the style descriptor to match your brand. If you use a specific color palette, reference it here.\n\nPass `{{ $json.imagePrompt }}`\n\nto the OpenAI node configured for DALL·E. Use `dall-e-3`\n\nfor better quality. `1024x1024`\n\nworks well for LinkedIn.\n\nStore the returned image URL as `{{ $json.imageUrl }}`\n\n.\n\n**This is the step most tutorials skip. Don't skip it.**\n\nAdd an IF node after image generation. The condition can be:\n\nFor the Slack path, the notification should include:\n\nA rejected post should either flag for manual editing or trigger a regeneration with a modified prompt.\n\n**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.\n\nUse the LinkedIn node in n8n configured for the `ugcPosts`\n\nor `shares`\n\nendpoint (check which your account type supports).\n\nYou'll need:\n\n**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.\n\nEvery n8n workflow that runs on a schedule needs an error branch. Minimum viable error handling:\n\n```\nOn Error:\n  → Log error details to Google Sheets (timestamp, node, error message)\n  → Send Slack/email alert to the team\n  → Set post status to \"failed\" in topic tracker\n```\n\nSpecific failures to handle:\n\nBe honest with yourself about these limitations:\n\n**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.\n\n**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.\n\n**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.\n\nThe workflow removes the mechanical parts of content production. The judgment still belongs to a person.\n\nIT 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.\n\nImport it into any n8n instance (self-hosted or Cloud), add your API credentials, and you're running.\n\n👉 [Download the free n8n workflow JSON here](https://www.itpathsolutions.com/ai-linkedin-post-automation-gemini-dalle-n8n)\n\nThe full guide on that page also covers:\n\nThe template handles one brand, simple publishing, straightforward approval. It gets complicated when you need:\n\nFor those cases, [IT Path Solutions builds custom n8n workflows](https://www.itpathsolutions.com/contact-us) for B2B teams — including the API setup, prompt engineering, testing, and documentation.\n\nThe 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.\n\nIf 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.\n\nIf you want a production-ready version without the setup overhead, the full guide and a contact form are both at [itpathsolutions.com](https://www.itpathsolutions.com/ai-linkedin-post-automation-gemini-dalle-n8n).\n\n*Have you built a similar workflow? What broke first in production? Drop it in the comments.*", "url": "https://wpnews.pro/news/stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built", "canonical_source": "https://dev.to/mateo_ruiz_6992b1fce47843/stop-writing-linkedin-posts-by-hand-heres-the-n8n-workflow-i-built-5g17", "published_at": "2026-07-15 10:03:04+00:00", "updated_at": "2026-07-15 10:30:13.276867+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "generative-ai", "large-language-models", "ai-tools"], "entities": ["n8n", "Google Gemini", "OpenAI DALL·E", "LinkedIn", "Google Sheets", "Slack"], "alternates": {"html": "https://wpnews.pro/news/stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built", "markdown": "https://wpnews.pro/news/stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built.md", "text": "https://wpnews.pro/news/stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built.txt", "jsonld": "https://wpnews.pro/news/stop-writing-linkedin-posts-by-hand-here-s-the-n8n-workflow-i-built.jsonld"}}