Creador de blog con IA (con Gemini, generación de imágenes de Replicate, publicación en Supabase y Slack)

Avanzado

Este es unautomatización que contiene 25 nodos.Utiliza principalmente nodos como If, Set, Code, Cron, Wait. Creación automatizada de blogs de noticias a publicación, usando Gemini, Ideogram y Slack

Requisitos previos
  • Bot Token de Slack o URL de Webhook
  • Pueden requerirse credenciales de autenticación para la API de destino

Categoría

-
Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "id": "EmPnnzwJEHxMuJaw",
  "meta": {
    "instanceId": "bd69d47c91060511db2b31f757484463dd5af5fe7228f5cd6f51444aefa5ac55",
    "templateCredsSetupCompleted": true
  },
  "name": "AI Blog Creator with Gemini, Replicate Image, Supabase Publishing & Slack",
  "tags": [],
  "nodes": [
    {
      "id": "e45d33d9-2fc2-476c-b0ff-63d16b30111a",
      "name": "Obtener tendencias de la industria",
      "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": {
          "id": "XbH4j2OBjd3qNhPr",
          "name": "newsapi"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "2c641b4b-9ce0-472d-a970-714d6a630f0c",
      "name": "Publicar en 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": {
          "id": "jaWa5lNkOeQCkOcg",
          "name": "UTSLsuperbase"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "17fcce85-bdf1-4c21-848a-3ce667e3aab5",
      "name": "Notificación Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        2720,
        -240
      ],
      "parameters": {
        "text": "=✅ *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": {
          "id": "O5jKBGGMM6lHXuRS",
          "name": "Slack account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5ecb7538-6358-4d89-ac55-8e4539f8d42a",
      "name": "Enviar mensaje a un modelo",
      "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’s 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": {
          "id": "ry9hnf20jfXpHAes",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5da2d4ee-d7b0-441a-8523-067a17182c6a",
      "name": "Enviar mensaje a un modelo1",
      "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–1500 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 → Insight → Case Studies → Conclusion → CTA.\nOutput JSON:\n{\n  \"title\": \"...\",\n  \"slug\": \"...\",\n  \"excerpt\": \"...\",\n  \"content\": \"...\",\n  \"keywords\": \"...\",\n  \"image_prompt\": \"...\"\n}\n"
            }
          ]
        }
      },
      "credentials": {
        "googlePalmApi": {
          "id": "ry9hnf20jfXpHAes",
          "name": "Google Gemini(PaLM) Api account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1369e40f-2008-4fb7-9123-d17b02a7d42d",
      "name": "Código en 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️⃣ Strip Markdown fences and language hints\ntext = text\n  .replace(/```json/gi, '')\n  .replace(/```/g, '')\n  .replace(/^#+\\s+/gm, '')\n  .trim();\n\n// 2️⃣ 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(/“|”/g, '\"')\n    .replace(/‘|’/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️⃣ 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️⃣ 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️⃣ Output ready-to-use normalized data\nreturn [parsed];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "02a8a518-fb7d-4f13-b72d-25dcbacfb033",
      "name": "Esperar",
      "type": "n8n-nodes-base.wait",
      "position": [
        1824,
        -240
      ],
      "webhookId": "c8b9eb51-2818-4db7-9c66-3a17afb79adc",
      "parameters": {
        "amount": 20
      },
      "typeVersion": 1.1
    },
    {
      "id": "e2f813a3-1808-44f7-9bae-842d8d6cecbc",
      "name": "Si",
      "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": "Editar campos",
      "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": "Activador programado",
      "type": "n8n-nodes-base.cron",
      "position": [
        0,
        -240
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "hour": 10
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "03a19edc-7128-40d1-a936-7fa3bce230a2",
      "name": "Nota adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -48
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 512,
        "content": "### 🌐 **Fetch Industry Trends (HTTP Request – NewsAPI)**\n\n**Purpose:**\nFetches the latest 10 articles related to “AI automation SaaS” from NewsAPI.\nThese articles are used as context for generating trending blog topics.\n\n**Credentials Required:**\n\n* `NewsAPI` (Generic Query Auth) — 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., “finance AI,” “healthcare automation,” etc.).\n* You can also adjust `pageSize` to fetch more or fewer results.\n* NewsAPI free tier allows 100 requests/day — plan accordingly if running multiple times.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dc40791a-0f73-45dd-8856-30d3ea8b88fe",
      "name": "Nota adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        304,
        -672
      ],
      "parameters": {
        "color": 5,
        "width": 352,
        "height": 416,
        "content": "### 🤖 **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., “Based on fintech trends…”).\n* Recommended model: `gemini-2.5-flash` for faster responses."
      },
      "typeVersion": 1
    },
    {
      "id": "b2863fad-0e3e-4f6d-a5e9-c083a37c7962",
      "name": "Nota adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        -48
      ],
      "parameters": {
        "color": 5,
        "width": 432,
        "height": 416,
        "content": "### ✍️ **Message a model1 (Google Gemini)**\n\n**Purpose:**\nGenerates a full-length blog (1200–1500 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 — the next node handles cleanup."
      },
      "typeVersion": 1
    },
    {
      "id": "c024e432-6579-4846-bd85-3d1d6cc8c047",
      "name": "Nota adhesiva3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -672
      ],
      "parameters": {
        "color": 3,
        "width": 400,
        "height": 416,
        "content": "### 🧹 **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💡 *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": "Nota adhesiva4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -16
      ],
      "parameters": {
        "color": 4,
        "width": 384,
        "height": 432,
        "content": "### 🖼️ **HTTP Request (Replicate – Generate Image)**\n\n**Purpose:**\nSends the `image_prompt` field to Replicate’s **Ideogram v3 Turbo** model to generate a 1024×1024 image.\n\n**Credentials Required:**\n\n* `Replicate Bearer Token` 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": "Solicitud HTTP1 (sondeo Replicate)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1600,
        -240
      ],
      "parameters": {
        "url": "={{ $json.urls.get }}",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "id": "IaV5B30kamGSSZgF",
          "name": "Bearer Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "6c7dfb6f-4f83-4d65-bea0-56c12a7b5393",
      "name": "Solicitud HTTP (Replicate – Generar imagen)",
      "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": {
          "id": "IaV5B30kamGSSZgF",
          "name": "Bearer Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9a54a8e9-938b-4e24-8f50-6681b64e53d7",
      "name": "Nota adhesiva5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1744,
        -32
      ],
      "parameters": {
        "width": 256,
        "height": 368,
        "content": "### ⏱️ **Wait**\n\n**Purpose:**\nAdds a 20-second delay before rechecking Replicate’s image status.\n\n**Notes:**\n\n* Replicate image generation takes ~10–20 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": "Nota adhesiva6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        -656
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 400,
        "content": "### ⏳ **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 Token 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": "Nota adhesiva7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1888,
        -592
      ],
      "parameters": {
        "width": 304,
        "height": 336,
        "content": "### ✅ **If**\n\n**Purpose:**\nChecks if the Replicate image generation has **succeeded**.\n\n**Notes:**\n\n* If the status = “succeeded,” workflow proceeds to the next step.\n* If not, it loops back to **HTTP Request1** to poll again.\n* This ensures the workflow doesn’t break while waiting for long image generations.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bdec9233-16ac-4054-b953-69e6351b9c50",
      "name": "Nota adhesiva8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        -80
      ],
      "parameters": {
        "width": 304,
        "height": 352,
        "content": "### 🧩 **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": "Nota adhesiva9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2272,
        -720
      ],
      "parameters": {
        "color": 4,
        "width": 432,
        "height": 480,
        "content": "### 🚀 **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_KEY`)\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": "Nota adhesiva10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        -80
      ],
      "parameters": {
        "color": 2,
        "width": 336,
        "height": 480,
        "content": "### 💬 **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": "Nota adhesiva11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -816
      ],
      "parameters": {
        "width": 480,
        "height": 336,
        "content": "## 🧩 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–2 minutes depending on image generation time.\n* **Timezone:** Set to `Asia/Kolkata` by default — adjust if needed in workflow settings.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "13f542b7-566c-429d-ba5d-45a63b7fd801",
      "name": "Nota adhesiva12",
      "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### **✨ Features**\n\n* 📰 **Fetch Trending Topics** — pulls the latest news or updates from your selected industry (via NewsAPI).\n* 🤖 **AI Topic Generation** — Gemini suggests trending blog topics relevant to AI, SaaS, and Automation.\n* 📝 **AI Blog Authoring** — Gemini then writes a full 1200-1500 word SEO-optimized article in Markdown.\n* 🧹 **Smart JSON Cleaner** — A resilient code node parses Gemini’s output and ensures clean, structured data.\n* 🖼️ **Auto-Generated Image** — Replicate’s Ideogram model creates a blog cover image based on the content prompt.\n* 🌐 **Automatic Publishing** — Posts are automatically published to your Supabase or custom backend.\n* 💬 **Slack Notification** — Notifies your team with blog details and live URL.\n* ⏰ **Fully Scheduled** — Runs automatically every day at your preferred time (default 10 AM IST).\n\n---\n\n### **⚙️ 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### **🔧 Setup Instructions**\n\n1. **Import the Workflow** in n8n and enable it.\n2. Create the following credentials:\n\n   * **NewsAPI (Query Auth)** — from [https://newsapi.org](https://newsapi.org)\n   * **Google Gemini (PaLM API)** — use your Gemini API key\n   * **Replicate (Bearer Auth)** — API key from [https://replicate.com/account](https://replicate.com/account)\n   * **Supabase (Header Auth)** — endpoint to your `/functions/v1/blog-api` (set your key in header)\n   * **Slack API** — 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 “Slack Notification”.\n6. (Optional) Change the **Schedule Trigger** time as per your timezone.\n\n---\n\n### **💡 Notes & Tips**\n\n* The **Code in JavaScript** node is robust against malformed or extra text in Gemini output — it sanitizes Markdown and reconstructs clean JSON safely.\n* You can replace Supabase with any CMS or Webhook endpoint by editing the “Publish to Supabase” node.\n* The Replicate model used is `ideogram-ai/ideogram-v3-turbo` — 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,
  "pinData": {},
  "settings": {
    "timezone": "Asia/Kolkata",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "EmPnnzwJEHxMuJaw",
    "executionOrder": "v1",
    "saveExecutionProgress": true,
    "saveDataErrorExecution": "all"
  },
  "versionId": "bc157604-a8a8-4745-a98d-d8b10da1b1ab",
  "connections": {
    "e2f813a3-1808-44f7-9bae-842d8d6cecbc": {
      "main": [
        [
          {
            "node": "b300ab84-eeea-42ea-a609-6bff06da4846",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "35e16700-c40d-4e8b-abda-a55b193b7e1f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "02a8a518-fb7d-4f13-b72d-25dcbacfb033": {
      "main": [
        [
          {
            "node": "e2f813a3-1808-44f7-9bae-842d8d6cecbc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b300ab84-eeea-42ea-a609-6bff06da4846": {
      "main": [
        [
          {
            "node": "2c641b4b-9ce0-472d-a970-714d6a630f0c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5ecb7538-6358-4d89-ac55-8e4539f8d42a": {
      "main": [
        [
          {
            "node": "5da2d4ee-d7b0-441a-8523-067a17182c6a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5da2d4ee-d7b0-441a-8523-067a17182c6a": {
      "main": [
        [
          {
            "node": "1369e40f-2008-4fb7-9123-d17b02a7d42d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "df01fb3f-d7dd-4d2b-9581-24df4472b3ea": {
      "main": [
        [
          {
            "node": "e45d33d9-2fc2-476c-b0ff-63d16b30111a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1369e40f-2008-4fb7-9123-d17b02a7d42d": {
      "main": [
        [
          {
            "node": "6c7dfb6f-4f83-4d65-bea0-56c12a7b5393",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "17fcce85-bdf1-4c21-848a-3ce667e3aab5": {
      "main": [
        []
      ]
    },
    "2c641b4b-9ce0-472d-a970-714d6a630f0c": {
      "main": [
        [
          {
            "node": "17fcce85-bdf1-4c21-848a-3ce667e3aab5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e45d33d9-2fc2-476c-b0ff-63d16b30111a": {
      "main": [
        [
          {
            "node": "5ecb7538-6358-4d89-ac55-8e4539f8d42a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "35e16700-c40d-4e8b-abda-a55b193b7e1f": {
      "main": [
        [
          {
            "node": "02a8a518-fb7d-4f13-b72d-25dcbacfb033",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6c7dfb6f-4f83-4d65-bea0-56c12a7b5393": {
      "main": [
        [
          {
            "node": "35e16700-c40d-4e8b-abda-a55b193b7e1f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿Cómo usar este flujo de trabajo?

Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.

¿En qué escenarios es adecuado este flujo de trabajo?

Avanzado

¿Es de pago?

Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos25
Categoría-
Tipos de nodos9
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor
Parag Javale

Parag Javale

@pollar-beer

Tech driven creative who turns ideas into impact. I blend storytelling, product strategy, and automation whether it’s hooky audio promos, smart LMS platforms, or AI driven workflows. I help businesses grab attention, streamline ops, and scale fast. Big on data, experiments, and building digital solutions that actually work.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34