This workflow follows the Agent → Google Gemini Chat 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 →
{
"name": "HVAC",
"nodes": [
{
"parameters": {
"content": "## Automated Missed Call Follow-Up[Sub worflow 1]\n\n### How it works\n\n1. A webhook receives incoming call data from a telephony provider. 2. The workflow filters for specific call statuses like missed or canceled calls. 3. Data is extracted and a new lead is created in GoHighLevel. 4. An opportunity is created in the designated CRM pipeline. 5. A follow-up SMS is sent to the lead via Twilio. 6. The CRM opportunity status is updated to complete the process.\n\n### Setup steps\n\n- Configure the Webhook URL in your telephony provider to send POST requests.\n- Set up GoHighLevel credentials and map the pipeline and status fields.\n- Connect your Twilio account and configure the sender phone number and message content.\n\n### Customization\n\nYou can modify the SMS template to include custom fields from the CRM or adjust the filtering logic to trigger on different call statuses.",
"height": 480,
"width": 480
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1728,
-192
],
"id": "a41e9f5b-256e-45fc-a5e9-69917c2b4b80",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## Receive and filter webhook calls\n\nReceives incoming webhook call and filters for relevant call statuses.",
"height": 304,
"width": 400,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2256,
-192
],
"id": "27e50622-8732-450a-b844-578f07dcfc3b",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "## Process lead and opportunity data\n\nExtracts call data and creates/updates records in GoHighLevel.",
"height": 288,
"width": 560,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2704,
-192
],
"id": "8537724f-c0b2-42e9-ab80-e2956e621fec",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "## Send SMS and finalize status\n\nSends an SMS follow-up and updates the final opportunity status.",
"height": 288,
"width": 400,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3296,
-192
],
"id": "5f9d642e-a956-4d54-92f9-f10e9f0cf8e6",
"name": "Sticky Note3"
},
{
"parameters": {
"httpMethod": "POST",
"path": "twillio-missed-call",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
2304,
-64
],
"id": "e1c47285-2551-4437-be4c-88efcc395ad0",
"name": "When Webhook Received"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "97130552-daee-4131-b8ee-df0ef7b84599",
"leftValue": "={{ $json.body.CallStatus }}",
"rightValue": "busy",
"operator": {
"type": "string",
"operation": "contains"
}
},
{
"id": "5f4b7f69-8c97-42c1-a490-76d27d30f746",
"leftValue": "={{ $json.body.CallStatus }}",
"rightValue": "no-answer",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
},
{
"id": "3ac8a45e-f335-4765-9058-a2bd7e4156c0",
"leftValue": "={{ $json.body.CallStatus }}",
"rightValue": "canceled",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "or"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
2512,
-64
],
"id": "9fd1f43f-ec78-4fc8-9611-0814d7d9cd17",
"name": "Filter Valid Call Statuses"
},
{
"parameters": {
"mode": "raw",
"jsonOutput": "={\n \"phone\": \"{{ $json.body.From }}\",\n \"phone_clean\": \"{{ $json.body.From.toString().replace('+', '') }}\",\n \"called_number\": \"{{ $json.body.To }}\",\n \"call_status\": \"{{ $json.body.CallStatus }}\",\n \"call_sid\": \"{{ $json.body.CallSid }}\",\n \"call_time\": \"{{ $json.body.Timestamp }}\",\n \"source\": \"twilio_missed_call\",\n \"tag\": \"missed-call-lead\"\n}",
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2752,
-80
],
"id": "1c0e7ba1-1578-4f48-88b3-b4b9bd993458",
"name": "Prepare Lead Data"
},
{
"parameters": {
"email": "={{ $json.phone_clean }}@missedcall.local",
"phone": "={{ $json.phone }}",
"additionalFields": {
"customFields": {
"values": [
{
"fieldId": {
"__rl": true,
"value": "FevKSYirCUsPi5lDGf4e",
"mode": "list",
"cachedResultName": "called phone number"
},
"fieldValue": "={{ $json.called_number }}"
},
{
"fieldId": {
"__rl": true,
"value": "4h1zVoyUGJ3JkQqmEOmo",
"mode": "list",
"cachedResultName": "call ssid"
},
"fieldValue": "={{ $json.call_sid }}"
}
]
},
"source": "={{ $json.source }}",
"tags": "={{ $json.tag }}, twilio, hvac-inbound-missed"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
2928,
-80
],
"id": "beef63ab-1d51-46e0-b316-92c9567541c6",
"name": "Create Lead in HighLevel",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "opportunity",
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"contactId": "={{ $json.id }}",
"name": "={{ 'Missed Call.... ' + $('Prepare Lead Data').item.json.phone_clean + '.... ' + $now.toFormat('dd LLL HH:mm') }}",
"additionalFields": {},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
3120,
-80
],
"id": "d4b659ea-cb1e-4984-8e78-665d2c0a867a",
"name": "Create Opportunity in HighLevel",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"from": "enter-your-twilio-number-here",
"to": "={{ $('Prepare Lead Data').item.json.phone }}",
"message": "Hi, I belive you missed a call with us. I am YOUR-NAME from ENTER-YOUR-COMPANY-NAME-HERE. Please state your issue directly here",
"options": {}
},
"type": "n8n-nodes-base.twilio",
"typeVersion": 1,
"position": [
3344,
-80
],
"id": "66a14a11-30d9-4fce-b8f6-0413f14fbf5a",
"name": "Send SMS via Twilio",
"credentials": {
"twilioApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "opportunity",
"operation": "update",
"opportunityId": "={{ $('Create Opportunity in HighLevel').item.json.opportunity.id }}",
"updateFields": {
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"stageId": "2fe0641a-9f82-4a06-8abf-d59cd2ea99c0"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
3552,
-80
],
"id": "cb001c24-758f-4f53-a1fa-51815dd8b546",
"name": "Update Opportunity Status",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"updates": [
"com.twilio.messaging.inbound-message.received"
]
},
"type": "n8n-nodes-base.twilioTrigger",
"typeVersion": 1,
"position": [
2336,
480
],
"id": "c5362924-8eba-41df-af6d-2306b05aa908",
"name": "When SMS Received",
"credentials": {
"twilioApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "=User SMS:\n{{ $('When SMS Received').item.json.Body }}\n\nExpected OUTPUT:\n{\n\t\"HVAC_oppurtunity?\": \"\"\n}",
"hasOutputParser": true,
"options": {
"systemMessage": "You are a helpful HVAC Oppurtunity finder Agent.\n\nYou understand the user SMS context and say whether it is an HVAC opputunity or not.\n\nAnd is it ok for us to send an appointment link.\n\nJust return the output in json.\n\n{\n\t\"HVAC_oppurtunity?\": \"\"\n}"
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
2992,
480
],
"id": "768fb6a0-81ff-4314-a1c7-422d76f61f29",
"name": "Lead Analyzer Agent"
},
{
"parameters": {
"modelName": "models/gemini-3.1-flash-lite-preview",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
2992,
688
],
"id": "190549d8-b837-480f-8243-90f76342894f",
"name": "Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsonSchemaExample": "{\n\t\"HVAC_oppurtunity?\": \"\"\n}"
},
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"typeVersion": 1.3,
"position": [
3136,
672
],
"id": "1f6780da-3b1b-49e4-aeb3-ed2816232fd7",
"name": "Parse Structured Output"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose",
"version": 3
},
"conditions": [
{
"id": "33812a3f-5d32-45bf-8381-ff7314ecd0a8",
"leftValue": "={{ $json.output['HVAC_oppurtunity?'] }}",
"rightValue": "yes",
"operator": {
"type": "string",
"operation": "contains"
}
},
{
"id": "83bf8ed8-7c4f-4956-8d87-c7c818cf37c0",
"leftValue": "={{ $json.output['HVAC_oppurtunity?'] }}",
"rightValue": "yeah",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "or"
},
"looseTypeValidation": true,
"options": {
"ignoreCase": true
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
3392,
480
],
"id": "37f27e71-85c4-49d6-bfa3-72321cbc61f5",
"name": "If HVAC Opportunity Found"
},
{
"parameters": {
"resource": "opportunity",
"operation": "getAll",
"filters": {
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"stageId": "",
"query": "={{ $('When SMS Received').item.json.From }}"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
2768,
480
],
"id": "bfa11b01-7d6f-435e-86b5-6da3bf5e139c",
"name": "Check Pipeline State",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "getAll",
"returnAll": true,
"filters": {
"query": "={{ $json.From }}"
},
"options": {},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
2544,
480
],
"id": "d2a46019-9786-4864-92b7-bfca01d54c27",
"name": "Check If Lead",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"from": "enter-your-twilio-number-here",
"to": "={{ $('When SMS Received').item.json.From }}",
"message": "Ok, Please schedule a visit here: enter-your-gohighlevel-scheduling-link-here",
"options": {}
},
"type": "n8n-nodes-base.twilio",
"typeVersion": 1,
"position": [
3648,
464
],
"id": "0fd1c5a4-06f3-4f5d-983b-83ace62a1142",
"name": "Send Response SMS",
"credentials": {
"twilioApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "opportunity",
"operation": "update",
"opportunityId": "={{ $('Check Pipeline State').item.json.id }}",
"updateFields": {
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"stageId": "271892d3-369e-430a-ac70-8961f0b619fd"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
3872,
464
],
"id": "6aba09f6-f104-48d2-b3fc-e5317d1134d1",
"name": "Update Lead Opportunity",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## AI-Powered SMS Lead Qualification & Booking[sub workflow 2]\n\n### How it works\n\n1. The workflow triggers upon receiving a new SMS via Twilio. 2. It verifies the sender's identity and retrieves their associated pipeline data. 3. An AI agent processes the message content to generate a contextual response. 4. The response is sent back to the user via SMS. 5. Finally, the lead's status is updated in the CRM based on the conversation outcome.\n\n### Setup steps\n\n- Configure the Twilio Trigger with your credentials and webhook URL.\n- Ensure the AI Agent is connected to a valid Google Gemini API key.\n- Configure the Twilio Send node to output messages to the correct phone numbers.\n- Map the update opportunity node to your specific CRM instance.\n\n### Customization\n\nAdjust the AI Agent prompt for specific business logic and update the CRM mapping fields to match your pipeline structure.",
"height": 480,
"width": 480
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1728,
352
],
"id": "ac98bdaf-e3b4-43a8-be06-5589195ec4a7",
"name": "Sticky Note4"
},
{
"parameters": {
"content": "## Receive and validate SMS message\n\nTriggers the workflow upon receiving a Twilio message and validates the sender.",
"height": 304,
"width": 400,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2288,
352
],
"id": "9f1c7263-821f-4582-afb7-2870690aa09c",
"name": "Sticky Note5"
},
{
"parameters": {
"content": "## Process message with AI agent\n\nRetrieves pipeline data and uses an AI agent to process the inbound message.",
"height": 496,
"width": 576,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2720,
352
],
"id": "679bec82-1332-4aae-bf9d-9dc0c1532cec",
"name": "Sticky Note6"
},
{
"parameters": {
"content": "## Route response and update CRM\n\nEvaluates the AI response and takes necessary actions in the CRM.",
"height": 288,
"width": 672,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
3344,
352
],
"id": "2793aa5d-22c5-4a4e-86ce-31f0de8cd60d",
"name": "Sticky Note7"
},
{
"parameters": {
"httpMethod": "POST",
"path": "appointment-booking",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
2336,
1056
],
"id": "2aab83bd-20ed-44c5-a523-7ccc8ae634af",
"name": "When Appointment Booked"
},
{
"parameters": {
"operation": "getAll",
"returnAll": true,
"filters": {
"query": "={{ $json.body.phone }}"
},
"options": {},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
2560,
1056
],
"id": "67361cb6-004b-48d2-ac2d-f23c35cc089c",
"name": "Check Lead SMS Origin",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"resource": "opportunity",
"operation": "update",
"opportunityId": "={{ $('Check Pipeline State1').item.json.id }}",
"updateFields": {
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"stageId": "7210c3dc-3898-43d5-8179-810db523270e"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
3232,
1056
],
"id": "62bd8dda-211c-4726-b0f9-9d5e7d3ab035",
"name": "Update Opportunity in HighLevel",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "update",
"contactId": "={{ $('When Appointment Booked').item.json.body.contact_id }}",
"updateFields": {
"email": "={{ $('When Appointment Booked').item.json.body.customData.contact_email }}",
"firstName": "={{ $('When Appointment Booked').item.json.body.customData.contact_first_name }}",
"lastName": "={{ $('When Appointment Booked').item.json.body.customData.contact_last_name }}",
"name": "={{ $('When Appointment Booked').item.json.body.customData.contact_full_name }}"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
3008,
1056
],
"id": "9fb8e39b-9df5-4e91-8387-7f3e2bba002c",
"name": "Update Contact in HighLevel",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## GoHighLevel Appointment Sync & Pipeline Advancement[sub workflow 3]\n\n### How it works\n\n1. The workflow triggers upon receiving an incoming SMS via a webhook. 2. It identifies the lead associated with the sender's phone number. 3. The workflow checks the current pipeline state for the identified lead. 4. It updates the contact and opportunity records based on the pipeline status.\n\n### Setup steps\n\n- - [ ] Configure the Webhook node URL in your external SMS service.\n- - [ ] Authenticate the HighLevel integration with your API key.\n- - [ ] Ensure the mapping of SMS data matches your HighLevel CRM fields.\n\n### Customization\n\nYou can add a branching condition to handle unrecognized phone numbers by creating a new contact.",
"height": 432,
"width": 480
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1728,
928
],
"id": "039450e6-a35b-42e7-8d03-553ee1358f48",
"name": "Sticky Note8"
},
{
"parameters": {
"content": "## Receive appointment and identify lead\n\nCaptures incoming new appointments via webhook and identifies the lead whether it is in our contacts or not.",
"height": 304,
"width": 416,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2288,
928
],
"id": "d11ae342-d747-4ee2-9440-b9ab11c575d9",
"name": "Sticky Note9"
},
{
"parameters": {
"content": "## Process pipeline and update records to fill the gap in contact data like name and email\n\nChecks pipeline status and updates related CRM records.",
"height": 304,
"width": 624,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2752,
928
],
"id": "37a2aab5-88e3-49ac-a311-bc8a6b852334",
"name": "Sticky Note10"
},
{
"parameters": {
"resource": "opportunity",
"operation": "getAll",
"filters": {
"pipelineId": "VUqGbIbOrFx1eaYAiZsZ",
"stageId": "271892d3-369e-430a-ac70-8961f0b619fd",
"query": "={{ $('When Appointment Booked').item.json.body.phone }}"
},
"requestOptions": {}
},
"type": "n8n-nodes-base.highLevel",
"typeVersion": 2,
"position": [
2800,
1056
],
"id": "c794b58d-507b-4b1e-9215-2e6be857870a",
"name": "Check Pipeline State1",
"credentials": {
"highLevelOAuth2Api": {
"name": "<your credential>"
}
}
}
],
"connections": {
"When Webhook Received": {
"main": [
[
{
"node": "Filter Valid Call Statuses",
"type": "main",
"index": 0
}
]
]
},
"Filter Valid Call Statuses": {
"main": [
[
{
"node": "Prepare Lead Data",
"type": "main",
"index": 0
}
]
]
},
"Prepare Lead Data": {
"main": [
[
{
"node": "Create Lead in HighLevel",
"type": "main",
"index": 0
}
]
]
},
"Create Lead in HighLevel": {
"main": [
[
{
"node": "Create Opportunity in HighLevel",
"type": "main",
"index": 0
}
]
]
},
"Create Opportunity in HighLevel": {
"main": [
[
{
"node": "Send SMS via Twilio",
"type": "main",
"index": 0
}
]
]
},
"Send SMS via Twilio": {
"main": [
[
{
"node": "Update Opportunity Status",
"type": "main",
"index": 0
}
]
]
},
"When SMS Received": {
"main": [
[
{
"node": "Check If Lead",
"type": "main",
"index": 0
}
]
]
},
"Lead Analyzer Agent": {
"main": [
[
{
"node": "If HVAC Opportunity Found",
"type": "main",
"index": 0
}
]
]
},
"Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Lead Analyzer Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Parse Structured Output": {
"ai_outputParser": [
[
{
"node": "Lead Analyzer Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"If HVAC Opportunity Found": {
"main": [
[
{
"node": "Send Response SMS",
"type": "main",
"index": 0
}
]
]
},
"Check Pipeline State": {
"main": [
[
{
"node": "Lead Analyzer Agent",
"type": "main",
"index": 0
}
]
]
},
"Check If Lead": {
"main": [
[
{
"node": "Check Pipeline State",
"type": "main",
"index": 0
}
]
]
},
"Send Response SMS": {
"main": [
[
{
"node": "Update Lead Opportunity",
"type": "main",
"index": 0
}
]
]
},
"When Appointment Booked": {
"main": [
[
{
"node": "Check Lead SMS Origin",
"type": "main",
"index": 0
}
]
]
},
"Check Lead SMS Origin": {
"main": [
[
{
"node": "Check Pipeline State1",
"type": "main",
"index": 0
}
]
]
},
"Update Contact in HighLevel": {
"main": [
[
{
"node": "Update Opportunity in HighLevel",
"type": "main",
"index": 0
}
]
]
},
"Check Pipeline State1": {
"main": [
[
{
"node": "Update Contact in HighLevel",
"type": "main",
"index": 0
}
]
]
}
},
"active": true,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"versionId": "44183828-8a45-42dc-a3e6-67c050240ff9",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "3slWrMuRkWzkS9m5",
"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.
googlePalmApihighLevelOAuth2ApitwilioApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
HVAC. Uses highLevel, twilio, twilioTrigger, agent. Webhook trigger; 32 nodes.
Source: https://gist.github.com/iamvaar-dev/df3b789baeeabba591d5950cd8ddd2a9 — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Before setting up the workflow in n8n, ensure you have completed the following foundational steps:
⏺ 🚀 How it works
Are you drowning in daily operational chaos, desperately trying to juggle sales, projects, content, and client communication? Imagine an AI brain that handles it all, freeing you to lead your business
LineOA. Uses httpRequest, agent, lmChatGoogleGemini, outputParserStructured. Webhook trigger; 69 nodes.
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.