AutomationFlowsEmail & Gmail › Hvacflow - Smart Hvac Service Management System Copy

Hvacflow - Smart Hvac Service Management System Copy

HVACFlow - Smart HVAC Service Management System copy. Uses mongoDb, gmail, twilio, googleCalendar. Scheduled trigger; 42 nodes.

Cron / scheduled trigger★★★★★ complexity42 nodesMongoDBGmailTwilioGoogle CalendarHTTP RequestForm Trigger
Email & Gmail Trigger: Cron / scheduled Nodes: 42 Complexity: ★★★★★ Added:

This workflow follows the Form Trigger → Gmail recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "HVACFlow - Smart HVAC Service Management System copy",
  "nodes": [
    {
      "parameters": {
        "content": "MODULE 1 - LEAD CAPTURE\n\nWebhook receives new lead form data (name, phone, email, address, service required, message).\nA Code node generates a unique Lead ID, then the lead is saved to MongoDB and the customer gets an email + SMS confirmation.",
        "height": 300,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 1 - LEAD CAPTURE\n",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -3424,
        48
      ],
      "id": "45f29f89-2b9a-4682-bba6-531ad188f177"
    },
    {
      "parameters": {
        "jsCode": "const body = $input.first().json.body || $input.first().json;\nconst leadId = 'LEAD-' + Date.now().toString(36).toUpperCase() + '-' + Math.floor(Math.random()*900+100);\nreturn [{\n  json: {\n    leadId,\n    name: body.name,\n    phone: body.phone,\n    email: body.Email,\n    address: body.address,\n    serviceRequired: body.serviceRequired,\n    message: body.message,\n    status: 'new',\n    createdAt: new Date().toISOString()\n  }\n}];"
      },
      "name": "Code - Generate Lead ID",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -3280,
        464
      ],
      "id": "2dc76330-36bf-48e2-beb8-a06f4b188590"
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "leads",
        "fields": "leadId,name,phone,email,address,serviceRequired,message,status,createdAt",
        "options": {}
      },
      "name": "MongoDB - Save Lead",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -3072,
        640
      ],
      "id": "3f69db2b-171e-41f7-9c78-3517ef8beefa",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "sendTo": "={{$json.email}}",
        "subject": "=We received your HVAC service request - {{$json.leadId}}",
        "message": "=Hi {{$json.name}},\n\nThank you for contacting HVACFlow. We've received your request for: {{$json.serviceRequired}}.\n\nYour reference ID is {{$json.leadId}}. A team member will review your request shortly and confirm your appointment.\n\nHVACFlow Team",
        "options": {}
      },
      "name": "Gmail - Lead Confirmation Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -2912,
        336
      ],
      "id": "3ea9bb24-4e65-4412-ab45-4aed1aec547e",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "from": "+18312822077",
        "to": "={{$json.phone}}",
        "message": "=Hi {{$json.name}}, HVACFlow received your request ({{$json.leadId}}). We'll confirm your appointment shortly!",
        "options": {}
      },
      "name": "Twilio - Lead Confirmation SMS",
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        -2768,
        480
      ],
      "id": "8c2b723a-6f0a-4a2d-9c88-b94955750022",
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "content": "MODULE 2 - AI LEAD CLASSIFICATION\n\nOpenAI reads the customer's message and returns a JSON summary, service type (Installation/Repair/Maintenance) and urgency (Low/Medium/High/Emergency). Results are parsed and saved back to the lead in MongoDB, then routed by urgency.",
        "height": 300,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 2 - AI LEAD CLASS",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -2576,
        -64
      ],
      "id": "1a2c8942-5db4-4c77-bf45-16b4a0d5a1c9"
    },
    {
      "parameters": {
        "jsCode": "const lead = $('Code - Generate Lead ID').first().json;\n\nlet aiRaw = $input.first().json.candidates[0].content.parts[0].text;\n\n// Remove markdown code fences if Gemini returns them\naiRaw = aiRaw\n  .replace(/```json/g, '')\n  .replace(/```/g, '')\n  .trim();\n\nlet ai;\n\ntry {\n  ai = JSON.parse(aiRaw);\n} catch (e) {\n  ai = {\n    summary: aiRaw,\n    serviceType: 'Repair',\n    urgency: 'Medium'\n  };\n}\n\nreturn [\n  {\n    json: {\n      ...lead,\n      aiSummary: ai.summary,\n      serviceType: ai.serviceType,\n      urgency: ai.urgency\n    }\n  }\n];"
      },
      "name": "Code - Parse AI Classification",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2368,
        432
      ],
      "id": "d19c9a66-8c4b-4320-9f77-8901a400d988"
    },
    {
      "parameters": {
        "operation": "update",
        "collection": "leads",
        "updateKey": "leadId",
        "fields": "aiSummary,serviceType,urgency,status",
        "options": {}
      },
      "name": "MongoDB - Update Lead AI Data",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -2128,
        432
      ],
      "id": "2da86320-f62c-425b-b36d-bfbe2e1ab9d2",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "expression",
        "output": "={{$json.urgency === 'Emergency' ? 0 : 1}}"
      },
      "name": "Switch - Route by Urgency",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        -1936,
        672
      ],
      "id": "991cbed6-d829-4b49-a675-06995a74f9fe",
      "notes": "Output 0 = Emergency (jump straight to booking). Output 1 = Standard (normal queue)."
    },
    {
      "parameters": {
        "content": "MODULE 3 - APPOINTMENT BOOKING\n\nAn appointment record is created, available technicians are queried from MongoDB, the first free technician is assigned, and a Google Calendar event is booked. Both the Emergency and Standard paths from the Switch feed into this same booking flow.",
        "height": 340,
        "width": 384,
        "color": 6
      },
      "name": "Note: MODULE 3 - APPOINTMENT B",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1380,
        64
      ],
      "id": "f529460f-9114-4814-a832-f2cacc84749c"
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "appointments",
        "fields": "leadId,name,phone,email,address,serviceType,urgency,status,createdAt",
        "options": {}
      },
      "name": "MongoDB - Create Appointment",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -1568,
        608
      ],
      "id": "507a4d87-f4b9-4fc0-9ee8-959b4e41b706",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "collection": "technicians",
        "options": {},
        "query": "={{ JSON.stringify({ status: 'available' }) }}"
      },
      "name": "MongoDB - Find Available Technicians",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -1360,
        448
      ],
      "id": "2fac7e77-582c-4048-a371-7f6d6ccb036e",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const appt = $('MongoDB - Create Appointment').first().json;\nconst techs = $input.all().map(i => i.json);\nconst tech = techs[0] || null;\nreturn [{\n  json: {\n    ...appt,\n    technicianId: tech ? tech.technicianId : null,\n    technicianName: tech ? tech.name : null,\n    technicianPhone: tech ? tech.phone : null,\n    technicianEmail: tech ? tech.email : null,\n    technicianFound: !!tech\n  }\n}];"
      },
      "name": "Code - Assign Technician",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1152,
        784
      ],
      "id": "921d0e29-a405-4fa1-a750-e5b07e138a62"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{$json.technicianFound}}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "id": "139a53a4-55b3-406f-addc-e3a046925754"
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "name": "IF - Technician Available",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -928,
        768
      ],
      "id": "abcf5023-5616-4ec6-a600-ba9719c84ca0"
    },
    {
      "parameters": {
        "calendar": "primary",
        "start": "={{$now.plus({days:1}).toISO()}}",
        "end": "={{$now.plus({days:1, hours:2}).toISO()}}",
        "additionalFields": {
          "description": "=Address: {{$json.address}}\\nUrgency: {{$json.urgency}}\\nTechnician: {{$json.technicianName}}",
          "summary": "=HVAC {{$json.serviceType}} - {{$json.name}}"
        }
      },
      "name": "Google Calendar - Book Appointment",
      "type": "n8n-nodes-base.googleCalendar",
      "typeVersion": 1.3,
      "position": [
        -656,
        512
      ],
      "id": "3c5e5573-33f9-491f-bfcf-0c2ed793fd74",
      "credentials": {
        "googleCalendarOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "notes": "Demo uses tomorrow as a placeholder slot. Replace with real slot logic from technicians.schedule for a production version."
    },
    {
      "parameters": {
        "operation": "update",
        "collection": "appointments",
        "updateKey": "=leadId",
        "fields": "technicianId,technicianName,status,calendarEventId",
        "options": {}
      },
      "name": "MongoDB - Update Appointment",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -256,
        480
      ],
      "id": "5c8147ea-2ef4-4fe6-a225-a286fdade0d4",
      "alwaysOutputData": false,
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "return [{ json: { ...$json, status: 'awaiting_technician' } }];"
      },
      "name": "Code - No Technician Available",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -640,
        768
      ],
      "id": "5557622c-e933-46ed-a3f2-fbc343f4ec53"
    },
    {
      "parameters": {
        "content": "MODULE 4 - TECHNICIAN NOTIFICATION\n\nHTTP Request geocodes the address into a Google Maps link, then the technician is emailed and texted the job details: customer, address, service type, map link, and appointment time.",
        "height": 320,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 4 - TECHNICIAN NO",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -368,
        -48
      ],
      "id": "6cf548b5-f9c4-4c74-81ab-93aedb56ad49"
    },
    {
      "parameters": {
        "jsCode": "const appt = $('Code - Assign Technician').first().json;\nreturn [{\n  json: {\n    ...appt,\n    mapsLink: 'https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(appt.address)\n  }\n}];"
      },
      "name": "Code - Build Maps Link",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        0,
        272
      ],
      "id": "4e98b5c5-2557-4070-881a-a7699b8ff9f1"
    },
    {
      "parameters": {
        "sendTo": "={{$json.technicianEmail}}",
        "subject": "=New job assigned - {{$json.serviceType}} ({{$json.urgency}})",
        "message": "=You have a new job.\n\nCustomer: {{$json.name}}\nAddress: {{$json.address}}\nMap: {{$json.mapsLink}}\nService: {{$json.serviceType}}\nUrgency: {{$json.urgency}}\nAppointment time: {{$json.start}}",
        "options": {}
      },
      "name": "Gmail - Notify Technician",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        272,
        160
      ],
      "id": "9445fe0e-3c52-4a29-baa0-4f43bfa53661",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "from": "+18312822077",
        "to": "={{$json.technicianPhone}}",
        "message": "=New {{$json.urgency}} job: {{$json.serviceType}} at {{$json.address}}. Map: {{$json.mapsLink}}",
        "options": {}
      },
      "name": "Twilio - Notify Technician SMS",
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        272,
        336
      ],
      "id": "09c4fa94-642a-4171-ab84-36815dc18f93",
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "content": "MODULE 5 - WORK ORDER CREATION\n\nGenerates a Work Order ID and saves a full record (customer info, technician info, service type, appointment details, status = Assigned) into MongoDB.",
        "height": 240,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 5 - WORK ORDER CR",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -480,
        944
      ],
      "id": "871f2e58-a909-447a-b590-8dc5a985e283"
    },
    {
      "parameters": {
        "jsCode": "const appt = $('Code - Build Maps Link').first().json;\nconst workOrderId = 'WO-' + Date.now().toString(36).toUpperCase();\nreturn [{\n  json: {\n    workOrderId,\n    leadId: appt.leadId,\n    customerName: appt.name,\n    customerPhone: appt.phone,\n    customerEmail: appt.email,\n    address: appt.address,\n    technicianId: appt.technicianId,\n    technicianName: appt.technicianName,\n    serviceType: appt.serviceType,\n    urgency: appt.urgency,\n    appointmentTime: appt.start,\n    status: 'Assigned',\n    createdAt: new Date().toISOString()\n  }\n}];"
      },
      "name": "Code - Generate Work Order",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        16,
        576
      ],
      "id": "840884d4-de5e-411e-a1f7-01dde248c690"
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "work_orders",
        "fields": "workOrderId,leadId,customerName,customerPhone,customerEmail,address,technicianId,technicianName,serviceType,urgency,appointmentTime,status,createdAt",
        "options": {}
      },
      "name": "MongoDB - Create Work Order",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        256,
        560
      ],
      "id": "977ed2f9-85fd-4b53-8c89-8d376ba5e068",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      },
      "notes": "Status field cycles through Assigned -> In Progress -> Completed as the technician updates the job (update this record from a separate technician-facing form/workflow)."
    },
    {
      "parameters": {
        "content": "MODULE 6 - CUSTOMER UPDATES\n\nThe customer is emailed and texted confirming their appointment and technician assignment. A Merge node combines both notification results before logging them to MongoDB.",
        "height": 300,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 6 - CUSTOMER UPDA",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        480,
        816
      ],
      "id": "ffe0b054-5e59-4f39-a617-6a80ad28c4a3"
    },
    {
      "parameters": {
        "sendTo": "={{$json.customerEmail}}",
        "subject": "=Your HVAC appointment is confirmed - {{$json.workOrderId}}",
        "message": "=Hi {{$json.customerName}},\n\nYour {{$json.serviceType}} appointment is confirmed.\nTechnician: {{$json.technicianName}}\nDate/time: {{$json.appointmentTime}}\n\nWork order: {{$json.workOrderId}}\n\nHVACFlow Team",
        "options": {}
      },
      "name": "Gmail - Customer Appointment Confirmed",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        560,
        176
      ],
      "id": "5a9e7efe-89e8-4346-b2fc-5490e8909f69",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "from": "+18312822077",
        "to": "={{$json.customerPhone}}",
        "message": "=Hi {{$json.customerName}}, your HVACFlow appointment is confirmed with {{$json.technicianName}} on {{$json.appointmentTime}}.",
        "options": {}
      },
      "name": "Twilio - Customer SMS Confirmation",
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        592,
        544
      ],
      "id": "320209c0-fef8-42a7-93a0-7bd943c4c7ad",
      "credentials": {
        "twilioApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {},
      "name": "Merge - Notification Results",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        848,
        320
      ],
      "id": "c0b84dd9-60c9-4e4d-a197-057325e9b32a"
    },
    {
      "parameters": {
        "operation": "insert",
        "collection": "notifications",
        "fields": "workOrderId,leadId,type,sentAt",
        "options": {}
      },
      "name": "MongoDB - Log Notifications",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        1008,
        192
      ],
      "id": "05fdeeaa-2005-491d-89c7-4ebf64069121",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      },
      "notes": "Logs that email + SMS notifications were sent, for auditing/debugging."
    },
    {
      "parameters": {
        "content": "MODULE 7 - DAILY ANALYTICS REPORT\n\nRuns every day at 8 AM. Counts today's leads, appointments booked, jobs completed, and emergency requests from MongoDB, then emails a summary report to the business owner.",
        "height": 300,
        "width": 380,
        "color": 6
      },
      "name": "Note: MODULE 7 - DAILY ANALYTI",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -2960,
        832
      ],
      "id": "dcc509a8-394e-4556-af3d-f11c6cdcab04"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "name": "Schedule Trigger - Daily 8AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -3344,
        1152
      ],
      "id": "e1c8c5d3-811a-4df7-aa47-b95c8af86cd3"
    },
    {
      "parameters": {
        "operation": "aggregate",
        "collection": "leads",
        "query": "={{ JSON.stringify([{ $match: { createdAt: { $gte: $today } } }, { $count: 'total' }]) }}"
      },
      "name": "MongoDB - Count Leads Today",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -3120,
        1040
      ],
      "id": "48ef2df5-35a0-47ff-b0cc-bbdc3baf1f1a",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      },
      "notes": "$today should be set via an upstream Set node, or replace with your preferred date-range query."
    },
    {
      "parameters": {
        "operation": "aggregate",
        "collection": "appointments",
        "query": "={{ JSON.stringify([{ $match: { createdAt: { $gte: $today } } }, { $count: 'total' }]) }}"
      },
      "name": "MongoDB - Count Appointments Today",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -3120,
        1152
      ],
      "id": "f309fe9b-e232-4859-9655-a5f6e7643a5f",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "aggregate",
        "collection": "work_orders",
        "query": "={{ JSON.stringify([{ $match: { status: 'Completed', createdAt: { $gte: $today } } }, { $count: 'total' }]) }}"
      },
      "name": "MongoDB - Count Completed Jobs",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -3120,
        1248
      ],
      "id": "184aefa0-1619-4ab3-9a7e-74e10b418e50",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "aggregate",
        "collection": "leads",
        "query": "={{ JSON.stringify([{ $match: { urgency: 'Emergency', createdAt: { $gte: $today } } }, { $count: 'total' }]) }}"
      },
      "name": "MongoDB - Count Emergency Requests",
      "type": "n8n-nodes-base.mongoDb",
      "typeVersion": 1.1,
      "position": [
        -3120,
        1344
      ],
      "id": "ffdb94fc-e327-44a4-9341-15aba6530918",
      "credentials": {
        "mongoDb": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {
          "includeUnpaired": true
        }
      },
      "name": "Merge - Combine Report Stats",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.1,
      "position": [
        -2896,
        1200
      ],
      "id": "d558a46d-981f-4f44-840e-d570033c3c41"
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all().map(i => i.json);\nconst get = (i) => (items[i] && items[i].total) ? items[i].total : 0;\nreturn [{\n  json: {\n    leadsToday: get(0),\n    appointmentsToday: get(1),\n    completedToday: get(2),\n    emergenciesToday: get(3),\n    reportDate: new Date().toDateString()\n  }\n}];"
      },
      "name": "Code - Format Daily Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -2688,
        1200
      ],
      "id": "6a7fe5eb-2efc-4bd4-a0b3-15813ad613cd"
    },
    {
      "parameters": {
        "sendTo": "muhammadaryangohar@gmail.com",
        "subject": "=HVACFlow daily report - {{$json.reportDate}}",
        "message": "=Daily summary for {{$json.reportDate}}:\n\nTotal leads: {{$json.leadsToday}}\nAppointments booked: {{$json.appointmentsToday}}\nJobs completed: {{$json.completedToday}}\nEmergency requests: {{$json.emergenciesToday}}\n\n- HVACFlow automated report",
        "options": {}
      },
      "name": "Gmail - Send Daily Report",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -2464,
        1200
      ],
      "id": "00d226ff-8cf5-4094-8409-2139d98ccf52",
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={{$env.GEMINI_API_KEY}}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ contents: [ { parts: [ { text: \"You are an HVAC dispatch assistant. Read the customer message and reply ONLY with strict JSON: {\\\"summary\\\": string, \\\"serviceType\\\": \\\"Installation|Repair|Maintenance\\\", \\\"urgency\\\": \\\"Low|Medium|High|Emergency\\\"}\\n\\nCustomer message: \" + $json.message } ] } ] }) }}",
        "options": {}
      },
      "name": "Gemini API - Classify Lead",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -2576,
        656
      ],
      "id": "693d1246-0e12-4052-8bda-e1a7c4c8d453",
      "notes": "Replace the Authorization header value with your real OpenAI API key or attach an HTTP Header Auth credential."
    },
    {
      "parameters": {
        "formTitle": "HVAC Service Request Portal",
        "formDescription": "Please fill out this form to request HVAC repair, installation, or maintenance services. Our team will contact you shortly.",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Full Name",
              "fieldName": "name",
              "placeholder": "Enter your full name",
              "requiredField": true
            },
            {
              "fieldLabel": "Phone Number",
              "fieldName": "phone",
              "placeholder": "+923001234567",
              "requiredField": true
            },
            {
              "fieldLabel": "Email Address",
              "fieldType": "email",
              "fieldName": "Email",
              "placeholder": "yourname@example.com",
              "requiredField": true
            },
            {
              "fieldLabel": "Service Address",
              "fieldName": "address",
              "placeholder": "House #, Street, City",
              "requiredField": true
            },
            {
              "fieldLabel": "serviceRequired",
              "fieldType": "dropdown",
              "fieldName": "serviceRequired",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Repair"
                  },
                  {
                    "option": "Installation"
                  },
                  {
                    "option": "Miantenance"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldLabel": "Describe the Problem",
              "fieldType": "textarea",
              "fieldName": "message",
              "placeholder": "Example: My AC is not cooling properly."
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.formTrigger",
      "typeVersion": 2.6,
      "position": [
        -3488,
        464
      ],
      "id": "e31b4c49-4e74-46ce-ada4-90275d9573a9",
      "name": "On form submission"
    },
    {
      "parameters": {
        "jsCode": "const appt = $('Code - Assign Technician').first().json;\nconst cal = $input.first().json;\nreturn [{\n  json: {\n    ...appt,\n    calendarEventId: cal.id,\n    status: 'confirmed'\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -464,
        496
      ],
      "id": "11c640ff-4fcb-4eae-82ff-505b82ed534b",
      "name": "Code in JavaScript"
    },
    {
      "parameters": {
        "jsCode": "const lead = $('Code - Parse AI Classification').first().json;\nreturn [{\n  json: {\n    ...lead,\n    status: 'appointment_pending',\n    createdAt: new Date().toISOString()\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1728,
        384
      ],
      "id": "d6baf4f5-e882-4b0a-b040-a1f63e1f8c60",
      "name": "Code in JavaScript1"
    }
  ],
  "connections": {
    "Code - Generate Lead ID": {
      "main": [
        [
          {
            "node": "MongoDB - Save Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Save Lead": {
      "main": [
        [
          {
            "node": "Gmail - Lead Confirmation Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Twilio - Lead Confirmation SMS",
            "type": "main",
            "index": 0
          },
          {
            "node": "Gemini API - Classify Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Parse AI Classification": {
      "main": [
        [
          {
            "node": "MongoDB - Update Lead AI Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Update Lead AI Data": {
      "main": [
        [
          {
            "node": "Switch - Route by Urgency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch - Route by Urgency": {
      "main": [
        [
          {
            "node": "MongoDB - Create Appointment",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Code in JavaScript1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Create Appointment": {
      "main": [
        [
          {
            "node": "MongoDB - Find Available Technicians",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Find Available Technicians": {
      "main": [
        [
          {
            "node": "Code - Assign Technician",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Assign Technician": {
      "main": [
        [
          {
            "node": "IF - Technician Available",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF - Technician Available": {
      "main": [
        [
          {
            "node": "Google Calendar - Book Appointment",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Code - No Technician Available",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Calendar - Book Appointment": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Update Appointment": {
      "main": [
        [
          {
            "node": "Code - Build Maps Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Build Maps Link": {
      "main": [
        [
          {
            "node": "Gmail - Notify Technician",
            "type": "main",
            "index": 0
          },
          {
            "node": "Twilio - Notify Technician SMS",
            "type": "main",
            "index": 0
          },
          {
            "node": "Code - Generate Work Order",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Generate Work Order": {
      "main": [
        [
          {
            "node": "MongoDB - Create Work Order",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Create Work Order": {
      "main": [
        [
          {
            "node": "Gmail - Customer Appointment Confirmed",
            "type": "main",
            "index": 0
          },
          {
            "node": "Twilio - Customer SMS Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail - Customer Appointment Confirmed": {
      "main": [
        [
          {
            "node": "Merge - Notification Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Twilio - Customer SMS Confirmation": {
      "main": [
        [
          {
            "node": "Merge - Notification Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge - Notification Results": {
      "main": [
        [
          {
            "node": "MongoDB - Log Notifications",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger - Daily 8AM": {
      "main": [
        [
          {
            "node": "MongoDB - Count Leads Today",
            "type": "main",
            "index": 0
          },
          {
            "node": "MongoDB - Count Appointments Today",
            "type": "main",
            "index": 0
          },
          {
            "node": "MongoDB - Count Completed Jobs",
            "type": "main",
            "index": 0
          },
          {
            "node": "MongoDB - Count Emergency Requests",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Count Leads Today": {
      "main": [
        [
          {
            "node": "Merge - Combine Report Stats",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MongoDB - Count Appointments Today": {
      "main": [
        [
          {
            "node": "Merge - Combine Report Stats",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge - Combine Report Stats": {
      "main": [
        [
          {
            "node": "Code - Format Daily Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code - Format Daily Report": {
      "main": [
        [
          {
            "node": "Gmail - Send Daily Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini API - Classify Lead": {
      "main": [
        [
          {
            "node": "Code - Parse AI Classification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Code - Generate Lead ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "MongoDB - Update Appointment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript1": {
      "main": [
        [
          {
            "node": "MongoDB - Create Appointment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "b85596b0-ebb9-4c90-aed4-23c74bbeffea",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodeGroups": [],
  "id": "utgQHRAhxEAqWzKW",
  "tags": []
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

HVACFlow - Smart HVAC Service Management System copy. Uses mongoDb, gmail, twilio, googleCalendar. Scheduled trigger; 42 nodes.

Source: https://github.com/muhammadaryangohar-dev/hvacflow-smart-hvac-automation/blob/main/workflows/hvacflow.json — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Relatórios aos Laboratórios. Uses httpRequest, gmail, formTrigger. Scheduled trigger; 54 nodes.

HTTP Request, Gmail, Form Trigger
Email & Gmail

Relatórios aos Laboratórios. Uses httpRequest, gmail, formTrigger. Scheduled trigger; 48 nodes.

HTTP Request, Gmail, Form Trigger
Email & Gmail

Splitout Googlecalendar. Uses httpRequest, scheduleTrigger, googleCalendar, splitOut. Scheduled trigger; 19 nodes.

HTTP Request, Google Calendar, Clearbit +1
Email & Gmail

It’s very important to come prepared to Sales calls. This often means a lot of manual research about the person you’re calling with. This workflow delivers the latest social media activity (LinkedIn +

HTTP Request, Google Calendar, Clearbit +1
Email & Gmail

Httprequest Workflow. Uses httpRequest, googleCalendar, clearbit, gmail. Scheduled trigger; 19 nodes.

HTTP Request, Google Calendar, Clearbit +1