{
  "name": "LGM 02 — Missed-Call Textback (SIMULATED)",
  "nodes": [
    {
      "parameters": {},
      "id": "f02-start",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        320
      ]
    },
    {
      "parameters": {
        "jsCode": "// Fictional missed-call webhook payload (what a real telephony provider\n// would POST). previousTouches in the last 24h is critical for the\n// duplicate-guard branch.\nconst fixture = {\n  event_id: 'MCE-' + Math.floor(Math.random() * 90000 + 10000),\n  event_type: 'missed_call',\n  occurred_at: new Date().toISOString(),\n  caller_name: 'Liam Park',\n  caller_phone: '+61400000222',\n  business_line: 'Brisbane Glass & Glazing',\n  previous_touches_24h: 1,\n  // Hint for the demo branch selector.\n  branch_hint: 'first-touch'\n};\nreturn [{ json: fixture }];"
      },
      "id": "f02-fixture",
      "name": "Build Fixture",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "combinator": "or",
          "conditions": [
            {
              "leftValue": "={{ $json.previous_touches_24h }}",
              "rightValue": 2,
              "operator": {
                "type": "number",
                "operation": "gte"
              }
            },
            {
              "leftValue": "={{ $json.branch_hint }}",
              "rightValue": "human_call",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ]
        }
      },
      "id": "f02-guard",
      "name": "Duplicate Guard",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        680,
        320
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.branch_hint }}",
                    "rightValue": "second-touch",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "second",
              "renameOutput": true
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.branch_hint }}",
                    "rightValue": "third-touch",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "third",
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "f02-switch",
      "name": "Choose Touch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        900,
        460
      ]
    },
    {
      "parameters": {
        "jsCode": "// Duplicate-guard escalation: too many touches in the last 24h —\n// route to a human-call task instead of sending another SMS.\nconst items = $input.all();\nconst $json = items[0].json;\n\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. Guard fired' },\n  { type: 'note', label: 'Duplicate guard',\n    text: `${$json.caller_name} has ${$json.previous_touches_24h} touches in the last 24h. Skipping auto-SMS; escalating to human.` },\n  { type: 'heading', label: '2. CRM tag (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Contact', value: `${$json.caller_name} <${$json.caller_phone}>` },\n    { label: 'Stage', value: 'Missed call → Human callback' },\n    { label: 'Touches / 24h', value: String($json.previous_touches_24h) }\n  ]},\n  { type: 'heading', label: '3. Internal task (SIMULATED Todoist)' },\n  { type: 'task', label: 'Todoist',\n    title: 'Phone-verify callback to caller',\n    owner: 'Reception',\n    dueIn: 'Within 30 minutes',\n    notes: `Ref: ${$json.event_id}` }\n];\n\nreturn [{ json: { ...$json, branch: 'human_call', simulatedOutputs } }];"
      },
      "id": "f02-guard-out",
      "name": "Build Guard Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        200
      ]
    },
    {
      "parameters": {
        "jsCode": "// First-touch SMS.\nconst items = $input.all();\nconst $json = items[0].json;\n\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM tag (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Contact', value: `${$json.caller_name} <${$json.caller_phone}>` },\n    { label: 'Stage', value: 'Missed call → 1st touch' }\n  ]},\n  { type: 'heading', label: '2. SMS (SIMULATED Chatwoot + WhatsApp Cloud)' },\n  { type: 'message', channel: 'sms', label: 'SMS', body:\n    `Hi, ${$json.business_line} here — sorry we missed your call. How can we help? Reply here or call back when suits.` },\n  { type: 'heading', label: '3. Reporting payload' },\n  { type: 'code', label: 'Analytics',\n    language: 'json',\n    body: JSON.stringify({ event: 'missed_call_textback', caller: $json.caller_name, branch: 'first-touch', duplicate_guard: false }, null, 2) }\n];\n\nreturn [{ json: { ...$json, branch: 'first-touch', simulatedOutputs } }];"
      },
      "id": "f02-first",
      "name": "Build First-Touch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// Second-touch SMS — gentle nudge, 30+ min after first touch.\nconst items = $input.all();\nconst $json = items[0].json;\n\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM tag (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Contact', value: `${$json.caller_name} <${$json.caller_phone}>` },\n    { label: 'Stage', value: 'Missed call → 2nd touch' }\n  ]},\n  { type: 'heading', label: '2. SMS (SIMULATED Chatwoot)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Hi again from ${$json.business_line}. We don't want to leave you hanging — are you still needing help with a glass repair or quote? Reply STOP to opt out.` }\n];\n\nreturn [{ json: { ...$json, branch: 'second-touch', simulatedOutputs } }];"
      },
      "id": "f02-second",
      "name": "Build Second-Touch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        540
      ]
    },
    {
      "parameters": {
        "jsCode": "// Third/final-touch SMS — last try + opt-out path.\nconst items = $input.all();\nconst $json = items[0].json;\n\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM tag (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Contact', value: `${$json.caller_name} <${$json.caller_phone}>` },\n    { label: 'Stage', value: 'Missed call → 3rd touch (final)' }\n  ]},\n  { type: 'heading', label: '2. SMS (SIMULATED Chatwoot)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Last try from ${$json.business_line}. If you'd prefer us to call you, reply CALL and a time. Otherwise we'll stop messaging from this number.` },\n  { type: 'note', label: 'Compliance',\n    text: 'STOP keyword routes to Chatwoot compliance queue; subscriber suppressed in Listmonk.' }\n];\n\nreturn [{ json: { ...$json, branch: 'third-touch', simulatedOutputs } }];"
      },
      "id": "f02-third",
      "name": "Build Third-Touch",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        680
      ]
    },
    {
      "parameters": {},
      "id": "f02-sink",
      "name": "Sink",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1380,
        460
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Build Fixture",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Fixture": {
      "main": [
        [
          {
            "node": "Duplicate Guard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Duplicate Guard": {
      "main": [
        [
          {
            "node": "Build Guard Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Choose Touch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Choose Touch": {
      "main": [
        [
          {
            "node": "Build First-Touch",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Second-Touch",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Third-Touch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Guard Output": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build First-Touch": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Second-Touch": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Third-Touch": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner"
  },
  "versionId": "lgm-02-missed-call-textback",
  "id": "lgm-02-missed-call-textback",
  "meta": {
    "templateCredsSetupCompleted": false,
    "description": "SIMULATED missed-call textback. Duplicate-guard branch escalates to a human callback when previous_touches_24h >= 2."
  },
  "tags": [
    {
      "name": "lgm-02-missed-call-textback"
    }
  ]
}
