{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "c4d9e999-cdd3-46db-aff4-498bc09d3119",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -624,
        -592
      ],
      "parameters": {
        "color": 4,
        "width": 492,
        "height": 1332,
        "content": "## Competitor YouTube Monitor \u2014 Weekly Airtable Intelligence Report \u2014 WayinVideo Summarization + GPT-4o-mini + Airtable\n\nFor marketing teams, product managers, and growth teams who want to automatically track what competitors are saying in their YouTube video content every week \u2014 without manually watching hours of competitor videos. Every Monday at 8AM this workflow reads competitor video URLs from your Google Sheet, submits each to WayinVideo Summarization API to get a structured summary with highlights and tags, then sends the summary directly to GPT-4o-mini which extracts ten competitive intelligence fields: content type, messaging angle, key claims, target audience signals, pricing signals, strengths, weaknesses and gaps, opportunity for your team, urgency score, and urgency reasoning. Each video is saved as a structured Airtable record. The Google Sheet row is marked as Processed.\n\n## How it works\n- **1. Schedule \u2014 Every Monday 8AM** triggers the pipeline automatically each week\n- **2. Google Sheets \u2014 Read Pending Videos** reads all rows from the Video Queue tab\n- **3. WayinVideo \u2014 Submit Summarization** submits the video URL to the Summarization API\n- **4. Wait \u2014 90 Seconds** gives the API initial processing time\n- **5. WayinVideo \u2014 Get Summary Results** polls the summaries results endpoint\n- **6. IF \u2014 Summary Complete?** checks for SUCCEEDED \u2014 if not, retries via 30-second wait\n- **8. AI Agent \u2014 Extract Competitive Intelligence** sends the WayinVideo summary directly to GPT-4o-mini with full context from the sheet row \u2014 no intermediate code node needed\n- **10. Code \u2014 Parse Intelligence Output** extracts all 10 sections via regex, calculates the Monday week date, and assembles the Airtable record\n- **11. HTTP \u2014 Save to Airtable** creates one record per video with all 16 intelligence fields\n- **12. Google Sheets \u2014 Mark as Processed** updates the Video Queue row with Processed status and date\n\n## Set up steps\n1. In **3. WayinVideo \u2014 Submit Summarization** and **5. WayinVideo \u2014 Get Summary Results** \u2014 replace YOUR_WAYINVIDEO_API_KEY\n2. In **9. OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI credential\n3. In **2** and **12** \u2014 connect Google Sheets OAuth2 and replace YOUR_COMPETITOR_SHEET_ID\n4. In **11. HTTP \u2014 Save to Airtable** \u2014 replace YOUR_AIRTABLE_API_KEY (Personal Access Token, scope: data.records:write), YOUR_AIRTABLE_BASE_ID, YOUR_AIRTABLE_TABLE_NAME\n5. Create a Google Sheet named Competitor Monitor with tab Video Queue and columns: Video URL, Video Title, Competitor Name, Your Product / Brand, Status, Processed Date\n6. Create an Airtable table named Competitor Intelligence with fields: Week (Date), Competitor Name, Video Title, Video URL, Content Type, Messaging Angle, Key Claims Made, Target Audience Signals, Pricing / Offer Signals, Strengths Identified, Weaknesses / Gaps, Opportunity for Us, Urgency Score (Number), Tags, Summary, Status (default: New)"
      },
      "typeVersion": 1
    },
    {
      "id": "97d60001-1f37-46d0-94b4-9329c4162c3f",
      "name": "Section \u2014 Schedule and Queue Read",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        -224
      ],
      "parameters": {
        "color": 5,
        "width": 500,
        "height": 372,
        "content": "## Schedule and Queue Read\nTriggers every Monday at 8AM. Reads all unprocessed competitor video rows from the Video Queue tab in Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "da629f07-b75a-494c-b2a5-87a6bcfc7d24",
      "name": "Section \u2014 WayinVideo Summarization Submit and Poll",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -224
      ],
      "parameters": {
        "color": 6,
        "width": 660,
        "height": 324,
        "content": "## WayinVideo Summarization Submit and Poll\nSubmits the competitor video URL to the Summarization API. Waits 90 seconds for initial processing. Polls the results endpoint until status equals SUCCEEDED."
      },
      "typeVersion": 1
    },
    {
      "id": "522ca8a1-7b52-49d9-b629-10e5b7f7ad5f",
      "name": "Section \u2014 Summary Status Check and Retry Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        -336
      ],
      "parameters": {
        "color": 6,
        "width": 276,
        "height": 820,
        "content": "## Summary Status Check and Retry Loop\nIF checks for SUCCEEDED status. TRUE proceeds directly to AI analysis. FALSE waits 30 seconds and polls again. Loop continues until summary is ready."
      },
      "typeVersion": 1
    },
    {
      "id": "2aa34d64-963b-4b31-b1f8-37e72d9892c1",
      "name": "Section \u2014 AI Competitive Intelligence Extraction",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        -416
      ],
      "parameters": {
        "color": 6,
        "width": 260,
        "height": 756,
        "content": "## AI Competitive Intelligence Extraction\nGPT-4o-mini reads the WayinVideo summary and sheet context directly \u2014 no intermediate code node. Extracts 10 competitive intelligence fields including urgency score and opportunity for your team."
      },
      "typeVersion": 1
    },
    {
      "id": "6099b088-5122-4f97-98ea-a9b2bff2331e",
      "name": "Section \u2014 Intelligence Parse, Airtable Save, and Sheet Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1840,
        -240
      ],
      "parameters": {
        "color": 4,
        "width": 756,
        "height": 420,
        "content": "## Intelligence Parse, Airtable Save, and Sheet Update\nRegex extracts all 10 intelligence sections and calculates the Monday week date. HTTP creates an Airtable record with 16 fields. Google Sheets marks the row as Processed."
      },
      "typeVersion": 1
    },
    {
      "id": "fee0931a-65d2-425f-ae38-1da2a6c83f7d",
      "name": "1. Schedule \u2014 Every Monday 8AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -48,
        -96
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fa08dc0d-8bee-4a4a-ba01-47cced8fdb91",
      "name": "2. Google Sheets \u2014 Read Pending Videos",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        240,
        -96
      ],
      "parameters": {
        "operation": "getAll",
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_COMPETITOR_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "c00291eb-6a62-4c47-bb41-542dd5b7f52e",
      "name": "3. WayinVideo \u2014 Submit Summarization",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        512,
        -96
      ],
      "parameters": {
        "url": "https://wayinvideo-api.wayin.ai/api/v2/summaries",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"video_url\": \"{{ $json['Video URL'] }}\",\n  \"target_lang\": \"en\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7b240c55-119c-43d2-a103-63cf643902bb",
      "name": "4. Wait \u2014 90 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        752,
        -96
      ],
      "parameters": {
        "amount": 90
      },
      "typeVersion": 1.1
    },
    {
      "id": "10f33fd0-6232-4a31-a0a7-86b99141d17c",
      "name": "5. WayinVideo \u2014 Get Summary Results",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        992,
        -96
      ],
      "parameters": {
        "url": "=https://wayinvideo-api.wayin.ai/api/v2/summaries/results/{{ $('3. WayinVideo \u2014 Submit Summarization').item.json.data.id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "x-wayinvideo-api-version",
              "value": "v2"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "5f06163f-c1da-4a46-b076-b596470b72ed",
      "name": "6. IF \u2014 Summary Complete?",
      "type": "n8n-nodes-base.if",
      "position": [
        1232,
        -96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "summary-status",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.data.status }}",
              "rightValue": "SUCCEEDED"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "2415e197-a9f1-4a17-a8f0-e15ca2b2a8d7",
      "name": "7. Wait \u2014 30 Seconds Retry",
      "type": "n8n-nodes-base.wait",
      "position": [
        1232,
        112
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "d17f9ff7-2dc0-4c94-8240-3e0e0a35f321",
      "name": "8. AI Agent \u2014 Extract Competitive Intelligence",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1552,
        -112
      ],
      "parameters": {
        "text": "=You are an expert competitive intelligence analyst who specializes in extracting strategic insights from competitor video content.\n\nA competitor has published a YouTube video. WayinVideo AI has already summarized it. Your job is to analyze the summary and extract structured competitive intelligence that a marketing or product team can act on.\n\n---\n\n## CONTEXT\n- Competitor Name: {{ $('2. Google Sheets \u2014 Read Pending Videos').item.json['Competitor Name'] }}\n- Video Title: {{ $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video Title'] }}\n- Our Brand / Product: {{ $('2. Google Sheets \u2014 Read Pending Videos').item.json['Your Product / Brand'] }}\n- Video URL: {{ $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video URL'] }}\n\n## WAYINVIDEO SUMMARY OUTPUT\n- Summary: {{ $('5. WayinVideo \u2014 Get Summary Results').item.json.data.summary }}\n- Key Highlights: {{ $('5. WayinVideo \u2014 Get Summary Results').item.json.data.highlights.map(h => h.desc).join(' | ') }}\n- Tags: {{ $('5. WayinVideo \u2014 Get Summary Results').item.json.data.tags.join(', ') }}\n\n---\n\n## YOUR TASK\nAnalyze this competitor video content and extract structured competitive intelligence.\n\n## RULES\n1. Base analysis ONLY on the summary and highlights provided \u2014 no outside knowledge\n2. Be specific and actionable \u2014 generic observations are not useful\n3. Opportunities must be specific things OUR team could do in response\n4. Urgency score: 1 = low threat, 10 = immediate action needed\n5. Keep each section concise \u2014 2-4 bullet points maximum per section\n\n---\n\n## OUTPUT FORMAT\nReturn in this exact structure:\n\nCONTENT_TYPE:\n[Choose one: Product Demo / Tutorial / Thought Leadership / Case Study / Comparison / Announcement / Customer Story / Promotional / Other]\n\nMESSAGING_ANGLE:\n[What is the core message or narrative they are pushing? 2-3 sentences.]\n\nKEY_CLAIMS:\n- [Specific claim 1 they are making about their product or service]\n- [Specific claim 2]\n- [Specific claim 3 if applicable]\n\nTARGET_AUDIENCE_SIGNALS:\n[Who are they targeting based on the content? What pain points are they addressing? 2-3 sentences.]\n\nPRICING_OFFER_SIGNALS:\n[Any pricing mentions, offers, discounts, or value propositions mentioned \u2014 or 'None detected']\n\nSTRENGTHS_IDENTIFIED:\n- [What they are doing well in this content]\n- [What advantage they are highlighting]\n\nWEAKNESSES_GAPS:\n- [What they are NOT addressing that we could own]\n- [Any weak claims or missing proof]\n\nOPPORTUNITY_FOR_US:\n- [Specific action our team should take in response]\n- [Content we should create to counter or differentiate]\n\nURGENCY_SCORE:\n[Number 1-10 only]\n\nURGENCY_REASONING:\n[1 sentence explaining why you gave this urgency score]",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "35416a93-f0ca-4fb9-b675-c3f8bb6ec966",
      "name": "9. OpenAI \u2014 GPT-4o-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1552,
        80
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {},
        "builtInTools": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "8cb30852-1eea-4c4c-886f-5ea1e2fcc8e5",
      "name": "10. Code \u2014 Parse Intelligence Output",
      "type": "n8n-nodes-base.code",
      "position": [
        1888,
        -112
      ],
      "parameters": {
        "jsCode": "// Parse AI competitive intelligence output\nconst output = $input.first().json.output || '';\n\n// Extract each section\nconst contentTypeMatch = output.match(/CONTENT_TYPE:\\s*([\\s\\S]*?)(?=\\nMESSAGING_ANGLE:|$)/);\nconst messagingMatch = output.match(/MESSAGING_ANGLE:\\s*([\\s\\S]*?)(?=\\nKEY_CLAIMS:|$)/);\nconst keyClaimsMatch = output.match(/KEY_CLAIMS:\\s*([\\s\\S]*?)(?=\\nTARGET_AUDIENCE_SIGNALS:|$)/);\nconst targetAudienceMatch = output.match(/TARGET_AUDIENCE_SIGNALS:\\s*([\\s\\S]*?)(?=\\nPRICING_OFFER_SIGNALS:|$)/);\nconst pricingMatch = output.match(/PRICING_OFFER_SIGNALS:\\s*([\\s\\S]*?)(?=\\nSTRENGTHS_IDENTIFIED:|$)/);\nconst strengthsMatch = output.match(/STRENGTHS_IDENTIFIED:\\s*([\\s\\S]*?)(?=\\nWEAKNESSES_GAPS:|$)/);\nconst weaknessesMatch = output.match(/WEAKNESSES_GAPS:\\s*([\\s\\S]*?)(?=\\nOPPORTUNITY_FOR_US:|$)/);\nconst opportunityMatch = output.match(/OPPORTUNITY_FOR_US:\\s*([\\s\\S]*?)(?=\\nURGENCY_SCORE:|$)/);\nconst urgencyScoreMatch = output.match(/URGENCY_SCORE:\\s*([\\d]+)/);\nconst urgencyReasoningMatch = output.match(/URGENCY_REASONING:\\s*([\\s\\S]*)$/);\n\nconst contentType = contentTypeMatch ? contentTypeMatch[1].trim() : 'Other';\nconst messagingAngle = messagingMatch ? messagingMatch[1].trim() : '';\nconst keyClaims = keyClaimsMatch ? keyClaimsMatch[1].trim() : '';\nconst targetAudience = targetAudienceMatch ? targetAudienceMatch[1].trim() : '';\nconst pricingSignals = pricingMatch ? pricingMatch[1].trim() : 'None detected';\nconst strengths = strengthsMatch ? strengthsMatch[1].trim() : '';\nconst weaknesses = weaknessesMatch ? weaknessesMatch[1].trim() : '';\nconst opportunity = opportunityMatch ? opportunityMatch[1].trim() : '';\nconst urgencyScore = urgencyScoreMatch ? parseInt(urgencyScoreMatch[1]) : 5;\nconst urgencyReasoning = urgencyReasoningMatch ? urgencyReasoningMatch[1].trim() : '';\n\n// Get video data\nconst videoUrl = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video URL'];\nconst videoTitle = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Video Title'];\nconst competitorName = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Competitor Name'];\nconst ourBrand = $('2. Google Sheets \u2014 Read Pending Videos').item.json['Your Product / Brand'];\n\n// Get summary data\nconst summary = $('5. WayinVideo \u2014 Get Summary Results').item.json.data.summary || '';\nconst tags = Array.isArray($('5. WayinVideo \u2014 Get Summary Results').item.json.data.tags)\n  ? $('5. WayinVideo \u2014 Get Summary Results').item.json.data.tags.join(', ')\n  : '';\n\n// Get current week Monday\nconst today = new Date();\nconst weekStart = new Date(today);\nweekStart.setDate(today.getDate() - today.getDay() + 1);\nconst weekDate = weekStart.toISOString().split('T')[0];\n\nreturn [{\n  json: {\n    weekDate,\n    competitorName,\n    videoTitle,\n    videoUrl,\n    ourBrand,\n    contentType,\n    messagingAngle,\n    keyClaims,\n    targetAudience,\n    pricingSignals,\n    strengths,\n    weaknesses,\n    opportunity,\n    urgencyScore,\n    urgencyReasoning,\n    summary,\n    tags\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "497e976e-7584-4a7f-a418-4d560910897a",
      "name": "11. HTTP \u2014 Save to Airtable",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2128,
        -112
      ],
      "parameters": {
        "url": "=https://api.airtable.com/v0/YOUR_AIRTABLE_BASE_ID/YOUR_AIRTABLE_TABLE_NAME",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"fields\": {\n    \"Week\": \"{{ $json.weekDate }}\",\n    \"Competitor Name\": \"{{ $json.competitorName }}\",\n    \"Video Title\": \"{{ $json.videoTitle }}\",\n    \"Video URL\": \"{{ $json.videoUrl }}\",\n    \"Content Type\": \"{{ $json.contentType }}\",\n    \"Messaging Angle\": \"{{ $json.messagingAngle }}\",\n    \"Key Claims Made\": \"{{ $json.keyClaims }}\",\n    \"Target Audience Signals\": \"{{ $json.targetAudience }}\",\n    \"Pricing / Offer Signals\": \"{{ $json.pricingSignals }}\",\n    \"Strengths Identified\": \"{{ $json.strengths }}\",\n    \"Weaknesses / Gaps\": \"{{ $json.weaknesses }}\",\n    \"Opportunity for Us\": \"{{ $json.opportunity }}\",\n    \"Urgency Score\": {{ $json.urgencyScore }},\n    \"Tags\": \"{{ $json.tags }}\",\n    \"Summary\": \"{{ $json.summary }}\",\n    \"Status\": \"New\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_TOKEN_HERE"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f3627c74-1e44-4598-924e-ce439abe8ac1",
      "name": "12. Google Sheets \u2014 Mark as Processed",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2368,
        -112
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "Processed",
            "Video URL": "={{ $('10. Code \u2014 Parse Intelligence Output').item.json.videoUrl }}",
            "Processed Date": "={{ $now.toFormat('dd MMMM yyyy') }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Video URL"
          ]
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Video Queue"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_COMPETITOR_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "connections": {
    "4. Wait \u2014 90 Seconds": {
      "main": [
        [
          {
            "node": "5. WayinVideo \u2014 Get Summary Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. IF \u2014 Summary Complete?": {
      "main": [
        [
          {
            "node": "8. AI Agent \u2014 Extract Competitive Intelligence",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "7. Wait \u2014 30 Seconds Retry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. Wait \u2014 30 Seconds Retry": {
      "main": [
        [
          {
            "node": "5. WayinVideo \u2014 Get Summary Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "11. HTTP \u2014 Save to Airtable": {
      "main": [
        [
          {
            "node": "12. Google Sheets \u2014 Mark as Processed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9. OpenAI \u2014 GPT-4o-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "8. AI Agent \u2014 Extract Competitive Intelligence",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "1. Schedule \u2014 Every Monday 8AM": {
      "main": [
        [
          {
            "node": "2. Google Sheets \u2014 Read Pending Videos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5. WayinVideo \u2014 Get Summary Results": {
      "main": [
        [
          {
            "node": "6. IF \u2014 Summary Complete?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10. Code \u2014 Parse Intelligence Output": {
      "main": [
        [
          {
            "node": "11. HTTP \u2014 Save to Airtable",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. WayinVideo \u2014 Submit Summarization": {
      "main": [
        [
          {
            "node": "4. Wait \u2014 90 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Google Sheets \u2014 Read Pending Videos": {
      "main": [
        [
          {
            "node": "3. WayinVideo \u2014 Submit Summarization",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8. AI Agent \u2014 Extract Competitive Intelligence": {
      "main": [
        [
          {
            "node": "10. Code \u2014 Parse Intelligence Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}