{
  "name": "Missed-call text-back (Plumbing & HVAC)",
  "nodes": [
    {
      "id": "b3544878-3bbf-51bd-a86b-59b7f1478ca9",
      "name": "Call ended (from Twilio)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "missed-call",
        "responseMode": "responseNode",
        "options": {}
      },
      "webhookId": "8c8b0abc-ecab-549a-88d7-6ebd41b1c555"
    },
    {
      "id": "1ad14324-d448-5662-90cd-dab218c611ce",
      "name": "Incoming text",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        300
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "incoming-sms",
        "responseMode": "responseNode",
        "options": {}
      },
      "webhookId": "d91271b0-8a1c-5775-a334-90cfe21d3987"
    },
    {
      "id": "135d8194-dde4-5cd6-b194-8fb2a8d224df",
      "name": "Config (edit me)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        140
      ],
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "314930a6-ca7d-5bc7-9092-2ebbf5f3777d",
              "name": "business_name",
              "value": "YOUR BUSINESS NAME",
              "type": "string"
            },
            {
              "id": "f6c674a5-b22c-55e1-ab38-58013fd11ecc",
              "name": "booking_link",
              "value": "https://YOUR-BOOKING-LINK",
              "type": "string"
            },
            {
              "id": "e5b3ffe8-bd9f-517d-a6fa-937b7f5953ca",
              "name": "hours",
              "value": "Mon-Fri 8am-6pm",
              "type": "string"
            },
            {
              "id": "5fab40da-ebc8-51a0-b2fb-571593814fbc",
              "name": "owner_email",
              "value": "you@example.com",
              "type": "string"
            },
            {
              "id": "4531eacb-bb6b-5212-8e05-63a7c931b8f5",
              "name": "owner_cell",
              "value": "+15555550100",
              "type": "string"
            },
            {
              "id": "cc412b7f-3c7e-596c-b1cc-bf74959c7716",
              "name": "twilio_number",
              "value": "+15555550199",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      }
    },
    {
      "id": "a7f0d4df-340a-5a73-8ac6-633437969410",
      "name": "Call or text?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        440,
        140
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "3fb29dbc-d7e2-5aaa-b2a4-83df178109fe",
              "leftValue": "={{ $json.body.DialCallStatus }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "6f949517-f57c-540a-a700-05ca31c0aeba",
      "name": "Tell Twilio what to say",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        660,
        0
      ],
      "parameters": {
        "respondWith": "text",
        "responseBody": "={{ $json.body.DialCallStatus === 'completed' ? '<Response><Hangup/></Response>' : '<Response><Say>Sorry we missed you. We are texting you right now.</Say><Hangup/></Response>' }}",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/xml"
              }
            ]
          }
        }
      }
    },
    {
      "id": "60d7bee6-8388-51d0-947d-25263450a63b",
      "name": "Was the call missed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        880,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "id": "43e74a7c-c380-561e-b2bf-e1e7b1a4ad17",
              "leftValue": "={{ $('Call ended (from Twilio)').item.json.body.DialCallStatus }}",
              "rightValue": "completed",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "273e3d32-829d-51a6-b287-6cc4df10d2ba",
      "name": "Text the caller",
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        1100,
        0
      ],
      "parameters": {
        "from": "={{ $('Config (edit me)').item.json.twilio_number }}",
        "to": "={{ $('Call ended (from Twilio)').item.json.body.From }}",
        "message": "=Hi, this is {{ $('Config (edit me)').item.json.business_name }}. Sorry we missed your call! We're probably on a job. Reply with what's going on (leak, no heat, no AC, etc.) and your address, and we'll call you right back. If it's an emergency, reply URGENT.",
        "options": {}
      },
      "credentials": {
        "twilioApi": {
          "id": "REPLACE_TWILIO_CREDENTIAL",
          "name": "Twilio account (placeholder)"
        }
      }
    },
    {
      "id": "5fecf21f-3064-510b-9c2a-cd82c825bbce",
      "name": "Email the owner",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1320,
        0
      ],
      "parameters": {
        "sendTo": "={{ $('Config (edit me)').item.json.owner_email }}",
        "subject": "=Missed call from {{ $('Call ended (from Twilio)').item.json.body.From }}",
        "emailType": "text",
        "message": "=We missed a call from {{ $('Call ended (from Twilio)').item.json.body.From }} and texted them automatically. Call them back when you can.",
        "options": {}
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "REPLACE_GMAIL_CREDENTIAL",
          "name": "Gmail account (placeholder)"
        }
      }
    },
    {
      "id": "d250fc72-ae20-54ad-b901-3f8ccfcb7986",
      "name": "Acknowledge Twilio (text)",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        660,
        420
      ],
      "parameters": {
        "respondWith": "text",
        "responseBody": "<Response></Response>",
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "text/xml"
              }
            ]
          }
        }
      }
    },
    {
      "id": "f3cb2fff-f39d-54f1-a1e1-818a0720eae2",
      "name": "AI writes reply",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 1.8,
      "position": [
        880,
        620
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "value": "gpt-5-mini",
          "mode": "id"
        },
        "messages": {
          "values": [
            {
              "content": "You are the friendly dispatcher for a local plumbing and HVAC company. Write one short, warm SMS reply (under 300 characters) to a new lead. Acknowledge their problem in plain words, say a technician will call them shortly, and if they describe water actively leaking, gas smell, no heat in freezing weather or no AC in extreme heat, tell them to reply URGENT. Never quote prices. Never promise an exact arrival time. Sign off with the business name.",
              "role": "system"
            },
            {
              "content": "=Business: {{ $('Config (edit me)').item.json.business_name }}\nHours: {{ $('Config (edit me)').item.json.hours }}\nBooking link: {{ $('Config (edit me)').item.json.booking_link }}\nCustomer's text: {{ $('Incoming text').item.json.body.Body }}"
            }
          ]
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "REPLACE_OPENAI_CREDENTIAL",
          "name": "OpenAI account (placeholder)"
        }
      }
    },
    {
      "id": "05500bc5-8fc8-564b-8b77-0bf892589de5",
      "name": "Text the AI reply",
      "type": "n8n-nodes-base.twilio",
      "typeVersion": 1,
      "position": [
        1100,
        620
      ],
      "parameters": {
        "from": "={{ $('Config (edit me)').item.json.twilio_number }}",
        "to": "={{ $('Incoming text').item.json.body.From }}",
        "message": "={{ $json.message.content }}",
        "options": {}
      },
      "credentials": {
        "twilioApi": {
          "id": "REPLACE_TWILIO_CREDENTIAL",
          "name": "Twilio account (placeholder)"
        }
      }
    },
    {
      "id": "7167ddc9-ae93-5c30-9a8b-2e1d9e49c937",
      "name": "Email owner about the text",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1320,
        620
      ],
      "parameters": {
        "sendTo": "={{ $('Config (edit me)').item.json.owner_email }}",
        "subject": "=New text from {{ $('Incoming text').item.json.body.From }}",
        "emailType": "text",
        "message": "=They wrote: {{ $('Incoming text').item.json.body.Body }}\n\nWe auto-replied: {{ $('AI writes reply').item.json.message.content }}",
        "options": {}
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "REPLACE_GMAIL_CREDENTIAL",
          "name": "Gmail account (placeholder)"
        }
      }
    },
    {
      "id": "ba84e5c3-e7ef-5561-8baa-fe92a52a7324",
      "name": "Setup steps",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -520,
        -120
      ],
      "parameters": {
        "content": "## Setup (about 1 hour)\n1. Open **Config (edit me)** and fill in your business name, booking link, hours, email, cell and Twilio number.\n2. Click each node with a red warning and connect your own **Twilio**, **OpenAI**, **Gmail** credentials.\n3. In Twilio, on your number: Voice > 'A call comes in' > TwiML Bin with:\n`<Response><Dial timeout=\"20\" action=\"YOUR_N8N_URL/webhook/missed-call\">+1YOURCELL</Dial></Response>`\n4. Messaging > 'A message comes in' > Webhook `YOUR_N8N_URL/webhook/incoming-sms` (POST).\n5. Register your number for A2P 10DLC in Twilio before texting customers.\n6. Activate the workflow.",
        "height": 440,
        "width": 480
      }
    }
  ],
  "connections": {
    "Call ended (from Twilio)": {
      "main": [
        [
          {
            "node": "Config (edit me)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Incoming text": {
      "main": [
        [
          {
            "node": "Config (edit me)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Config (edit me)": {
      "main": [
        [
          {
            "node": "Call or text?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call or text?": {
      "main": [
        [
          {
            "node": "Tell Twilio what to say",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Acknowledge Twilio (text)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tell Twilio what to say": {
      "main": [
        [
          {
            "node": "Was the call missed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Was the call missed?": {
      "main": [
        [
          {
            "node": "Text the caller",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text the caller": {
      "main": [
        [
          {
            "node": "Email the owner",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Acknowledge Twilio (text)": {
      "main": [
        [
          {
            "node": "AI writes reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI writes reply": {
      "main": [
        [
          {
            "node": "Text the AI reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Text the AI reply": {
      "main": [
        [
          {
            "node": "Email owner about the text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "templateCredsSetupCompleted": false,
    "generatedBy": "Speed-to-Lead Playbooks"
  },
  "tags": []
}