AutomationFlowsAI & RAG › Automated Blog Creation From News to Publication Using Gemini, Ideogram & Slack

Automated Blog Creation From News to Publication Using Gemini, Ideogram & Slack

ByParag Javale @pollar-beer on n8n.io

The AI Blog Creator with Gemini, Replicate Image, Supabase Publishing & Slack is a fully automated content generation and publishing workflow designed for modern marketing and SaaS teams. It automatically fetches the latest industry trends, generates SEO-optimized blogs using…

Cron / scheduled trigger★★★★☆ complexityAI-powered25 nodesHTTP RequestSlackGoogle Gemini
AI & RAG Trigger: Cron / scheduled Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:
Automated Blog Creation From News to Publication Using Gemini, Ideogram & Slack — n8n workflow card showing HTTP Request, Slack, Google Gemini integration

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

This workflow follows the Googlegemini → HTTP Request 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": "EmPnnzwJEHxMuJaw",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Blog Creator with Gemini, Replicate Image, Supabase Publishing & Slack",
  "tags": [],
  "nodes": [
    {
      "id": "e45d33d9-2fc2-476c-b0ff-63d16b30111a",
      "name": "Fetch Industry Trends",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        224,
        -240
      ],
      "parameters": {
        "url": "https://newsapi.org/v2/everything?q=AI automation SaaS&sortBy=publishedAt&pageSize=10",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth"
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "2c641b4b-9ce0-472d-a970-714d6a630f0c",
      "name": "Publish to Supabase",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2496,
        -240
      ],
      "parameters": {
        "url": "https://your.supabase.co/functions/v1/blog-api",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "title",
              "value": "={{ $json.title }}"
            },
            {
              "name": "slug",
              "value": "={{ $json.slug }}"
            },
            {
              "name": "excerpt",
              "value": "={{ $json.excerpt }}"
            },
            {
              "name": "content",
              "value": "={{ $json.content }}"
            },
            {
              "name": "image_url",
              "value": "={{ $json.image_url }}"
            },
            {
              "name": "published",
              "value": "true"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "17fcce85-bdf1-4c21-848a-3ce667e3aab5",
      "name": "Slack Notification",
      "type": "n8n-nodes-base.slack",
      "position": [
        2720,
        -240
      ],
      "parameters": {
        "text": "=\u2705 *New Blog Published!*  \n*Title:* {{$json['title']}}  \n*Slug:* {{$json['slug']}}  \n*URL:* https://yoururl.com/blog/{{$json['slug']}}",
        "channel": "#blog-automation",
        "attachments": [],
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5ecb7538-6358-4d89-ac55-8e4539f8d42a",
      "name": "Message a model",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        448,
        -240
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Act as an AI market analyst. Based on these current trends and articles:\n\"{{ $json.articles }}\"\nGenerate 1 trending blog topic ideas relevant to SaaS, AI, Automation, and industry innovation that would benefit our company\u2019s brand authority.\nReturn them in strict JSON with fields: title, description, keywords.\nno exta text, details etc. give me direct json output without pre and post text.\n"
            }
          ]
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5da2d4ee-d7b0-441a-8523-067a17182c6a",
      "name": "Message a model1",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        800,
        -240
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are an expert SEO content strategist. Write a 1200\u20131500 word blog in Markdown on the topic:\n\"{{ $json.content.parts[0].text }}\"\n\nRequirements:\n- Use high-ranking keywords naturally.\n- Include an SEO title, meta description, and excerpt.\n- Use markdown headings, bullet points, and bold keywords.\n- Structure: Introduction \u2192 Insight \u2192 Case Studies \u2192 Conclusion \u2192 CTA.\nOutput JSON:\n{\n  \"title\": \"...\",\n  \"slug\": \"...\",\n  \"excerpt\": \"...\",\n  \"content\": \"...\",\n  \"keywords\": \"...\",\n  \"image_prompt\": \"...\"\n}\n"
            }
          ]
        }
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1369e40f-2008-4fb7-9123-d17b02a7d42d",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        1152,
        -240
      ],
      "parameters": {
        "jsCode": "// --- Ultra-Resilient Gemini Blog Cleaner ---\n// Works with Markdown fences, nested JSON, or plain text\n\nconst raw = $json.content?.parts?.[0]?.text || '';\nif (!raw) throw new Error('Gemini returned empty response.');\n\nlet text = raw.trim();\n\n// 1\ufe0f\u20e3 Strip Markdown fences and language hints\ntext = text\n  .replace(/```json/gi, '')\n  .replace(/```/g, '')\n  .replace(/^#+\\s+/gm, '')\n  .trim();\n\n// 2\ufe0f\u20e3 Find the innermost JSON block\nlet matches = text.match(/\\{[\\s\\S]*\\}/g);\nlet parsed = {};\n\nif (matches && matches.length) {\n  // pick the deepest block (most nested)\n  let jsonText = matches[matches.length - 1]\n    .replace(/\u201c|\u201d/g, '\"')\n    .replace(/\u2018|\u2019/g, \"'\")\n    .replace(/,\\s*([}\\]])/g, '$1')\n    .replace(/'/g, '\"')\n    .trim();\n\n  try {\n    parsed = JSON.parse(jsonText);\n  } catch (err) {\n    // attempt repair if invalid JSON\n    let repaired = jsonText.replace(/([{,]\\s*)([A-Za-z0-9_]+)\\s*:/g, '$1\"$2\":');\n    try {\n      parsed = JSON.parse(repaired);\n    } catch (err2) {\n      parsed = {};\n    }\n  }\n}\n\n// 3\ufe0f\u20e3 Regex fallback if still not parsed\nif (!parsed.title) {\n  parsed.title = text.match(/\"title\"\\s*:\\s*\"([^\"]+)\"/i)?.[1]\n    || text.match(/title\\s*[:\\-]\\s*(.+)/i)?.[1]?.trim()\n    || '';\n}\nif (!parsed.slug) {\n  parsed.slug = text.match(/\"slug\"\\s*:\\s*\"([^\"]+)\"/i)?.[1]\n    || text.match(/slug\\s*[:\\-]\\s*(.+)/i)?.[1]?.trim()\n    || '';\n}\nif (!parsed.excerpt) {\n  parsed.excerpt = text.match(/\"excerpt\"\\s*:\\s*\"([^\"]+)\"/i)?.[1]\n    || text.match(/excerpt\\s*[:\\-]\\s*(.+)/i)?.[1]?.trim()\n    || '';\n}\nif (!parsed.content) {\n  const contentMatch = text.match(/\"content\"\\s*:\\s*\"([\\s\\S]+)\"/i);\n  parsed.content = contentMatch\n    ? contentMatch[1]\n    : text.match(/content\\s*[:\\-]\\s*([\\s\\S]+)/i)?.[1]?.trim()\n    || '';\n}\nif (!parsed.keywords) {\n  parsed.keywords = text.match(/\"keywords\"\\s*:\\s*\"([^\"]+)\"/i)?.[1]\n    || text.match(/keywords?\\s*[:\\-]\\s*(.+)/i)?.[1]?.trim()\n    || '';\n}\nif (!parsed.image_prompt) {\n  parsed.image_prompt = text.match(/\"image_prompt\"\\s*:\\s*\"([^\"]+)\"/i)?.[1]\n    || text.match(/image[_\\s]?prompt\\s*[:\\-]\\s*(.+)/i)?.[1]?.trim()\n    || '';\n}\n\n// 4\ufe0f\u20e3 Normalize and sanitize output\nparsed.title = parsed.title?.replace(/^[\"']|[\"']$/g, '') || 'Untitled Blog';\nparsed.slug =\n  parsed.slug ||\n  parsed.title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');\nparsed.excerpt = parsed.excerpt?.replace(/^[\"']|[\"']$/g, '') || parsed.content.slice(0, 160);\nparsed.content = parsed.content?.replace(/^[\"']|[\"']$/g, '') || '';\nparsed.keywords = parsed.keywords?.replace(/^[\"']|[\"']$/g, '') || '';\nparsed.image_prompt =\n  parsed.image_prompt?.replace(/^[\"']|[\"']$/g, '') || parsed.title;\n\n// 5\ufe0f\u20e3 Output ready-to-use normalized data\nreturn [parsed];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "02a8a518-fb7d-4f13-b72d-25dcbacfb033",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1824,
        -240
      ],
      "parameters": {
        "amount": 20
      },
      "typeVersion": 1.1
    },
    {
      "id": "e2f813a3-1808-44f7-9bae-842d8d6cecbc",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        2048,
        -240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "31dea76b-5ba5-464c-a85f-cac7facabdfb",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "=succeeded"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b300ab84-eeea-42ea-a609-6bff06da4846",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2272,
        -240
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"title\": \"{{ $('Code in JavaScript').item.json.title }}\",\n  \"slug\": \"{{ $('Code in JavaScript').item.json.slug }}\",\n  \"excerpt\": \"{{ $('Code in JavaScript').item.json.excerpt }}\",\n  \"content\": \"{{ $('Code in JavaScript').item.json.content }}\",\n  \"image_url\": \"{{ $json.output }}\",\n  \"published\": true\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "df01fb3f-d7dd-4d2b-9581-24df4472b3ea",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.cron",
      "position": [
        0,
        -240
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "hour": 10
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "03a19edc-7128-40d1-a936-7fa3bce230a2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -48
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 512,
        "content": "### \ud83c\udf10 **Fetch Industry Trends (HTTP Request \u2013 NewsAPI)**\n\n**Purpose:**\nFetches the latest 10 articles related to \u201cAI automation SaaS\u201d from NewsAPI.\nThese articles are used as context for generating trending blog topics.\n\n**Credentials Required:**\n\n* `NewsAPI` (Generic Query Auth) \u2014 Use your API key from [https://newsapi.org](https://newsapi.org).\n\n**Notes:**\n\n* You can modify the `q` parameter to match your industry (e.g., \u201cfinance AI,\u201d \u201chealthcare automation,\u201d etc.).\n* You can also adjust `pageSize` to fetch more or fewer results.\n* NewsAPI free tier allows 100 requests/day \u2014 plan accordingly if running multiple times.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dc40791a-0f73-45dd-8856-30d3ea8b88fe",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -672
      ],
      "parameters": {
        "color": 5,
        "width": 352,
        "height": 416,
        "content": "### \ud83e\udd16 **Message a model (Google Gemini)**\n\n**Purpose:**\nAsks Gemini to analyze current news trends and generate **1 trending blog topic** idea in JSON format (title, description, keywords).\n\n**Credentials Required:**\n\n* `Google Gemini (PaLM) API Key`\n\n**Notes:**\n\n* Returns strict JSON to make downstream parsing easier.\n* You can modify the prompt for your own industry context (e.g., \u201cBased on fintech trends\u2026\u201d).\n* Recommended model: `gemini-2.5-flash` for faster responses."
      },
      "typeVersion": 1
    },
    {
      "id": "b2863fad-0e3e-4f6d-a5e9-c083a37c7962",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        -48
      ],
      "parameters": {
        "color": 5,
        "width": 432,
        "height": 416,
        "content": "### \u270d\ufe0f **Message a model1 (Google Gemini)**\n\n**Purpose:**\nGenerates a full-length blog (1200\u20131500 words) on the selected topic, optimized for SEO and structured in Markdown.\n\n**Credentials Required:**\n\n* Same `Google Gemini (PaLM)` credential as above.\n\n**Notes:**\n\n* The prompt includes explicit instructions for SEO title, meta description, excerpt, and structured JSON output.\n* You can tune word length or format (e.g., shorter LinkedIn post version) by editing the prompt text.\n* Output is JSON, but sometimes Gemini may include Markdown or text noise \u2014 the next node handles cleanup."
      },
      "typeVersion": 1
    },
    {
      "id": "c024e432-6579-4846-bd85-3d1d6cc8c047",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -672
      ],
      "parameters": {
        "color": 3,
        "width": 400,
        "height": 416,
        "content": "### \ud83e\uddf9 **Code in JavaScript**\n\n**Purpose:**\nCleans, parses, and repairs any messy AI output to ensure consistent JSON fields (title, slug, excerpt, content, keywords, image_prompt).\n\n**Notes:**\n\n* This code is **resilient** against broken Markdown, mixed quotes, and malformed JSON.\n* It automatically normalizes the slug, removes extra quotation marks, and trims long text.\n* If Gemini output fails to parse, it still produces fallback fields like `Untitled Blog`.\n* No credentials required.\n\n\ud83d\udca1 *You can safely modify this node if you add or remove output fields from the AI prompt.*"
      },
      "typeVersion": 1
    },
    {
      "id": "1792857d-0095-4aaf-93d3-3137a6f7c59d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -16
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 432,
        "content": "### \ud83d\uddbc\ufe0f **HTTP Request (Replicate \u2013 Generate Image)**\n\n**Purpose:**\nSends the `image_prompt` field to Replicate\u2019s **Ideogram v3 Turbo** model to generate a 1024\u00d71024 image.\n\n**Credentials Required:**\n\n* `Replicate Bearer YOUR_TOKEN_HERE` from [https://replicate.com/account](https://replicate.com/account)\n\n**Notes:**\n\n* Modify `width`/`height` for other image sizes.\n* You can swap model endpoint with any text-to-image API you prefer.\n* Returns a `prediction ID` and temporary URL for polling."
      },
      "typeVersion": 1
    },
    {
      "id": "35e16700-c40d-4e8b-abda-a55b193b7e1f",
      "name": "HTTP Request1 (Replicate Polling)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1600,
        -240
      ],
      "parameters": {
        "url": "={{ $json.urls.get }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6c7dfb6f-4f83-4d65-bea0-56c12a7b5393",
      "name": "HTTP Request (Replicate \u2013 Generate Image)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1376,
        -240
      ],
      "parameters": {
        "url": "https://api.replicate.com/v1/models/ideogram-ai/ideogram-v3-turbo/predictions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"input\": {\n    \"prompt\": \"{{ $json.image_prompt }}\",\n    \"width\": 1024,\n    \"height\": 1024\n  }\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9a54a8e9-938b-4e24-8f50-6681b64e53d7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1744,
        -32
      ],
      "parameters": {
        "width": 256,
        "height": 368,
        "content": "### \u23f1\ufe0f **Wait**\n\n**Purpose:**\nAdds a 20-second delay before rechecking Replicate\u2019s image status.\n\n**Notes:**\n\n* Replicate image generation takes ~10\u201320 seconds usually.\n* You can increase or decrease the wait time depending on your model speed.\n* Prevents rate-limit errors by spacing out API calls.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e4691aa3-b13b-447a-9a13-86787ecacac6",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        -656
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 400,
        "content": "### \u23f3 **HTTP Request1 (Replicate Polling)**\n\n**Purpose:**\nFetches the status of the image generation request from Replicate using the returned `prediction ID`.\n\n**Credentials Required:**\n\n* Same Replicate Bearer YOUR_TOKEN_HERE as above.\n\n**Notes:**\n\n* The polling is used in combination with the **Wait** and **If** nodes.\n* Returns `status` = `succeeded` once image is ready.\n* You can also extract error messages if the job fails."
      },
      "typeVersion": 1
    },
    {
      "id": "a363eaf7-f137-4977-aec6-e714d761f3ff",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1888,
        -592
      ],
      "parameters": {
        "width": 304,
        "height": 336,
        "content": "### \u2705 **If**\n\n**Purpose:**\nChecks if the Replicate image generation has **succeeded**.\n\n**Notes:**\n\n* If the status = \u201csucceeded,\u201d workflow proceeds to the next step.\n* If not, it loops back to **HTTP Request1** to poll again.\n* This ensures the workflow doesn\u2019t break while waiting for long image generations.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bdec9233-16ac-4054-b953-69e6351b9c50",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        -80
      ],
      "parameters": {
        "width": 304,
        "height": 352,
        "content": "### \ud83e\udde9 **Edit Fields (Set Node)**\n\n**Purpose:**\nCombines cleaned text and generated image URL into a final JSON payload for publishing.\n\n**Notes:**\n\n* Merges `title`, `slug`, `excerpt`, `content`, and `image_url` fields into one structured object.\n* Adds `\"published\": true` flag for Supabase insert.\n* You can add extra custom fields like `category` or `author` here easily.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f00d7334-5237-4b3c-ac73-d07164ad5ab7",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2272,
        -720
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 480,
        "content": "### \ud83d\ude80 **Publish to Supabase (HTTP Request)**\n\n**Purpose:**\nPublishes the final blog post to Supabase via your custom function endpoint.\n\n**Credentials Required:**\n\n* `Supabase Header Auth` (e.g., `Authorization: Bearer YOUR_TOKEN_HERE`)\n\n**Notes:**\n\n* The example endpoint is:\n\n  ```\n  https://your-project.supabase.co/functions/v1/blog-api\n  ```\n* Make sure your Supabase Edge Function expects JSON with the fields provided.\n* You can replace this with your own CMS (WordPress, Ghost, Webflow, etc.) API endpoint."
      },
      "typeVersion": 1
    },
    {
      "id": "5fe82ef4-24c2-46ae-b0de-e6986bcb3668",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        -80
      ],
      "parameters": {
        "color": 2,
        "width": 336,
        "height": 480,
        "content": "### \ud83d\udcac **Slack Notification**\n\n**Purpose:**\nNotifies your Slack channel with the published blog details.\n\n**Credentials Required:**\n\n* Slack API token (with `chat:write` permission).\n\n**Notes:**\n\n* Message includes blog title, slug, and URL (`https://utsltech.com/blog/{{slug}}`).\n* You can customize channel name and message formatting (supports Block Kit).\n* Great for instant visibility of published content.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b1208c9f-d79c-405a-8d1c-96d0a5ec7389",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -816
      ],
      "parameters": {
        "width": 480,
        "height": 336,
        "content": "## \ud83e\udde9 General Notes for Template\n\n* **All credentials** should be created before importing the workflow.\n* **Error handling:** This workflow includes a fallback for Gemini output; you can add a global error workflow for API failures.\n* **Customization:** You can easily extend the flow to auto-share to LinkedIn, Twitter, or email subscribers.\n* **Runtime:** Average runtime ~1\u20132 minutes depending on image generation time.\n* **Timezone:** Set to `Asia/Kolkata` by default \u2014 adjust if needed in workflow settings.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "13f542b7-566c-429d-ba5d-45a63b7fd801",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1040,
        -816
      ],
      "parameters": {
        "width": 784,
        "height": 1696,
        "content": "The **AI Blog Creator with Gemini, Replicate Image, Supabase Publishing & Slack** is a fully automated content generation and publishing workflow designed for modern marketing and SaaS teams.\nIt automatically fetches the latest industry trends, generates SEO-optimized blogs using AI, creates a relevant featured image, publishes the post to your CMS (e.g., Supabase or custom API), and notifies your team via Slack all on a daily schedule.\n\nThis workflow connects multiple services NewsAPI, Google Gemini, Replicate, Supabase, and Slack into one intelligent content pipeline that runs hands-free once set up.\n\n---\n\n### **\u2728 Features**\n\n* \ud83d\udcf0 **Fetch Trending Topics** \u2014 pulls the latest news or updates from your selected industry (via NewsAPI).\n* \ud83e\udd16 **AI Topic Generation** \u2014 Gemini suggests trending blog topics relevant to AI, SaaS, and Automation.\n* \ud83d\udcdd **AI Blog Authoring** \u2014 Gemini then writes a full 1200-1500 word SEO-optimized article in Markdown.\n* \ud83e\uddf9 **Smart JSON Cleaner** \u2014 A resilient code node parses Gemini\u2019s output and ensures clean, structured data.\n* \ud83d\uddbc\ufe0f **Auto-Generated Image** \u2014 Replicate\u2019s Ideogram model creates a blog cover image based on the content prompt.\n* \ud83c\udf10 **Automatic Publishing** \u2014 Posts are automatically published to your Supabase or custom backend.\n* \ud83d\udcac **Slack Notification** \u2014 Notifies your team with blog details and live URL.\n* \u23f0 **Fully Scheduled** \u2014 Runs automatically every day at your preferred time (default 10 AM IST).\n\n---\n\n### **\u2699\ufe0f Workflow Structure**\n\n| Step | Node                                | Purpose                                         |\n| ---- | ----------------------------------- | ----------------------------------------------- |\n| 1    | **Schedule Trigger**                | Runs daily at 10 AM                             |\n| 2    | **Fetch Industry Trends (NewsAPI)** | Retrieves trending articles                     |\n| 3    | **Message a model (Gemini)**        | Generates trending topic ideas                  |\n| 4    | **Message a model1 (Gemini)**       | Writes full SEO blog content                    |\n| 5    | **Code in JavaScript**              | Cleans, validates, and normalizes Gemini output |\n| 6    | **HTTP Request (Replicate)**        | Generates an image using Ideogram               |\n| 7    | **HTTP Request1**                   | Retrieves generated image URL                   |\n| 8    | **Wait + If**                       | Polls until image generation succeeds           |\n| 9    | **Edit Fields**                     | Assembles blog fields into final JSON           |\n| 10   | **Publish to Supabase**             | Posts to your CMS                               |\n| 11   | **Slack Notification**              | Sends message to your Slack channel             |\n\n---\n\n### **\ud83d\udd27 Setup Instructions**\n\n1. **Import the Workflow** in n8n and enable it.\n2. Create the following credentials:\n\n   * **NewsAPI (Query Auth)** \u2014 from [https://newsapi.org](https://newsapi.org)\n   * **Google Gemini (PaLM API)** \u2014 use your Gemini API key\n   * **Replicate (Bearer YOUR_TOKEN_HERE)** \u2014 API key from [https://replicate.com/account](https://replicate.com/account)\n   * **Supabase (Header Auth)** \u2014 endpoint to your `/functions/v1/blog-api` (set your key in header)\n   * **Slack API** \u2014 create a Slack App token with `chat:write` permission\n3. Edit the **NewsAPI URL** query parameter to match your industry (e.g., `q=AI automation SaaS`).\n4. Update the **Supabase publish URL** to your project endpoint if needed.\n5. Adjust the **Slack Channel** name under \u201cSlack Notification\u201d.\n6. (Optional) Change the **Schedule Trigger** time as per your timezone.\n\n---\n\n### **\ud83d\udca1 Notes & Tips**\n\n* The **Code in JavaScript** node is robust against malformed or extra text in Gemini output \u2014 it sanitizes Markdown and reconstructs clean JSON safely.\n* You can replace Supabase with any CMS or Webhook endpoint by editing the \u201cPublish to Supabase\u201d node.\n* The Replicate model used is `ideogram-ai/ideogram-v3-turbo` \u2014 you can swap it with Stable Diffusion or another model for different aesthetics.\n* Use the `slug` field in your blog URLs for SEO-friendly links.\n* Test with one manual execution before activating scheduled runs.\n* If Slack notification fails, verify the token scopes and channel permissions.\n\n"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "timezone": "Asia/Kolkata",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "EmPnnzwJEHxMuJaw",
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveDataErrorExecution": "all"
  },
  "versionId": "bc157604-a8a8-4745-a98d-d8b10da1b1ab",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "HTTP Request1 (Replicate Polling)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Publish to Supabase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model": {
      "main": [
        [
          {
            "node": "Message a model1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message a model1": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Fetch Industry Trends",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "HTTP Request (Replicate \u2013 Generate Image)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack Notification": {
      "main": [
        []
      ]
    },
    "Publish to Supabase": {
      "main": [
        [
          {
            "node": "Slack Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Industry Trends": {
      "main": [
        [
          {
            "node": "Message a model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1 (Replicate Polling)": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request (Replicate \u2013 Generate Image)": {
      "main": [
        [
          {
            "node": "HTTP Request1 (Replicate Polling)",
            "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

The AI Blog Creator with Gemini, Replicate Image, Supabase Publishing & Slack is a fully automated content generation and publishing workflow designed for modern marketing and SaaS teams. It automatically fetches the latest industry trends, generates SEO-optimized blogs using…

Source: https://n8n.io/workflows/9658/ — 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

Automatically monitors restaurant ratings on Google Places daily, detects meaningful changes, uses Google Gemini AI to diagnose the root cause from real customer reviews, and delivers smart alerts to

Google Sheets, HTTP Request, Google Gemini +1
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 workflow is a complete outbound automation system that discovers local businesses, extracts contact emails, generates personalized cold emails using AI, and runs a multi-step follow-up sequence —

Stop And Error, Google Sheets, HTTP Request +2
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