Skip to content

In n8n, copy this file and paste it onto the canvas, or use Import from File.

{
  "name": "03 - Google Sheets Lead Tracker",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lead",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "m03-webhook",
      "name": "New Lead",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [0, 100],
      "webhookId": "course-03-lead"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            { "id": "n1", "name": "email", "value": "={{ String($json.body.email ?? '').trim().toLowerCase() }}", "type": "string" },
            { "id": "n2", "name": "name", "value": "={{ String($json.body.name ?? '').trim() }}", "type": "string" },
            { "id": "n3", "name": "source", "value": "={{ String($json.body.source ?? 'website').trim().toLowerCase() }}", "type": "string" },
            { "id": "n4", "name": "updated_at", "value": "={{ $now.toISO() }}", "type": "string" }
          ]
        },
        "options": {}
      },
      "id": "m03-normalize",
      "name": "Normalize",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [220, 100]
    },
    {
      "parameters": {
        "conditions": {
          "options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 },
          "conditions": [
            {
              "id": "v1",
              "leftValue": "={{ $json.email }}",
              "rightValue": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
              "operator": { "type": "string", "operation": "regex" }
            },
            {
              "id": "v2",
              "leftValue": "={{ $json.name }}",
              "rightValue": "",
              "operator": { "type": "string", "operation": "notEmpty", "singleValue": true }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "m03-valid",
      "name": "Valid Lead?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [440, 100]
    },
    {
      "parameters": {
        "operation": "appendOrUpdate",
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit"
        },
        "sheetName": { "__rl": true, "mode": "name", "value": "Leads" },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "email": "={{ $json.email }}",
            "name": "={{ $json.name }}",
            "source": "={{ $json.source }}",
            "updated_at": "={{ $json.updated_at }}"
          },
          "matchingColumns": ["email"],
          "schema": [
            { "id": "email", "displayName": "email", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": true },
            { "id": "name", "displayName": "name", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": true },
            { "id": "source", "displayName": "source", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": true },
            { "id": "updated_at", "displayName": "updated_at", "required": false, "defaultMatch": false, "display": true, "type": "string", "canBeUsedToMatch": true }
          ]
        },
        "options": {}
      },
      "id": "m03-sheets",
      "name": "Save Lead",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.7,
      "position": [660, 0]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { status: 'saved', email: $('Normalize').item.json.email } }}",
        "options": {}
      },
      "id": "m03-ok",
      "name": "Respond OK",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [880, 0]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            { "id": "e1", "name": "error", "value": "a name and a valid email are required", "type": "string" }
          ]
        },
        "options": {}
      },
      "id": "m03-error",
      "name": "Build Error",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [660, 200]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json }}",
        "options": { "responseCode": 400 }
      },
      "id": "m03-400",
      "name": "Respond Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [880, 200]
    }
  ],
  "connections": {
    "New Lead": { "main": [[{ "node": "Normalize", "type": "main", "index": 0 }]] },
    "Normalize": { "main": [[{ "node": "Valid Lead?", "type": "main", "index": 0 }]] },
    "Valid Lead?": {
      "main": [
        [{ "node": "Save Lead", "type": "main", "index": 0 }],
        [{ "node": "Build Error", "type": "main", "index": 0 }]
      ]
    },
    "Save Lead": { "main": [[{ "node": "Respond OK", "type": "main", "index": 0 }]] },
    "Build Error": { "main": [[{ "node": "Respond Error", "type": "main", "index": 0 }]] }
  },
  "pinData": {},
  "settings": { "executionOrder": "v1" }
}