{
  "id": "UGLIZpcTDotxu1nV",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "11 Monitor Social Ad Performance",
  "tags": [],
  "nodes": [
    {
      "id": "72af5a15-95d1-488b-a9a8-6eb31dc6eb4c",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        460,
        240
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "37046d2c-78fd-48fe-aa34-8151eadff9f0",
      "name": "MCP Client",
      "type": "n8n-nodes-mcp.mcpClientTool",
      "position": [
        600,
        240
      ],
      "parameters": {
        "toolName": "scrape_as_markdown",
        "operation": "executeTool",
        "toolParameters": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Tool_Parameters', ``, 'json') }}"
      },
      "credentials": {
        "mcpClientApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ee246d60-83c9-45bb-9537-65bc2054c561",
      "name": "\ud83d\udd01 Check Ads Every Hour",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "1ea00dae-2733-42af-8ad3-7560210a214d",
      "name": "\ud83d\udce5 Set facebook ad dashboard URL",
      "type": "n8n-nodes-base.set",
      "position": [
        220,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "25ed5a8d-5316-493e-aa16-d93b1dfa9ba8",
              "name": "url",
              "type": "string",
              "value": "https://www.facebook.com/ads/library/?active_status=all&ad_type=all&country=US&q=nike&sort_data[direction]=desc&sort_data[mode]=relevancy_monthly_grouped"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "61aceca9-5347-462f-b037-b0f89db55f87",
      "name": "\ud83e\udde0 Scrape Ads via MCP Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        480,
        0
      ],
      "parameters": {
        "text": "=scrape the data from the from facebook ads dashboard:\n{{ $json.url }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2
    },
    {
      "id": "5ce15013-60bf-41b2-afa3-bfbdc014c007",
      "name": "\ud83d\udd04 Return One Ad at a Time",
      "type": "n8n-nodes-base.code",
      "position": [
        920,
        0
      ],
      "parameters": {
        "jsCode": "// Input: full JSON from agent, stored in $json\n// Assumes: $json.ads is an array of ad objects\n\nconst ads = $json.ads;\n\n// Return only the first ad\nif (ads && ads.length > 0) {\n  return [ads[0]];\n} else {\n  return []; // no ads found\n}\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c4f10143-aac8-44c9-b02f-9c6262d5a442",
      "name": "\ud83d\udea8 Is Ad Underperforming?",
      "type": "n8n-nodes-base.if",
      "position": [
        1100,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bc9e2914-a4df-4a01-a093-a788dff98603",
              "operator": {
                "type": "number",
                "operation": "lt"
              },
              "leftValue": "={{ $json.estimated_ctr }}",
              "rightValue": 1
            },
            {
              "id": "aa6b27ad-9603-486d-b063-12712082c555",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.estimated_cpa }}",
              "rightValue": 10
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7d6e60e6-4d6a-4fc8-a63b-0b301d6ebf10",
      "name": "\ud83d\udcec Send Alert Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1440,
        -100
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<h2>\ud83d\udcc9 Ad Alert: Performance Below Threshold</h2><p><strong>Ad Title:</strong> {{$json.ad_title}}</p><p><strong>Status:</strong> {{$json.status}}</p><p><strong>Estimated CTR:</strong> {{$json.estimated_ctr}}%</p><p><strong>Estimated CPA:</strong> ${{$json.estimated_cpa}}</p><p><strong>Start Date:</strong> {{$json.start_date}}</p><p><strong>Platforms:</strong> {{$json.platforms.join(', ')}}</p><p><strong>Ad Text:</strong><br>{{$json.ad_text}}</p><p><a href='{{$json.media_url}}'>View Media</a></p>",
        "options": {},
        "subject": "\ud83d\udea8 Underperforming Ad Detected"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ec09018c-78e8-4c08-935b-d98e7b23ecbe",
      "name": "\u2705 Do Nothing (Ad is OK)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1440,
        100
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "f5749714-9f5b-4230-9314-68555ce76171",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -60,
        -700
      ],
      "parameters": {
        "color": 2,
        "width": 420,
        "height": 880,
        "content": "## \ud83e\udde9 SECTION 1: **Trigger & Input Setup**\n\n**\ud83d\udd01 Check Ads Every Hour** + **\ud83d\udce5 Set Query Input (Brand or URL)**\n\ud83d\udccd *Nodes: `Schedule Trigger`, `Edit Fields`*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83d\udd01 Schedule Trigger** fires the workflow automatically (e.g., every hour).\n* **\ud83d\udce5 Edit Fields** lets you define what brand or keyword to track (e.g., \u201cNike\u201d).\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nThis section is like setting the alarm clock \u23f0 and telling the system **what you're looking for**.\nYou don\u2019t need to code\u2014just input the keyword (like \u201cNike\u201d) and the rest is automatic.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a4fc03cf-b7a2-4612-aeab-c17ac3069486",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        440,
        -1080
      ],
      "parameters": {
        "color": 5,
        "width": 320,
        "height": 1260,
        "content": "## \ud83e\udd16 SECTION 2: **Scrape Ads via AI Agent (Bright Data MCP)**\n\n**\ud83e\udde0 Scrape Ads via MCP Agent**\n\ud83d\udccd *Node: `AI Agent` (with sub-nodes: `OpenAI Chat`, `MCP Client`, `Structured Output Parser`)*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83e\udde0 AI Agent** uses Bright Data MCP to simulate a real user and scrape ad data from the Facebook Ads Library.\n* It sends the query input from Section 1 and fetches ad performance data (CTR, CPA, media, text, etc.).\n* The result is parsed cleanly into JSON.\n\n### \ud83e\udd16 Behind the Scenes:\n\n* \ud83d\udd10 Logs in with mobile headers via Bright Data MCP\n* \ud83d\udcc4 Extracts only **relevant ad details**\n* \ud83e\udd16 Uses OpenAI model to structure & clean the output\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nYou don\u2019t have to worry about scraping code or browser automation.\nThis **AI Agent does the dirty work**, like a robot assistant crawling Facebook ads and bringing back a summary of ad performance.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "79a75c43-404f-426c-bbc5-c3ea755cde3f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -920
      ],
      "parameters": {
        "color": 6,
        "width": 340,
        "height": 1100,
        "content": "## \ud83d\udd0e SECTION 3: **Process a Single Ad & Check If It's Underperforming**\n\n**\ud83d\udd04 Return One Ad at a Time** + **\ud83d\udea8 Is Ad Underperforming?**\n\ud83d\udccd *Nodes: `Code`, `If`*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83d\udd04 Code Node** reads the list of ads from the agent and **returns only one ad per run**.\n  It uses **n8n\u2019s memory** to remember which ad was shown last and avoids repeats.\n* **\ud83d\udea8 If Node** checks:\n\n  * Is CTR less than 1%?\n  * Is CPA greater than \\$10?\n\nIf both are true, it's considered **underperforming**.\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nThink of this like flipping through a file one page at a time \ud83d\udcc4.\nThe system checks each ad: \u201cIs this one bad?\u201d\u2014if yes, it takes action.\nIf no, it skips quietly.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7b51b10e-00d7-42d9-b699-d28732f04943",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        -1040
      ],
      "parameters": {
        "color": 3,
        "width": 280,
        "height": 1280,
        "content": "## \ud83d\udcec SECTION 4: **Take Action Based on Ad Quality**\n\n**\ud83d\udcec Send Alert Email** + **\u2705 Do Nothing (Ad is OK)**\n\ud83d\udccd *Nodes: `Gmail`, `No Operation`*\n\n### \ud83d\udd27 What Happens:\n\n* If the ad is **underperforming**, the **\ud83d\udcec Gmail Node** sends you an alert:\n\n  * Ad Title\n  * Performance stats (CTR, CPA)\n  * Link to the media\n* If it\u2019s performing well, the flow silently ends at **\u2705 Do Nothing**.\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nYou\u2019ll get an email only **when action is needed**, so your inbox stays clean.\nIf the ad is fine, the workflow smartly does nothing \u2705\u2014saving time and distractions.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a496134d-ecc0-4f90-bdd9-0e0cd102794d",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1960,
        -680
      ],
      "parameters": {
        "color": 4,
        "width": 1300,
        "height": 320,
        "content": "=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4652568e-1bcc-4ba8-bcaa-79043084b1a3",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1960,
        -340
      ],
      "parameters": {
        "color": 4,
        "width": 1289,
        "height": 2778,
        "content": "# \ud83d\udea8 Smart Ad Monitor: Auto-Scrape Facebook Ads & Alert on Underperformance (via Bright Data MCP)\n---\n\n## \ud83c\udfaf **Workflow Goal:**\n\nAutomatically monitor Facebook Ads (via Bright Data MCP), analyze performance, and send alerts if ads are underperforming.\n\n---\n\n## \ud83e\udde9 SECTION 1: **Trigger & Input Setup**\n\n**\ud83d\udd01 Check Ads Every Hour** + **\ud83d\udce5 Set Query Input (Brand or URL)**\n\ud83d\udccd *Nodes: `Schedule Trigger`, `Edit Fields`*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83d\udd01 Schedule Trigger** fires the workflow automatically (e.g., every hour).\n* **\ud83d\udce5 Edit Fields** lets you define what brand or keyword to track (e.g., \u201cNike\u201d).\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nThis section is like setting the alarm clock \u23f0 and telling the system **what you're looking for**.\nYou don\u2019t need to code\u2014just input the keyword (like \u201cNike\u201d) and the rest is automatic.\n\n---\n\n## \ud83e\udd16 SECTION 2: **Scrape Ads via AI Agent (Bright Data MCP)**\n\n**\ud83e\udde0 Scrape Ads via MCP Agent**\n\ud83d\udccd *Node: `AI Agent` (with sub-nodes: `OpenAI Chat`, `MCP Client`, `Structured Output Parser`)*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83e\udde0 AI Agent** uses Bright Data MCP to simulate a real user and scrape ad data from the Facebook Ads Library.\n* It sends the query input from Section 1 and fetches ad performance data (CTR, CPA, media, text, etc.).\n* The result is parsed cleanly into JSON.\n\n### \ud83e\udd16 Behind the Scenes:\n\n* \ud83d\udd10 Logs in with mobile headers via Bright Data MCP\n* \ud83d\udcc4 Extracts only **relevant ad details**\n* \ud83e\udd16 Uses OpenAI model to structure & clean the output\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nYou don\u2019t have to worry about scraping code or browser automation.\nThis **AI Agent does the dirty work**, like a robot assistant crawling Facebook ads and bringing back a summary of ad performance.\n\n---\n\n## \ud83d\udd0e SECTION 3: **Process a Single Ad & Check If It's Underperforming**\n\n**\ud83d\udd04 Return One Ad at a Time** + **\ud83d\udea8 Is Ad Underperforming?**\n\ud83d\udccd *Nodes: `Code`, `If`*\n\n### \ud83d\udd27 What Happens:\n\n* **\ud83d\udd04 Code Node** reads the list of ads from the agent and **returns only one ad per run**.\n  It uses **n8n\u2019s memory** to remember which ad was shown last and avoids repeats.\n* **\ud83d\udea8 If Node** checks:\n\n  * Is CTR less than 1%?\n  * Is CPA greater than \\$10?\n\nIf both are true, it's considered **underperforming**.\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nThink of this like flipping through a file one page at a time \ud83d\udcc4.\nThe system checks each ad: \u201cIs this one bad?\u201d\u2014if yes, it takes action.\nIf no, it skips quietly.\n\n---\n\n## \ud83d\udcec SECTION 4: **Take Action Based on Ad Quality**\n\n**\ud83d\udcec Send Alert Email** + **\u2705 Do Nothing (Ad is OK)**\n\ud83d\udccd *Nodes: `Gmail`, `No Operation`*\n\n### \ud83d\udd27 What Happens:\n\n* If the ad is **underperforming**, the **\ud83d\udcec Gmail Node** sends you an alert:\n\n  * Ad Title\n  * Performance stats (CTR, CPA)\n  * Link to the media\n* If it\u2019s performing well, the flow silently ends at **\u2705 Do Nothing**.\n\n### \ud83e\uddd1\u200d\ud83d\udcbc For Beginners:\n\nYou\u2019ll get an email only **when action is needed**, so your inbox stays clean.\nIf the ad is fine, the workflow smartly does nothing \u2705\u2014saving time and distractions.\n\n---\n\n## \ud83c\udf08 **Summary (with Icons)**\n\n| Section                  | Purpose                                | Icons    |\n| ------------------------ | -------------------------------------- | -------- |\n| \ud83d\udd01 **Trigger & Input**   | Start on schedule, set query keyword   | \u23f0 \ud83d\udcdd     |\n| \ud83e\udd16 **AI Agent Scraping** | Use Bright Data MCP to collect ad data | \ud83e\udde0 \ud83d\udce1 \ud83d\udcc4 |\n| \ud83d\udd0d **Ad Evaluation**     | Check ad metrics one-by-one            | \ud83d\udd04 \ud83d\udcca    |\n| \ud83d\udcec **Action Section**    | Alert via Gmail or do nothing          | \ud83d\udce7 \u2705     |\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9bf1083f-82d7-4a5d-8006-b160e97ca7a9",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1720,
        -1040
      ],
      "parameters": {
        "color": 7,
        "width": 380,
        "height": 240,
        "content": "## I\u2019ll receive a tiny commission if you join Bright Data through this link\u2014thanks for fueling more free content!\n\n### https://get.brightdata.com/1tndi4600b25"
      },
      "typeVersion": 1
    },
    {
      "id": "58f73834-e35a-42d3-9385-76ee106eeb1d",
      "name": "Auto-fixing Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserAutofixing",
      "position": [
        740,
        240
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "4337a0cc-b008-494b-ae51-ada351830438",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        700,
        460
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "df736167-a084-49b2-bca8-1e9b12862f79",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        880,
        460
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"ads\": [\n    {\n      \"ad_id\": \"1234567890\",\n      \"advertiser\": \"Nike\",\n      \"ad_title\": \"Just Do It - Air Max 2025\",\n      \"platforms\": [\"Facebook\", \"Instagram\"],\n      \"status\": \"Active\",\n      \"start_date\": \"2025-06-25\",\n      \"ad_text\": \"Feel the future. Experience Air Max like never before.\",\n      \"media_type\": \"Image\",\n      \"media_url\": \"https://example.com/ad1.jpg\",\n      \"impressions\": 150000,\n      \"engagement\": {\n        \"likes\": 1200,\n        \"shares\": 300,\n        \"comments\": 220\n      },\n      \"estimated_ctr\": 0.85,\n      \"estimated_cpa\": 11.20\n    },\n    {\n      \"ad_id\": \"0987654321\",\n      \"advertiser\": \"Nike\",\n      \"ad_title\": \"Nike Running Club Promo\",\n      \"platforms\": [\"Facebook\"],\n      \"status\": \"Active\",\n      \"start_date\": \"2025-06-20\",\n      \"ad_text\": \"Join the Nike Running Club and push your limits.\",\n      \"media_type\": \"Video\",\n      \"media_url\": \"https://example.com/ad2.mp4\",\n      \"impressions\": 80000,\n      \"engagement\": {\n        \"likes\": 600,\n        \"shares\": 80,\n        \"comments\": 95\n      },\n      \"estimated_ctr\": 0.45,\n      \"estimated_cpa\": 15.90\n    },\n    {\n      \"ad_id\": \"1122334455\",\n      \"advertiser\": \"Nike\",\n      \"ad_title\": \"Summer Sale \u2013 Up to 40% Off!\",\n      \"platforms\": [\"Messenger\", \"Instagram\"],\n      \"status\": \"Inactive\",\n      \"start_date\": \"2025-06-10\",\n      \"ad_text\": \"Heat up your summer with big savings on Nike gear.\",\n      \"media_type\": \"Image\",\n      \"media_url\": \"https://example.com/ad3.jpg\",\n      \"impressions\": 200000,\n      \"engagement\": {\n        \"likes\": 1900,\n        \"shares\": 410,\n        \"comments\": 350\n      },\n      \"estimated_ctr\": 1.20,\n      \"estimated_cpa\": 7.60\n    }\n  ],\n  \"scraped_at\": \"2025-06-30T20:50:00Z\"\n}\n"
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9cafbbb6-0fe7-4384-ac97-e1d781957885",
  "connections": {
    "MCP Client": {
      "ai_tool": [
        [
          {
            "node": "\ud83e\udde0 Scrape Ads via MCP Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "\ud83e\udde0 Scrape Ads via MCP Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Auto-fixing Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "\ud83e\udde0 Scrape Ads via MCP Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Auto-fixing Output Parser",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd01 Check Ads Every Hour": {
      "main": [
        [
          {
            "node": "\ud83d\udce5 Set facebook ad dashboard URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udea8 Is Ad Underperforming?": {
      "main": [
        [
          {
            "node": "\ud83d\udcec Send Alert Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\u2705 Do Nothing (Ad is OK)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd04 Return One Ad at a Time": {
      "main": [
        [
          {
            "node": "\ud83d\udea8 Is Ad Underperforming?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udde0 Scrape Ads via MCP Agent": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Return One Ad at a Time",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce5 Set facebook ad dashboard URL": {
      "main": [
        [
          {
            "node": "\ud83e\udde0 Scrape Ads via MCP Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}