{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "3e3ea39f-f61d-4508-a0de-aee87fbbfbc7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        576,
        96
      ],
      "parameters": {
        "width": 480,
        "height": 448,
        "content": "## HVAC Lead Collect & Diagnosis\n\n### How it works\n\n1. The workflow triggers upon a new form submission containing file data. 2. It extracts the file contents and sends them to an external API to calculate a repair score. 3. The workflow parses the AI score and saves the lead details into GoHighLevel. 4. Finally, it retrieves the original image and sends a summary notification to the lead technician via WhatsApp.\n\n### Setup steps\n\n- Configure the Form Trigger to receive appropriate file fields.\n- Ensure the AI API credentials are set for the repair score calculation.\n- Connect your GoHighLevel account to save lead information.\n- Authenticate your WhatsApp Business account for notifications.\n\n### Customization\n\nYou can modify the notification message template to include additional CRM fields or change the communication channel from WhatsApp to Email."
      },
      "typeVersion": 1
    },
    {
      "id": "dfaa406d-19a8-4cf2-931f-da526416d57a",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 272,
        "content": "## Trigger and extract input data\n\nReceives input and extracts file data."
      },
      "typeVersion": 1
    },
    {
      "id": "f3264a8b-2d29-4435-ba26-7a4fd432db61",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1680,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 272,
        "content": "## Calculate automated repair score\n\nPerforms AI analysis on extracted data."
      },
      "typeVersion": 1
    },
    {
      "id": "bfd1321a-c7ab-4d1d-b1ab-71a680a18d16",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2112,
        96
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 288,
        "content": "## Update CRM and notify technician\n\nSaves result to CRM and notifies technician."
      },
      "typeVersion": 1
    },
    {
      "id": "cd263103-ba33-46cd-9af5-7ae34d1a4b18",
      "name": "When Form Submitted",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        1184,
        208
      ],
      "parameters": {
        "options": {
          "customCss": ":root {\n\t/* Fonts */\n\t--font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n\t--font-weight-normal: 400;\n\t--font-weight-bold: 600;\n\t--font-size-body: 12px;\n\t--font-size-label: 14px;\n\t--font-size-test-notice: 12px;\n\t--font-size-input: 14px;\n\t--font-size-header: 22px; \n\t--font-size-paragraph: 14px;\n\t--font-size-link: 12px;\n\t--font-size-error: 12px;\n\t--font-size-html-h1: 28px;\n\t--font-size-html-h2: 20px;\n\t--font-size-html-h3: 16px;\n\t--font-size-html-h4: 14px;\n\t--font-size-html-h5: 12px;\n\t--font-size-html-h6: 10px;\n\t--font-size-subheader: 14px;\n\n\t/* Colors - Adjusted for seamless immersion */\n\t--color-background: #ffffff; /* Pure white page background */\n\t--color-test-notice-text: #000000;\n\t--color-test-notice-bg: #f0f0f0;\n\t--color-test-notice-border: transparent;\n\t--color-card-bg: transparent; /* Removes the white box background */\n\t--color-card-border: transparent; /* Removes the box outline */\n\t--color-card-shadow: transparent; /* Removes the box shadow color */\n\t--color-link: #000000;\n\t--color-header: #000000;\n\t--color-label: #111111; \n\t--color-input-border: #cccccc;\n\t--color-input-text: #000000;\n\t--color-focus-border: #000000; \n\t--color-submit-btn-bg: #000000;\n\t--color-submit-btn-text: #ffffff;\n\t--color-error: #000000; \n\t--color-required: #000000;\n\t--color-clear-button-bg: #aaaaaa;\n\t--color-html-text: #333333;\n\t--color-html-link: #000000;\n\t--color-header-subtext: #666666;\n\n\t/* Border Radii */\n\t--border-radius-card: 0px;\n\t--border-radius-input: 0px; \n\t--border-radius-clear-btn: 50%;\n\t--card-border-radius: 0px;\n\n\t/* Spacing - Card padding removed so it doesn't act like an invisible box */\n\t--padding-container-top: 40px;\n\t--padding-card: 0px; /* Stripped to remove the invisible box constraints */\n\t--padding-test-notice-vertical: 12px;\n\t--padding-test-notice-horizontal: 24px;\n\t--margin-bottom-card: 24px;\n\t--padding-form-input: 14px;\n\t--card-padding: 0px; /* Stripped */\n\t--card-margin-bottom: 24px;\n\n\t/* Dimensions */\n\t--container-width: 480px; \n\t--submit-btn-height: 48px;\n\t--checkbox-size: 16px;\n\n\t/* Others */\n\t--box-shadow-card: none; /* Fully turns off the shadow effect */\n\t--opacity-placeholder: 0.4;\n}",
          "appendAttribution": false
        },
        "formTitle": "HVAC Repairs And Maintainence | Service Request Form",
        "formFields": {
          "values": [
            {
              "fieldName": "Your Name",
              "fieldLabel": "Your Name",
              "requiredField": true
            },
            {
              "fieldName": "Email Address",
              "fieldType": "email",
              "fieldLabel": "Email Address",
              "requiredField": true
            },
            {
              "fieldName": "Phone Number",
              "fieldLabel": "Phone Number",
              "requiredField": true
            },
            {
              "fieldName": "Property Address",
              "fieldType": "textarea",
              "fieldLabel": "What is your Property Address?",
              "requiredField": true
            },
            {
              "fieldName": "image",
              "fieldType": "file",
              "fieldLabel": "Upload the image of HVAC unit's nameplate | AC's data sticker photo",
              "requiredField": true
            },
            {
              "fieldName": "issue",
              "fieldType": "textarea",
              "fieldLabel": "what was the issue",
              "requiredField": true
            }
          ]
        },
        "formDescription": "This is a service request form for HVAC Maintainence & Repairs"
      },
      "typeVersion": 2.5
    },
    {
      "id": "d9184684-c54e-469d-8b76-282a35e32cdd",
      "name": "Extract File Content",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1456,
        208
      ],
      "parameters": {
        "options": {
          "keepSource": "binary"
        },
        "operation": "binaryToPropery",
        "binaryPropertyName": "image"
      },
      "typeVersion": 1.1
    },
    {
      "id": "411f5d1f-7cee-4746-bef4-3496678a21fe",
      "name": "Parse API Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1920,
        208
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.candidates[0].content.parts[0].text;\n\n// Extract JSON block\nconst jsonMatch = raw.match(/\\{[\\s\\S]*\\}/);\n\nif (!jsonMatch) {\n  throw new Error(\"No JSON found in model output\");\n}\n\n// Parse JSON safely\nconst parsed = JSON.parse(jsonMatch[0]);\n\nreturn [{ json: parsed }];"
      },
      "typeVersion": 2
    },
    {
      "id": "44ead0e1-100f-4262-89a2-9dab2ee45838",
      "name": "Prepare Binary Image",
      "type": "n8n-nodes-base.code",
      "position": [
        2368,
        208
      ],
      "parameters": {
        "jsCode": "// 1. Keep the current JSON data from your HighLevel node\nconst currentJson = $input.first().json;\n\n// 2. Teleport the binary image directly from your early node\nconst originalImage = $('Extract File Content').first().binary.image;\n\n// 3. Staple them together and send them to WhatsApp\nreturn [{\n  json: currentJson,\n  binary: {\n    image: originalImage\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0bc87566-d782-4708-b653-6a6eca51b243",
      "name": "Create Lead in GoHighLevel",
      "type": "n8n-nodes-base.highLevel",
      "position": [
        2160,
        208
      ],
      "parameters": {
        "email": "={{ $('When Form Submitted').item.json['Email Address'] }}",
        "phone": "={{ $('When Form Submitted').item.json['Phone Number'] }}",
        "requestOptions": {},
        "additionalFields": {
          "name": "={{ $('When Form Submitted').item.json['Your Name'] }}",
          "customFields": {
            "values": [
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "8nC9gJn1mP5L4SPqN4OU",
                  "cachedResultName": "Property Address"
                },
                "fieldValue": "={{ $('When Form Submitted').item.json['Property Address'] }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "MGU3zM7TjUX5d33hNzfF",
                  "cachedResultName": "issue"
                },
                "fieldValue": "={{ $('When Form Submitted').item.json.issue }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "uLfMm6uf0fvQTDtFmQ2n",
                  "cachedResultName": "brand"
                },
                "fieldValue": "={{ $json.brand }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "6YwyqhDJbuJPvk8G5Cz5",
                  "cachedResultName": "Model Number"
                },
                "fieldValue": "={{ $json.model_number }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "krKIgZSiDw3r3wBDKeFO",
                  "cachedResultName": "Serial Number"
                },
                "fieldValue": "={{ $json.serial_number }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "1nO0a7HDLA8dPJVgpR6F",
                  "cachedResultName": "Manufactured Date"
                },
                "fieldValue": "={{ $json.manufacture_date }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "98rwR45lBaxPicsuOH1w",
                  "cachedResultName": "Refrigerant type"
                },
                "fieldValue": "={{ $json.refrigerant_type }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "URAPehNpcWqYXbMJUa1n",
                  "cachedResultName": "Probable Issue[ai generated]"
                },
                "fieldValue": "={{ $json.probable_issue }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "kNNNjRuEp94gCVBgHwNX",
                  "cachedResultName": "Repair Action"
                },
                "fieldValue": "={{ $json.repair_action }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "UPaP4A1oy4GsaQbmUVdO",
                  "cachedResultName": "Estimated cost level"
                },
                "fieldValue": "={{ $json.estimated_cost_level }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "gPizCz3eyj7iSdqhNCsJ",
                  "cachedResultName": "repair score"
                },
                "fieldValue": "={{ $json.repair_score }}"
              },
              {
                "fieldId": {
                  "__rl": true,
                  "mode": "list",
                  "value": "8zXXeWQ2cCGXoZ0BLRT6",
                  "cachedResultName": "AI Recommendation"
                },
                "fieldValue": "={{ $json.recommendation }}"
              }
            ]
          }
        }
      },
      "credentials": {
        "highLevelOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ca2103cd-0133-42a7-92c3-d147c9662466",
      "name": "Post to Gemini API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1728,
        208
      ],
      "parameters": {
        "url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite-preview:generateContent",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"You are an expert HVAC diagnostic assistant.\\n\\nYou will receive:\\n1. An equipment image (nameplate or unit photo)\\n2. A reported issue from the user\\n\\nYour tasks:\\n\\nSTEP 1: Extract equipment details from the image.\\nReturn the following fields:\\n- brand\\n- model_number\\n- serial_number\\n- manufacture_date (Month/Year)\\n- refrigerant_type\\n\\nIf any value is unreadable, return null.\\n\\nSTEP 2: Analyze the reported issue and equipment condition.\\n\\nUser reported issue:\\n\\\"{{ $('When Form Submitted').item.json.issue }}\\\"\\n\\nBased on:\\n- Extracted refrigerant type, especially if R-22 or not\\n- Typical failure patterns such as gas leak, compressor, airflow issues\\n- Age of unit if manufacture date is available\\n\\nGenerate:\\n- probable_issue\\n- repair_action\\n- estimated_cost_level (low / medium / high)\\n- repair_score (0 to 100)\\n\\nRepair Score Meaning:\\n0 to 30 = Not worth repairing, replace recommended\\n31 to 60 = Risky repair, temporary fix\\n61 to 100 = Good candidate for repair\\n\\nSTEP 3: Provide recommendation:\\n- recommendation: repair or replace\\n\\nOutput STRICT JSON ONLY in this format:\\n{\\n  \\\"brand\\\": null,\\n  \\\"model_number\\\": null,\\n  \\\"serial_number\\\": null,\\n  \\\"manufacture_date\\\": null,\\n  \\\"refrigerant_type\\\": null,\\n  \\\"probable_issue\\\": \\\"\\\",\\n  \\\"repair_action\\\": \\\"\\\",\\n  \\\"estimated_cost_level\\\": \\\"\\\",\\n  \\\"repair_score\\\": 0,\\n  \\\"recommendation\\\": \\\"\\\"\\n}\"\n        },\n        {\n          \"inlineData\": {\n            \"mimeType\": \"image/jpeg\",\n            \"data\": \"{{ $json.data }}\"\n          }\n        }\n      ]\n    }\n  ],\n  \"generationConfig\": {\n    \"response_mime_type\": \"application/json\"\n  }\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "googlePalmApi"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "afb43b6f-2e9f-4bdb-9015-023a66161381",
      "name": "Send WhatsApp to Technician",
      "type": "n8n-nodes-base.whatsApp",
      "position": [
        2640,
        208
      ],
      "parameters": {
        "mediaPath": "useMedian8n",
        "operation": "send",
        "messageType": "image",
        "phoneNumberId": "1083481144853090",
        "additionalFields": {
          "mediaCaption": "=*Client Details:*\nName: {{ $('When Form Submitted').item.json['Your Name'] }}\n\n*Reported Issue:*\n{{ $('When Form Submitted').item.json.issue }}\n\n*Property Address*\n{{ $('When Form Submitted').item.json['Property Address'] }}\n\n*AI Diagnosis Summary:*\nPossible Issue: {{ $('Parse API Response').item.json.probable_issue }}\nEstimated Cost Level: {{ $('Parse API Response').item.json.estimated_cost_level }}\n\n*Next Steps:*\nReview the issue and diagnosis, then proceed with further inspection or contact the client for confirmation if needed. Check your gohighlevel CRM for the customer contact details"
        },
        "mediaPropertyName": "image",
        "recipientPhoneNumber": "={{ $('When Form Submitted').item.json['Phone Number'] }}"
      },
      "credentials": {
        "whatsAppApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    }
  ],
  "connections": {
    "Parse API Response": {
      "main": [
        [
          {
            "node": "Create Lead in GoHighLevel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post to Gemini API": {
      "main": [
        [
          {
            "node": "Parse API Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Form Submitted": {
      "main": [
        [
          {
            "node": "Extract File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract File Content": {
      "main": [
        [
          {
            "node": "Post to Gemini API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Binary Image": {
      "main": [
        [
          {
            "node": "Send WhatsApp to Technician",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Lead in GoHighLevel": {
      "main": [
        [
          {
            "node": "Prepare Binary Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}