|

n8n Content Pipeline: From Topic Idea to WordPress Draft Automatically

The most valuable thing you can do with an n8n content pipeline is eliminate the part of content creation that costs you the most time — going from a topic idea to a publishable draft. Not the thinking. Not the strategy. The actual writing, structuring, and formatting that turns an idea into something WordPress can render. This guide walks you through building a pipeline that does exactly that, triggered by a single click in a Google Sheet.

This is System 03 from The Automation Playbook. It’s a deliberately simplified version of the pipeline powering alexanderharte.com — stripped of the proprietary research layer and image generation, but fully functional for solopreneurs who want to go from topic to draft without writing a single paragraph manually.

What you get at the end: a Google Sheet as your content command centre, an n8n workflow that generates an outline, writes the full article in HTML, produces SEO metadata, and pushes a draft to WordPress — all triggered from a custom menu in your spreadsheet.

Build time: 60–90 minutes. Then every article in your queue takes under 10 minutes of your active time.


What You’ll Build

  • A Google Sheet tracker with a custom App Script menu that fires the pipeline on demand
  • An n8n webhook that receives the article brief from the sheet
  • A Claude AI outline generator that structures the article before writing begins
  • A full article writer using Claude — HTML-formatted, SEO-optimised, in your brand voice
  • An automatic SEO metadata generator (title, meta description, URL slug)
  • A WordPress REST API node that creates the post as a draft — never published automatically
  • A status writeback to your Google Sheet confirming the draft is ready and linking to it

Every post stays as a draft until you review it. The pipeline does the writing — you do the editing, add the screenshots, set the featured image, and hit publish.


Why This n8n Content Pipeline Stack Works

Three tools, three jobs. n8n orchestrates the data flow — receiving the brief, routing it through Claude, parsing the outputs, and pushing to WordPress. Claude does the writing — outline first, then full article, then metadata, each as a separate API call so the context stays clean. Google Sheets acts as the interface — a familiar, zero-friction place to manage your content queue without logging into n8n every time you want to run a job.

The Google Apps Script custom menu is what makes this feel like a proper tool rather than a developer project. You add a topic to the sheet, select the row, click a menu item, and walk away. The draft is in WordPress within a few minutes.

This n8n content pipeline deliberately skips Perplexity, Google Docs research storage, and AI image generation. Those are the layers that make the production version powerful — and proprietary. What’s here is enough to produce solid, publishable first drafts that need a human review pass, not a complete rewrite.


System Overview

StepToolWhat Happens
1. TriggerGoogle Sheets + App ScriptSelect a row and click the Content Pipeline menu. App Script sends the row data to your n8n webhook.
2. Extract fieldsn8n Set nodeTopic, target keyword, tone of voice, and notes are extracted from the webhook payload.
3. Generate outlineClaude API (n8n HTTP Request)Claude generates a structured outline with H2s, H3s, and section briefs based on your topic and keyword.
4. Save outlineGoogle SheetsThe outline is written back to the Article Outline column. Status updates to Outline Ready.
5. Write articleClaude API (n8n HTTP Request)Claude writes the full article in HTML using the outline. Keyword-optimised, in your brand voice.
6. Generate metadataClaude API (n8n HTTP Request)Claude generates the SEO title, meta description, and URL slug as a JSON object.
7. Push to WordPressn8n WordPress nodeThe draft post is created in WordPress with the title, content, and slug. Status: Draft.
8. Update sheetGoogle SheetsStatus updates to Draft Ready. The WordPress draft URL is written to the Article Link column.

n8n content pipeline
Full n8n workflow canvas, all nodes connected The complete n8n content pipeline. Eleven nodes from webhook trigger to pipeline complete — Google Sheets fires the brief, Claude handles the writing in three separate calls, and WordPress receives the finished draft automatically.

Before You Start: What You Need

  • A self-hosted or cloud n8n instance (self-hosted on AWS Lightsail or similar recommended)
  • An Anthropic API account with credits loaded — get one at console.anthropic.com
  • A Google account with access to Google Sheets and Google Cloud Console
  • A WordPress site with admin access (self-hosted WordPress.org, not WordPress.com)
  • 60–90 minutes

