{
  "name": "Kundenanfragen automatisch sortieren",
  "nodes": [
    {
      "id": "4898c62f-72f9-4dc8-a57f-191b0fa5a068",
      "name": "Notiz 1",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -60,
        -460
      ],
      "parameters": {
        "content": "## So richtest du den Ablauf ein\n1. Im Knoten **Neue E-Mail im Postfach** deine IMAP-Zugangsdaten eintragen (stehen bei deinem Mail-Anbieter).\n2. Mit **Test: Start per Klick** ausprobieren: Die Beispiel-Mails laufen durch, ohne dass etwas gesendet wird.\n3. In **Nach Stichwörtern einordnen** die Wörterlisten an deine Mails anpassen.\n4. Die ausgeschalteten E-Mail-Knoten mit deinen SMTP-Daten einrichten und einschalten.\n5. Optional: **KI ordnet unklare Mails ein** mit einem Anthropic-API-Schlüssel einrichten und einschalten.\n\nVorlage von Ablaufhelfer. Keine Zugangsdaten enthalten.",
        "height": 300,
        "width": 520,
        "color": 4
      }
    },
    {
      "id": "9a520329-018b-4451-ac4d-cff6fa18b8cb",
      "name": "Test: Start per Klick",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        160
      ],
      "parameters": {},
      "notes": "Startet den Ablauf von Hand, zum Testen mit den Beispieldaten."
    },
    {
      "id": "a57287dc-7884-47fc-ae9d-270ea789fbc6",
      "name": "Neue E-Mail im Postfach",
      "type": "n8n-nodes-base.emailReadImap",
      "typeVersion": 2,
      "position": [
        240,
        0
      ],
      "parameters": {
        "mailbox": "INBOX",
        "postProcessAction": "read",
        "format": "simple",
        "downloadAttachments": false,
        "options": {}
      },
      "notes": "Holt neue, ungelesene Mails per IMAP und markiert abgeholte Mails als gelesen."
    },
    {
      "id": "a58e0eb7-f22e-43dc-ad74-ab4a8315289c",
      "name": "Testdaten: 6 Beispiel-Mails",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        160
      ],
      "parameters": {
        "jsCode": "// Erfundene Beispiel-Mails im selben Aufbau, den der IMAP-Knoten liefert.\nconst mails = [\n  {\n    from: 'Lena Hoffmann <lena.hoffmann@example.com>',\n    subject: 'Anfrage: Angebot für neue Website',\n    textPlain:\n      'Hallo, wir möchten unsere Website erneuern und hätten gern ein Angebot. Wann hätten Sie Zeit für ein kurzes Telefonat? Viele Grüße, Lena Hoffmann',\n  },\n  {\n    from: 'Buchhaltung Muster Hosting <rechnung@example.net>',\n    subject: 'Ihre Rechnung RE-2026-1042',\n    textPlain: 'Guten Tag, anbei erhalten Sie Ihre Rechnung für November. Der Betrag wird per Lastschrift eingezogen.',\n  },\n  {\n    from: 'Tom Becker <tom.becker@example.org>',\n    subject: 'Termin am Donnerstag verschieben?',\n    textPlain: 'Hi, können wir unseren Termin am Donnerstag auf Freitag 10 Uhr verschieben? Gruß Tom',\n  },\n  {\n    from: 'Super Deals <news@example.com>',\n    subject: 'Nur heute: 30 % Rabatt auf alles!',\n    textPlain: 'Sichern Sie sich jetzt unseren Rabatt. Zum Abmelden vom Newsletter hier klicken.',\n  },\n  {\n    from: 'Sandra Wolf <s.wolf@example.org>',\n    subject: 'Dringend: Kostenvoranschlag bis Freitag',\n    textPlain:\n      'Sehr geehrte Damen und Herren, wir brauchen dringend einen Kostenvoranschlag für die Überarbeitung unseres Logos. Die Frist ist Freitag. Was würde das kosten?',\n  },\n  {\n    from: 'Max <max@example.com>',\n    subject: 'Kurze Frage',\n    textPlain: 'Hallo, haben Sie meine Unterlagen von letzter Woche bekommen? Danke!',\n  },\n];\nreturn mails.map((m) => ({ json: { ...m, date: new Date().toISOString() } }));\n"
      },
      "notes": "Sechs erfundene Mails zum Ausprobieren. Ersetzt beim echten Betrieb nichts."
    },
    {
      "id": "7fb8d9ee-ec97-48e4-a403-5dff763346e4",
      "name": "Nach Stichwörtern einordnen",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        80
      ],
      "parameters": {
        "jsCode": "// Stichwörter je Kategorie. Ein Treffer im Betreff zählt doppelt.\n// Beispiel für eine Webdesignerin: Ergänze die Wörter, die in DEINEN Mails vorkommen.\nconst REGELN = {\n  Anfrage: ['anfrage', 'angebot', 'kostenvoranschlag', 'preis', 'kosten', 'beauftragen', 'auftrag', 'interesse', 'projekt', 'website', 'logo'],\n  Rechnung: ['rechnung', 'beleg', 'zahlung', 'lastschrift', 'mahnung', 'gutschrift', 'quittung', 'invoice', 'betrag'],\n  Termin: ['termin', 'verschieben', 'absagen', 'uhr', 'kalender', 'besprechung', 'treffen'],\n  Werbung: ['newsletter', 'abmelden', 'rabatt', 'gutschein', 'gewinnspiel', 'unsubscribe', 'nur heute'],\n};\nconst DRINGEND = ['dringend', 'sofort', 'eilig', 'asap', 'frist', 'heute noch'];\nconst MINDESTPUNKTE = 2; // weniger Punkte = \"unklar\"\n\n// findet Wörter am Wortanfang, auch mit Umlauten (\"Rechnungen\" passt zu \"rechnung\")\nconst kommtVor = (text, wort) => new RegExp(`(^|[^\\\\p{L}])${wort}`, 'iu').test(text);\n\nreturn $input.all().map(({ json: m }) => {\n  const betreff = String(m.subject ?? '');\n  const text = String(m.textPlain ?? m.text ?? m.textHtml ?? '').replace(/<[^>]+>/g, ' ');\n  const punkte = {};\n  const treffer = [];\n  for (const [kategorie, woerter] of Object.entries(REGELN)) {\n    punkte[kategorie] = 0;\n    for (const wort of woerter) {\n      if (kommtVor(betreff, wort)) {\n        punkte[kategorie] += 2;\n        treffer.push(wort);\n      }\n      if (kommtVor(text, wort)) {\n        punkte[kategorie] += 1;\n        treffer.push(wort);\n      }\n    }\n  }\n  const sortiert = Object.entries(punkte).sort((x, y) => y[1] - x[1]);\n  const [beste, bestePunkte] = sortiert[0];\n  const gleichstand = sortiert[1][1] === bestePunkte;\n  const kategorie = bestePunkte >= MINDESTPUNKTE && !gleichstand ? beste : 'unklar';\n  return {\n    json: {\n      absender: String(m.from ?? ''),\n      betreff,\n      auszug: text.slice(0, 300),\n      kategorie,\n      dringend: DRINGEND.some((w) => kommtVor(`${betreff} ${text}`, w)),\n      punkte,\n      treffer: [...new Set(treffer)],\n      eingeordnetVon: kategorie === 'unklar' ? 'noch offen' : 'Stichwörter',\n    },\n  };\n});\n"
      },
      "notes": "Vergibt Punkte je Kategorie anhand von Stichwörtern. Läuft ohne KI und ohne Kosten."
    },
    {
      "id": "84c5e89c-0aa6-45dc-a5f3-9a0e79d92450",
      "name": "Unklar?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        720,
        80
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "dd79158c-888e-4c5b-af89-06384303b071",
              "leftValue": "={{ $json.kategorie }}",
              "rightValue": "unklar",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "notes": "Mails ohne eindeutiges Ergebnis gehen zur KI, alle anderen direkt weiter."
    },
    {
      "id": "fb6627a7-6e34-4220-ab6d-1fca70ee7e3b",
      "name": "KI ordnet unklare Mails ein",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        960,
        -60
      ],
      "disabled": true,
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: 'claude-haiku-5-5', max_tokens: 64, thinking: { type: 'disabled' }, messages: [{ role: 'user', content: 'Ordne diese E-Mail genau einer Kategorie zu: Anfrage, Rechnung, Termin, Werbung oder Sonstiges. Antworte nur mit diesem einen Wort.\\n\\nBetreff: ' + $json.betreff + '\\n\\n' + $json.auszug }] }) }}",
        "options": {}
      },
      "notes": "Optional, beim Import ausgeschaltet. Braucht einen Anthropic-API-Schlüssel (Zugang \"Header Auth\", Name x-api-key). Ausgeschaltet gehen unklare Mails unverändert weiter."
    },
    {
      "id": "d3f35f42-be19-40b4-a731-8abde43676a5",
      "name": "KI-Ergebnis übernehmen",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        -60
      ],
      "parameters": {
        "jsCode": "const originale = $('Unklar?').all(0);\nconst ERLAUBT = ['Anfrage', 'Rechnung', 'Termin', 'Werbung', 'Sonstiges'];\nreturn $input.all().map((item, i) => {\n  const original = originale[i]?.json ?? item.json;\n  const textBlock = (item.json?.content ?? []).find((b) => b.type === 'text');\n  const antwort = String(textBlock?.text ?? '').trim().toLowerCase();\n  const kategorie = ERLAUBT.find((k) => antwort.startsWith(k.toLowerCase()));\n  return {\n    json: {\n      ...original,\n      kategorie: kategorie ?? 'Sonstiges',\n      eingeordnetVon: kategorie ? 'KI' : 'niemand (KI-Schritt ausgeschaltet)',\n    },\n  };\n});\n"
      },
      "notes": "Liest die Antwort der KI. Ist der KI-Schritt ausgeschaltet, landet die Mail unter \"Sonstiges\"."
    },
    {
      "id": "69d9043b-cdf1-4c01-a237-18b9fdcb7b1c",
      "name": "Nach Kategorie verteilen",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        1440,
        80
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "524c1cbe-c6be-4b44-a1ce-ba58c9e63a07",
                    "leftValue": "={{ $json.kategorie }}",
                    "rightValue": "Anfrage",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Anfrage"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "9c2060c4-a2d8-4720-ac7e-d8b6cf7e627a",
                    "leftValue": "={{ $json.kategorie }}",
                    "rightValue": "Rechnung",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Rechnung"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "8e8987dd-45d3-42fc-aadc-a329a0c9ece9",
                    "leftValue": "={{ $json.kategorie }}",
                    "rightValue": "Termin",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Termin"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": false,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "1cd1bd51-cb5e-4fc4-a75c-a942371fbd5a",
                    "leftValue": "={{ $json.kategorie }}",
                    "rightValue": "Werbung",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Werbung"
            }
          ]
        },
        "looseTypeValidation": true,
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Sonstiges"
        }
      },
      "notes": "Schickt jede Mail in den passenden Zweig."
    },
    {
      "id": "e2b87027-d1df-486f-aefa-6403024e5ccb",
      "name": "Anfrage: Nachricht an dich",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1720,
        -200
      ],
      "disabled": true,
      "parameters": {
        "fromEmail": "Ablauf <deine-adresse@example.com>",
        "toEmail": "deine-adresse@example.com",
        "subject": "={{ ($json.dringend ? '[DRINGEND] ' : '') + 'Neue Anfrage: ' + $json.betreff }}",
        "emailFormat": "text",
        "text": "=Neue Kundenanfrage von {{ $json.absender }}\n\n{{ $json.auszug }}",
        "options": {
          "appendAttribution": false
        }
      },
      "notes": "Benachrichtigt dich über neue Anfragen, dringende mit Kennzeichen im Betreff. Beim Import ausgeschaltet."
    },
    {
      "id": "0075e030-b029-4bbc-a2d4-7b78db2449c8",
      "name": "Rechnung: Hinweis an Buchhaltung",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1720,
        -40
      ],
      "disabled": true,
      "parameters": {
        "fromEmail": "Ablauf <deine-adresse@example.com>",
        "toEmail": "buchhaltung@example.com",
        "subject": "={{ 'Rechnung eingegangen: ' + $json.betreff }}",
        "emailFormat": "text",
        "text": "=Absender: {{ $json.absender }}\n\n{{ $json.auszug }}",
        "options": {
          "appendAttribution": false
        }
      },
      "notes": "Gibt der Buchhaltung Bescheid. Beim Import ausgeschaltet."
    },
    {
      "id": "bc2a4cd2-b9e5-4425-a75c-8ba1549fd241",
      "name": "Termin: Nachricht an dich",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1720,
        120
      ],
      "disabled": true,
      "parameters": {
        "fromEmail": "Ablauf <deine-adresse@example.com>",
        "toEmail": "deine-adresse@example.com",
        "subject": "={{ 'Terminfrage: ' + $json.betreff }}",
        "emailFormat": "text",
        "text": "=Von {{ $json.absender }}\n\n{{ $json.auszug }}",
        "options": {
          "appendAttribution": false
        }
      },
      "notes": "Erinnert dich an Terminfragen. Beim Import ausgeschaltet."
    },
    {
      "id": "84c11b18-f36e-4fab-a4fc-f55cc7207ce6",
      "name": "Werbung: nichts tun",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1720,
        280
      ],
      "parameters": {},
      "notes": "Werbung bleibt einfach liegen."
    },
    {
      "id": "a5fc711b-2cd3-4208-a59c-555e58d48af6",
      "name": "Sonstiges: später ansehen",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1720,
        440
      ],
      "parameters": {},
      "notes": "Alles andere schaust du selbst an."
    }
  ],
  "connections": {
    "Test: Start per Klick": {
      "main": [
        [
          {
            "node": "Testdaten: 6 Beispiel-Mails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Neue E-Mail im Postfach": {
      "main": [
        [
          {
            "node": "Nach Stichwörtern einordnen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Testdaten: 6 Beispiel-Mails": {
      "main": [
        [
          {
            "node": "Nach Stichwörtern einordnen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Nach Stichwörtern einordnen": {
      "main": [
        [
          {
            "node": "Unklar?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Unklar?": {
      "main": [
        [
          {
            "node": "KI ordnet unklare Mails ein",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Nach Kategorie verteilen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "KI ordnet unklare Mails ein": {
      "main": [
        [
          {
            "node": "KI-Ergebnis übernehmen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "KI-Ergebnis übernehmen": {
      "main": [
        [
          {
            "node": "Nach Kategorie verteilen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Nach Kategorie verteilen": {
      "main": [
        [
          {
            "node": "Anfrage: Nachricht an dich",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Rechnung: Hinweis an Buchhaltung",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Termin: Nachricht an dich",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Werbung: nichts tun",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sonstiges: später ansehen",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Europe/Berlin"
  },
  "pinData": {}
}
