{
  "id": "mTKf5ngESISFLcY5",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered IPL Post-Match Analyzer That Generates Tactical Breakdowns and Weekly Roundups Automatically",
  "tags": [],
  "nodes": [
    {
      "id": "612a7a89-f2d6-43e4-9e51-f99308c05f49",
      "name": "Every 30 Min Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 30
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "3f6aaa7c-3229-4701-b9ef-232b7e7b4227",
      "name": "Read Match Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        464,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit#gid=0",
          "cachedResultName": "Match Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit?usp=drivesdk",
          "cachedResultName": "IPL Post Match Analyzer"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "3654c841-7996-40cf-bc57-01ba62365759",
      "name": "Find New Completed IPL Match",
      "type": "n8n-nodes-base.code",
      "position": [
        672,
        0
      ],
      "parameters": {
        "jsCode": "const response = $('Fetch Recent Matches').first().json;\nconst matchLog = $('Read Match Log').all();\n\nconst matches = response.data || [];\n\n// Build set of already analyzed match IDs\nconst analyzedIds = new Set(\n  matchLog\n    .filter(r => r.json.analyzed === 'true' || r.json.analyzed === true)\n    .map(r => r.json.match_id)\n);\n\n// Find completed IPL match not yet analyzed\nconst completedIPL = matches.find(m => {\n  const name = (m.name || '').toUpperCase();\n  const isIPL = name.includes('IPL') || \n                name.includes('INDIAN PREMIER LEAGUE');\n  const isT20 = (m.matchType || '').toLowerCase() === 't20';\n  const isCompleted = m.matchStarted === true && \n                      m.matchEnded === true;\n  const notAnalyzed = !analyzedIds.has(m.id);\n  return isIPL && isT20 && isCompleted && notAnalyzed;\n});\n\n// Fallback for testing \u2014 use any completed T20\nconst fallback = matches.find(m =>\n  (m.matchType || '').toLowerCase() === 't20' &&\n  m.matchStarted === true &&\n  m.matchEnded === true &&\n  m.score && m.score.length >= 2 &&\n  !analyzedIds.has(m.id)\n);\n\nconst match = completedIPL || fallback;\n\nif (!match) {\n  return [{ json: { skip: true, reason: 'No new completed matches' } }];\n}\n\n// Parse scores\nconst scores = match.score || [];\nconst innings1 = scores[0] || {};\nconst innings2 = scores[1] || {};\n\n// Determine winner from status string\nconst status = match.status || '';\n\nreturn [{\n  json: {\n    skip: false,\n    matchId: match.id,\n    matchName: match.name,\n    matchDate: match.date,\n    teams: match.teams || [],\n    team1: match.teams?.[0] || 'Team A',\n    team2: match.teams?.[1] || 'Team B',\n    status,\n    innings1Score: `${innings1.r || 0}/${innings1.w || 0} (${innings1.o || 0} ov)`,\n    innings2Score: `${innings2.r || 0}/${innings2.w || 0} (${innings2.o || 0} ov)`,\n    innings1Runs: innings1.r || 0,\n    innings1Wickets: innings1.w || 0,\n    innings1Overs: innings1.o || 0,\n    innings2Runs: innings2.r || 0,\n    innings2Wickets: innings2.w || 0,\n    innings2Overs: innings2.o || 0,\n    isLiveIPL: !!completedIPL\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "030e9e80-e8ba-4b60-a7e7-93d33a2b7369",
      "name": "Fetch Recent Matches",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        256,
        0
      ],
      "parameters": {
        "url": "https://api.cricapi.com/v1/currentMatches",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "your_api_key"
            },
            {
              "name": "offset",
              "value": "0"
            }
          ]
        }
      },
      "typeVersion": 4.3
    },
    {
      "id": "fbe37132-dcc0-4a61-a570-fb0f67708272",
      "name": "Save to Match Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1168,
        -16
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ $json.matchDate }}",
            "winner": "={{ $json.status }}",
            "analyzed": "false",
            "match_id": "={{ $json.matchId }}",
            "match_name": "={{ $json.matchName }}",
            "analysis_sent": "false"
          },
          "schema": [
            {
              "id": "match_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "match_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "match_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "match_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "winner",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "winner",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "analyzed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "analyzed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "analysis_sent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "analysis_sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit#gid=0",
          "cachedResultName": "Match Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit?usp=drivesdk",
          "cachedResultName": "IPL Post Match Analyzer"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "4bced3d8-5bcf-4c12-baee-895c9a8f92c3",
      "name": "Weekly Monday 9AM Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        80,
        768
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "f28ccf08-53d4-46ce-8782-eb6ca2b80216",
      "name": "Read Analysis Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        768
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419911676,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit#gid=419911676",
          "cachedResultName": "Analysis Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit?usp=drivesdk",
          "cachedResultName": "IPL Post Match Analyzer"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "e681ec41-e244-47f3-903f-f49cfaa6f99f",
      "name": "Build Weekly Digest Prompt",
      "type": "n8n-nodes-base.code",
      "position": [
        496,
        768
      ],
      "parameters": {
        "jsCode": "const analyses = $input.all();\n\nif (analyses.length === 0) {\n  return [{ json: { skip: true, reason: 'No analyses this week' } }];\n}\n\n// Get last 7 days of analyses\nconst sevenDaysAgo = new Date();\nsevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);\n\nconst thisWeek = analyses.filter(a => {\n  const matchDate = new Date(a.json.date);\n  return matchDate >= sevenDaysAgo;\n});\n\nif (thisWeek.length === 0) {\n  return [{ json: { skip: true, reason: 'No matches this week' } }];\n}\n\nlet matchSummaries = '';\nthisWeek.forEach((a, i) => {\n  matchSummaries += `Match ${i+1}: ${a.json.match_name}\nResult: ${a.json.winner}\nPlayer of Match: ${a.json.player_of_match || 'N/A'}\nSummary: ${a.json.analysis_summary}\n\\n`;\n});\n\nconst prompt = `You are an IPL cricket journalist writing a weekly roundup newsletter.\n\nThis week's IPL matches:\n${matchSummaries}\n\nGenerate a weekly digest in this JSON format:\n{\n  \"week_headline\": \"Catchy headline summarizing this week's IPL action\",\n  \"week_intro\": \"2-3 sentence intro capturing the week's drama and key themes\",\n  \"match_recaps\": [\n    {\n      \"match\": \"match name\",\n      \"one_liner\": \"One punchy sentence recap of the match\"\n    }\n  ],\n  \"player_of_week\": \"Name and one sentence on the standout performer of the week\",\n  \"week_talking_point\": \"The biggest talking point or controversy from this week\",\n  \"next_week_preview\": \"2 sentences building anticipation for next week's matches\"\n}\n\nRules:\n- Write like a cricket journalist\n- Be opinionated and engaging\n- Use cricket language fans love`;\n\nreturn [{\n  json: {\n    prompt,\n    matchCount: thisWeek.length,\n    weekOf: new Date().toDateString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "029d18a8-ff0d-435b-9d6f-95b0b46dc942",
      "name": "Weekly Journalist",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1040,
        752
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "={{ $json.prompt }}"
            },
            {
              "role": "system",
              "content": "You are an expert IPL cricket journalist. Always respond in valid JSON only. No markdown, no code blocks."
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "54999499-3144-49cc-bd1e-645515ae10e8",
      "name": "Parse & Build Weekly Email",
      "type": "n8n-nodes-base.code",
      "position": [
        1392,
        752
      ],
      "parameters": {
        "jsCode": "const response = items[0].json.output[0].content[0].text;\nconst cleaned = response.replace(/```json|```/g, '').trim();\nconst parsed = JSON.parse(cleaned);\n\nconst data = $('Build Weekly Digest Prompt').first().json;\n\nconst recapsList = (parsed.match_recaps || [])\n  .map(m => `\n    <div style=\"background:#f5f5f5; border-left:4px solid #1a237e; padding:12px 16px; border-radius:6px; margin:10px 0;\">\n      <div style=\"font-weight:bold; color:#1a237e; font-size:13px;\">${m.match}</div>\n      <div style=\"margin-top:4px;\">${m.one_liner}</div>\n    </div>`\n  ).join('');\n\nconst htmlEmail = `<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; background: #f5f5f5; margin: 0; padding: 0; }\n    .container { max-width: 600px; margin: 30px auto; background: #ffffff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }\n    .header { background: linear-gradient(135deg, #1a237e, #283593); padding: 30px; text-align: center; color: white; }\n    .header h1 { margin: 0; font-size: 22px; }\n    .header p { margin: 8px 0 0 0; font-size: 13px; opacity: 0.85; }\n    .body { padding: 30px; color: #333; }\n    .section-title { font-size: 13px; font-weight: bold; color: #1a237e; text-transform: uppercase; letter-spacing: 1px; margin: 20px 0 8px 0; }\n    .highlight-box { background: #e8eaf6; padding: 16px 20px; border-radius: 8px; margin: 12px 0; }\n    .potw { background: linear-gradient(135deg, #1a237e, #283593); color: white; padding: 16px 20px; border-radius: 8px; text-align: center; margin: 20px 0; }\n    .preview-box { background: #fff8e1; border-left: 4px solid #ff6f00; padding: 14px 18px; border-radius: 8px; margin: 12px 0; }\n    .footer { background: #f5f5f5; padding: 16px; text-align: center; font-size: 12px; color: #999; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>\ud83c\udfcf IPL Weekly Roundup</h1>\n      <p>Week of ${data.weekOf} \u00b7 ${data.matchCount} Matches Analyzed</p>\n    </div>\n    <div class=\"body\">\n      <h2 style=\"color:#1a237e; margin-top:0;\">${parsed.week_headline}</h2>\n      <p>${parsed.week_intro}</p>\n\n      <div class=\"section-title\">\ud83d\udccb Match Recaps</div>\n      ${recapsList}\n\n      <div class=\"potw\">\n        <div style=\"font-size:12px; opacity:0.8; margin-bottom:6px;\">\u2b50 PLAYER OF THE WEEK</div>\n        <div style=\"font-size:16px; font-weight:bold;\">${parsed.player_of_week}</div>\n      </div>\n\n      <div class=\"section-title\">\ud83d\udcac Talking Point of the Week</div>\n      <div class=\"highlight-box\">${parsed.week_talking_point}</div>\n\n      <div class=\"section-title\">\ud83d\udc40 Next Week Preview</div>\n      <div class=\"preview-box\">${parsed.next_week_preview}</div>\n    </div>\n    <div class=\"footer\">IPL Weekly Roundup \u00b7 Powered by AI Analysis<br/>You are receiving this because you subscribed to IPL insights.</div>\n  </div>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    ...data,\n    htmlEmail,\n    subject: `\ud83c\udfcf IPL Weekly Roundup \u2014 ${parsed.week_headline}`\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "2fec8592-672f-405d-ae0f-68d7539a22e7",
      "name": "Send Weekly Digest",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1696,
        752
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "={{ $json.htmlEmail }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2c8fb2a5-332d-45ac-a27c-b8e37df7d66a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -528
      ],
      "parameters": {
        "width": 400,
        "height": 544,
        "content": "## Workflow Overview\n\n### How It Works\nEvery IPL match tells a story that the scoreboard \nalone cannot capture. This workflow automatically \ndetects completed IPL matches, fetches the full \nscorecard, and sends it to GPT-4o which produces \na detailed journalist-style analysis covering \ninnings breakdowns, tactical decisions, key moments, \nplayer of the match, and what the result means for \nboth teams going forward. Every Monday it also \ngenerates a weekly roundup digest summarizing all \nthe week's matches in one beautifully designed email.\n\n### Setup Steps\n1. Sign up at cricapi.com and get your API key\n2. Add CRICAPI KEY in http nodes\n3. Create the Google Sheet with 2 sheets \u2014 \n   Match Log and Analysis Log\n4. Connect Google Sheets, OpenAI, and Gmail \n   credentials\n5. Add your email to both Gmail nodes\n6. Activate the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "4a87cd3f-6c93-461a-97ba-d2a6feed9e8b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 1504,
        "height": 400,
        "content": "Match Completion Detector runs every 30 minutes and polls CricAPI for recently completed T20 matches. It reads the Match Log sheet to check which matches have already been analyzed and finds any new completed IPL match that hasn't been processed yet. When a new match is found it saves it to the Match Log with analyzed set to false and passes all match data forward to the analysis engine. If no new match is found the workflow stops cleanly."
      },
      "typeVersion": 1
    },
    {
      "id": "61664b7a-0574-4a05-bc18-63d81cd41b57",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        848,
        256
      ],
      "parameters": {
        "color": 7,
        "width": 1504,
        "height": 288,
        "content": "This flow receives the completed match data and builds a structured analytical prompt containing both innings stats, run rates, and result context. GPT-4o acts as a cricket analyst and produces a headline, match summary, innings analysis, key moments, tactical breakdown, and player of the match. The response is assembled into a branded HTML email and sent immediately. Both the Match Log and Analysis Log sheets are updated after every send."
      },
      "typeVersion": 1
    },
    {
      "id": "4b2a3526-aaf2-4208-9227-490b59573367",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        608
      ],
      "parameters": {
        "color": 7,
        "width": 1872,
        "height": 352,
        "content": "Weekly Digest runs every Monday at 9AM. It reads all match analyses from the past 7 days in the Analysis Log sheet and sends them to GPT-4o which generates a weekly roundup \u2014 a headline, match recaps, player of the week, the biggest talking point, and a preview of the week ahead. The digest is sent as a branded HTML email. If no matches were analyzed in the past 7 days the workflow stops cleanly without sending anything."
      },
      "typeVersion": 1
    },
    {
      "id": "7b2d03dc-3fe0-444f-b7c0-383ab7f52eb0",
      "name": "IF Matches This Week",
      "type": "n8n-nodes-base.if",
      "position": [
        704,
        768
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "326354c3-5283-430a-96c3-9638e80ffe0f",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.skip }}",
              "rightValue": "true"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "4badffe7-6af0-4ec3-bf9e-ff4a2eb90c31",
      "name": "IF New Match Found",
      "type": "n8n-nodes-base.if",
      "position": [
        880,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d0f44d2f-b525-4203-b94a-d3b9c3082378",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.skip }}",
              "rightValue": "true"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "042debc4-f746-4160-be19-a20e55081f83",
      "name": "Send Analysis Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1744,
        368
      ],
      "parameters": {
        "sendTo": "your_email_id",
        "message": "={{ $json.htmlEmail }}",
        "options": {},
        "subject": "={{ $json.subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "dde48779-b714-462a-9fd7-3f5d500fa10a",
      "name": "Log to Analysis Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2192,
        368
      ],
      "parameters": {
        "columns": {
          "value": {
            "date": "={{ new Date().toISOString().split('T')[0] }}",
            "winner": "={{ $('Parse Analysis & Build Email').item.json.status }}",
            "email_sent": "true",
            "match_name": "={{ $('Parse Analysis & Build Email').item.json.matchName }}",
            "player_of_match": "={{ $('Parse Analysis & Build Email').item.json.player_of_match }}",
            "analysis_summary": "={{ $('Parse Analysis & Build Email').item.json.analysis_summary }}"
          },
          "schema": [
            {
              "id": "date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "match_name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "match_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "winner",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "winner",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "player_of_match",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "player_of_match",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "top_batter",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "top_batter",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "top_bowler",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "top_bowler",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "analysis_summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "analysis_summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email_sent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email_sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 419911676,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit#gid=419911676",
          "cachedResultName": "Analysis Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit?usp=drivesdk",
          "cachedResultName": "IPL Post Match Analyzer"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "78d66cec-e495-4b95-bf3e-33c2c234a73f",
      "name": "Update Match Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1968,
        368
      ],
      "parameters": {
        "columns": {
          "value": {
            "analyzed": "true",
            "match_id": "={{ $('Parse Analysis & Build Email').item.json.matchId }}",
            "analysis_sent": "true"
          },
          "schema": [
            {
              "id": "match_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "match_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "match_name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "match_name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "winner",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "winner",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "analyzed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "analyzed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "analysis_sent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "analysis_sent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "match_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit#gid=0",
          "cachedResultName": "Match Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1wbTiDSQnwHaoUDQ_jLR3VxtTVCg_TCOvlXHAs8mvbMU/edit?usp=drivesdk",
          "cachedResultName": "IPL Post Match Analyzer"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "5784097b-e1d2-476e-b2c9-08f1a4071e9c",
      "name": "Parse Analysis & Build Email",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        368
      ],
      "parameters": {
        "jsCode": "const response = items[0].json.output[0].content[0].text;\nconst cleaned = response.replace(/```json|```/g, '').trim();\nconst parsed = JSON.parse(cleaned);\n\nconst data = $('Build Analysis Prompt').first().json;\n\nconst keyMomentsList = (parsed.key_moments || [])\n  .map(m => `<li style=\"margin-bottom:10px;\">${m}</li>`)\n  .join('');\n\nconst htmlEmail = `<!DOCTYPE html>\n<html>\n<head>\n  <style>\n    body { font-family: Arial, sans-serif; background: #f5f5f5; margin: 0; padding: 0; }\n    .container { max-width: 600px; margin: 30px auto; background: #ffffff; border-radius: 12px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }\n    .header { background: linear-gradient(135deg, #1a237e, #283593); padding: 30px; text-align: center; color: white; }\n    .header h1 { margin: 0; font-size: 22px; }\n    .header p { margin: 8px 0 0 0; font-size: 13px; opacity: 0.85; }\n    .scores { display: flex; background: #e8eaf6; padding: 16px 24px; justify-content: space-around; text-align: center; }\n    .score-block { flex: 1; }\n    .score-team { font-size: 12px; color: #555; text-transform: uppercase; font-weight: bold; }\n    .score-runs { font-size: 22px; font-weight: bold; color: #1a237e; }\n    .body { padding: 30px; color: #333; }\n    .section { margin: 20px 0; }\n    .section-title { font-size: 13px; font-weight: bold; color: #1a237e; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }\n    .analysis-box { background: #f5f5f5; border-left: 4px solid #1a237e; padding: 14px 18px; border-radius: 8px; margin: 12px 0; }\n    .moments-box { background: #e8eaf6; padding: 16px 20px; border-radius: 8px; margin: 12px 0; }\n    .tactical-box { background: #fff8e1; border-left: 4px solid #ff6f00; padding: 14px 18px; border-radius: 8px; margin: 12px 0; }\n    .potm { background: linear-gradient(135deg, #1a237e, #283593); color: white; padding: 16px 20px; border-radius: 8px; text-align: center; margin: 20px 0; }\n    .footer { background: #f5f5f5; padding: 16px; text-align: center; font-size: 12px; color: #999; }\n  </style>\n</head>\n<body>\n  <div class=\"container\">\n    <div class=\"header\">\n      <h1>\ud83c\udfcf Post-Match Deep Dive</h1>\n      <p>${data.matchName} \u00b7 ${data.matchDate}</p>\n    </div>\n    <div class=\"scores\">\n      <div class=\"score-block\">\n        <div class=\"score-team\">${data.team1}</div>\n        <div class=\"score-runs\">${data.innings1Score}</div>\n      </div>\n      <div style=\"padding-top:12px; font-size:13px; color:#888;\">vs</div>\n      <div class=\"score-block\">\n        <div class=\"score-team\">${data.team2}</div>\n        <div class=\"score-runs\">${data.innings2Score}</div>\n      </div>\n    </div>\n    <div class=\"body\">\n      <h2 style=\"color:#1a237e; margin-top:0;\">${parsed.headline}</h2>\n      <p>${parsed.match_summary}</p>\n\n      <div class=\"section\">\n        <div class=\"section-title\">\ud83d\udcca 1st Innings Analysis</div>\n        <div class=\"analysis-box\">${parsed.innings1_analysis}</div>\n      </div>\n\n      <div class=\"section\">\n        <div class=\"section-title\">\ud83c\udfc3 2nd Innings Analysis</div>\n        <div class=\"analysis-box\">${parsed.innings2_analysis}</div>\n      </div>\n\n      <div class=\"section\">\n        <div class=\"section-title\">\u26a1 Key Moments</div>\n        <div class=\"moments-box\">\n          <ul style=\"padding-left:20px; margin:0;\">\n            ${keyMomentsList}\n          </ul>\n        </div>\n      </div>\n\n      <div class=\"section\">\n        <div class=\"section-title\">\ud83e\udde0 Tactical Breakdown</div>\n        <div class=\"tactical-box\">${parsed.tactical_breakdown}</div>\n      </div>\n\n      <div class=\"potm\">\n        <div style=\"font-size:12px; opacity:0.8; margin-bottom:6px;\">\u2b50 PLAYER OF THE MATCH</div>\n        <div style=\"font-size:16px; font-weight:bold;\">${parsed.player_of_match}</div>\n      </div>\n\n      <div class=\"section\">\n        <div class=\"section-title\">\ud83d\udc40 What to Watch Next</div>\n        <p>${parsed.what_to_watch_next}</p>\n      </div>\n    </div>\n    <div class=\"footer\">IPL Post-Match Deep Dive \u00b7 Powered by AI Analysis<br/>You are receiving this because you subscribed to IPL insights.</div>\n  </div>\n</body>\n</html>`;\n\nreturn [{\n  json: {\n    ...data,\n    headline: parsed.headline,\n    match_summary: parsed.match_summary,\n    player_of_match: parsed.player_of_match,\n    analysis_summary: parsed.analysis_summary,\n    htmlEmail,\n    subject: `\ud83c\udfcf Post-Match Analysis: ${parsed.headline}`\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "199a16b3-d2ba-4e21-b067-3b176811c78e",
      "name": "Match Analyst",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1168,
        368
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "={{ $json.prompt }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "191a93d8-8b59-423e-aea7-1c2793d1fabf",
      "name": "Build Analysis Prompt",
      "type": "n8n-nodes-base.code",
      "position": [
        944,
        368
      ],
      "parameters": {
        "jsCode": "const data = $('Find New Completed IPL Match').first().json;\n\nconst prompt = `You are an expert IPL cricket analyst and sports journalist. Analyze this completed T20 match and produce a detailed post-match breakdown.\n\nMatch: ${data.matchName}\nResult: ${data.status}\n${data.team1} Score: ${data.innings1Score}\n${data.team2} Score: ${data.innings2Score}\n\nInnings 1 Details:\n- Runs: ${data.innings1Runs}\n- Wickets: ${data.innings1Wickets}\n- Overs: ${data.innings1Overs}\n- Run Rate: ${data.innings1Overs > 0 ? (data.innings1Runs / data.innings1Overs).toFixed(2) : 'N/A'}\n\nInnings 2 Details:\n- Runs: ${data.innings2Runs}\n- Wickets: ${data.innings2Wickets}\n- Overs: ${data.innings2Overs}\n- Run Rate: ${data.innings2Overs > 0 ? (data.innings2Runs / data.innings2Overs).toFixed(2) : 'N/A'}\n\nRespond ONLY in this JSON format:\n{\n  \"headline\": \"Punchy match headline like a newspaper\",\n  \"match_summary\": \"3-4 sentence overview of how the match played out\",\n  \"innings1_analysis\": \"2-3 sentence tactical breakdown of the first innings \u2014 scoring rate, key phases, pressure points\",\n  \"innings2_analysis\": \"2-3 sentence tactical breakdown of the second innings \u2014 chase strategy, turning points, momentum shifts\",\n  \"key_moments\": [\n    \"Key moment 1 that decided the match\",\n    \"Key moment 2\",\n    \"Key moment 3\"\n  ],\n  \"tactical_breakdown\": \"2-3 sentences on the tactical decisions that won or lost the match \u2014 field settings, bowling changes, batting approach\",\n  \"player_of_match\": \"Name and one sentence on why they were the standout performer\",\n  \"what_to_watch_next\": \"One sentence on what this result means for both teams going forward\",\n  \"analysis_summary\": \"One sentence summary for logging\"\n}\n\nRules:\n- Write like a cricket journalist not a robot\n- Be specific about the numbers provided\n- Use cricket terminology fans understand\n- Be opinionated and analytical not neutral`;\n\nreturn [{\n  json: {\n    ...data,\n    prompt\n  }\n}];"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "77c8bff3-30ad-494a-a05e-24d0ca3791ef",
  "connections": {
    "Match Analyst": {
      "main": [
        [
          {
            "node": "Parse Analysis & Build Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Match Log": {
      "main": [
        [
          {
            "node": "Find New Completed IPL Match",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Match Log": {
      "main": [
        [
          {
            "node": "Log to Analysis Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Analysis Log": {
      "main": [
        [
          {
            "node": "Build Weekly Digest Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Journalist": {
      "main": [
        [
          {
            "node": "Parse & Build Weekly Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF New Match Found": {
      "main": [
        [
          {
            "node": "Save to Match Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Analysis Email": {
      "main": [
        [
          {
            "node": "Update Match Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every 30 Min Trigger": {
      "main": [
        [
          {
            "node": "Fetch Recent Matches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Recent Matches": {
      "main": [
        [
          {
            "node": "Read Match Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Matches This Week": {
      "main": [
        [
          {
            "node": "Weekly Journalist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Analysis Prompt": {
      "main": [
        [
          {
            "node": "Match Analyst",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Weekly Monday 9AM Trigger": {
      "main": [
        [
          {
            "node": "Read Analysis Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Weekly Digest Prompt": {
      "main": [
        [
          {
            "node": "IF Matches This Week",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse & Build Weekly Email": {
      "main": [
        [
          {
            "node": "Send Weekly Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find New Completed IPL Match": {
      "main": [
        [
          {
            "node": "IF New Match Found",
            "type": "main",
            "index": 0
          },
          {
            "node": "Build Analysis Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Analysis & Build Email": {
      "main": [
        [
          {
            "node": "Send Analysis Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}