This workflow corresponds to n8n.io template #16722 — we link there as the canonical source.
This workflow follows the Agent → OpenAI Chat recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "WrlMDVogrh8Ddavr",
"name": "AI salutation generator for email messaging via OpenAI and KlickTipp",
"tags": [],
"nodes": [
{
"id": "8fb4d696-99f4-407b-8608-f0f9d94e4be1",
"name": "Structured Output Parser1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1152,
304
],
"parameters": {
"jsonSchemaExample": "{\n \"salutation\": \"\",\n \"salutation_quality\": 0,\n \"style\": \"formal/informal\",\n \"language\": \"de/en\",\n \"signoff_type\": \"team/personal\",\n \"reason\": \"\"\n}"
},
"typeVersion": 1.3
},
{
"id": "8cde79d0-4a59-463a-aece-d4cfcd287b47",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
976,
304
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-5-mini",
"cachedResultName": "gpt-5-mini"
},
"options": {}
},
"credentials": {},
"typeVersion": 1.2
},
{
"id": "7a51b10e-4f31-4ae9-b419-29fa7872baab",
"name": "Contact Tagged in KlickTipp",
"type": "n8n-nodes-klicktipp.klicktippTrigger",
"position": [
768,
80
],
"parameters": {},
"credentials": {},
"typeVersion": 1
},
{
"id": "338e60e0-c082-4492-886f-89bcbf793fa1",
"name": "Generate a salutation",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
992,
80
],
"parameters": {
"text": "=Process this contact information:\n- First name: {{ $json.fieldFirstName }}\n- Last name: {{$json.fieldLastName}}\n- Email: {{$json.email}}\n- Company name: {{$json.fieldCompanyName}}\n- Street 1: {{$json.fieldStreet1}}\n- Street 2: {{$json.fieldStreet2}}\n- City: {{$json.fieldCity}}\n- State: {{$json.fieldState}}\n- Zip: {{$json.fieldZip}}\n- Country: {{$json.fieldCountry}}\n- Website: {{$json.fieldWebsite}}\n- Birthday: {{$json.fieldBirthday}}",
"options": {
"systemMessage": "=**Role / Context** \nYou generate an email salutation (the formal header / opening line) for KlickTipp contacts.\n\nDefinition: a salutation is the written opening address line at the start of an email/letter (e.g., \"Dear [Name],\", \"Guten Tag Herr M\u00fcller,\").\n\n---\n\n**Task / Goal** \n\nCreate a reusable, HTML-ready email salutation based on contact information below.\n\nReturn ONLY valid JSON that matches the provided schema. No extra text.\n\n---\n\n**Constraints / Rules** \n\n- salutation_html: ONE short HTML string. No <p> tags. You may use <br /> only if needed (prefer no <br />). Always end with a comma.\n- salutation_quality: integer 0\u2013100 indicating how appropriate and safe the salutation is.\n- style: \"formal\" or \"informal\".\n- language: \"de\" or \"en\".\n- address_basis: \"full_name\" | \"first_name\" | \"last_name\" | \"email_only\" | \"generic\"\n- reason: short internal note if quality is low.\n\nDecision rules:\n1) Determine language:\n - If Country suggests Germany/Austria/Switzerland OR the data looks German -> language=\"de\"\n - Otherwise default to language=\"en\"\n\n2) Determine style (distance):\n - If Company name exists OR Website exists OR address fields clearly indicate business -> prefer style=\"formal\"\n - Otherwise style=\"informal\"\n - If First name exists and looks like a real person -> informal is allowed, but formal is still acceptable for business contexts.\n\n3) Choose the best salutation (in this priority order):\n A) If language=\"de\" AND style=\"formal\":\n - If Last name exists: \"Guten Tag {{$json.fieldLastName}},\"\n - If only First name exists: \"Guten Tag {{$json.fieldFirstName}},\"\n - If no usable name: \"Guten Tag,\"\n B) If language=\"de\" AND style=\"informal\":\n - If First name exists: \"Hallo {{$json.fieldFirstName}},\"\n - Else if Last name exists: \"Hallo {{$json.fieldLastName}},\"\n - Else: \"Hallo,\"\n C) If language=\"en\" AND style=\"formal\":\n - If Last name exists: \"Dear {{$json.fieldLastName}},\"\n - If only First name exists: \"Dear {{$json.fieldFirstName}},\"\n - Else: \"Dear Sir or Madam,\"\n D) If language=\"en\" AND style=\"informal\":\n - If First name exists: \"Hi {{$json.fieldFirstName}},\"\n - Else: \"Hi,\"\n\n4) Important constraints:\n- Do NOT guess titles (Mr/Ms/Dr) unless explicitly provided in the input (we don't have it here, so don't use them).\n- Do NOT infer gender from first/last name for formal titles.\n- Do NOT include the company name in the salutation.\n- Do NOT mention any private contact details (address, birthday, email) in the salutation.\n- Keep it short and conventional.\n\n5) salutation_quality scoring:\n- 95\u2013100: clear name + appropriate style + clear language\n- 80\u201394: good guess but minor ambiguity\n- 50\u201379: name missing or language unclear -> generic safe salutation\n- <50: contact looks like a system mailbox (info@, support@, noreply@) -> generic formal with low score"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.1
},
{
"id": "ce062f3d-3cf9-421f-8490-15e424e51670",
"name": "Update Contact in KlickTipp",
"type": "n8n-nodes-klicktipp.klicktipp",
"position": [
1600,
80
],
"parameters": {
"fields": {
"dataFields": [
{
"fieldId": "field228722",
"fieldValue": "={{ $json.output.salutation }}"
}
]
},
"resource": "subscriber",
"operation": "update",
"subscriberId": "={{ $('Contact Tagged in KlickTipp').item.json.id }}",
"identifierType": "id"
},
"credentials": {},
"typeVersion": 3
},
{
"id": "e59c503f-3794-44d8-9f13-fcfcefa6a39a",
"name": "Salutation quality >= 80% ?",
"type": "n8n-nodes-base.filter",
"position": [
1360,
80
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9f2f1911-5417-494b-b07c-1499d8ea4c19",
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.output.salutation_quality }}",
"rightValue": 80
}
]
}
},
"typeVersion": 2.3
},
{
"id": "ced2f9f6-52a6-4d7f-b652-3aa6d095f0cd",
"name": "Documentation",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-48
],
"parameters": {
"width": 695,
"height": 764,
"content": "Community Node Disclaimer: This workflow uses KlickTipp community nodes.\n\n## Introduction\nThis workflow automatically generates a personalized **email salutation** for KlickTipp contacts using **OpenAI**, and stores it as a reusable KlickTipp custom field. When a contact is tagged, the workflow creates a suitable salutation such as **\u201cGuten Tag M\u00fcller,\u201d**, **\u201cHallo Ren\u00e9,\u201d**, or a safe fallback like **\u201cGuten Tag,\u201d** when data is incomplete. It also returns a **salutation quality score (0\u2013100)** to help you decide whether the result is reliable enough to store and reuse.\n\nThis automation is especially useful for marketers, coaches, creators, agencies, and service-based businesses who want consistent personalization at scale, while keeping messaging professional 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 salutation for email messaging`)\n2. **OpenAI: Generate a salutation** using available contact data (name, email, company, location)\n3. **Filter: salutation_quality >= 80** (adjustable threshold)\n4. **Update contact in KlickTipp** by saving found **salutation**\n\n## Setup Instructions\n1. **KlickTipp preparation**\n - Create a trigger **tag** (e.g., `HTML AI salutation for email messaging`)\n - Create **custom field**:\n - **HTML AI placeholders | salutation**\n - Add **webhook**:\n - **Activation tag:** `HTML AI salutation 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 a **API Key** .\n\n## Customization\n- **Threshold**: increase (stricter) or decrease (more coverage)\n- **Tone/language**: enforce in the OpenAI prompt if you want consistent output"
},
"typeVersion": 1
},
{
"id": "3a88d88f-5f15-4ccb-ace6-e70deec5170e",
"name": "1. Trigger from a KlickTipp",
"type": "n8n-nodes-base.stickyNote",
"position": [
688,
-48
],
"parameters": {
"color": 7,
"width": 232,
"height": 524,
"content": "## 1. Trigger from a KlickTipp"
},
"typeVersion": 1
},
{
"id": "73ee5879-7c2c-4bb9-8678-f9c4f74c755a",
"name": "2. Generate salutation via OpenAI",
"type": "n8n-nodes-base.stickyNote",
"position": [
928,
-48
],
"parameters": {
"color": 7,
"width": 360,
"height": 524,
"content": "## 2. Generate salutation via OpenAI"
},
"typeVersion": 1
},
{
"id": "a282ad31-0793-4c1d-84a7-6cf8cd8194a3",
"name": "3. Filter results",
"type": "n8n-nodes-base.stickyNote",
"position": [
1296,
-48
],
"parameters": {
"color": 7,
"width": 232,
"height": 524,
"content": "## 3. Filter results"
},
"typeVersion": 1
},
{
"id": "9da0ed4e-bd9d-4e89-9db4-4f2dc00d9c6b",
"name": "4. Update contact with salutation",
"type": "n8n-nodes-base.stickyNote",
"position": [
1536,
-48
],
"parameters": {
"color": 7,
"width": 232,
"height": 524,
"content": "## 4. Update contact with salutation"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "d1b8193e-ccfb-4c4d-88cb-563946097187",
"nodeGroups": [],
"connections": {
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "Generate a salutation",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Generate a salutation": {
"main": [
[
{
"node": "Salutation quality >= 80% ?",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser1": {
"ai_outputParser": [
[
{
"node": "Generate a salutation",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Contact Tagged in KlickTipp": {
"main": [
[
{
"node": "Generate a salutation",
"type": "main",
"index": 0
}
]
]
},
"Salutation quality >= 80% ?": {
"main": [
[
{
"node": "Update Contact in KlickTipp",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow triggers when a contact is tagged in KlickTipp, uses OpenAI to generate an HTML-ready email salutation with a quality score, and updates the KlickTipp subscriber record with the salutation only when it meets a defined confidence threshold. Triggers when a contact…
Source: https://n8n.io/workflows/16722/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow triggers when a contact is tagged in KlickTipp, uses OpenAI to estimate gender from the contact’s first name or to extract a name from the email address, and then writes an HTML greeting
This workflow uses KlickTipp community nodes, available for self-hosted n8n instances only.
Enrich Property Inventory Survey With Image Recognition And Ai Agent. Uses manualTrigger, lmChatOpenAi, airtable, executeWorkflowTrigger. Event-driven trigger; 29 nodes.
Manual Http. Uses manualTrigger, lmChatOpenAi, airtable, executeWorkflowTrigger. Event-driven trigger; 29 nodes.
Inbox Manager. Uses gmailTrigger, lmChatOpenAi, outputParserStructured, agent. Event-driven trigger; 29 nodes.