{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Score and auto-reply to new leads with OpenAI and Gmail",
  "tags": [],
  "nodes": [
    {
      "id": "form-trigger",
      "name": "Lead Intake Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        128,
        112
      ],
      "parameters": {
        "options": {},
        "formTitle": "Contact Us",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Name",
              "placeholder": "Your full name",
              "requiredField": true
            },
            {
              "fieldLabel": "Email",
              "placeholder": "your@email.com",
              "requiredField": true
            },
            {
              "fieldLabel": "Company",
              "placeholder": "Your company name (optional)"
            },
            {
              "fieldLabel": "Budget Range",
              "placeholder": "e.g. $1,000 - $5,000",
              "requiredField": true
            },
            {
              "fieldLabel": "Project Description",
              "placeholder": "Describe your project, goals, and timeline",
              "requiredField": true
            },
            {
              "fieldLabel": "Referral Source",
              "placeholder": "How did you hear about us?"
            }
          ]
        },
        "formDescription": "Tell us about your project and we'll get back to you within minutes."
      },
      "typeVersion": 2.5
    },
    {
      "id": "set-config",
      "name": "Configure Your Settings",
      "type": "n8n-nodes-base.set",
      "position": [
        416,
        112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1",
              "name": "businessName",
              "type": "string",
              "value": "Your Business Name"
            },
            {
              "id": "2",
              "name": "ownerName",
              "type": "string",
              "value": "Your Name"
            },
            {
              "id": "3",
              "name": "ownerEmail",
              "type": "string",
              "value": "user@example.com"
            },
            {
              "id": "4",
              "name": "calendarLink",
              "type": "string",
              "value": "https://calendly.com/your-link"
            },
            {
              "id": "5",
              "name": "businessDescription",
              "type": "string",
              "value": "We help businesses automate their workflows and grow faster."
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "openai-score",
      "name": "Score Lead & Draft Reply",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        688,
        112
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "role": "system",
              "content": "You are a lead qualification AI assistant. Analyze incoming leads and return a JSON response.\n\nRespond with ONLY valid JSON (no markdown, no code blocks, no extra text) in this exact format:\n{\"score\": <number 1-100>, \"tier\": \"<Hot|Warm|Cold>\", \"reasoning\": \"<2-3 sentences for internal use>\", \"emailSubject\": \"<personalized subject line>\", \"emailBody\": \"<personalized HTML email body>\"}\n\nScoring criteria:\n- Budget alignment (higher budget = higher score)\n- Project clarity and specificity (detailed descriptions score higher)\n- Overall fit for the business\n\nTier thresholds:\n- Hot (70-100): Enthusiastic, eager tone. Include a calendar booking call-to-action.\n- Warm (40-69): Helpful, encouraging tone. Suggest next steps and resources.\n- Cold (1-39): Polite, professional acknowledgment. Keep the door open.\n\nEmail guidelines:\n- Address the lead by first name\n- Reference specific details from their submission\n- Keep it 3-5 short paragraphs\n- For Hot leads, prominently include the calendar booking link\n- Format as clean HTML with inline styles\n- Sign off with the business owner's name"
            },
            {
              "content": "=Business Context:\n- Business: {{ $json.businessName }}\n- Description: {{ $json.businessDescription }}\n- Owner: {{ $json.ownerName }}\n- Calendar Link: {{ $json.calendarLink }}\n\nLead Submission:\n- Name: {{ $json.Name }}\n- Email: {{ $json.Email }}\n- Company: {{ $json.Company }}\n- Budget: {{ $json[\"Budget Range\"] }}\n- Project: {{ $json[\"Project Description\"] }}\n- Source: {{ $json[\"Referral Source\"] }}"
            }
          ]
        },
        "builtInTools": {}
      },
      "typeVersion": 2.1
    },
    {
      "id": "code-parse",
      "name": "Parse AI Response",
      "type": "n8n-nodes-base.code",
      "position": [
        976,
        112
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// OpenAI Responses API returns data in output[0].content[0].text\nlet aiText = '';\n\nif ($json.output && Array.isArray($json.output)) {\n  // Responses API format\n  aiText = $json.output[0].content[0].text;\n} else if ($json.text) {\n  aiText = $json.text;\n} else if ($json.content) {\n  aiText = $json.content;\n} else {\n  aiText = JSON.stringify($json);\n}\n\n// Extract JSON from response (handles ```json blocks or raw JSON)\nlet jsonStr = aiText;\nconst jsonMatch = aiText.match(/```json\\s*([\\s\\S]*?)```/);\nif (jsonMatch) {\n  jsonStr = jsonMatch[1];\n} else {\n  const objMatch = aiText.match(/\\{[\\s\\S]*\\}/);\n  if (objMatch) jsonStr = objMatch[0];\n}\n\nconst parsed = JSON.parse(jsonStr.trim());\n\n// Get original form + config data from the Set node\nconst formData = $('Configure Your Settings').first().json;\n\nreturn {\n  json: {\n    leadName: formData['Name'] || '',\n    leadEmail: formData['Email'] || '',\n    company: formData['Company'] || '',\n    budgetRange: formData['Budget Range'] || '',\n    projectDescription: formData['Project Description'] || '',\n    referralSource: formData['Referral Source'] || '',\n    businessName: formData.businessName || '',\n    ownerName: formData.ownerName || '',\n    ownerEmail: formData.ownerEmail || '',\n    calendarLink: formData.calendarLink || '',\n    score: parsed.score,\n    tier: parsed.tier,\n    reasoning: parsed.reasoning,\n    emailSubject: parsed.emailSubject,\n    emailBody: parsed.emailBody,\n    timestamp: new Date().toISOString()\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "switch-route",
      "name": "Route by Lead Quality",
      "type": "n8n-nodes-base.switch",
      "position": [
        1248,
        112
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Hot",
              "conditions": {
                "options": {
                  "version": 2,
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "Hot"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Warm",
              "conditions": {
                "options": {
                  "version": 2,
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "Warm"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Cold",
              "conditions": {
                "options": {
                  "version": 2,
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.tier }}",
                    "rightValue": "Cold"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "gmail-hot",
      "name": "Reply to Hot Lead",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1536,
        -112
      ],
      "parameters": {
        "sendTo": "={{ $json.leadEmail }}",
        "message": "={{ $json.emailBody }}",
        "options": {
          "senderName": "={{ $json.ownerName }}"
        },
        "subject": "={{ $json.emailSubject }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "gmail-warm",
      "name": "Reply to Warm Lead",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1584,
        80
      ],
      "parameters": {
        "sendTo": "={{ $json.leadEmail }}",
        "message": "={{ $json.emailBody }}",
        "options": {
          "senderName": "={{ $json.ownerName }}"
        },
        "subject": "={{ $json.emailSubject }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "gmail-cold",
      "name": "Reply to Cold Lead",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1584,
        224
      ],
      "parameters": {
        "sendTo": "={{ $json.leadEmail }}",
        "message": "={{ $json.emailBody }}",
        "options": {
          "senderName": "={{ $json.ownerName }}"
        },
        "subject": "={{ $json.emailSubject }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "sheets-log",
      "name": "Log Lead with Score",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1120,
        -48
      ],
      "parameters": {
        "columns": {
          "value": {},
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "sticky-main",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -576
      ],
      "parameters": {
        "width": 520,
        "height": 850,
        "content": "## Score and Auto-Reply to New Leads with OpenAI and Gmail\n\n### Who is this for\nSmall business owners, freelancers, and agencies who receive inbound leads and want instant, personalized follow-up.\n\n### What it does\n1. Scores the lead 1-100 using OpenAI\n2. Classifies as Hot, Warm, or Cold\n3. Sends a personalized email reply\n4. Logs everything to Google Sheets\n\n### How to set up\n1. Fill in the **Configure Your Settings** node with your business name, email, calendar link, and description\n2. Connect your Gmail and Google Sheets credentials\n3. Add your OpenAI API key\n4. Create a Google Sheet with these column headers in Row 1:\n   `timestamp` \u00b7 `leadName` \u00b7 `leadEmail` \u00b7 `company` \u00b7 `budgetRange` \u00b7 `projectDescription` \u00b7 `referralSource` \u00b7 `score` \u00b7 `tier` \u00b7 `reasoning` \u00b7 `emailSubject` \u00b7 `emailBody`\n5. Paste your Sheet URL into the **Log Lead with Score** node\n6. Activate the workflow and share the form URL\n\n### Requirements\n- n8n account (cloud or self-hosted)\n- OpenAI API key\n- Gmail account (OAuth2)\n- Google Sheets (one blank sheet)\n\n### How to customize\n- Edit the OpenAI system prompt to adjust scoring criteria for your industry\n- Modify the tier thresholds (currently Hot 70+, Warm 40-69, Cold 0-39)\n- Add or remove form fields to match your intake needs"
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-trigger",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        -400
      ],
      "parameters": {
        "color": 6,
        "width": 350,
        "height": 232,
        "content": "## 1. Trigger & Configuration\n\nThe **Lead Intake Form** creates a web form that captures lead information. When submitted, data flows to **Configure Your Settings** where your business details are added.\n\n**Setup:** Update the Set node with your business name, email, calendar link, and a brief business description."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-ai",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        576,
        -400
      ],
      "parameters": {
        "color": 6,
        "width": 350,
        "height": 232,
        "content": "## 2. AI Lead Scoring\n\nOpenAI analyzes each lead based on budget, project clarity, and fit. It returns a score (1-100), tier (Hot/Warm/Cold), reasoning, and a fully personalized email draft.\n\n**Customize:** Edit the system prompt in the OpenAI node to match your industry and ideal customer profile."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-reply",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        976,
        -400
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 264,
        "content": "## 3. Smart Auto-Reply\n\nLeads are routed by quality tier. Each path sends a tailored email:\n- **Hot (70+):** Enthusiastic reply with calendar booking link\n- **Warm (40-69):** Helpful response with next steps\n- **Cold (0-39):** Polite acknowledgment\n\n**Customize:** Edit each Gmail node to add CC recipients, attachments, or custom behavior per tier."
      },
      "typeVersion": 1
    },
    {
      "id": "sticky-log",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1424,
        -400
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 280,
        "content": "## 4. Lead Logging\nEvery lead is logged to Google Sheets with score, tier, reasoning, and all form data.\n\n**Setup:** Create a Google Sheet and add these exact column headers in Row 1:\n\n`timestamp` \u00b7 `leadName` \u00b7 `leadEmail` \u00b7 `company` \u00b7 `budgetRange` \u00b7 `projectDescription` \u00b7 `referralSource` \u00b7 `score` \u00b7 `tier` \u00b7 `reasoning` \u00b7 `emailSubject` \u00b7 `emailBody`\n\nThen paste your Sheet URL into the Log Lead with Score node."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Lead Intake Form": {
      "main": [
        [
          {
            "node": "Configure Your Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Response": {
      "main": [
        [
          {
            "node": "Route by Lead Quality",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Lead with Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Lead Quality": {
      "main": [
        [
          {
            "node": "Reply to Hot Lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply to Warm Lead",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply to Cold Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Your Settings": {
      "main": [
        [
          {
            "node": "Score Lead & Draft Reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score Lead & Draft Reply": {
      "main": [
        [
          {
            "node": "Parse AI Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}