{
  "id": "WORKFLOW_ID_PLACEHOLDER",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "MCP: Pinterest Keyword-Based Content Scraper with AI Agent & BrightData Automation",
  "tags": [],
  "nodes": [
    {
      "id": "5234018f-d12c-439f-9713-2a7cd9cb239f",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        -240,
        320
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-20250514",
          "cachedResultName": "Claude 4 Sonnet"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e3ebf96d-a8d9-41cf-b5bc-d7eda3776aa2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        -200
      ],
      "parameters": {
        "color": 2,
        "width": 500,
        "height": 260,
        "content": "\ud83e\udd16 AI Agent  \nProcesses input keyword via language model (Claude). Acts as controller for all scraping-related steps.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b47df625-4d67-4d9c-b94c-dc32a09077be",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1080,
        260
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 260,
        "content": "\u23f1\ufe0f Wait Timer (Disabled)  \nWaits 1 minute before retrying scraping status. Currently disabled but useful for longer jobs.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a674d3dc-ff9f-42fc-8bc4-737a64ef0bd1",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        700,
        360
      ],
      "parameters": {
        "color": 5,
        "width": 320,
        "height": 260,
        "content": "\ud83d\udce6 Download Scraped Data  \nFetches scraped Pinterest data once the snapshot status is \"ready\". This returns actual content data.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "966c2317-199b-439a-9651-37fde866eae2",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        380,
        360
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 260,
        "content": "\ud83d\udd04 Check Snapshot Progress  \nContinuously checks scraping status (like \"running\", \"ready\") using `snapshot_id`. Loops until data is ready.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "28aaa784-5cb2-42db-b170-284cbf3bfcdb",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        40,
        280
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 280,
        "content": "\ud83d\ude80 Launch Scraping Job  \nSends the keyword to BrightData API using POST request to create a scraping snapshot. Returns a `snapshot_id`.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "38c7467d-cc5f-4e7e-acfc-339e9700ff49",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        200
      ],
      "parameters": {
        "width": 280,
        "height": 260,
        "content": "\ud83e\udde0 Claude Sonnet 4 Model  \nUsed to intelligently process, understand, or enrich keywords before initiating scrape via the AI agent.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "5fc7d5ee-83a4-4f5f-b41b-270af43f6f2c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -240
      ],
      "parameters": {
        "color": 6,
        "width": 260,
        "height": 280,
        "content": "\ud83d\udce5 Keyword Input Form  \nUser submits keywords here to initiate scraping. This is the entry trigger for the Pinterest automation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "dcdb9696-579f-49fc-bab0-3f81a4f87595",
      "name": "BrightData Pinterest Scraping",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        140,
        400
      ],
      "parameters": {
        "url": "https://api.brightdata.com/datasets/v3/trigger",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('JSON', `This HTTP POST request sends the user's chat input (like \"Food\") to the BrightData Pinterest collector. The collector uses this input to create a new scraping snapshot based on the keyword. The request body includes a sessionId, action, and chatInput, and the response will return a snapshot_id which will be used in the next steps to fetch the scraped data.\n[{\"keyword\":\"food\"}]`, 'json') }}",
        "sendBody": true,
        "sendQuery": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "queryParameters": {
          "parameters": [
            {
              "name": "dataset_id",
              "value": "gd_lk0sjs4d21kdr7cnlv"
            },
            {
              "name": "include_errors",
              "value": "true"
            },
            {
              "name": "type",
              "value": "discover_new"
            },
            {
              "name": "discover_by",
              "value": "keyword"
            },
            {
              "name": "limit_per_input",
              "value": "2"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9657f18e-62d4-44d4-8537-39175b983f17",
      "name": "Check Scraping Status",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        460,
        480
      ],
      "parameters": {
        "url": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', `use snapshot id to create http request url \nfor example:\nhttps://api.brightdata.com/datasets/v3/progress/your_snapshot_id`, 'string') }}",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "format",
              "value": "json"
            }
          ]
        },
        "toolDescription": "Makes an HTTP request to check the status of snapshot_id and returns the status like \"ready\" or \"running\". If the status received is \"running\", then make another HTTP request.",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d2af5353-509f-4a82-b861-f66c5add7abb",
      "name": "Fetch Pinterest Snapshot Data",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        800,
        460
      ],
      "parameters": {
        "url": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', `make http request URL with snapshot_id \nfor example:\nhttps://api.brightdata.com/datasets/v3/snapshot/your_snapshot_id`, 'string') }}",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "format",
              "value": "json"
            }
          ]
        },
        "toolDescription": "Makes an HTTP request if when you snapshot_id in ready status and returns the response data",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "72be1274-d741-46b1-8fb9-edfd4dc44e69",
      "name": "Pinterest Keyword Input",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        40,
        -120
      ],
      "parameters": {
        "options": {},
        "formTitle": "Pinterest",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Keywords",
              "requiredField": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ea43cb15-38f9-46c7-b1da-320a2687d65a",
      "name": "Wait for 1 Minute",
      "type": "@n8n/n8n-nodes-langchain.toolCode",
      "disabled": true,
      "position": [
        1180,
        360
      ],
      "parameters": {
        "jsCode": "async function sleep(ms) {\n  return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// \u23f1\ufe0f 1 Minute = 60000 ms\nawait sleep(60000);\n\nreturn [\n  {\n    json: {\n      message: \"1 minute wait done\",\n      originalInput: $json[\"message\"] || \"No input\"\n    }\n  }\n];\n"
      },
      "typeVersion": 1.2
    },
    {
      "id": "834ca6f4-0f62-4de3-a321-20455864df1f",
      "name": "Keyword-based Scraping Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        360,
        -120
      ],
      "parameters": {
        "text": "=\nYou are an AI-powered Pinterest content scraping agent. Your goal is to find relevant content based on user-provided keywords.\n\n**Instructions:**\n1. The user will provide a keyword {{ $json.Keywords }}.\n2. Your primary task is to initiate a Pinterest content scraping job using the provided `BrightData Pinterest Scraping` tool with the given keyword.\n3. Once the scraping job is launched, you must use the `Check Scraping Status` tool to monitor its progress. You need to keep checking the status until it reports \"ready\". If the status is \"running\", you should indicate that you are waiting and will check again.\n4. Once the status is \"ready\", use the `Fetch Pinterest Snapshot Data` tool to download the scraped content.\n5. After successfully fetching the data, present the raw scraped data as your final output.",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "29790c94-25fc-4bb3-89ec-1bc64bf0558d",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -440,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 660,
        "height": 140,
        "content": "\ud83d\udccc Notes Placeholder  \nCurrently unused \u2014 ideal for adding documentation, reminders, or tips related to this automation.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "65d06d4d-4ff4-4db6-a8fa-3ffb4cc144e6",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        -200
      ],
      "parameters": {
        "color": 3,
        "width": 380,
        "height": 280,
        "content": "\"This is the final output step where formatted Pinterest content is saved for future use, reporting, or distribution.\""
      },
      "typeVersion": 1
    },
    {
      "id": "7bad4070-9b30-4929-89c0-7130a6021349",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -220
      ],
      "parameters": {
        "width": 260,
        "height": 280,
        "content": "Extracts and structures scraped Pinterest data into clean fields like Title, URL, Content, Image URL, Hashtags, etc."
      },
      "typeVersion": 1
    },
    {
      "id": "e5e34ef4-5344-4aff-9dc9-3094362c35f0",
      "name": "Format & Extract Pinterest Content",
      "type": "n8n-nodes-base.code",
      "position": [
        880,
        -120
      ],
      "parameters": {
        "jsCode": "const results = [];\n\nfor (const item of $input.all()) {\n  const rawOutput = item.json.output;\n\n  if (!rawOutput) continue;\n\n  const records = rawOutput.split(/\\*\\*Pin \\d+:\\*\\*/g);\n\n  for (let i = 1; i < records.length; i++) {\n    const recordText = records[i];\n    if (recordText.trim() === '') continue;\n\n    const extractedItem = {};\n\n    // Extract fields using updated regex\n    const urlMatch = recordText.match(/- \\*\\*URL:\\*\\* (.*)/);\n    if (urlMatch) extractedItem.URL = urlMatch[1].trim();\n\n    const postIdMatch = recordText.match(/- \\*\\*Post ID:\\*\\* (.*)/);\n    if (postIdMatch) extractedItem.PostID = postIdMatch[1].trim();\n\n    const titleMatch = recordText.match(/- \\*\\*Title:\\*\\* (.*)/);\n    if (titleMatch) extractedItem.Title = titleMatch[1].trim();\n\n    const contentMatch = recordText.match(/- \\*\\*Content:\\*\\* (.*)/);\n    if (contentMatch) extractedItem.Content = contentMatch[1].trim();\n\n    const datePostedMatch = recordText.match(/- \\*\\*Date Posted:\\*\\* (.*)/);\n    if (datePostedMatch) extractedItem.DatePosted = datePostedMatch[1].trim();\n\n    const userMatch = recordText.match(/- \\*\\*User:\\*\\* (.*)/);\n    if (userMatch) extractedItem.User = userMatch[1].trim();\n\n    const engagementMatch = recordText.match(/- \\*\\*Engagement:\\*\\* (\\d+) likes, (\\d+) comment/);\n    if (engagementMatch) {\n      extractedItem.Likes = parseInt(engagementMatch[1], 10);\n      extractedItem.Comments = parseInt(engagementMatch[2], 10);\n    }\n\n    const mediaMatch = recordText.match(/- \\*\\*Media:\\*\\* (.*)/);\n    if (mediaMatch) extractedItem.Media = mediaMatch[1].trim();\n\n    const imageUrlMatch = recordText.match(/- \\*\\*Image URL:\\*\\* (.*)/);\n    if (imageUrlMatch) extractedItem.ImageURL = imageUrlMatch[1].trim();\n\n    const categoriesMatch = recordText.match(/- \\*\\*Categories:\\*\\* (.*)/);\n    if (categoriesMatch) {\n      extractedItem.Categories = categoriesMatch[1].split(',').map(s => s.trim());\n    }\n\n    const hashtagsMatch = recordText.match(/- \\*\\*Hashtags:\\*\\* (.*)/);\n    if (hashtagsMatch) {\n      extractedItem.Hashtags = hashtagsMatch[1].split(',').map(s => s.trim());\n    }\n\n    const commentMatch = recordText.match(/- \\*\\*Comment:\\*\\* (.*)/);\n    if (commentMatch) extractedItem.Comment = commentMatch[1].trim();\n\n    const commentsSectionMatch = recordText.match(/- \\*\\*Comments:\\*\\* (.*)/);\n    if (commentsSectionMatch) {\n      extractedItem.CommentsText = commentsSectionMatch[1].split(',').map(s => s.trim());\n    }\n\n    if (Object.keys(extractedItem).length > 0) {\n      results.push({ json: extractedItem });\n    }\n  }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "7528da1f-032c-49f6-b088-997119a72b36",
      "name": "Save Pinterest Data to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1260,
        -120
      ],
      "parameters": {
        "columns": {
          "value": {
            "Title": "={{ $json.Title }}",
            "Content": "={{ $json.Content }}",
            "Post URL": "={{ $json.URL }}",
            "Image URL": "={{ $json.ImageURL }}"
          },
          "schema": [
            {
              "id": "Post URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Post URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Content",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Image URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Image URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "GOOGLE_SHEET_ID_PLACEHOLDER"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.6
    },
    {
      "id": "1ed9bda3-86ca-4699-b5a5-c90672a7dc9f",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        700,
        -520
      ],
      "parameters": {
        "color": 7,
        "content": "Create a copy of this sample sheet:\n\nhttps://docs.google.com/spreadsheets/d/SAMPLE_SHEET_ID/edit"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "WORKFLOW_VERSION_ID",
  "connections": {
    "Wait for 1 Minute": {
      "ai_tool": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check Scraping Status": {
      "ai_tool": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Pinterest Keyword Input": {
      "main": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keyword-based Scraping Agent": {
      "main": [
        [
          {
            "node": "Format & Extract Pinterest Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "BrightData Pinterest Scraping": {
      "ai_tool": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Pinterest Snapshot Data": {
      "ai_tool": [
        [
          {
            "node": "Keyword-based Scraping Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Format & Extract Pinterest Content": {
      "main": [
        [
          {
            "node": "Save Pinterest Data to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}