{
  "id": "5cLAXSzFC5fMxoad",
  "name": "AI greeting generator for email messaging via OpenAI and KlickTipp",
  "tags": [],
  "nodes": [
    {
      "id": "7bf7120e-0a73-4bc9-a32d-a250b4d51a22",
      "name": "2. Get Gender based on First Name from KlickTipp",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 636,
        "content": "## 2. Get Gender based on First Name from KlickTipp"
      },
      "typeVersion": 1
    },
    {
      "id": "942d5b36-2e9e-4bcc-a2e2-8f57a65e3502",
      "name": "1. Trigger from a KlickTipp",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 232,
        "height": 1292,
        "content": "## 1. Trigger from a KlickTipp"
      },
      "typeVersion": 1
    },
    {
      "id": "dcb16b46-8c13-49b5-ac1f-175c43cd43dd",
      "name": "4. Get Gender and First Name  based on Email address from KlickTipp",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        736,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 636,
        "content": "## 4. Get Gender and First Name  based on Email address from KlickTipp"
      },
      "typeVersion": 1
    },
    {
      "id": "c8b0b9ed-acf7-4873-b6cb-9aaaae89888c",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1248,
        1008
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"first_name\": \"\u2026\",\n  \"last_name\": \"\u2026\",\n  \"first_name_probability\": 0,\n  \"last_name_probability\": 0,\n  \"gender\": \"male|female|neutral\",\n  \"gender_probability\": 0\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "b47afcfe-06b4-48c9-bbae-d386ea89f030",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1088,
        992
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {}
      },
      "credentials": {},
      "typeVersion": 1.2
    },
    {
      "id": "af51a981-60ef-4e81-9013-d9d32d8f8e06",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1248,
        336
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"gender\": \"male|female|neutral\",\n  \"gender_probability\": 0\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "f13faa3a-a78d-4ac1-ae61-bb499086ae21",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1088,
        320
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {}
      },
      "credentials": {},
      "typeVersion": 1.2
    },
    {
      "id": "ab0f2c4d-2f09-493f-b1e0-316c6cb67d4c",
      "name": "Get First Name and Gender via AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1088,
        800
      ],
      "parameters": {
        "text": "=Process this email address:\n\"{{ $json.email }}\"",
        "options": {
          "systemMessage": "=**Role / Context**  \nYou are a **smart name parser and gender estimator** for email addresses.  \n\n**Task / Goal**  \nExtract and return only the JSON object, no explanation or extra text.  \n\n---\n\n**Parsing Rules**  \n\n1. **Source priority**  \n   - Use the local part before \u201c@\u201d.  \n   - If the local part is a generic mailbox (`info`, `contact`, `sales`, `support`, `help`, `team`, `office`, `admin`, `webmaster`, `noreply`, `newsletter`), try to extract a name from the domain (exclude TLD).  \n   - If domain tokens look like **business/industry words** (e.g., \u201cfirst\u201d, \u201cplanner\u201d, \u201ctravel\u201d, \u201cdesign\u201d, \u201cmedia\u201d), treat them as **not names**.  \n   - If the domain contains a hyphenated two-word pattern resembling a real human name (e.g., `hermann-scherer.com`), map to first and last names.  \n\n2. **Tokenization**  \n   - Split on `.`, `_`, `-`, `+`, and digits.  \n   - Remove digits.  \n   - Preserve hyphens in surnames (e.g., `smith-jones` \u2192 `Smith-Jones`).  \n\n3. **Honorifics & suffixes**  \n   - Remove: `mr`, `mrs`, `ms`, `dr`, `prof`, `jr`, `sr`, `ii`, `iii`, `iv`, `phd`, `md`, `mba`.  \n\n4. **Normalization**\n   - Restore diacritics where obvious:\n     - `Juergen` \u2192 `J\u00fcrgen`\n     - `Joerg` \u2192 `J\u00f6rg`\n     - `Goetz` \u2192 `G\u00f6tz`\n     - `Schoen` \u2192 `Sch\u00f6n`\n\n   - **German umlaut transliterations for selected name tokens (deterministic with guardrails):**\n     - Apply the following ONLY to tokens that you have already selected as `first_name` or `last_name` AND that you believe are real human names.\n     - If the selected name token contains these sequences, convert them.\n     - **Important: treat `ae/oe/ue` as transliteration digraphs (2 letters \u2192 1 character):**\n       - Replace the full sequence (`ae`, `oe`, `ue`) with the umlaut character (`\u00e4`, `\u00f6`, `\u00fc`) as **one character**.\n       - **Do NOT keep the trailing `e`** after conversion.\n       - Avoid invalid outcomes like: `Kl\u00fcenter`, `M\u00fceller`, `Sch\u00e4efer`.\n     - Conversions:\n       - `ae` \u2192 `\u00e4` (and `Ae` \u2192 `\u00c4`)\n       - `oe` \u2192 `\u00f6` (and `Oe` \u2192 `\u00d6`)\n       - `ue` \u2192 `\u00fc` (and `Ue` \u2192 `\u00dc`)\n     - **Do NOT convert** if any of these exclusions apply:\n       - `ue` occurs immediately after `q` (e.g., `que...`, `queue...`)\n       - the entire token is an obvious English word (e.g., `blue`, `true`, `glue`)\n       - the token was not confidently classified as a human name\n     - Examples (correct):\n       - `Kluenter` \u2192 `Kl\u00fcnter` (NOT `Kl\u00fcenter`)\n       - `Mueller` \u2192 `M\u00fcller` (NOT `M\u00fceller`)\n       - `Schaefer` \u2192 `Sch\u00e4fer` (NOT `Sch\u00e4efer`)\n       - `Goetz` \u2192 `G\u00f6tz` (NOT `G\u00f6etz`)\n     - Post-check:\n       - After normalization, the output must not contain the patterns `\u00e4e`, `\u00f6e`, `\u00fce` created by a failed transliteration.\n       - If such a pattern appears, fix it by removing the extra `e` (e.g., `Kl\u00fcenter` \u2192 `Kl\u00fcnter`).\n     - If conversion is applied, keep Title Case and reduce the corresponding probability by **5\u201310 points** (unless it is a very common case like `Mueller` \u2192 `M\u00fcller`).\n\n   - Use **Title Case**.\n   - Do not invent longer names from single letters (e.g., `\"u\"` \u2260 `\"Uwe\"`).\n   - If unsure about normalization, leave unchanged.\n\n5. **Real names only**  \n   - Assign `first_name_probability` and `last_name_probability` between 0\u2013100.  \n   - `100` = certain it is a valid first/last name, `0` = clearly not a human name. \n   - Reject non-names: single letters and strings without clear meaning (e.g., grd), generic words, common nouns, professions, or concepts.\n   - Use your general world knowledge of real given names and surnames across cultures.\n   - Be conservative: if in doubt, lower probability rather than guessing.\n\n---\n\n**Name Ordering**  \n- If `first.last` pattern \u2192 assign directly.  \n- If ambiguous, choose the token with higher **given-name probability** as `first_name`.  \n- If only one valid name is found \u2192 set as `first_name`, leave `last_name` empty.  \n- Preserve hyphenated surnames.  \n- Keep aliases/nicknames (e.g., `Katie`).  \n- Always Title Case names.  \n\n---\n\n**Gender & Probability Rules**  \n- Base gender **only on first_name**.  \n- `gender` \u2208 `{male, female, neutral}`.  \n- `gender_probability` \u2208 `[0\u2013100]`.  \n- If `<85` \u2192 set `gender = neutral`.  \n- **Ambiguous names** (Chris, Alex, Sam, Pat, Taylor, Jordan, Robin): reduce gender probability by **15\u201325 points** from usual. If below 85, set neutral.  \n- Do not infer gender from last_name.  \n- If no valid first_name \u2192 set:\n{\n  \"first_name\": \"\",\n  \"last_name\": \"\",\n  \"first_name_probability\": 0,\n  \"last_name_probability\": 0,\n  \"gender\": \"neutral\",\n  \"gender_probability\": 0\n}\n\n---\n\n**Few-shot Guidance (do not echo back)**  \n- `janet.smith@company.com` \u2192 `{\"first_name\":\"Janet\",\"last_name\":\"Smith\",\"first_name_probability\":100,\"last_name_probability\":100,\"gender\":\"female\",\"gender_probability\":95}`  \n- `alex.johnson@domain.org` \u2192 `{\"first_name\":\"Alex\",\"last_name\":\"Johnson\",\"first_name_probability\":100,\"last_name_probability\":100,\"gender\":\"neutral\",\"gender_probability\":82}`  \n- `michael.jr@service.com` \u2192 `{\"first_name\":\"Michael\",\"last_name\":\"\",\"first_name_probability\":100,\"last_name_probability\":0,\"gender\":\"male\",\"gender_probability\":95}`  \n- `patricia_m@techfirm.net` \u2192 `{\"first_name\":\"Patricia\",\"last_name\":\"\",\"first_name_probability\":100,\"last_name_probability\":0,\"gender\":\"female\",\"gender_probability\":95}`  \n- `chris.martin@company.co` \u2192 `{\"first_name\":\"Chris\",\"last_name\":\"Martin\",\"first_name_probability\":100,\"last_name_probability\":100,\"gender\":\"neutral\",\"gender_probability\":75}`  \n- `taylor.smith-jones@workplace.org` \u2192 `{\"first_name\":\"Taylor\",\"last_name\":\"Smith-Jones\",\"first_name_probability\":100,\"last_name_probability\":100,\"gender\":\"neutral\",\"gender_probability\":67}`  \n- `info@hermann-scherer.com` \u2192 `{\"first_name\":\"Hermann\",\"last_name\":\"Scherer\",\"first_name_probability\":100,\"last_name_probability\":100,\"gender\":\"male\",\"gender_probability\":95}`"
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "d44349b4-33c3-44b0-9ae9-d2101e0f4e41",
      "name": "Get Gender via AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1088,
        144
      ],
      "parameters": {
        "text": "=Process this first name:  \n`\"{{ $('Contact Tagged in KlickTipp').item.json.fieldFirstName }}\"`",
        "options": {
          "systemMessage": "=**Role / Context**  \nYou are a **gender estimator for first names**.  \n\n---\n\n**Task / Goal**  \nEstimate the most likely gender for a given first name.  \nReturn a JSON object with:  \n- `gender`: `\"male\"`, `\"female\"`, or `\"neutral\"`  \n- `gender_probability`: integer between 0\u2013100  \n\n---\n\n**Constraints / Rules**  \n\n\u2705 Rules for classification:  \n- Use only the **first_name** for gender estimation.  \n- `gender_probability` must be an integer (0\u2013100).  \n- If `gender_probability < 85` \u2192 set `gender = \"neutral\"`.  \n- If the input is not a valid first name \u2192  \n{\n  gender = \"neutral\"\n  gender_probability = 0\n}\n\n\n\u274c Do not:  \n- Infer gender from last names.  \n- Output anything other than the required JSON object.  \n\n\u2696\ufe0f Ambiguous / diminutive name handling:  \n- If the name is a well-known short form, diminutive, or unisex nickname (e.g., Chris, Alex, Sam, Pat, Taylor, Jordan, Robin), **reduce gender certainty by 15\u201325 points** from the usual most-likely value.  \n- If this reduction pushes probability below 85, return `\"neutral\"`.  \n- Example: `\"Chris\"` \u2192 originally ~90% male \u2192 reduce to ~75% \u2192 return `\"neutral\"`.  "
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 2.1
    },
    {
      "id": "d99918d6-f44d-45b7-9d47-3320286003ce",
      "name": "Contact Tagged in KlickTipp",
      "type": "n8n-nodes-klicktipp.klicktippTrigger",
      "position": [
        544,
        496
      ],
      "parameters": {},
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "e5c7ccaf-728a-4e4b-ad15-baf393ad1632",
      "name": "Update Contact in KlickTipp",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        352
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Lieber {{ $('Contact Tagged in KlickTipp').item.json.fieldFirstName }},<br /><br />"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "f95456bd-4d82-4617-8520-b038afc08df8",
      "name": "Update Contact in KlickTipp1",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        160
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Liebe {{ $('Contact Tagged in KlickTipp').item.json.fieldFirstName }},<br /><br />"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "b2a312fc-df88-46cc-8c22-7598c8308c9a",
      "name": "Update Contact in KlickTipp2",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        -48
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Hallo {{ $('Contact Tagged in KlickTipp').item.json.fieldFirstName }},<br /><br />"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "ee011a0d-1783-4e70-a11e-ebe6305c0065",
      "name": "Documentation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -224,
        -96
      ],
      "parameters": {
        "width": 679,
        "height": 940,
        "content": "Community Node Disclaimer: This workflow uses KlickTipp community nodes.\n\n## Introduction\nThis workflow automatically generates a personalized **email greeting** for KlickTipp contacts using **OpenAI**, and stores it as a reusable KlickTipp custom field. When a contact is tagged, the workflow creates a suitable greeting such as **\u201cLieber Ren\u00e9,\u201d**, **\u201cLiebe Laura,\u201d**, or a safe fallback like **\u201cHallo Ren\u00e9,\u201d** when the gender is uncertain. It also returns **confidence scores (0\u2013100)** so you can decide whether the detected gender and/or extracted name is reliable enough to use.\n\nThis automation is especially useful for marketers, coaches, creators, agencies, and service-based businesses who want consistent personalization at scale, while keeping messaging safe through confidence-based fallbacks and reducing the need for manual contact cleanup.\n\n## How it works\n1. **Trigger: Contact tagged in KlickTipp** (e.g., `HTML AI greeting for email messaging`)\n2. **Check contact data**\n   - If **first name exists** \u2192 OpenAI estimates gender based on the first name.\n   - If **first name is missing but email exists** \u2192 OpenAI extracts a first name from the email and estimates gender.\n3. **Filter by confidence**\n   - If confidence is high (e.g., **>= 85**) \u2192 allow gendered greeting (**Lieber/Liebe**)\n   - Otherwise \u2192 use neutral greeting (**Hallo {FirstName},**)\n4. **Update contact in KlickTipp**\n   - Save the final **HTML greeting** into a dedicated custom field (reusable in all email templates)\n   - Update the first name if it was extracted from email\n\n## Setup Instructions\n1. **KlickTipp preparation**\n   - Create a trigger **tag** (e.g., `HTML AI greeting for email messaging`)\n   - Create **custom field**:\n     - **HTML AI placeholders | greeting**\n   - Add **webhook**:\n     - **Activation tag:** `HTML AI greeting for email messaging`\n     - **Activation URL:** webhook URL from triggers\n\n2. **Credential Configuration**\n     - Authenticate your KlickTipp connection with **username/password** credentials (API access required).\n     - Connect your OpenAI account using an **API Key**.\n\n## Customization\n- **Threshold**: increase (stricter) or decrease (more coverage)\n- **Adjust greeting style**: if needed, change \u201cLieber/Liebe/Hallo\u201d to other words and phrases"
      },
      "typeVersion": 1
    },
    {
      "id": "39fd6111-411d-4e87-b715-7610ae562160",
      "name": "Update Contact in KlickTipp5",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        608
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Hallo {{ $json.output.first_name }},<br /><br />"
            },
            {
              "fieldId": "fieldFirstName",
              "fieldValue": "={{ $json.output.first_name }}"
            },
            {
              "fieldId": "fieldLastName",
              "fieldValue": "={{ $json.output.last_name_probability >= 85 ? $json.output.last_name : $('Contact Tagged in KlickTipp').item.json.fieldLastName }}"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "8d7fc29f-a881-403f-be47-f000ecd298ce",
      "name": "Update Contact in KlickTipp4",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        816
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Liebe {{ $json.output.first_name }},<br /><br />"
            },
            {
              "fieldId": "fieldFirstName",
              "fieldValue": "={{ $json.output.first_name }}"
            },
            {
              "fieldId": "fieldLastName",
              "fieldValue": "={{ $json.output.last_name_probability >= 85 ? $json.output.last_name : $('Contact Tagged in KlickTipp').item.json.fieldLastName }}"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "a243f7cd-c7d0-4f54-9e57-c17768f3d5d3",
      "name": "Update Contact in KlickTipp3",
      "type": "n8n-nodes-klicktipp.klicktipp",
      "position": [
        2400,
        1008
      ],
      "parameters": {
        "fields": {
          "dataFields": [
            {
              "fieldId": "field228721",
              "fieldValue": "=Lieber {{ $json.output.first_name }},<br /><br />"
            },
            {
              "fieldId": "fieldFirstName",
              "fieldValue": "={{ $json.output.first_name }}"
            },
            {
              "fieldId": "fieldLastName",
              "fieldValue": "={{ $json.output.last_name_probability >= 85 ? $json.output.last_name : $('Contact Tagged in KlickTipp').item.json.fieldLastName }}"
            }
          ]
        },
        "resource": "subscriber",
        "operation": "update",
        "subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}"
      },
      "credentials": {},
      "typeVersion": 2
    },
    {
      "id": "d3b1634e-218e-4b78-af4c-1c55b67dc67c",
      "name": "Gender probability >= 85% ?",
      "type": "n8n-nodes-base.switch",
      "notes": "How the probability field works:\n\u2022 It ranges from 0 to 1 (or 0-100 %).\n\u2022 It reflects how often that name appeared with the returned gender in the dataset.\n\u2022 The higher the value, the more confident the service is.\n\nProbability \u2265 0.95 - Very strong signal - safe to use (examples: Laura, Michael)\nProbability 0.85 - 0.94 - High confidence - good for personalised greeting (examples: Claudia, Thomas)\nProbability 0.70 - 0.84 - Medium - fine for light personalisation, but expect a few errors (examples: Kim (female-leaning), Alex (male-leaning))\nProbability < 0.70 - Weak/unisex - treat as \"unknown\" (examples: Pat, Sam)",
      "position": [
        1776,
        144
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "No",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fa57f4c3-deb2-4df7-9f1f-0673aa6eb1c9",
                    "operator": {
                      "type": "number",
                      "operation": "lt"
                    },
                    "leftValue": "={{ $json.output.gender_probability }}",
                    "rightValue": 85
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Yes",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "471264b3-1008-4dae-b787-ddd88d72a8f6",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.output.gender_probability }}",
                    "rightValue": 85
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "notesInFlow": true,
      "typeVersion": 3.2
    },
    {
      "id": "584f04a1-39a4-4546-a89c-5c4bea31c492",
      "name": "First name probability >= 85%",
      "type": "n8n-nodes-base.filter",
      "position": [
        1520,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a84bed0c-e1c3-46d9-a022-c2001216edc8",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.output.first_name_probability }}",
              "rightValue": 85
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6d206b87-3a1c-459b-aadd-9d583ac48bad",
      "name": "Gender probability >= 85% ?1",
      "type": "n8n-nodes-base.switch",
      "notes": "How the probability field works:\n\u2022 It ranges from 0 to 1 (or 0-100 %).\n\u2022 It reflects how often that name appeared with the returned gender in the dataset.\n\u2022 The higher the value, the more confident the service is.\n\nProbability \u2265 0.95 - Very strong signal - safe to use (examples: Laura, Michael)\nProbability 0.85 - 0.94 - High confidence - good for personalised greeting (examples: Claudia, Thomas)\nProbability 0.70 - 0.84 - Medium - fine for light personalisation, but expect a few errors (examples: Kim (female-leaning), Alex (male-leaning))\nProbability < 0.70 - Weak/unisex - treat as \"unknown\" (examples: Pat, Sam)",
      "position": [
        1776,
        800
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "No",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fa57f4c3-deb2-4df7-9f1f-0673aa6eb1c9",
                    "operator": {
                      "type": "number",
                      "operation": "lt"
                    },
                    "leftValue": "={{ $json.output.gender_probability }}",
                    "rightValue": 85
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Yes",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "471264b3-1008-4dae-b787-ddd88d72a8f6",
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    },
                    "leftValue": "={{ $json.output.gender_probability }}",
                    "rightValue": 85
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "notesInFlow": true,
      "typeVersion": 3.2
    },
    {
      "id": "0bb0edac-8625-43b1-ac06-0022c5655db8",
      "name": "Route via gender",
      "type": "n8n-nodes-base.switch",
      "position": [
        2048,
        144
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Neutral",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "51346472-68bb-437e-b9dd-76530f946f4d",
                    "operator": {
                      "type": "string",
                      "operation": "notRegex"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "male"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Female",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ed64f4e2-bfa3-4a55-b190-58f654465198",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "female"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Male",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "471264b3-1008-4dae-b787-ddd88d72a8f6",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "male"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "17c778b7-0072-489e-96d7-e9be7c95ab24",
      "name": "Route via gender1",
      "type": "n8n-nodes-base.switch",
      "position": [
        2048,
        800
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Neutral",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "51346472-68bb-437e-b9dd-76530f946f4d",
                    "operator": {
                      "type": "string",
                      "operation": "notRegex"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "male"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Female",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ed64f4e2-bfa3-4a55-b190-58f654465198",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "female"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Male",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "471264b3-1008-4dae-b787-ddd88d72a8f6",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.output.gender }}",
                    "rightValue": "male"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "5860379c-e51e-4a96-b547-011a2897420a",
      "name": "3. Filter results and update contacts with greeting",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 1144,
        "height": 636,
        "content": "## 3. Filter results and update contacts with greeting"
      },
      "typeVersion": 1
    },
    {
      "id": "7b3a96d6-a6b3-4f1f-b31c-555afe3a0f99",
      "name": "5. Filter results and update contacts with greeting and first name",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 1144,
        "height": 636,
        "content": "## 5. Filter results and update contacts with greeting and first name"
      },
      "typeVersion": 1
    },
    {
      "id": "44dd68bd-7c74-4691-99b8-0bbdc23da3da",
      "name": "First name present",
      "type": "n8n-nodes-base.filter",
      "position": [
        848,
        144
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a84bed0c-e1c3-46d9-a022-c2001216edc8",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.fieldFirstName }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "8ae4f5c8-fb00-4a29-92da-b4f18fc87187",
      "name": "First name absent, email present",
      "type": "n8n-nodes-base.filter",
      "position": [
        864,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a84bed0c-e1c3-46d9-a022-c2001216edc8",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.fieldFirstName }}",
              "rightValue": ""
            },
            {
              "id": "1bc8c842-8449-499e-a10d-9b7ef743539e",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.email }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "c081765d-6915-4bf9-a5a6-3733cbe0aaf1",
  "nodeGroups": [],
  "connections": {
    "Route via gender": {
      "main": [
        [
          {
            "node": "Update Contact in KlickTipp2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Contact in KlickTipp1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Contact in KlickTipp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Get First Name and Gender via AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Route via gender1": {
      "main": [
        [
          {
            "node": "Update Contact in KlickTipp5",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Contact in KlickTipp4",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Contact in KlickTipp3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "First name present": {
      "main": [
        [
          {
            "node": "Get Gender via AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Get Gender via AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get Gender via AI Agent": {
      "main": [
        [
          {
            "node": "Gender probability >= 85% ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Get First Name and Gender via AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Get Gender via AI Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Contact Tagged in KlickTipp": {
      "main": [
        [
          {
            "node": "First name present",
            "type": "main",
            "index": 0
          },
          {
            "node": "First name absent, email present",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gender probability >= 85% ?": {
      "main": [
        [
          {
            "node": "Update Contact in KlickTipp2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route via gender",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gender probability >= 85% ?1": {
      "main": [
        [
          {
            "node": "Update Contact in KlickTipp5",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route via gender1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "First name probability >= 85%": {
      "main": [
        [
          {
            "node": "Gender probability >= 85% ?1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "First name absent, email present": {
      "main": [
        [
          {
            "node": "Get First Name and Gender via AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get First Name and Gender via AI Agent": {
      "main": [
        [
          {
            "node": "First name probability >= 85%",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}