AutomationFlowsAI & RAG › AI Blog Post Generator for Ghost CMS

AI Blog Post Generator for Ghost CMS

Original n8n title: Automated Blog Post Generation with Gpt-4 and Publishing to Ghost CMS

ByThomas @darkrangeholdings on n8n.io

🧠 Writes original, thought-provoking blog posts using AI 🕓 Runs every 12 hours automatically ✍️ Publishes directly to Ghost blog with title, tags, and SEO meta

Cron / scheduled trigger★★★★☆ complexityAI-powered8 nodesOpenAIHTTP Request
AI & RAG Trigger: Cron / scheduled Nodes: 8 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #5934 — we link there as the canonical source.

This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "ePvpXpyW3KKPjM4x",
  "name": "OpenAI->Ghost Blog",
  "tags": [],
  "nodes": [
    {
      "id": "d3434c5a-8579-47cf-ac05-a4cfef3fd3c4",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 12,
              "triggerAtMinute": 34
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "54953abf-38c2-4d1a-a4e2-13ee43a6e4db",
      "name": "OpenAI",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        220,
        0
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini-2025-04-14",
          "cachedResultName": "GPT-4.1-MINI-2025-04-14"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "Write a high-quality blog post on a creative or thought-provoking topic. The tone should be engaging and immersive. Length: 2\u20134 paragraphs.\n\nThen add a brief paragraph offering an alternative perspective or logical counterpoint.\n\nFinally, generate:\n- Blog post title\n- Meta description\n- 5 tags"
            }
          ]
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "63a4cf0d-1fdd-435c-a477-d6880590c42e",
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1040,
        0
      ],
      "parameters": {
        "url": "https://yourcustomurl.com/ghost/api/admin/posts/",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify($json) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "ghostAdminApi"
      },
      "credentials": {
        "ghostAdminApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4c460c9f-0074-4b9a-be5c-f0cfb8bae9bd",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        600,
        0
      ],
      "parameters": {
        "jsCode": "const content = $json.message.content;\n\n// Extract Blog Post Title\nconst titleMatch = content.match(/\\*\\*Blog Post Title:\\*\\*\\s*(.+)/i);\nconst title = titleMatch ? titleMatch[1].trim() : 'Untitled';\n\n// Extract Meta Description\nconst metaMatch = content.match(/\\*\\*Meta Description:\\*\\*\\s*(.+)/i);\nconst meta = metaMatch ? metaMatch[1].trim() : '';\n\n// Extract Tags\nconst tagsMatch = content.match(/\\*\\*Tags:\\*\\*\\s*(.+)/i);\nconst rawTags = tagsMatch ? tagsMatch[1] : '';\nconst tags = rawTags.split(',').map(t => t.trim()).filter(t => t);\n\n// Strip metadata from the body\nconst body = content\n  .split('\\n\\n')\n  .filter(p => !/\\*\\*Blog Post Title:\\*\\*/i.test(p) && !/\\*\\*Meta Description:\\*\\*/i.test(p) && !/\\*\\*Tags:\\*\\*/i.test(p))\n  .join('\\n\\n');\n\n// Wrap in clean HTML\nconst html = `<div style=\"text-align:center; white-space:pre-line;\">${body.trim()}</div>`;\n\n// Return Ghost-compatible JSON\nreturn [\n  {\n    json: {\n      title,\n      html,\n      status: 'published',\n      tags,\n      meta_description: meta\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "cb384074-daf5-4945-adf6-40657498493d",
      "name": "Code1",
      "type": "n8n-nodes-base.code",
      "position": [
        820,
        0
      ],
      "parameters": {
        "jsCode": "const title = $json.title;\nconst status = $json.status || 'published';\nconst tags = ($json.tags || []).map(tag => ({ name: tag }));\n\n// Already wrapped with styling and line breaks \u2014 use as-is\nconst htmlContent = $json.html;\n\nconst mobiledoc = JSON.stringify({\n  version: '0.3.1',\n  atoms: [],\n  cards: [['html', { html: htmlContent }]],\n  markups: [],\n  sections: [[10, 0]]\n});\n\nreturn [\n  {\n    posts: [\n      {\n        title,\n        mobiledoc,\n        status,\n        tags\n      }\n    ]\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "59c2276c-1ea7-4c95-929f-4fd894289909",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -180,
        -180
      ],
      "parameters": {
        "width": 280,
        "height": 140,
        "content": "\ud83d\ude80 This workflow runs every 12 hours and creates a blog post using OpenAI."
      },
      "typeVersion": 1
    },
    {
      "id": "842d8b2e-bc1c-43cd-9555-9117f1bdc5e1",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        220,
        -200
      ],
      "parameters": {
        "content": "\u270d\ufe0f The AI generates content + metadata (title, tags, meta desc)."
      },
      "typeVersion": 1
    },
    {
      "id": "19550cb9-26ed-4aae-b17c-1d9e2a46db2a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        -240
      ],
      "parameters": {
        "content": "\ud83d\udce4 Posts are sent to your Ghost CMS via authenticated API."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "d05670de-d0e0-4dfe-9338-2c219515e6d4",
  "connections": {
    "Code": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "OpenAI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

🧠 Writes original, thought-provoking blog posts using AI 🕓 Runs every 12 hours automatically ✍️ Publishes directly to Ghost blog with title, tags, and SEO meta

Source: https://n8n.io/workflows/5934/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets

Google Sheets, XML, HTTP Request +3
AI & RAG

Overview This is a production-grade, fully automated stock analysis system built entirely in n8n. It combines institutional-level financial analysis, dual AI model consensus, and a self-improving back

Google Sheets, XML, HTTP Request +3
AI & RAG

This automation is a complete end-to-end system designed to find, qualify, and contact B2B leads — fully automated and powered by AI. Searches for target companies on LinkedIn via Ghost Genius API, us

Google Sheets, HTTP Request, OpenAI +1
AI & RAG

This comprehensive n8n automation template orchestrates a complete end-to-end workflow for generating engaging short-form Point-of-View (POV) style videos using multiple AI services and automatically

HTTP Request, OpenAI, Google Drive +4
AI & RAG

A professional AI equity analysis automation built on n8n that transforms structured financial data and real-time news into disciplined, risk-adjusted price targets and actionable BUY/HOLD/SELL signal

Google Sheets, OpenAI, XML +3