AutomationFlowsAI & RAG › Analyze Competitor Instagram Engagement with Bright Data

Analyze Competitor Instagram Engagement with Bright Data

Original n8n title: Analyze Competitor Instagram Engagement with Bright Data and Gpt-5.5

ByYaron Been @yaron-nofluff on n8n.io

Analyze competitor Instagram engagement by scraping profiles with Bright Data and scoring them with GPT-5.5.

Cron / scheduled trigger★★★★☆ complexityAI-powered20 nodesGoogle SheetsHTTP RequestAgentOpenAI ChatGmail
AI & RAG Trigger: Cron / scheduled Nodes: 20 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Gmail 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
{
  "nodes": [
    {
      "id": "58d72e7d-b991-4504-be10-41530abb1568",
      "name": "Daily Engagement Scan",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        480,
        688
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cee353f1-b8bc-4775-b411-2432e9da5c27",
      "name": "Read Competitor Accounts",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        752,
        688
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "competitor_accounts"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3442733f-9516-44e8-9957-d426dae69428",
      "name": "Scrape Instagram Profiles",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1232,
        688
      ],
      "parameters": {
        "url": "=https://api.brightdata.com/datasets/v3/scrape?dataset_id=gd_l1vikfch901nx3by4&format=json",
        "method": "POST",
        "options": {
          "timeout": 60000
        },
        "jsonBody": "={{ JSON.stringify({ input: [{ url: $json.url }] }) }}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "82fe687d-c4ae-43cd-8347-6497179bf210",
      "name": "Validate BD Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1488,
        688
      ],
      "parameters": {
        "jsCode": "const input = $input.first().json;\n\n// Handle array response (synchronous success)\nif (Array.isArray(input)) {\n  if (input.length === 0) {\n    return [{ json: { error: 'Bright Data returned empty results', status: 'no_data' } }];\n  }\n  return input.map(item => ({ json: { ...item, status: 'ok' } }));\n}\n\n// Handle object response\nif (input.snapshot_id) {\n  return [{ json: { error: 'Async response - snapshot not ready', snapshot_id: input.snapshot_id, status: 'async_pending' } }];\n}\n\nif (input.error || input.message) {\n  return [{ json: { error: input.error || input.message, status: 'api_error' } }];\n}\n\n// Pass through valid single-object response\nreturn [{ json: { ...input, status: 'ok' } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "be302640-982d-4f89-af14-03355442d886",
      "name": "Analyze Engagement",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueErrorOutput",
      "position": [
        2000,
        688
      ],
      "parameters": {
        "text": "Analyze this Instagram competitor profile.\n\nCompetitor: {{ $json.competitor_name }}\nIndustry: {{ $json.our_industry }}\n\nScraped profile data:\n{{ JSON.stringify($json, null, 2) }}",
        "options": {
          "systemMessage": "You are an Instagram competitive intelligence analyst.\nYou receive scraped Instagram profile data for a competitor account.\n\nYour task: analyze the profile metrics and score the competitor on engagement quality.\n\nScoring rubric (0-25 each, total engagement_score 0-100):\n\nfollower_growth_signal (0-25):\n  0-5: Declining or stagnant follower count, signs of bought followers\n  6-12: Slow but organic growth patterns\n  13-19: Steady growth with periodic spikes from viral content\n  20-25: Strong consistent growth indicating high audience demand\n\nengagement_rate_quality (0-25):\n  0-5: Below 0.5% engagement rate or engagement looks artificial\n  6-12: 0.5-2% rate, mostly passive likes with few comments\n  13-19: 2-5% rate with genuine comment threads\n  20-25: 5%+ rate with deep audience interaction and saves/shares\n\ncontent_consistency (0-25):\n  0-5: Sporadic posting, no visual or thematic coherence\n  6-12: Semi-regular posting, some brand consistency\n  13-19: Regular cadence with clear content pillars\n  20-25: Highly consistent brand voice, posting schedule, and visual identity\n\naudience_authenticity (0-25):\n  0-5: High bot/fake follower indicators\n  6-12: Some suspicious patterns but mostly real\n  13-19: Predominantly authentic audience\n  20-25: Highly authentic, engaged community with UGC signals\n\nCRITICAL OUTPUT RULES:\n- Return ONLY a raw JSON object. Nothing else.\n- No markdown. No code fences. No explanations before or after.\n\nOutput schema:\n{\n  \"competitor_name\": \"string\",\n  \"follower_count\": number,\n  \"follower_growth_signal\": number,\n  \"engagement_rate_quality\": number,\n  \"content_consistency\": number,\n  \"audience_authenticity\": number,\n  \"engagement_score\": number,\n  \"top_content_types\": [\"string\"],\n  \"posting_frequency\": \"string\",\n  \"key_strengths\": [\"string\"],\n  \"key_weaknesses\": [\"string\"],\n  \"strategic_takeaway\": \"string\",\n  \"eval\": {\n    \"confidence\": 0.0,\n    \"reasoning\": \"string\",\n    \"data_quality\": \"high|medium|low\",\n    \"evidence_count\": 0\n  }\n}\n\nSELF-EVALUATION (mandatory):\nInclude an \"eval\" object in your response with:\n- confidence: float 0.0-1.0, your confidence in the analysis quality\n- reasoning: 1 sentence explaining your confidence level\n- data_quality: \"high\", \"medium\", or \"low\" based on input completeness\n- evidence_count: integer, number of data points you based the analysis on"
        },
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "509961a9-0df1-45c1-9b4e-4267424aecdc",
      "name": "GPT-5.5 Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2000,
        928
      ],
      "parameters": {
        "model": "gpt-5.5",
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "64d17917-37d7-4b5a-affd-4591b8209696",
      "name": "Parse AI Output",
      "type": "n8n-nodes-base.code",
      "position": [
        2272,
        688
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.output || $input.first().json.text || '';\nconst clean = raw.replace(/```json\\n?/g, '').replace(/```\\n?/g, '').trim();\n\nlet parsed;\ntry {\n  parsed = JSON.parse(clean);\n} catch (e) {\n  parsed = {\n    error: 'Failed to parse AI response',\n    parse_error: e.message,\n    raw_preview: raw.substring(0, 200)\n  };\n}\nconst original = $(\"Read Competitor Accounts\").first().json;\n\nreturn [{ json: { ...original, ...parsed, processed_at: new Date().toISOString() } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "bb4228b8-6760-427e-9655-d1ddd6eb207d",
      "name": "IF Confidence >= 0.7",
      "type": "n8n-nodes-base.if",
      "onError": "continueErrorOutput",
      "position": [
        2528,
        688
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "87d141e2-e963-4e85-93d1-ac205bdf08a0",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.eval.confidence }}",
              "rightValue": 0.7
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9d4e2c5e-faa9-4f72-812b-1d7b53038064",
      "name": "IF Engagement >= 75",
      "type": "n8n-nodes-base.if",
      "onError": "continueErrorOutput",
      "position": [
        2784,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "33d3c50a-635f-4643-a195-8215feb812b2",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "{{ $json.engagement_score }}",
              "rightValue": 75
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f6f6a556-df6d-4f61-be8c-3e4e68056b3f",
      "name": "Alert Top Performer",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3040,
        400
      ],
      "parameters": {
        "sendTo": "={{ $('Read Competitor Accounts').first().json.team_email || 'team@company.com' }}",
        "message": "=Competitor {{ $json.competitor_name }} scored {{ $json.engagement_score }}/100 on engagement analysis.\n\nKey strengths: {{ $json.key_strengths }}\nStrategic takeaway: {{ $json.strategic_takeaway }}",
        "options": {},
        "subject": "=High-Performing Competitor: {{ $json.competitor_name }} (Score: {{ $json.engagement_score }}/100)",
        "emailType": "text"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e7f72917-6374-4673-8088-d67103561400",
      "name": "Append Top Performers",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3040,
        544
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "top_performers"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4750a4c4-d84f-4ac1-a7a2-2e128f295bde",
      "name": "Append Engagement Analysis",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3040,
        768
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "engagement_analysis"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "05c441ad-a699-49e9-9877-fffa614d8ac4",
      "name": "Append Low Confidence",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2784,
        768
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "low_confidence_engagement"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8aa665c6-af9d-4c38-8dad-21643fbb942e",
      "name": "Calculate Raw Engagement Metrics",
      "type": "n8n-nodes-base.code",
      "position": [
        1744,
        688
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nreturn items.map(item => {\n  const d = item.json;\n  const followers = d.followers_count || d.follower_count || 1;\n  const avgLikes = d.avg_likes || d.edge_liked_by || 0;\n  const avgComments = d.avg_comments || 0;\n  const engagementRate = ((avgLikes + avgComments) / followers * 100).toFixed(2);\n  const postsPerWeek = d.media_count ? Math.min(d.media_count / 52, 20).toFixed(1) : 'unknown';\n  return { json: { ...d, calculated_engagement_rate: parseFloat(engagementRate),\n    posts_per_week: postsPerWeek, metrics_calculated: true } };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "f528564a-35c3-4e31-84df-950f9c27b293",
      "name": "Process Items One by One",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        992,
        688
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "b72803b0-5834-4313-8d00-6dccb93c4632",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        -96
      ],
      "parameters": {
        "width": 560,
        "height": 720,
        "content": "### How it works\n\nThis workflow monitors competitor Instagram accounts on a daily schedule. It reads profile URLs from a Google Sheet, scrapes each one through the Bright Data Instagram Profiles API, and calculates raw engagement metrics like engagement rate and posting frequency.\n\nGPT-5.5 then analyzes each profile across four dimensions: follower growth signals, engagement rate quality, content consistency, and audience authenticity. Each dimension is scored 0-25 for a total engagement score of 0-100.\n\nTwo quality gates filter the results. A confidence check (>= 0.7) discards unreliable AI outputs. An engagement threshold (>= 75) separates top performers from the rest. High scorers go to the 'top_performers' sheet and trigger a Gmail alert. All other results go to 'engagement_analysis'. Low-confidence outputs land in 'low_confidence_engagement' for review.\n\n### Setup\n\n1. Create a Google Sheet with a tab named 'competitor_accounts' and a 'url' column containing Instagram profile URLs\n2. Add your Bright Data API key as an HTTP Header Auth credential (Bearer token)\n3. Add your OpenAI API key\n4. Connect Google Sheets via OAuth\n5. Connect Gmail via OAuth for alerts\n6. Update the recipient in the 'Alert Top Performer' node\n\nCost: ~$0.01-0.03 per profile (Bright Data) + ~$0.005 per analysis (GPT-5.5)"
      },
      "typeVersion": 1
    },
    {
      "id": "69ff9502-6db9-4c0e-9920-d304badf2990",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        496
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 296,
        "content": "## 1. Data Input\n\nTriggers daily at 8 AM. Reads competitor Instagram profile URLs from the 'competitor_accounts' sheet and processes them one at a time."
      },
      "typeVersion": 1
    },
    {
      "id": "a5062c63-4a9f-4e37-9dea-7ada7a71bd21",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        464
      ],
      "parameters": {
        "color": 7,
        "width": 672,
        "height": 328,
        "content": "## 2. Scrape & Validate\n\nSends each URL to the Bright Data Instagram API, validates the response, and calculates raw engagement metrics."
      },
      "typeVersion": 1
    },
    {
      "id": "8313d152-591c-4ab9-8e03-31e27d9615ca",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1984,
        416
      ],
      "parameters": {
        "color": 7,
        "width": 396,
        "height": 448,
        "content": "## 3. AI Analysis\n\nGPT-5.5 scores each profile on follower growth, engagement quality, content consistency, and audience authenticity (0-100)."
      },
      "typeVersion": 1
    },
    {
      "id": "ed241d1d-2609-4d1d-91e1-0cd416cec306",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2480,
        320
      ],
      "parameters": {
        "color": 7,
        "width": 832,
        "height": 728,
        "content": "## 4. Quality Gates & Output\n\nConfidence gate (>= 0.7) and engagement threshold (>= 75) route results to three sheets. Top performers trigger Gmail alerts."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "GPT-5.5 Model": {
      "ai_languageModel": [
        [
          {
            "node": "Analyze Engagement",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Output": {
      "main": [
        [
          {
            "node": "IF Confidence >= 0.7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Engagement": {
      "main": [
        [
          {
            "node": "Parse AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Engagement >= 75": {
      "main": [
        [
          {
            "node": "Alert Top Performer",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append Top Performers",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Append Engagement Analysis",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Confidence >= 0.7": {
      "main": [
        [
          {
            "node": "IF Engagement >= 75",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Append Low Confidence",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate BD Response": {
      "main": [
        [
          {
            "node": "Calculate Raw Engagement Metrics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Low Confidence": {
      "main": [
        [
          {
            "node": "Process Items One by One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Top Performers": {
      "main": [
        [
          {
            "node": "Process Items One by One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Engagement Scan": {
      "main": [
        [
          {
            "node": "Read Competitor Accounts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Items One by One": {
      "main": [
        [
          {
            "node": "Scrape Instagram Profiles",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Competitor Accounts": {
      "main": [
        [
          {
            "node": "Process Items One by One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape Instagram Profiles": {
      "main": [
        [
          {
            "node": "Validate BD Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append Engagement Analysis": {
      "main": [
        [
          {
            "node": "Process Items One by One",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Raw Engagement Metrics": {
      "main": [
        [
          {
            "node": "Analyze Engagement",
            "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

Analyze competitor Instagram engagement by scraping profiles with Bright Data and scoring them with GPT-5.5.

Source: https://n8n.io/workflows/14014/ — 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

This n8n automation workflow automates the creation, scripting, production, and posting of YouTube videos. It leverages AI (OpenAI), image generation (PIAPI), video rendering (Shotstack), and platform

Agent, OpenAI Chat, Airtable Tool +7
AI & RAG

Created by: Peyton Leveillee Last updated: October 2025

OpenAI Chat, Google Sheets, HTTP Request +5
AI & RAG

The Multi-Model Agency Content Engine is a high-performance editorial system designed for agencies. It solves the "blank page" problem by alternating between real-world social proof and strategic expe

Google Sheets, Gmail, Google Drive +6
AI & RAG

This workflow automates the creation, rendering, approval, and posting of TikTok-style POV (Point of View) videos to Instagram, with cross-posting to Facebook and YouTube. It eliminates manual video p

OpenAI Chat, Output Parser Item List, HTTP Request +10
AI & RAG

SEO Blog Article Generation Workflow. Uses outputParserStructured, httpRequest, agent, lmChatOpenAi. Scheduled trigger; 56 nodes.

Output Parser Structured, HTTP Request, Agent +4