{
  "name": "Retell Appointment MVP (v2) \u2013 kompatibel",
  "nodes": [
    {
      "id": "Webhook",
      "name": "Webhook (Retell)",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        -480,
        0
      ],
      "parameters": {
        "path": "retell/appointment.create",
        "httpMethod": "POST",
        "responseMode": "responseNode",
        "options": {}
      }
    },
    {
      "id": "SwitchIntent",
      "name": "Intent w\u00e4hlen",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 2,
      "position": [
        -220,
        0
      ],
      "parameters": {
        "value1": "={{$json[\"intent\"]}}",
        "rules": [
          {
            "operation": "equal",
            "value2": "create_appointment"
          },
          {
            "operation": "equal",
            "value2": "update_appointment"
          },
          {
            "operation": "equal",
            "value2": "cancel_appointment"
          }
        ]
      }
    },
    {
      "id": "FnCreate",
      "name": "Create: validieren & Zeit berechnen",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        40,
        -140
      ],
      "parameters": {
        "functionCode": "const p = items[0].json;\n// --- Defaults / Demo-\u00d6ffnungszeiten ---\nconst DURATION_MIN = Number(p.duration_min ?? 30);\nfunction parseISO(s) { try { return new Date(s); } catch(e) { return null; } }\nconst start = parseISO(p.requested_time) || new Date(Date.now()+60*60*1000);\nconst end = new Date(start.getTime()+DURATION_MIN*60000);\n// einfache Mittwochs-Sperre (Demo)\nif (start.getDay() === 3) {\n  return [{ json: {\n    status: \"ok\",\n    booked: false,\n    message_for_caller: \"Mittwochs haben wir Ruhetag. Passt Ihnen Donnerstag zwischen 9 und 20 Uhr?\"\n  }}];\n}\nreturn [{ json: {\n  status: \"ok\",\n  booked: true,\n  start_time: start.toISOString(),\n  end_time: end.toISOString(),\n  message_for_caller: `Alles klar, ich habe Sie am ${start.toLocaleDateString('de-DE', { weekday: 'long' })} um ${start.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })} vorgemerkt.`\n}}];"
      }
    },
    {
      "id": "FnUpdate",
      "name": "Update: pr\u00fcfen & Antwort bauen",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        40,
        0
      ],
      "parameters": {
        "functionCode": "const p = items[0].json;\nconst newStart = new Date(Date.now()+2*60*60*1000);\nconst newEnd = new Date(newStart.getTime()+ (Number(p.duration_min ?? 30))*60000);\nreturn [{ json: {\n  status: \"ok\",\n  booked: true,\n  start_time: newStart.toISOString(),\n  end_time: newEnd.toISOString(),\n  message_for_caller: `Ich habe Ihren Termin aktualisiert: ${newStart.toLocaleDateString('de-DE', { weekday: 'long' })} ${newStart.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' })}.`\n}}];"
      }
    },
    {
      "id": "FnCancel",
      "name": "Cancel: stornieren (Demo)",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        40,
        140
      ],
      "parameters": {
        "functionCode": "return [{ json: {\n  status: \"ok\",\n  booked: false,\n  message_for_caller: \"Ihr Termin wurde storniert. M\u00f6chten Sie gleich einen neuen Wunschzeitraum nennen?\"\n}}];"
      }
    },
    {
      "id": "RespondCreate",
      "name": "Antwort an Retell (Create)",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        300,
        -140
      ],
      "parameters": {
        "responseBody": "={{$json}}"
      }
    },
    {
      "id": "RespondUpdate",
      "name": "Antwort an Retell (Update)",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        300,
        0
      ],
      "parameters": {
        "responseBody": "={{$json}}"
      }
    },
    {
      "id": "RespondCancel",
      "name": "Antwort an Retell (Cancel)",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        300,
        140
      ],
      "parameters": {
        "responseBody": "={{$json}}"
      }
    },
    {
      "id": "FnDefault",
      "name": "Fallback: unklarer Intent",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        40,
        280
      ],
      "parameters": {
        "functionCode": "return [{ json: {\n  status: \"ok\",\n  booked: false,\n  message_for_caller: \"Gern! Sagen Sie mir bitte Ihren Namen, eine Telefonnummer und eine Uhrzeit \u2013 dann trage ich Sie ein.\"\n}}];"
      }
    },
    {
      "id": "RespondDefault",
      "name": "Antwort an Retell (Fallback)",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        300,
        280
      ],
      "parameters": {
        "responseBody": "={{$json}}"
      }
    }
  ],
  "connections": {
    "Webhook (Retell)": {
      "main": [
        [
          {
            "node": "Intent w\u00e4hlen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Intent w\u00e4hlen": {
      "main": [
        [
          {
            "node": "Create: validieren & Zeit berechnen",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update: pr\u00fcfen & Antwort bauen",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Cancel: stornieren (Demo)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fallback: unklarer Intent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create: validieren & Zeit berechnen": {
      "main": [
        [
          {
            "node": "Antwort an Retell (Create)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update: pr\u00fcfen & Antwort bauen": {
      "main": [
        [
          {
            "node": "Antwort an Retell (Update)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Cancel: stornieren (Demo)": {
      "main": [
        [
          {
            "node": "Antwort an Retell (Cancel)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fallback: unklarer Intent": {
      "main": [
        [
          {
            "node": "Antwort an Retell (Fallback)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null
}