Important — Anthropic billing: The API uses a prepaid credit system. Your API key will not process requests until you have loaded credits in your account. Go to Plans & Billing in the Anthropic Console and add a payment method before testing. A full article run costs roughly $0.03–0.05 in API credits at current Claude Sonnet pricing.


Step-by-Step Build Guide

Step 1: Set Up Your Google Sheet Tracker

The tracker is your content command centre. Download the template from this guide and upload it to Google Drive, or create a new sheet with these columns in row 1:

Title / Topic | Target Keyword | Tone of Voice | Notes | Status | Article Outline | Article Link | Date Added

The first four columns are inputs you fill in manually. The last four are outputs the pipeline fills automatically. Status uses a dropdown with options: Pending, Outline Ready, Draft Ready, and Published.

Fill in a test row before setting up the App Script — something real you actually want to write. The pipeline uses your topic and keyword directly in Claude’s prompts, so a vague test entry produces a vague output.

Google Sheet tracker with headers and a sample row The content tracker. Fill in the first four columns — topic, keyword, tone, and notes — and the pipeline fills the rest. Status, outline, and the WordPress draft link all write back automatically.

Step 2: Add the App Script

In your Google Sheet, go to Extensions → Apps Script. Delete any existing code and paste the following:

const WEBHOOK_URL = "https://your-n8n-domain/webhook/content-pipeline";
const SHEET_NAME = "Articles";
const HEADER_ROW = 1;

function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Content Pipeline')
    .addItem('Run Selected Row', 'sendSelectedRow')
    .addToUi();
}

function sendSelectedRow() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const row = sheet.getActiveRange().getRow();
  if (row <= HEADER_ROW) {
    SpreadsheetApp.getUi().alert('Select a data row first');
    return;
  }
  const lastCol = sheet.getLastColumn();
  const headers = sheet.getRange(HEADER_ROW, 1, 1, lastCol).getValues()[0];
  const rowData = sheet.getRange(row, 1, 1, lastCol).getValues()[0];
  const record = {};
  headers.forEach((h, i) => { if (h) record[h] = rowData[i]; });
  const payload = { rowNumber: row, data: record };
  UrlFetchApp.fetch(WEBHOOK_URL, {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(payload),
    muteHttpExceptions: true
  });
  SpreadsheetApp.getUi().alert('Row ' + row + ' sent to pipeline');
}

Replace https://your-n8n-domain/webhook/content-pipeline with your actual n8n webhook URL — you’ll get this in Step 3. Save the script (Ctrl+S / Cmd+S) and close the Apps Script editor. Refresh your Google Sheet and the Content Pipeline menu will appear in the top menu bar.

Step 3: Build the n8n Workflow

Create a new workflow in n8n. The full workflow is available to import — see the download link at the bottom of this post. If you’re building manually, here are the eleven nodes in sequence.

Node 1 — Webhook (trigger)

Add a Webhook node. Set the HTTP method to POST. Set the path to content-pipeline. Set Response Mode to When Last Node Finishes. Once saved, n8n shows you two URLs — a Test URL and a Production URL. Copy the Test URL and paste it into your App Script as the WEBHOOK_URL value. Switch to the Production URL after activating the workflow for live use.

Node 2 — Set Article Fields

Add a Set node. Create five fields mapping from the webhook payload:

  • topic{{ $json.body.data['Title / Topic'] }}
  • target_keyword{{ $json.body.data['Target Keyword'] }}
  • tone{{ $json.body.data['Tone of Voice'] || 'Direct, practical, no fluff.' }}
  • notes{{ $json.body.data.Notes || '' }}
  • rowNumber{{ $json.body.rowNumber }}

Node 3 — Generate Outline (HTTP Request → Anthropic API)

Add an HTTP Request node. This is your first Claude call. Configure it:

  • Method: POST
  • URL: https://api.anthropic.com/v1/messages
  • Authentication: Predefined credential type → Anthropic API
  • Headers: anthropic-version: 2023-06-01 and content-type: application/json

Body (raw JSON):

={
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 1000,
  "messages": [{
    "role": "user",
    "content": "Create a detailed article outline.\n\nTopic: {{ $json.topic }}\nTarget Keyword: {{ $json.target_keyword }}\nTone: {{ $json.tone }}\nNotes: {{ $json.notes }}\n\nReturn ONLY the outline — no commentary. Use this format:\n\n# [Title including keyword]\n\n## [H2 Section]\n- Key point\n- Key point\n\nInclude 5-7 H2 sections, an intro, FAQ, and conclusion."
  }]
}

