Créateur de blog IA (avec Gemini, génération d'images Replicate, publication Supabase et Slack)

Avancé

Ceci est uncontenant 25 nœuds.Utilise principalement des nœuds comme If, Set, Code, Cron, Wait. Création automatisée de blog du à la publication, en utilisant Gemini, Ideogram et Slack

Prérequis
  • Token Bot Slack ou URL Webhook
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

Catégorie

-
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "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": "Récupérer les Tendances du Secteur",
      "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": "Publier vers 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": "Notification 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": "Envoyer un message à un modèle",
      "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": "Envoyer un message à un modèle1",
      "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": "Coder 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": "Attendre",
      "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": "Modifier les Champs",
      "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": "Déclencheur Planifié",
      "type": "n8n-nodes-base.cron",
      "position": [
        0,
        -240
      ],
      "parameters": {
        "triggerTimes": {
          "item": [
            {
              "hour": 10
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "03a19edc-7128-40d1-a936-7fa3bce230a2",
      "name": "Note Adhésive",
      "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": "Note Adhésive1",
      "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": "Note Adhésive2",
      "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": "Note Adhésive3",
      "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": "Note Adhésive4",
      "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": "Requête HTTP1 (Sondage 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": "Requête HTTP (Replicate – Générer une 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": {
          "id": "IaV5B30kamGSSZgF",
          "name": "Bearer Auth account"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9a54a8e9-938b-4e24-8f50-6681b64e53d7",
      "name": "Note Adhésive5",
      "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": "Note Adhésive6",
      "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": "Note Adhésive7",
      "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": "Note Adhésive8",
      "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": "Note Adhésive9",
      "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": "Note Adhésive10",
      "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": "Note Adhésive11",
      "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": "Note Adhésive12",
      "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
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds25
Catégorie-
Types de nœuds9
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
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.

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34