AutomationFlowsAI & RAG › Generate Pinterest Pin Copy CSV From Blog RSS with Openai-compatible Chat

Generate Pinterest Pin Copy CSV From Blog RSS with Openai-compatible Chat

Byseo dong min @dongmari on n8n.io

Turn your latest blog posts into Pinterest-ready pin titles, descriptions and keywords, exported as a CSV formatted for Pinterest's native bulk upload. An AI writes one conversion-focused pin per post from your RSS feed — curiosity-preserving titles under 90 characters, natural…

Event trigger★★★★☆ complexity12 nodesRSS Feed ReadHTTP Request
AI & RAG Trigger: Event Nodes: 12 Complexity: ★★★★☆ Added:

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

This workflow follows the HTTP Request → RSS Feed Read recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "FreePinCopyGen03",
  "name": "Pinterest Pin Copy Generator (Blog Posts to Bulk CSV)",
  "nodes": [
    {
      "id": "aa94d6d2-8a07-46ce-88f4-f7a2235fa525",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        -112
      ],
      "parameters": {
        "width": 480,
        "height": 800,
        "content": "## Pinterest Pin Copy Generator (Blog Posts to Bulk CSV)\n\n### How it works\n\nThis workflow manually generates Pinterest pin copy from recent blog posts. It reads a configured RSS feed, selects the latest posts, sends them to an AI API for copy generation, then formats the results as a Pinterest bulk-upload CSV for download.\n\n### Setup steps\n\n- Open the \u2699\ufe0f Configure node and set the blog RSS feed URL in `feedUrl`.\n- Set `postCount` to control how many recent posts are processed.\n- Set `pinterestBoard` to the target board name used in the CSV output.\n- Set `apiBaseUrl` to the AI copy-generation API endpoint base URL and configure any required HTTP authentication or headers in the AI request node.\n- Run the workflow manually from the Run It node and download the generated CSV from the final node.\n\n### Customization\n\nAdjust the code in Take Latest Posts to change post filtering or ordering, and update Shape CSV Rows if your Pinterest CSV template needs different columns or formatting."
      },
      "typeVersion": 1
    },
    {
      "id": "3215671c-a3e8-4fbc-b6ae-fe428a1fb64e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 336,
        "content": "## Start and configure\n\nManual launch and workflow settings are defined here, including the RSS feed URL, number of posts to process, Pinterest board, and AI API base URL."
      },
      "typeVersion": 1
    },
    {
      "id": "0e711012-5f69-4be4-899d-3c6f568dca90",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Read latest posts\n\nFetches the configured blog RSS feed and narrows the results to the newest configured number of posts."
      },
      "typeVersion": 1
    },
    {
      "id": "a42b1097-c685-40d2-95f1-944ef1d02691",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1200,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 240,
        "height": 336,
        "content": "## Generate pin copy\n\nSends each selected blog post to the configured AI endpoint to create Pinterest-ready pin copy."
      },
      "typeVersion": 1
    },
    {
      "id": "da3159b0-29ee-44ac-acab-29b6d0ee740f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Export bulk CSV\n\nParses the AI response into Pinterest bulk-upload rows and converts the shaped data into a downloadable CSV file."
      },
      "typeVersion": 1
    },
    {
      "id": "manual-trigger",
      "name": "Manual Start Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        340,
        60
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "configure3",
      "name": "Set Configuration Parameters",
      "type": "n8n-nodes-base.set",
      "position": [
        560,
        60
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-feed3",
              "name": "feedUrl",
              "type": "string",
              "value": "https://YOUR-SITE.com/feed/"
            },
            {
              "id": "cfg-count",
              "name": "postCount",
              "type": "number",
              "value": 5
            },
            {
              "id": "cfg-board",
              "name": "pinterestBoard",
              "type": "string",
              "value": "YOUR BOARD NAME"
            },
            {
              "id": "cfg-baseurl3",
              "name": "apiBaseUrl",
              "type": "string",
              "value": "https://api.openai.com/v1"
            },
            {
              "id": "cfg-model3",
              "name": "model",
              "type": "string",
              "value": "gpt-4o-mini"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "rss-read3",
      "name": "Retrieve Blog Feed",
      "type": "n8n-nodes-base.rssFeedRead",
      "position": [
        780,
        60
      ],
      "parameters": {
        "url": "={{ $json.feedUrl }}",
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "take-n",
      "name": "Select Newest Blog Posts",
      "type": "n8n-nodes-base.code",
      "position": [
        1000,
        60
      ],
      "parameters": {
        "jsCode": "// Take the newest N posts\nconst n = $('Set Configuration Parameters').first().json.postCount || 5;\nconst items = $input.all().slice(0, n).map(i => ({\n  title: i.json.title,\n  link: i.json.link,\n  snippet: (i.json.contentSnippet || '').slice(0, 250),\n}));\nreturn [{ json: { posts: items } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "ai-pins",
      "name": "Post Pin Copy to AI",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1248,
        64
      ],
      "parameters": {
        "url": "={{ $('Set Configuration Parameters').item.json.apiBaseUrl }}/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({ model: $('Set Configuration Parameters').item.json.model, response_format: { type: 'json_object' }, messages: [ { role: 'system', content: 'You write Pinterest pin copy that earns saves and clicks. Rules: titles under 90 chars, curiosity-preserving (never give the full answer), no clickbait words like INSANE or SECRET; descriptions 150-300 chars, natural keywords woven in, end with a soft call to action; keywords: 4-6 comma-separated search terms. Reply as JSON: {\"pins\":[{\"title\":\"\",\"description\":\"\",\"keywords\":\"\",\"link\":\"\"}]} with one pin per post, keeping each post\\'s link.' }, { role: 'user', content: 'Write one pin per post: ' + JSON.stringify($json.posts) } ] }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "shape-rows",
      "name": "Format Rows for Pinterest CSV",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        64
      ],
      "parameters": {
        "jsCode": "// Parse AI JSON and shape rows for Pinterest bulk CSV\nconst board = $('Set Configuration Parameters').first().json.pinterestBoard;\nlet parsed;\ntry {\n  parsed = JSON.parse($input.first().json.choices[0].message.content);\n} catch (e) {\n  throw new Error('AI did not return valid JSON. Run again or lower postCount. Raw: ' + String($input.first().json.choices?.[0]?.message?.content).slice(0, 200));\n}\nconst rows = (parsed.pins || []).map(p => ({\n  json: {\n    'Title': p.title,\n    'Media URL': 'https://PASTE-YOUR-PIN-IMAGE-URL.jpg',\n    'Pinterest board': board,\n    'Description': p.description,\n    'Link': p.link,\n    'Publish date': '',\n    'Keywords': p.keywords,\n  }\n}));\nif (rows.length === 0) throw new Error('No pins generated.');\nreturn rows;"
      },
      "typeVersion": 2
    },
    {
      "id": "to-csv",
      "name": "Export as CSV File",
      "type": "n8n-nodes-base.convertToFile",
      "position": [
        1744,
        64
      ],
      "parameters": {
        "options": {
          "fileName": "pinterest-bulk-pins.csv"
        },
        "operation": "csv"
      },
      "typeVersion": 1.1
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Retrieve Blog Feed": {
      "main": [
        [
          {
            "node": "Select Newest Blog Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Pin Copy to AI": {
      "main": [
        [
          {
            "node": "Format Rows for Pinterest CSV",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Start Trigger": {
      "main": [
        [
          {
            "node": "Set Configuration Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Newest Blog Posts": {
      "main": [
        [
          {
            "node": "Post Pin Copy to AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Configuration Parameters": {
      "main": [
        [
          {
            "node": "Retrieve Blog Feed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Rows for Pinterest CSV": {
      "main": [
        [
          {
            "node": "Export as CSV File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Turn your latest blog posts into Pinterest-ready pin titles, descriptions and keywords, exported as a CSV formatted for Pinterest's native bulk upload. An AI writes one conversion-focused pin per post from your RSS feed — curiosity-preserving titles under 90 characters, natural…

Source: https://n8n.io/workflows/17277/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Monitors multiple technology websites 24/7 Uses AI to read and understand each article Filters out low-quality content automatically. Saves the best articles to Notion with summaries. Sends you Telegr

RSS Feed Read, Notion, HTTP Request +1
AI & RAG

This workflow helps you repurpose your YouTube videos across multiple social media platforms with zero manual effort. It’s designed for creators, businesses, and marketers who want to maximize reach w

HTTP Request, RSS Feed Read, Discord +4
AI & RAG

Triggered by a GitLab MR webhook, this workflow automatically assists your team in writing customer-facing release notes by combining Linear issue data with Claude AI.

HTTP Request, RSS Feed Read, Gitlab Trigger +1
AI & RAG

Transform YouTube Videos to Social Media Content with Vizard AI and GPT‑4.1

HTTP Request, Google Sheets, Gmail +2
AI & RAG

legal_rag_telegram_api_current_github_ready. Uses telegramTrigger, httpRequest. Event-driven trigger; 56 nodes.

Telegram Trigger, HTTP Request