Node 4 — Extract Outline (Code node)

Add a Code node to parse Claude’s response and pass the outline forward alongside the original fields:

const outline = $input.first().json.content[0].text;
return [{
  json: {
    topic: $('Set Article Fields').first().json.topic,
    target_keyword: $('Set Article Fields').first().json.target_keyword,
    tone: $('Set Article Fields').first().json.tone,
    notes: $('Set Article Fields').first().json.notes,
    rowNumber: $('Set Article Fields').first().json.rowNumber,
    outline: outline
  }
}];

Node 5 — Save Outline to Sheet (Google Sheets node)

Add a Google Sheets node. Set operation to Update. Connect your Google credential (setup covered in the credentials section below). Set the Document ID to your sheet URL and Sheet Name to Articles. Map Article Outline to {{ $json.outline }} and Status to the string Outline Ready. Use the row number from {{ $json.rowNumber }} to target the correct row.

Node 6 — Write Article (HTTP Request → Anthropic API)

Add a second HTTP Request node with the same Anthropic credential. This is the main article generation call — increase max_tokens to 8000:

={
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 8000,
  "messages": [{
    "role": "user",
    "content": "Write a complete, SEO-optimised blog article based on this outline.\n\nTopic: {{ $json.topic }}\nTarget Keyword: {{ $json.target_keyword }}\nTone: {{ $json.tone }}\nOutline:\n{{ $json.outline }}\n\nRequirements:\n- HTML format: h2, h3, p, ul, ol tags\n- Include keyword in first paragraph and at least one H2\n- 150-300 words per section minimum\n- No H1 tag — set separately\n- Return raw HTML only — no markdown, no backticks\n- End with a short conclusion and CTA"
  }]
}

Node 7 — Generate Metadata (HTTP Request → Anthropic API)

Add a third HTTP Request node. This call generates your SEO fields as a JSON object:

={
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 400,
  "messages": [{
    "role": "user",
    "content": "Generate SEO metadata. Topic: {{ $('Extract Outline').first().json.topic }}. Keyword: {{ $('Extract Outline').first().json.target_keyword }}.\n\nReturn ONLY valid JSON:\n{\n  \"seo_title\": \"[Under 60 chars, includes keyword, positive/negative sentiment word]\",\n  \"meta_description\": \"[Under 155 chars, includes keyword, action-oriented]\",\n  \"slug\": \"[lowercase-hyphenated]\"\n}"
  }]
}

Node 8 — Parse and Assemble (Code node)

Add a Code node to parse the metadata JSON and assemble the final payload:

const articleBody = $('Write Article').first().json.content[0].text;
const metaRaw = $input.first().json.content[0].text;

let meta;
try {
  meta = JSON.parse(metaRaw);
} catch(e) {
  const match = metaRaw.match(/```json?\n?([\s\S]*?)```/);
  if (match) { meta = JSON.parse(match[1]); }
  else { throw new Error('Could not parse metadata: ' + metaRaw.substring(0, 200)); }
}

const outline = $('Extract Outline').first().json;
return [{
  json: {
    title: meta.seo_title,
    slug: meta.slug,
    meta_description: meta.meta_description,
    content: articleBody,
    rowNumber: outline.rowNumber
  }
}];

Node 9 — Create WordPress Draft (WordPress node)

Add a WordPress node. Connect your WordPress credential (setup below). Set Resource to Post, Operation to Create. Map Title to {{ $json.title }}, Content to {{ $json.content }}, Status to Draft, and Slug to {{ $json.slug }}.

Nodes 10 and 11 — Update Sheet and Pipeline Complete

Add a second Google Sheets node to write the status back. Map Status to Draft Ready and Article Link to {{ $json.link }} — the WordPress draft URL returned by the previous node. Finish with a No Operation node as a clean termination point.

Generate Outline HTTP Request node open, showing Anthropic credential and prompt The Generate Outline node. The Anthropic credential is selected at the top, and the prompt maps the topic and keyword from the Set Article Fields node dynamically using n8n expressions.

Step 4: Connect Your Credentials

There are three credential types to configure. Do these in order — Anthropic first, then Google, then WordPress.

Anthropic API credential

