{
  "name": "Google Sheets Webhook",
  "nodes": [
    {
      "id": "342ea752-c11d-455d-9465-1fedc18dcefa",
      "name": "Webhook",
      "parameters": {
        "options": {},
        "path": "sheets",
        "responseMode": "responseNode"
      },
      "position": [
        -848,
        -32
      ],
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1
    },
    {
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "YOUR_GOOGLE_SHEETS_CREDENTIAL"
        }
      },
      "id": "2afcf6e4-00b6-4c3e-bfba-0cabaa917d0d",
      "name": "Get row(s) in sheet",
      "parameters": {
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.source }}"
        },
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "0"
        }
      },
      "position": [
        -384,
        -32
      ],
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7
    },
    {
      "id": "1bdd24fc-b487-49a3-9af9-375ae485d757",
      "name": "Spreadsheet to JSON",
      "parameters": {
        "jsCode": "const columns = $('Configuration').first().json.columns;\nconst aggregations = $('Configuration').first().json.aggregations;\n\nconst items = $input.all().map((item) => {\n  const row = item.json;\n  const out = {};\n  for (const col of columns) {\n    out[col.header] = row[col.header];\n  }\n  return out;\n});\n\nconst aggregators = {\n  sum: (vals) => vals.reduce((a, b) => a + Number(b || 0), 0),\n  avg: (vals) => (vals.length ? vals.reduce((a, b) => a + Number(b || 0), 0) / vals.length : 0),\n  min: (vals) => (vals.length ? Math.min(...vals.map(Number)) : null),\n  max: (vals) => (vals.length ? Math.max(...vals.map(Number)) : null),\n  count: (vals) => vals.length,\n};\n\nconst aggResult = {};\nfor (const agg of aggregations) {\n  const fn = aggregators[agg.agg];\n  const outKey = agg.name || agg.field;\n\n  if (agg.group_by) {\n    const grouped = {};\n    for (const item of items) {\n      const key = String(item[agg.group_by]);\n      (grouped[key] ||= []).push(item[agg.field]);\n    }\n    const groupOut = {};\n    for (const [key, vals] of Object.entries(grouped)) {\n      groupOut[key] = fn(vals);\n    }\n    aggResult[outKey] = groupOut;\n  } else {\n    aggResult[outKey] = fn(items.map((i) => i[agg.field]));\n  }\n}\n\nreturn [{ json: { items, aggregations: aggResult } }];"
      },
      "position": [
        -160,
        -32
      ],
      "type": "n8n-nodes-base.code",
      "typeVersion": 2
    },
    {
      "id": "3e8510a7-e91b-4700-9bf8-4e6555911813",
      "name": "Respond to Webhook",
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ $json }}"
      },
      "position": [
        80,
        -32
      ],
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5
    },
    {
      "id": "23b071eb-2710-4c8a-bcab-227687d4adad",
      "name": "Configuration",
      "parameters": {
        "jsCode": "return {\n  source: \"YOUR_GOOGLE_SHEET_ID\",\n  columns: [\n    {\"position\": 0, \"header\": \"category\", \"type\": \"text\"},\n    {\"position\": 1, \"header\": \"budget\", \"type\": \"number\"},\n    {\"position\": 2, \"header\": \"spent\", \"type\": \"number\"},\n    {\"position\": 3, \"header\": \"left\", \"type\": \"number\"},\n    {\"position\": 4, \"header\": \"owner\", \"type\": \"text\"}\n  ],\n  aggregations: [\n    {\"name\":\"savings\",\"group_by\":\"owner\",\"field\":\"left\",\"agg\":\"sum\"},\n    {\"name\":\"responsibilities\",\"group_by\":\"owner\",\"field\":\"owner\",\"agg\":\"count\"}\n  ]\n};"
      },
      "position": [
        -608,
        -32
      ],
      "type": "n8n-nodes-base.code",
      "typeVersion": 2
    }
  ],
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "index": 0,
            "node": "Get row(s) in sheet",
            "type": "main"
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "index": 0,
            "node": "Spreadsheet to JSON",
            "type": "main"
          }
        ]
      ]
    },
    "Spreadsheet to JSON": {
      "main": [
        [
          {
            "index": 0,
            "node": "Respond to Webhook",
            "type": "main"
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "index": 0,
            "node": "Configuration",
            "type": "main"
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": []
}