8
n8n 한국어amn8n.com

Groq, Gemini, Slack 승인 시스템을 사용한 RSS에서 Medium 자동 게시

고급

이것은Content Creation, Multimodal AI분야의자동화 워크플로우로, 41개의 노드를 포함합니다.주로 If, Set, Code, Wait, Gmail 등의 노드를 사용하며. Groq, Gemini 및 Slack 승인 시스템을 통한 RSS에서 Medium 발행 자동화 워크플로

사전 요구사항
  • Google 계정 및 Gmail API 인증 정보
  • Slack Bot Token 또는 Webhook URL
  • Google Drive API 인증 정보
  • 대상 API의 인증 정보가 필요할 수 있음
  • Google Sheets API 인증 정보
  • Google Gemini API Key
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "meta": {
    "instanceId": "f017b44b21ba61cea5dc4f23d9caf22ea07787f59e04d4e1a2c79c65ce2d2d61",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "e5c20787-21b2-4fc5-ab07-1d94d1c19f22",
      "name": "Create Google Doc",
      "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": "Check Approval Status",
      "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": "Publish to 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": "Rejection Notification",
      "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": "일정 트리거",
      "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": "Basic LLM 체인",
      "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": "Groq Chat Model",
      "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": "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": "Generate Image Prompt (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": "분할 출력",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        1800,
        920
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "text"
      },
      "typeVersion": 1
    },
    {
      "id": "e58d0ba8-99e1-43de-9025-37de102975be",
      "name": "Get row(s) in sheet",
      "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": "병합",
      "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": "Pick Random Post",
      "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": "Check if Already Posted",
      "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": "Edit Fields",
      "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": "코드1",
      "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": "분할 출력1",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2880,
        1180
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "title"
      },
      "typeVersion": 1
    },
    {
      "id": "d83446f1-8905-444f-b1e1-0b6df0c14377",
      "name": "병합1",
      "type": "n8n-nodes-base.merge",
      "position": [
        3360,
        1180
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "1dba58b0-e518-4fb8-888c-f43d985a9d7f",
      "name": "대기1",
      "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": "코드2",
      "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": "REFORMAT 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": "Upload file",
      "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": "병합2",
      "type": "n8n-nodes-base.merge",
      "position": [
        3020,
        900
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "8e4f4d04-41a4-4276-8581-4c044dbd3f31",
      "name": "분할 출력2",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        4020,
        1040
      ],
      "parameters": {
        "include": "allOtherFields",
        "options": {},
        "fieldToSplitOut": "formattedArticle"
      },
      "typeVersion": 1
    },
    {
      "id": "48fd5492-391e-45c6-940d-f0eec99b927c",
      "name": "병합3",
      "type": "n8n-nodes-base.merge",
      "position": [
        4400,
        1060
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineAll"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c4e4faa4-7964-4e43-acd6-8c6534309099",
      "name": "작업 없음, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        4220,
        1160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "2bf68eb8-f554-4da1-ab62-1b5519307156",
      "name": "Update Doc",
      "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": "Send message and wait for response",
      "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": "Send a 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": "Edit Fields1",
      "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": "Send a 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": "병합4",
      "type": "n8n-nodes-base.merge",
      "position": [
        3440,
        920
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "5ad5719d-ded8-4044-bd3d-547a56a8b711",
      "name": "메모",
      "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": "메모1",
      "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": "Create 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": "DOWNLOAD 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": "메모2",
      "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": "메모3",
      "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": {
    "Code1": {
      "main": [
        [
          {
            "node": "Split Out1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code2": {
      "main": [
        [
          {
            "node": "402776a8-6a12-45d4-a259-a68e12b73f7a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "50133553-12b7-41b0-ae5d-948cb0e85b7a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait1": {
      "main": [
        [
          {
            "node": "Merge1",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge1": {
      "main": [
        [
          {
            "node": "Code2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge2": {
      "main": [
        [
          {
            "node": "ce9a0b0f-8e8f-4394-a8fc-9c97e402a375",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge3": {
      "main": [
        [
          {
            "node": "8d47451f-0181-4456-96f7-9acd85885936",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge4": {
      "main": [
        [
          {
            "node": "9e2d4a36-a825-4b2a-8418-741308038a40",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "71de7319-6d01-4366-8dce-752056ee5d4c",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge2",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Split Out1": {
      "main": [
        [
          {
            "node": "e5c20787-21b2-4fc5-ab07-1d94d1c19f22",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out2": {
      "main": [
        [
          {
            "node": "2bf68eb8-f554-4da1-ab62-1b5519307156",
            "type": "main",
            "index": 0
          },
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a50ac409-0d3f-42a0-8815-fed78c470b5a": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2bf68eb8-f554-4da1-ab62-1b5519307156": {
      "main": [
        [
          {
            "node": "Merge3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9e2d4a36-a825-4b2a-8418-741308038a40": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1b9bdcb8-239a-43c9-a7be-57d32c47c7db": {
      "main": [
        [
          {
            "node": "Merge2",
            "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
          }
        ]
      ]
    },
    "Basic LLM Chain": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dc564a60-340f-44f1-9411-a2b0ccc137dc": {
      "ai_languageModel": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "ce9a0b0f-8e8f-4394-a8fc-9c97e402a375": {
      "main": [
        [
          {
            "node": "Merge4",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "4812fe1b-7999-46fd-87ac-4c501fb0ce00": {
      "main": [
        [
          {
            "node": "Basic LLM Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "402776a8-6a12-45d4-a259-a68e12b73f7a": {
      "main": [
        [
          {
            "node": "Split Out2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "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": "Merge1",
            "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": "Merge",
            "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
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "71de7319-6d01-4366-8dce-752056ee5d4c",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "No Operation, do nothing": {
      "main": [
        [
          {
            "node": "Merge3",
            "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
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

고급 - 콘텐츠 제작, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
고급
노드 수41
카테고리2
노드 유형19
난이도 설명

고급 사용자를 위한 16+개 노드의 복잡한 워크플로우

저자
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. 🤝

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34