Go to console.anthropic.com and sign up or log in. Once inside:

  1. Click API Keys in the left sidebar
  2. Click + Create Key in the top right
  3. Give it a descriptive name — something like n8n-content-pipeline
  4. Click Create Key — copy the key immediately. Anthropic shows it only once
  5. Go to Plans & Billing and add a payment method if you haven’t already — the API won’t process requests without loaded credits

In n8n, go to Settings → Credentials → Add Credential. Search for Anthropic and select it. Paste your API key and save. Name it Anthropic SEO API to match the workflow nodes. All three Claude nodes use this same credential.

Anthropic Console API Keys section, Create Key button visible, no actual keys shown The Anthropic Console API Keys section. Click + Create Key, name it something recognisable like n8n-content-pipeline, and copy the key immediately — it’s shown only once.

Google Sheets credential (self-hosted n8n)

n8n Cloud users: You can skip the Google Cloud Console steps entirely. In the Google Sheets node, select the credential dropdown, choose Create new credential, and click Sign in with Google. The Managed OAuth2 flow handles everything. Self-hosted users need to follow the full process below.

For self-hosted n8n, you need to create a Google Cloud project and OAuth credentials:

  1. Go to console.cloud.google.com and create a new project — name it something like n8n-automation
  2. With the project selected, go to APIs & Services → Library. Search for Google Sheets API and enable it
  3. Go to APIs & Services → OAuth consent screen. Choose External. Fill in the app name and your email, then save
  4. Under the Audience tab, add your Google email address as a Test User
  5. Go to APIs & Services → Credentials → + Create credentials → OAuth client ID
  6. Application type: Web application. Under Authorised redirect URIs, paste your n8n OAuth callback URL — find this in n8n under Settings → Credentials when creating a new Google Sheets credential
  7. Click Create. Copy the Client ID and Client Secret — the Client Secret is shown only once

Back in n8n, go to Settings → Credentials → Add Credential. Search for Google Sheets OAuth2 API. Paste the Client ID and Client Secret. Click Sign in with Google and complete the OAuth flow. You may see a “Google hasn’t verified this app” warning — this is normal for personal projects. Click Continue to proceed.

Important: You only need to create one Google Cloud OAuth credential. It can be reused for Google Sheets, Google Drive, Google Docs, and other Google nodes in n8n from the same project.

WordPress credential

WordPress uses Application Passwords for API authentication — a 24-character key that authorises external tools like n8n without exposing your main admin password. This is available on any self-hosted WordPress.org install running WordPress 5.6 or later.

  1. Log into your WordPress admin dashboard
  2. Go to Users → Profile (or Users → All Users → edit your admin user)
  3. Scroll to the bottom of the profile page to the Application Passwords section
  4. Type a name for the password — something like n8n Content Pipeline
  5. Click Add New Application Password
  6. Copy the password immediately — WordPress shows it once. Remove the spaces before using it in n8n

