Automatisation de la publication RSS vers Medium avec Groq, Gemini et un système d'approbation Slack

Avancé

Ceci est unContent Creation, Multimodal AIworkflow d'automatisation du domainecontenant 41 nœuds.Utilise principalement des nœuds comme If, Set, Code, Wait, Gmail. Automatisation du flux de publication de RSS vers Medium avec Groq, Gemini et le système d'approbation Slack

Prérequis
  • Compte Google et informations d'identification Gmail API
  • Token Bot Slack ou URL Webhook
  • Informations d'identification Google Drive API
  • Peut nécessiter les informations d'identification d'authentification de l'API cible
  • Informations d'identification Google Sheets API
  • Clé API Google Gemini
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
{
  "meta": {
    "instanceId": "f017b44b21ba61cea5dc4f23d9caf22ea07787f59e04d4e1a2c79c65ce2d2d61",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "e5c20787-21b2-4fc5-ab07-1d94d1c19f22",
      "name": "Créer un document Google",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        3140,
        1140
      ],
      "parameters": {
        "title": "={{ $json.title }}",
        "folderId": "1uOuxdhJ2w64JPJGBZhRo8-k4_cd8B_JA"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "id": "AJJ1zQdvDia6yFpf",
          "name": "empty"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "df72645e-cee2-4196-8dec-0d66fd843ed0",
      "name": "Vérifier le statut d'approbation",
      "type": "n8n-nodes-base.if",
      "position": [
        5100,
        1060
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-approval",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6adb13c6-c613-49e0-8da5-21a2f1cf3de5",
      "name": "Publier sur Medium",
      "type": "n8n-nodes-base.httpRequest",
      "disabled": true,
      "position": [
        5380,
        1060
      ],
      "parameters": {
        "url": "http://your-vps-ip:8000/rpc",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "jsonrpc",
              "value": "2.0"
            },
            {
              "name": "method",
              "value": "createMediumPost"
            },
            {
              "name": "params",
              "value": "={{ {\n  \"title\": $('The Verge – Tech').item.json.title,\n  \"content\": $('Generate Blog Article').item.json.choices[0].message.content + '<br><img src=\"' + $('Image Generator').item.json.data[0].url + '\">',\n  \"tags\": [\"AI\", \"Automation\", \"Tech\"],\n  \"publishStatus\": \"public\"\n} }}"
            },
            {
              "name": "id",
              "value": "1"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.1
    },
    {
      "id": "a1026202-fb3d-45e4-ae3f-748d57ca1e59",
      "name": "Notification de rejet",
      "type": "n8n-nodes-base.slack",
      "position": [
        5320,
        1260
      ],
      "webhookId": "33cc03d5-a827-4aba-821a-187b208a96d3",
      "parameters": {
        "text": "❌ **Article Rejected**\n\n",
        "user": {
          "__rl": true,
          "mode": "username",
          "value": ""
        },
        "select": "user",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "t7c5QwXSklleBr8d",
          "name": "empty"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "49301421-b71f-4851-b29a-9e28d9b93d53",
      "name": "Déclencheur planifié",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -120,
        940
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6,
              "triggerAtMinute": 10
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a50ac409-0d3f-42a0-8815-fed78c470b5a",
      "name": "TechCrunch",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        480,
        760
      ],
      "parameters": {
        "url": "https://techcrunch.com/feed",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "7c0cbeb1-b3db-4d84-aacc-6d8d69496b1a",
      "name": "The Verge – Tech",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        80,
        840
      ],
      "parameters": {
        "url": "https://www.theverge.com/rss/index.xml",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "cf7b1583-091a-44f8-90a4-b6a2bcdcbafe",
      "name": "Ars Technica – Technology Lab",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        280,
        780
      ],
      "parameters": {
        "url": "https://feeds.arstechnica.com/arstechnica/technology-lab",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "36c0f639-cd05-42a8-bc17-f7a64caf0d40",
      "name": "Chaîne LLM de base",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1360,
        920
      ],
      "parameters": {
        "text": "=Generate a well formatted Medium Post with the content.\n {{ $json.title }}{{ $json.content }}{{ $json.contentSnippet }}{{ $json.link }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "=[{\"role\": \"system\", \"content\": \"You are a professional tech blogger. Transform the RSS feed content into an engaging Medium article with proper formatting, introduction, and conclusion. Keep it informative yet accessible.\"}, {\"role\": \"user\", \"content\": \"Title: {{ $json.title }}\\n\\nSummary: {{ $json.contentSnippet }}\\n\\nWrite a comprehensive blog post about this topic.\"}]"
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "dc564a60-340f-44f1-9411-a2b0ccc137dc",
      "name": "Modèle de chat Groq",
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "position": [
        1420,
        1100
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "groqApi": {
          "id": "gfoeFNgs3poLdnF9",
          "name": "empty"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "06abfd6e-7352-401a-8695-21c435d0c9ad",
      "name": "Modèle de chat Google Gemini",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        2020,
        1100
      ],
      "parameters": {
        "options": {},
        "modelName": "models/gemini-2.5-flash-lite-preview-06-17"
      },
      "credentials": {
        "googlePalmApi": {
          "id": "b64KEEQh1y3E9kcq",
          "name": "empty"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "71de7319-6d01-4366-8dce-752056ee5d4c",
      "name": "Générer un prompt d'image (Gemini)",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        2060,
        920
      ],
      "parameters": {
        "text": "=Based on the following article, generate a descriptive image prompt for the cover of a medium post: it should be for marketing and professional style image\n{{ $json.text }}",
        "messages": {
          "messageValues": [
            {
              "message": "You are a professional image prompt engineer. Your task is to generate concise, highly descriptive prompts suitable for AI image generation based on article content.  Always create a vivid visual concept that aligns with the tone, subject, and theme of the input text. Use stylistic and visual descriptors relevant to photography, illustration, painting, or graphic design.  Follow these rules strictly:  Start with the main subject of the article.  Describe setting, mood, and style.  Use artistic keywords (e.g., “vector art”, “digital painting”, “cinematic lighting”).  Output only the image prompt — no introduction, explanation, or formatting.  The final prompt should be clear, specific, and optimized for tools like Midjourney or DALL·E. Keep length between 25–75 words."
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "224265b0-368f-43fb-93b6-55987e0b54f7",
      "name": "Diviser",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1800,
        920
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "text"
      },
      "typeVersion": 1
    },
    {
      "id": "e58d0ba8-99e1-43de-9025-37de102975be",
      "name": "Obtenir ligne(s) dans la feuille",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        280,
        940
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1s8BaF5C88tDXgH0YxVEzsFsEJEmsrd6cC_a9ERcroAk/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1s8BaF5C88tDXgH0YxVEzsFsEJEmsrd6cC_a9ERcroAk",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1s8BaF5C88tDXgH0YxVEzsFsEJEmsrd6cC_a9ERcroAk/edit?usp=drivesdk",
          "cachedResultName": "Mediuedium Pipeline"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "6QNuP6aQQqe4yd4A",
          "name": "empty"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "7f491390-b343-4d46-9eab-39572602d24a",
      "name": "Fusionner",
      "type": "n8n-nodes-base.merge",
      "position": [
        560,
        920
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "joinMode": "keepEverything",
        "fieldsToMatchString": "link"
      },
      "typeVersion": 3.2
    },
    {
      "id": "4812fe1b-7999-46fd-87ac-4c501fb0ce00",
      "name": "Choisir un article aléatoire",
      "type": "n8n-nodes-base.code",
      "position": [
        1040,
        920
      ],
      "parameters": {
        "jsCode": "if (items.length === 0) {\n  throw new Error(\"No fresh posts available to pick from.\");\n}\n\nconst randomIndex = Math.floor(Math.random() * items.length);\nreturn [items[randomIndex]];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "50133553-12b7-41b0-ae5d-948cb0e85b7a",
      "name": "Vérifier si déjà publié",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        920
      ],
      "parameters": {
        "jsCode": "// Separate merged items into RSS posts and Sheet URLs\nconst rssItems = [];\nconst usedUrls = new Set();\n\nfor (const item of items) {\n  const link = item.json.link;\n  const url = item.json.url;\n\n  if (link && !rssItems.find(i => i.json.link === link)) {\n    // This is from RSS\n    rssItems.push(item);\n  } else if (url) {\n    // This is from Sheet\n    usedUrls.add(url);\n  }\n}\n\n// Filter out RSS posts whose link already exists in the sheet\nconst freshPosts = rssItems.filter(item => !usedUrls.has(item.json.link));\n\nreturn freshPosts;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9e2d4a36-a825-4b2a-8418-741308038a40",
      "name": "Modifier les champs",
      "type": "n8n-nodes-base.set",
      "position": [
        3640,
        880
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9bfad590-ce07-469b-a875-06c0452b977b",
              "name": "text",
              "type": "string",
              "value": "={{ $json.text }}"
            },
            {
              "id": "e75780c5-42ff-464e-8d91-60e7dad705bb",
              "name": "drive_url",
              "type": "string",
              "value": "={{ $json.webViewLink }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "09b483fb-f264-4be7-93ed-82894509065a",
      "name": "Code1",
      "type": "n8n-nodes-base.code",
      "position": [
        3820,
        940
      ],
      "parameters": {
        "jsCode": "const articleText = $json.text;\nconst driveImageURL = $json.drive_url || 'Image URL not found';\nconst date = new Date().toLocaleString('en-US', { timeZone: 'Africa/Lagos' });\nconst creator = '@OBISDEV';\n\n// Extract title from the first **bolded** line\nconst titleMatch = articleText.match(/\\*\\*(.*?)\\*\\*/);\nconst title = titleMatch ? titleMatch[1] : 'Untitled Article';\n\n// Prepare final formatted text\nconst formattedArticle = \n`${title}\\n\\n` +\n`[IMAGE ATTACHED BELOW]\\n${driveImageURL}\\n\\n` +\n`[DATE]\\n${date}\\n\\n` +\n`[CREATOR]\\nWritten by ${creator}\\n\\n` +\n`[ARTICLE]\\n${articleText}\\n\\n` +\n`[FOLLOW]\\nStay updated with more insights and tools from Obisdev:\\n` +\n`X: @OBISDEV\\nInstagram: @OBISDEV\\nGumroad: @OBISDEV NWUDE`;\n\nreturn [\n  {\n    json: {\n      title,\n      formattedArticle,\n      driveImageURL\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1826d383-0f4c-4ce7-9967-af63e29dfd0e",
      "name": "Diviser1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2880,
        1180
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "title"
      },
      "typeVersion": 1
    },
    {
      "id": "d83446f1-8905-444f-b1e1-0b6df0c14377",
      "name": "Fusionner1",
      "type": "n8n-nodes-base.merge",
      "position": [
        3360,
        1180
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "1dba58b0-e518-4fb8-888c-f43d985a9d7f",
      "name": "Attendre1",
      "type": "n8n-nodes-base.wait",
      "position": [
        3140,
        1340
      ],
      "webhookId": "00b01ae1-5f35-4071-a98c-849616ea3b48",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "3ff425ca-3aa6-41f3-86b7-846c565ff6dc",
      "name": "Code2",
      "type": "n8n-nodes-base.code",
      "position": [
        3600,
        1180
      ],
      "parameters": {
        "jsCode": "// Filter out the item with the doc ID and the one with the article\nlet idItem = items.find(item => item.json.id);\nlet articleItem = items.find(item => item.json.formattedArticle);\n\n// Output a single object with id, formatted article, and drive image URL\nreturn [\n  {\n    json: {\n      id: idItem.json.id,\n      formattedArticle: articleItem.json.formattedArticle,\n      driveImageURL: articleItem.json.driveImageURL\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "402776a8-6a12-45d4-a259-a68e12b73f7a",
      "name": "REFORMATER L'ARTICLE",
      "type": "n8n-nodes-base.code",
      "position": [
        3800,
        1180
      ],
      "parameters": {
        "jsCode": "// Safely find input parts\nconst docId = items.find(item => item.json.id)?.json.id;\nconst article = items.find(item => item.json.formattedArticle)?.json.formattedArticle || '';\n\n// Try to get title from a dedicated field, fallback to bolded headline\nlet title = items.find(item => item.json.title)?.json.title;\nif (!title) {\n  const match = article.match(/\\*\\*(.+?)\\*\\*/);\n  title = match ? match[1] : 'Untitled Article';\n}\n\n// Remove bolded title if it appears again inside the content\nconst cleanedArticle = article.replace(new RegExp(`\\\\*\\\\*${title}\\\\*\\\\*`, 'i'), '');\n\n// Remove all structural [TAGS] except [Link: ...]\nconst mainContent = cleanedArticle\n  .replace(/\\[(?!Link:).*?\\]/g, '')\n  .trim();\n\n// Compose final content\nconst content = `${title}\n\n[Image will be inserted here]\n\nPublished: ${new Date().toLocaleString('en-US', { timeZone: 'Africa/Lagos' })}\nBy: @OBISDEV\n\n${mainContent}\n`;\n\nreturn [\n  {\n    json: {\n      id: docId,\n      formattedArticle: content\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "1b9bdcb8-239a-43c9-a7be-57d32c47c7db",
      "name": "Téléverser le fichier",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        2860,
        760
      ],
      "parameters": {
        "name": "={{$json[\"fileName\"] || \"image.jpg\"}}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1uOuxdhJ2w64JPJGBZhRo8-k4_cd8B_JA",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1uOuxdhJ2w64JPJGBZhRo8-k4_cd8B_JA",
          "cachedResultName": "MEDIUM PIPELINE"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "o7NebpAeNGzz7i7A",
          "name": "empty"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "ea031055-b133-4a0e-b172-7c7751ea0994",
      "name": "Fusionner2",
      "type": "n8n-nodes-base.merge",
      "position": [
        3020,
        900
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "8e4f4d04-41a4-4276-8581-4c044dbd3f31",
      "name": "Diviser2",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        4020,
        1040
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "formattedArticle"
      },
      "typeVersion": 1
    },
    {
      "id": "48fd5492-391e-45c6-940d-f0eec99b927c",
      "name": "Fusionner3",
      "type": "n8n-nodes-base.merge",
      "position": [
        4400,
        1060
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c4e4faa4-7964-4e43-acd6-8c6534309099",
      "name": "Aucune opération",
      "type": "n8n-nodes-base.noOp",
      "position": [
        4220,
        1160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2bf68eb8-f554-4da1-ab62-1b5519307156",
      "name": "Mettre à jour le document",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        4240,
        920
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $json.formattedArticle }}",
              "action": "insert",
              "locationChoice": "location"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $json.id }}"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "id": "AJJ1zQdvDia6yFpf",
          "name": "empty"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "41801c0d-9f05-4c12-a483-5b188a2823df",
      "name": "Envoyer un message et attendre la réponse",
      "type": "n8n-nodes-base.slack",
      "position": [
        4880,
        1060
      ],
      "webhookId": "5c064123-2ce2-4962-ac14-6fa6c1d33b20",
      "parameters": {
        "user": {
          "__rl": true,
          "mode": "username",
          "value": ""
        },
        "message": "=🚀 *New Article Ready for Review*\n\nTo approve, reply in this channel with: *APPROVE ARTICLE*\n",
        "options": {},
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double",
            "buttonApprovalStyle": "secondary"
          }
        }
      },
      "credentials": {
        "slackApi": {
          "id": "t7c5QwXSklleBr8d",
          "name": "empty"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "647de0dd-4da4-4e92-afa5-d37b0306cd4f",
      "name": "Envoyer un message1",
      "type": "n8n-nodes-base.gmail",
      "position": [
        5320,
        860
      ],
      "webhookId": "5e7ce835-a678-490b-875f-5af707cd36ef",
      "parameters": {
        "message": "=THE ARTICLE\n\n{{ $('Split Out2').item.json.formattedArticle }}",
        "options": {},
        "subject": "Medium Content",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "E7BGKwmzoKIRlW0z",
          "name": "empty"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "8d47451f-0181-4456-96f7-9acd85885936",
      "name": "Modifier les champs1",
      "type": "n8n-nodes-base.set",
      "position": [
        4640,
        1060
      ],
      "parameters": {
        "options": {
          "dotNotation": true,
          "ignoreConversionErrors": true
        },
        "assignments": {
          "assignments": [
            {
              "id": "5fad9b34-9bae-4d70-a3a1-dc9fe7177292",
              "name": "formattedArticle",
              "type": "string",
              "value": "={{ $json.formattedArticle }}"
            }
          ]
        }
      },
      "executeOnce": false,
      "typeVersion": 3.4,
      "alwaysOutputData": true
    },
    {
      "id": "ce9a0b0f-8e8f-4394-a8fc-9c97e402a375",
      "name": "Envoyer un message2",
      "type": "n8n-nodes-base.slack",
      "position": [
        3260,
        960
      ],
      "webhookId": "4ffab5ad-840d-4e62-9ca4-bcd6aa19b9e3",
      "parameters": {
        "text": "=REVIEW THE ARTICLE FOR MEDIUM POST\n\n{{ $json.text }}\n\n{{ $json.webViewLink }}",
        "user": {
          "__rl": true,
          "mode": "username",
          "value": ""
        },
        "select": "user",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "t7c5QwXSklleBr8d",
          "name": "empty"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0fe455a9-8bf6-4978-8791-73d202fe1bf6",
      "name": "Fusionner4",
      "type": "n8n-nodes-base.merge",
      "position": [
        3440,
        920
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "5ad5719d-ded8-4044-bd3d-547a56a8b711",
      "name": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -260,
        60
      ],
      "parameters": {
        "width": 1520,
        "height": 1420,
        "content": "## 📰 RSS for Content Fetching\n\nNodes involved:\n\nSchedule Trigger\nThe Verge - Tech RSS\nTechCrunch RSS\n\nThis section uses a scheduled trigger to pull in fresh content from two tech-focused RSS feeds: The Verge and TechCrunch. These feeds act as the primary sources for news articles. It ensures that every run starts with up-to-date, relevant tech content from reputable platforms.\n\n\n\n## 🧮 Sort, Merge, and Pick a Post\nNodes involved:\n\nGet row(s) in sheet : TITLE, IMAGE_URL, CREATOR, & DESCRIPTION\n\nMerge\n\nPick Random Post[Customize to your preferred Niche]\n\nNote:\nFetched articles are merged into a single list. The workflow then checks a Google Sheet to verify which articles were already posted before. One new, unique article is picked randomly from the valid entries to be used for further processing. This ensures no duplicate publishing and supports content diversity.\n\n\n🚫 Check If Already Posted\nNodes involved:\n\nCheck If Already Posted\n\nNote:\nThis node verifies if the selected article has already been used in a past run by comparing its title or link with existing records in the Google Sheet. If already posted, it either halts or skips the duplicate to maintain uniqueness in published content."
      },
      "typeVersion": 1
    },
    {
      "id": "5730e2ba-de00-41ff-9edb-32d6e92107ec",
      "name": "Note adhésive1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        60
      ],
      "parameters": {
        "width": 1520,
        "height": 1420,
        "content": "🧠 Agent Article & Image Generation\nNodes involved:\n\nGoogle Gemini Model (text generation)\n\nBasic LLM Chain (structured content)\n\nGroq Chat Model (content expansion)\n\nGenerate Image Prompt\n\nCreate Image with Pollinations and get the URL\n\nHTTP Request (fetch/download image)\n\nDownload Image file \n\nNote:\nThis is the AI generation stage:\n\nText: Google Gemini and Groq LLM models are used to generate a well-written article based on the RSS content.\n\nImage: Pollinations AI generates a relevant visual image from a text prompt. An HTTP node is used to fetch the image, which is then uploaded to the cloud (possibly Drive or another host).\n\nOutput is split to handle both article and image streams for better control downstream.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b98fd668-02cb-4f71-9b82-a52fc5277f4b",
      "name": "Créer Pollinations + URL",
      "type": "n8n-nodes-base.code",
      "position": [
        2440,
        840
      ],
      "parameters": {
        "jsCode": "const width = 1024;\nconst height = 800;\nconst randomSeed = Math.floor(Math.random() * 100000);\n\nconst finalPrompt = $json.text;\nconst imageUrl = `https://image.pollinations.ai/prompt/${encodeURIComponent(finalPrompt)}.jpg?width=${width}&height=${height}&seed=${randomSeed}&model=flux&nologo=true`;\n\nreturn [\n  {\n    json: {\n      text: finalPrompt,\n      imageUrl\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9e652275-2271-47ba-83bb-f6106fcbd92b",
      "name": "TÉLÉCHARGER L'IMAGE",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2660,
        760
      ],
      "parameters": {
        "url": "={{ $json.imageUrl }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e661e000-c91f-4c80-b295-d2eca71a4cb4",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2820,
        60
      ],
      "parameters": {
        "width": 1980,
        "height": 1420,
        "content": "☁️ Upload to Google Drive\nNodes involved:\n\nCreate Google Doc\n\nMerge4\n\nUpdate Doc\n\nEdit Fields\n\nNote:\nThe generated article and image are uploaded and stored in Google Drive. A Google Doc is created, updated with the AI-generated content, and linked back to the system. This provides a centralized place for human reviewers and stores the article for archiving or reuse.\n\nHere We Send the post to Slack DM or Channel for the user to Review the Article."
      },
      "typeVersion": 1
    },
    {
      "id": "27b27f67-ec8c-4a67-b509-23bad83afaac",
      "name": "Note adhésive3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4820,
        60
      ],
      "parameters": {
        "width": 820,
        "height": 1420,
        "content": "📤 Slack Notification for Approval\nNodes involved:\n\nSend a message2\n\nSend a message and wait for response\n\nCheck Approval Status\n\nNote:\nSlack is used as the manual review checkpoint. The system sends a message with the content preview and waits for a response (approval or rejection) from a designated reviewer or group. This introduces human judgment before public publishing.\n\n✅ Approved = Publish to Medium + Gmail\nNodes involved:\n\nPublish to Medium\n\nSend a message1 (Gmail)\n\nNote:\nOnce content is approved via Slack, it's automatically published to Medium through an API call. At the same time, an email is sent via Gmail, which could be used to notify stakeholders, send to a mailing list, or archive the content. This step ensures distribution across multiple channels.\n\n❌ Rejected = Notify on Slack\nNodes involved:\n\nRejection Notification\n\nNote:\nIf the reviewer rejects the article in Slack, a rejection notification is triggered and sent to the same Slack user or group. This keeps the content creation team informed and ready to revise or skip the rejected content. It closes the loop with proper rejection feedback.\n\n"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "09b483fb-f264-4be7-93ed-82894509065a": {
      "main": [
        [
          {
            "node": "1826d383-0f4c-4ce7-9967-af63e29dfd0e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3ff425ca-3aa6-41f3-86b7-846c565ff6dc": {
      "main": [
        [
          {
            "node": "402776a8-6a12-45d4-a259-a68e12b73f7a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7f491390-b343-4d46-9eab-39572602d24a": {
      "main": [
        [
          {
            "node": "50133553-12b7-41b0-ae5d-948cb0e85b7a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1dba58b0-e518-4fb8-888c-f43d985a9d7f": {
      "main": [
        [
          {
            "node": "d83446f1-8905-444f-b1e1-0b6df0c14377",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "d83446f1-8905-444f-b1e1-0b6df0c14377": {
      "main": [
        [
          {
            "node": "3ff425ca-3aa6-41f3-86b7-846c565ff6dc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ea031055-b133-4a0e-b172-7c7751ea0994": {
      "main": [
        [
          {
            "node": "ce9a0b0f-8e8f-4394-a8fc-9c97e402a375",
            "type": "main",
            "index": 0
          },
          {
            "node": "0fe455a9-8bf6-4978-8791-73d202fe1bf6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "48fd5492-391e-45c6-940d-f0eec99b927c": {
      "main": [
        [
          {
            "node": "8d47451f-0181-4456-96f7-9acd85885936",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0fe455a9-8bf6-4978-8791-73d202fe1bf6": {
      "main": [
        [
          {
            "node": "9e2d4a36-a825-4b2a-8418-741308038a40",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "224265b0-368f-43fb-93b6-55987e0b54f7": {
      "main": [
        [
          {
            "node": "71de7319-6d01-4366-8dce-752056ee5d4c",
            "type": "main",
            "index": 0
          },
          {
            "node": "ea031055-b133-4a0e-b172-7c7751ea0994",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "1826d383-0f4c-4ce7-9967-af63e29dfd0e": {
      "main": [
        [
          {
            "node": "e5c20787-21b2-4fc5-ab07-1d94d1c19f22",
            "type": "main",
            "index": 0
          },
          {
            "node": "1dba58b0-e518-4fb8-888c-f43d985a9d7f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8e4f4d04-41a4-4276-8581-4c044dbd3f31": {
      "main": [
        [
          {
            "node": "2bf68eb8-f554-4da1-ab62-1b5519307156",
            "type": "main",
            "index": 0
          },
          {
            "node": "c4e4faa4-7964-4e43-acd6-8c6534309099",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a50ac409-0d3f-42a0-8815-fed78c470b5a": {
      "main": [
        [
          {
            "node": "7f491390-b343-4d46-9eab-39572602d24a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2bf68eb8-f554-4da1-ab62-1b5519307156": {
      "main": [
        [
          {
            "node": "48fd5492-391e-45c6-940d-f0eec99b927c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9e2d4a36-a825-4b2a-8418-741308038a40": {
      "main": [
        [
          {
            "node": "09b483fb-f264-4be7-93ed-82894509065a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1b9bdcb8-239a-43c9-a7be-57d32c47c7db": {
      "main": [
        [
          {
            "node": "ea031055-b133-4a0e-b172-7c7751ea0994",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8d47451f-0181-4456-96f7-9acd85885936": {
      "main": [
        [
          {
            "node": "41801c0d-9f05-4c12-a483-5b188a2823df",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9e652275-2271-47ba-83bb-f6106fcbd92b": {
      "main": [
        [
          {
            "node": "1b9bdcb8-239a-43c9-a7be-57d32c47c7db",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "36c0f639-cd05-42a8-bc17-f7a64caf0d40": {
      "main": [
        [
          {
            "node": "224265b0-368f-43fb-93b6-55987e0b54f7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dc564a60-340f-44f1-9411-a2b0ccc137dc": {
      "ai_languageModel": [
        [
          {
            "node": "36c0f639-cd05-42a8-bc17-f7a64caf0d40",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "ce9a0b0f-8e8f-4394-a8fc-9c97e402a375": {
      "main": [
        [
          {
            "node": "0fe455a9-8bf6-4978-8791-73d202fe1bf6",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "4812fe1b-7999-46fd-87ac-4c501fb0ce00": {
      "main": [
        [
          {
            "node": "36c0f639-cd05-42a8-bc17-f7a64caf0d40",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "402776a8-6a12-45d4-a259-a68e12b73f7a": {
      "main": [
        [
          {
            "node": "8e4f4d04-41a4-4276-8581-4c044dbd3f31",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "49301421-b71f-4851-b29a-9e28d9b93d53": {
      "main": [
        [
          {
            "node": "e58d0ba8-99e1-43de-9025-37de102975be",
            "type": "main",
            "index": 0
          },
          {
            "node": "7c0cbeb1-b3db-4d84-aacc-6d8d69496b1a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e5c20787-21b2-4fc5-ab07-1d94d1c19f22": {
      "main": [
        [
          {
            "node": "d83446f1-8905-444f-b1e1-0b6df0c14377",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7c0cbeb1-b3db-4d84-aacc-6d8d69496b1a": {
      "main": [
        [
          {
            "node": "cf7b1583-091a-44f8-90a4-b6a2bcdcbafe",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e58d0ba8-99e1-43de-9025-37de102975be": {
      "main": [
        [
          {
            "node": "7f491390-b343-4d46-9eab-39572602d24a",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "df72645e-cee2-4196-8dec-0d66fd843ed0": {
      "main": [
        [
          {
            "node": "647de0dd-4da4-4e92-afa5-d37b0306cd4f",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "a1026202-fb3d-45e4-ae3f-748d57ca1e59",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "50133553-12b7-41b0-ae5d-948cb0e85b7a": {
      "main": [
        [
          {
            "node": "4812fe1b-7999-46fd-87ac-4c501fb0ce00",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "06abfd6e-7352-401a-8695-21c435d0c9ad": {
      "ai_languageModel": [
        [
          {
            "node": "71de7319-6d01-4366-8dce-752056ee5d4c",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "c4e4faa4-7964-4e43-acd6-8c6534309099": {
      "main": [
        [
          {
            "node": "48fd5492-391e-45c6-940d-f0eec99b927c",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "b98fd668-02cb-4f71-9b82-a52fc5277f4b": {
      "main": [
        [
          {
            "node": "9e652275-2271-47ba-83bb-f6106fcbd92b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "71de7319-6d01-4366-8dce-752056ee5d4c": {
      "main": [
        [
          {
            "node": "b98fd668-02cb-4f71-9b82-a52fc5277f4b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "cf7b1583-091a-44f8-90a4-b6a2bcdcbafe": {
      "main": [
        [
          {
            "node": "a50ac409-0d3f-42a0-8815-fed78c470b5a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "41801c0d-9f05-4c12-a483-5b188a2823df": {
      "main": [
        [
          {
            "node": "df72645e-cee2-4196-8dec-0d66fd843ed0",
            "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é - Création de contenu, IA Multimodale

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œuds41
Catégorie2
Types de nœuds19
Description de la difficulté

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

Auteur
ObisDev

ObisDev

@obisdev

Let's scale your Business 5x with AI automation. Yes that's my Job. 💻Software Developer 🤖AI Agent Builder | N8N ⛓️Automation and Workflow Engineer. 🤝

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34