In n8n, go to Settings → Credentials → Add Credential. Search for WordPress. Enter your WordPress site URL (including https://), your WordPress username, and the application password you just generated. Click Test to verify the connection before saving.

WordPress Application Passwords section in admin profile, Add New input visible The WordPress Application Passwords section, found at the bottom of your user profile. Name it n8n Content Pipeline, generate the password, and remove the spaces before pasting it into n8n.

Step 5: Test the Full Pipeline

Before activating, run a complete end-to-end test:

  1. In n8n, open the workflow and click Test workflow at the bottom — this activates the Test URL for your webhook
  2. Go to your Google Sheet, select a row with a real topic filled in
  3. Click Content Pipeline → Run Selected Row
  4. Switch back to n8n and watch the execution — each node should turn green in sequence
  5. Check your Google Sheet — the Article Outline column should be populated and Status should show Outline Ready, then update to Draft Ready
  6. Check WordPress — the draft post should be visible under Posts → Drafts

If any node fails, click it in the execution panel to see the error. The most common failure points are credential issues on the Google Sheets nodes (wrong sheet ID or OAuth not connected) and the WordPress node (application password contains spaces — remove them).

Once the test passes, activate the workflow using the toggle in the top right. Update the App Script WEBHOOK_URL to use the Production URL instead of the Test URL. You’re live.

n8n execution panel all nodes green, WordPress node selected showing draft URL A successful end-to-end test run. All nodes green, the WordPress draft URL visible in the Create WordPress Draft output — copy it into your browser to confirm the draft landed correctly.

Troubleshooting: Common Problems and Fixes

App Script menu doesn’t appear after saving

Refresh the Google Sheet — the onOpen trigger only runs when the sheet opens. If it still doesn’t appear, go to Extensions → Apps Script, click Run on the onOpen function manually, and grant the required permissions when prompted.

n8n webhook receives the payload but field values are empty

The column name in the App Script payload must match exactly what’s in the Set Article Fields node expression. Check for trailing spaces, capitalisation differences, or special characters in your column headers. If your header is Title / Topic, the expression must be $json.body.data['Title / Topic'] — not $json.body.data.Title.

Claude returns an error or the Code node fails to parse

Open the HTTP Request node that called Claude and check the output. If the response code is 401, your Anthropic credential is invalid — regenerate the key. If the response code is 529 or 529, you have no credits loaded in your Anthropic account. If Claude returned valid content but the Code node failed, it likely wrapped the JSON in markdown fences — the fallback parser in the code handles this, so check the actual error message for what went wrong.

Google Sheets node fails with “access denied” or 403

For self-hosted n8n: your Google email isn’t added as a Test User in the OAuth consent screen. Go to Google Cloud Console → APIs & Services → OAuth consent screen → Audience tab → Add your email under Test Users. For n8n Cloud: re-authorise the credential by clicking Sign in with Google again — tokens expire after 7 days for apps in Testing status.

WordPress credential test fails

The most common cause is spaces in the application password. WordPress generates the password in groups of four separated by spaces — remove all spaces before pasting into n8n. Also confirm your WordPress site URL includes https:// and does not have a trailing slash.

Draft created in WordPress but Article Link is blank in the sheet

The Update Sheet Status node maps {{ $json.link }} to the Article Link column. The WordPress node returns the post URL as link in its output — check the node output in the execution panel to confirm the field name. If WordPress returned the URL under a different key, update the mapping accordingly.


Taking This Further

  • Add a review gate. The outline is saved to your sheet before the article is written. If you want to review and edit the outline before Claude writes the full article, split the workflow into two — one that generates and saves the outline, and a second triggered separately that reads the outline from the sheet and writes the article. This gives you editorial control at the outline stage.
  • Customise the voice prompt. The article writing prompt currently says “direct, practical, no fluff.” Replace this with a detailed description of your brand voice — sentence length preferences, words to avoid, structural patterns you always use. The more specific you are, the closer the first draft gets to publishable.
  • Add RankMath schema data. Once the WordPress draft is created, an additional HTTP Request node can call the WordPress REST API to set RankMath focus keyword and meta description via custom fields — eliminating the manual RankMath setup step entirely.
  • Queue multiple articles at once. The App Script Send All Rows function from the full template can fire every Pending row in sequence. Add a delay between calls to avoid hitting Anthropic rate limits on back-to-back requests.

What This Actually Costs You

ToolCostNotes
n8n (self-hosted)~$5–10/monthAWS Lightsail or similar. n8n Cloud starts at $20/month if you prefer managed.
Claude API (Anthropic)~$0.03–0.05 per articleThree API calls per run — outline, article, metadata. Claude Sonnet pricing as of March 2026.
Google SheetsFreeStandard Google account. No Workspace subscription required.
WordPressYour existing hostingNo plugins required. Uses the built-in REST API available in all WordPress 5.6+ installs.
Your time60–90 min setupThen under 10 minutes per article — review, images, featured image, publish.

At two articles per week, the API cost is under $5 per month. The time saving — from 3–4 hours per article to under 10 minutes of active work — is the real number that matters.


Ready to Build It?

If you haven’t worked through System 01 or System 02 yet, start there. System 01 builds your lead capture funnel. System 02 automatically distributes every post you publish to Facebook and Instagram. This pipeline generates the posts — the other two systems capture and amplify them.

System 04 is next: the AI Brand Asset Generator — using fal.ai’s API to produce on-brand visual assets on demand, no designer, no GPU management, no monthly SaaS fees.


Affiliate disclosure: Some links in this post may be affiliate links. If you sign up or purchase through my link, I may earn a small commission at no extra cost to you. I only recommend tools I actually use in my own stack.


Alex Harte | alexanderharte.com

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *