This workflow corresponds to n8n.io template #15676 — we link there as the canonical source.
This workflow follows the Gmail → OpenAI 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": "cX045Xn8vWdlrwFU",
"name": "Auto-generated offering for service based business",
"tags": [],
"nodes": [
{
"id": "a69127c6-5861-4a60-8a0f-a2b65e54712b",
"name": "Set Quote Variables (EFH/MFH)",
"type": "n8n-nodes-base.set",
"position": [
2080,
688
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "df8eadc8-486e-4384-8b21-22d7dd2659e5",
"name": "name",
"type": "string",
"value": "={{ $json.kundenname }}"
},
{
"id": "01322fd4-1629-4664-9afe-dfcc3497faee",
"name": "email",
"type": "string",
"value": "={{ $json.email }}"
},
{
"id": "13120ee8-f2a2-4b8d-8889-045163d8a76c",
"name": "Telefonnummer",
"type": "string",
"value": "={{ $json.telefonnummer }}"
},
{
"id": "4467d8be-dc4c-48b4-8f0c-940ed04842d3",
"name": "qm",
"type": "string",
"value": "={{ $json.quadratmeter }}"
},
{
"id": "f3f8e3b7-de4a-484f-a9b6-2ed61c9ca004",
"name": "Service",
"type": "string",
"value": "={{ $json.reinigungsservice }}"
},
{
"id": "21701790-73d0-4afa-8ae6-33a87142de4a",
"name": "ausstellungsDatum",
"type": "string",
"value": "={{ $now.toISO() }}"
},
{
"id": "74211ec1-b936-4a7d-99a9-496e8db75dd0",
"name": "gueltigBis",
"type": "string",
"value": "={{ $now.plus(30, 'days').toISO() }}"
},
{
"id": "80e28595-dfbf-484b-a5f1-3d4a7dd34a72",
"name": "angebotNummer",
"type": "string",
"value": "ANG-001"
},
{
"id": "2f8ff24e-b634-4b5a-b59d-bf3c1ab86f18",
"name": "preisProQm",
"type": "string",
"value": "50"
},
{
"id": "dc946d61-d8ab-4d5e-8259-7ba066e988da",
"name": "Geb\u00e4udetyp",
"type": "string",
"value": "={{ $json.gebaudetyp }}"
},
{
"id": "5d1d777a-7e84-4228-a12d-e825c765170d",
"name": "adresse",
"type": "string",
"value": "={{ $json.adresse }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "56ded72e-026b-47ef-9e79-16208848f433",
"name": "Route by Request Category",
"type": "n8n-nodes-base.switch",
"position": [
1408,
1200
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cc737de4-5b94-4951-80d3-120d1dae2f41",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "=ANGEBOT_DACHREINIGUNG_MFH",
"rightValue": "={{ $json.kategorie }}"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a1bcf5cf-8ec9-4c5a-8b71-c7e03216fbec",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "EMAIL_GESCHAEFTSLEITUNG",
"rightValue": "={{ $json.kategorie }}"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "19e21d42-84d6-4c70-bfd0-57129ac6665b",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "ANGEBOT_DACHREINIGUNG_EFH",
"rightValue": "={{ $json.kategorie }}"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5b7712cb-fc6a-407d-ad89-0835e5896183",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "NOTFALL_AKUTSCHADEN",
"rightValue": "={{ $json.kategorie }}"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7c92a163-73a8-44d9-abe6-666fe8de8c6d",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "TERMIN_VOR_ORT",
"rightValue": "={{ $json.kategorie }}"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "6a5ac830-1477-4cc4-a6f6-cd31c2c4b916",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "SONSTIGES",
"rightValue": "={{ $json.kategorie }}"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "cd9c08f1-2ecc-4325-bd1e-2ddcb4d7c941",
"name": "Telegram: Notify Management",
"type": "n8n-nodes-base.telegram",
"position": [
2080,
1056
],
"parameters": {
"text": "=Neue Email an Gesch\u00e4ftsleitung von {{ $('Format Tally Data').item.json.kundenname }}: \nAnliegen: {{ $('Format Tally Data').item.json.sonderanliegen }}\nEmail: {{ $('Tally Trigger').item.json.question_E1zP1B.value }}\nTelefon: {{ $('Tally Trigger').item.json.question_rKylK2.value }}\nAdresse: {{ $('Tally Trigger').item.json.question_4kX2kA.value }}",
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "d7fc83eb-814a-46fc-9790-6361edc4dbad",
"name": "Telegram: Emergency Alert",
"type": "n8n-nodes-base.telegram",
"position": [
2080,
1248
],
"parameters": {
"text": "=Neuer Notfall/ Akutschaden von {{ $('Tally Trigger').item.json.question_1KPrDW.value }}: {{ $('Format Tally Data').item.json.schadensbeschreibung }}\nTelefon: {{ $('Tally Trigger').item.json.question_MOKAvX.value }}",
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "615191ee-862c-4381-8764-75825d7a002d",
"name": "Telegram: On-Site Appointment Request",
"type": "n8n-nodes-base.telegram",
"position": [
2080,
1440
],
"parameters": {
"text": "=Neuer Vorort-Termin von {{ $('Format Tally Data').item.json.kundenname }}:\nMaterialwahl: {{ $('Format Tally Data').item.json.materialwahl }} \nBesichtigung: {{ $('Format Tally Data').item.json.vorortBesichtigung }}\nTelefon: {{ $('Tally Trigger').item.json.question_rKylK2.value }}\nEmail: {{ $('Tally Trigger').item.json.question_E1zP1B.value }}\nAdresse: {{ $('Tally Trigger').item.json.question_4kX2kA.value }}\n",
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "47b748ee-7032-44a1-ae0c-4a3e753ac236",
"name": "Telegram: Special Request",
"type": "n8n-nodes-base.telegram",
"position": [
2080,
1632
],
"parameters": {
"text": "=Neues Sonderanliegen von {{ $('Format Tally Data').item.json.kundenname }}: {{ $('Format Tally Data').item.json.sonderanliegen }}",
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"additionalFields": {}
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "3d1c11a2-a3df-44a7-9739-9ccd84f5fd4d",
"name": "Tally Trigger: New Form Submission",
"type": "n8n-nodes-tallyforms.tallyTrigger",
"position": [
144,
1120
],
"parameters": {
"formId": "YOUR_TALLY_FORM_ID"
},
"credentials": {
"tallyApi": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "776402e3-0115-46d5-9478-44e0f05a2720",
"name": "Classify Request with GPT-4.1-mini",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
688,
1184
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini",
"cachedResultName": "GPT-4.1-MINI"
},
"options": {},
"responses": {
"values": [
{
"content": "=Du erh\u00e4ltst die Gespr\u00e4chsdaten eines Anrufs oder Formulardaten einer Tally-Anfrage bei [YOUR_BUSINESS_NAME].\n\nGeb\u00e4udetyp: {{ $json.gebaudetyp ?? \"\" }}\nReinigungsservice: {{ $json.reinigungsservice ?? \"\" }}\nKundenname: {{ $json.kundenname ?? \"\" }}\nEmail: {{ $json.email ?? \"\" }}\nTelefonnummer: {{ $json.telefonnummer ?? \"\" }}\nAdresse: {{ $json.adresse ?? \"\" }}\nQuadratmeter: {{ $json.quadratmeter ?? \"\" }}\nReparaturbeschreibung: {{ $json.reparaturbeschreibung ?? \"\" }}\nMaterialwahl: {{ $json.materialwahl ?? \"\" }}\nVor-Ort Besichtigung: {{ $json.vorortBesichtigung ?? \"\" }}\nSchadensbeschreibung: {{ $json.schadensbeschreibung ?? \"\" }}\nSonderanliegen: {{ $json.sonderanliegen ?? \"\" }}\nService: {{ $json.service ?? \"\" }}\n\nRegeln in dieser Priorit\u00e4tsreihenfolge:\n1. Ist \"Schadensbeschreibung\" ausgef\u00fcllt? \u2192 NOTFALL_AKUTSCHADEN\n2. Ist \"Sonderanliegen\" ausgef\u00fcllt? \u2192 EMAIL_GESCHAEFTSLEITUNG\n3. Ist \"Materialwahl\" oder \"Vor-Ort Besichtigung\" ausgef\u00fcllt? \u2192 TERMIN_VOR_ORT\n4. Ist \"Reinigungsservice\" ausgef\u00fcllt UND Geb\u00e4udetyp ist Einfamilienhaus? \u2192 ANGEBOT_DACHREINIGUNG_EFH\n5. Ist \"Reinigungsservice\" ausgef\u00fcllt UND Geb\u00e4udetyp ist Mehrfamilienhaus? \u2192 ANGEBOT_DACHREINIGUNG_MFH\n6. Nichts trifft zu \u2192 SONSTIGES\n\nAntworte NUR mit dem Kategorie-Schl\u00fcssel. Absolut kein weiterer Text, keine Backticks, keine Erkl\u00e4rung."
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "18793a4f-5dbc-46a6-8005-9a8688fe3875",
"name": "Map Tally Fields to Schema",
"type": "n8n-nodes-base.set",
"position": [
432,
1120
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "1",
"name": "gebaudetyp",
"type": "string",
"value": "={{ $json.question_G1vr1L.value }}"
},
{
"id": "2",
"name": "reinigungsservice",
"type": "string",
"value": "={{ $json.question_OP1APY.value }}"
},
{
"id": "3",
"name": "kundenname",
"type": "string",
"value": "={{ $json.question_PEjAEB.value }}"
},
{
"id": "4",
"name": "email",
"type": "string",
"value": "={{ $json.question_E1zP1B.value }}"
},
{
"id": "5",
"name": "telefonnummer",
"type": "string",
"value": "={{ $json.question_rKylK2.value }}"
},
{
"id": "6",
"name": "adresse",
"type": "string",
"value": "={{ $json.question_4kX2kA.value }}"
},
{
"id": "7",
"name": "quadratmeter",
"type": "string",
"value": "={{ $json.question_jMDBMJ.value }}"
},
{
"id": "8",
"name": "reparaturbeschreibung",
"type": "string",
"value": "={{ $json.question_2k84kD.value }}"
},
{
"id": "9",
"name": "materialwahl",
"type": "string",
"value": "={{ $json.question_xQxdQv.value }}"
},
{
"id": "10",
"name": "vorortBesichtigung",
"type": "string",
"value": "={{ $json.question_R4Kz4j.value }}"
},
{
"id": "11",
"name": "sonderanliegen",
"type": "string",
"value": "={{ $json.question_G1vr1k.value }}"
},
{
"id": "12",
"name": "schadensbeschreibung",
"type": "string",
"value": "={{ $json.question_PEjAEe.value }}"
},
{
"id": "670cd7ef-195b-4ea8-8f5f-1a2c9fbe3fd9",
"name": "service",
"type": "string",
"value": "={{ $json.question_oB6ABO.value }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "6aa361bb-9ba8-4284-b9f5-d479db0e0f16",
"name": "Route by Building Type (EFH vs MFH)",
"type": "n8n-nodes-base.switch",
"position": [
2304,
688
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "49fc066b-bad8-456b-9f4c-1d20713c3945",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Geb\u00e4udetyp }}",
"rightValue": "Einfamilienhaus"
}
]
}
},
{
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b172f3c0-7823-4572-9a25-1cf22b314264",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Geb\u00e4udetyp }}",
"rightValue": "Mehrfamilienhaus"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.4
},
{
"id": "2d972a96-34b7-410f-8bb7-d098e144b4eb",
"name": "Telegram: Approval Request EFH",
"type": "n8n-nodes-base.telegram",
"position": [
2800,
608
],
"parameters": {
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"message": "=\ud83d\udd14 Neue Angebotsanfrage\n\n\ud83d\udc64 Kunde:{{ $('Edit Fields').item.json.name }}\n\ud83d\udce7 Email: {{ $('Edit Fields').item.json.email }}\n\ud83d\udcde Telefon: {{ $('Edit Fields').item.json.Telefonnummer }}\n\ud83c\udfe2 Geb\u00e4udetyp: {{ $('Edit Fields').item.json['Geb\u00e4udetyp'] }}\n\ud83d\udcd0 Quadratmeter: {{ $('Edit Fields').item.json.qm }}m\u00b2\n\ud83d\udcb0 Preis pro m\u00b2: 50\u20ac\n\nAngebot versenden?",
"options": {},
"operation": "sendAndWait"
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "10a4fd73-8c3c-4801-8248-f98b5ac442c4",
"name": "Generate Quote PDF: Single-Family Home",
"type": "n8n-nodes-pdfmonkey.pdfMonkey",
"position": [
2576,
592
],
"parameters": {
"payload": "={{ { \"name\": $('Edit Fields').item.json.name, \"email\": $('Edit Fields').item.json.email, \"Telefonnummer\": $('Edit Fields').item.json.Telefonnummer, \"qm\": $('Edit Fields').item.json.qm, \"Service\": $('Edit Fields').item.json.Service, \"leistungsart\": $('Edit Fields').item.json.Service, \"ausstellungsDatum\": $now.toISO(), \"gueltigBis\": $now.plus(30, \"days\").toISO(), \"angebotNummer\": \"ANG-\" + $('Edit Fields').item.json.name.substring(0, 3).toUpperCase() + \"-001\", \"preisProQm\": 50 } }}",
"documentTemplateId": "=YOUR_PDFMONKEY_TEMPLATE_ID_EFH"
},
"credentials": {
"pdfMonkeyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "71866b6f-bf50-4a4d-ae30-4aab36e1832c",
"name": "Gmail: Send Approved Quote EFH",
"type": "n8n-nodes-base.gmail",
"position": [
3248,
592
],
"parameters": {
"sendTo": "={{ $('Edit Fields').item.json.email }}",
"message": "=<p>Hallo {{ $('Edit Fields').item.json.name }},</p>\n\n<p>vielen Dank f\u00fcr Ihr Interesse! Anbei finden Sie Ihr pers\u00f6nliches Angebot.</p>\n\n<p>Wir haben es sorgf\u00e4ltig auf Ihre Anforderungen abgestimmt und freuen uns auf Ihre R\u00fcckmeldung.</p>\n\n<p>Hier k\u00f6nnen Sie Ihr <a href=\"{{ $('PDFMonkey').item.json.document_card.download_url }}\">Angebot</a> finden.</p>\n\n<p>Bei Fragen stehen wir Ihnen jederzeit gerne zur Verf\u00fcgung.</p>\n\n<p>Mit freundlichen Gr\u00fc\u00dfen,<br>\nElias</p>",
"options": {},
"subject": "Angebot"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "99f14f2c-f580-4e30-9b5d-134ba69ec7a0",
"name": "If Approval Approved EFH",
"type": "n8n-nodes-base.if",
"position": [
3008,
608
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "be62f349-76c6-4ad6-b3a5-d39cf6849da2",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $('Send Approval Request').item.json.data.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "557941d6-7c78-48f5-9904-7e6c03c9d071",
"name": "Generate Quote PDF: Multi-Family Home",
"type": "n8n-nodes-pdfmonkey.pdfMonkey",
"position": [
2560,
768
],
"parameters": {
"payload": "={}",
"documentTemplateId": "YOUR_PDFMONKEY_TEMPLATE_ID_MFH"
},
"credentials": {
"pdfMonkeyApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "5d8b6c9d-1ade-4c15-a801-f7fa57b194aa",
"name": "Telegram: Approval Request MFH",
"type": "n8n-nodes-base.telegram",
"position": [
2800,
784
],
"parameters": {
"chatId": "YOUR_TELEGRAM_CHAT_ID",
"message": "=\ud83d\udd14 Neue Angebotsanfrage\n\n\ud83d\udc64 Kunde: {{ $('Edit Fields').item.json.name }}\n\ud83d\udce7 Email: {{ $('Edit Fields').item.json.email }}\n\ud83d\udcde Telefon: {{ $('Edit Fields').item.json.Telefonnummer }}\n\ud83c\udfe2 Geb\u00e4udetyp: {{ $('Edit Fields').item.json['Geb\u00e4udetyp'] }}\n\ud83e\uddf9 Service: {{ $('Edit Fields').item.json.Service }}\nAngebot versenden?",
"options": {},
"operation": "sendAndWait"
},
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "78fc8023-a5c3-43f9-b2e9-8c705ad06b3a",
"name": "Gmail: Send Approved Quote MFH",
"type": "n8n-nodes-base.gmail",
"position": [
3248,
768
],
"parameters": {
"sendTo": "={{ $('Edit Fields').item.json.email }}",
"message": "=<p>Hallo {{ $('Edit Fields').item.json.name }},</p>\n\n<p>vielen Dank f\u00fcr Ihr Interesse! Anbei finden Sie Ihr pers\u00f6nliches Angebot.</p>\n\n<p>Wir haben es sorgf\u00e4ltig auf Ihre Anforderungen abgestimmt und freuen uns auf Ihre R\u00fcckmeldung.</p>\n\n<p>Hier k\u00f6nnen Sie Ihr <a href=\"{{ $('PDFMonkey2').item.json.document_card.download_url }}\">Angebot</a> finden.</p>\n\n<p>Bei Fragen stehen wir Ihnen jederzeit gerne zur Verf\u00fcgung.</p>\n\n<p>Mit freundlichen Gr\u00fc\u00dfen,<br>\nElias</p>",
"options": {},
"subject": "Angebot"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "9dea242f-5133-448a-9715-7296e31e64f0",
"name": "If Approval Approved MFH",
"type": "n8n-nodes-base.if",
"position": [
3008,
784
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "be62f349-76c6-4ad6-b3a5-d39cf6849da2",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $('Send Approval Request1').item.json.data.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "20547759-6d13-4731-b191-6304bf1850df",
"name": "Gmail: Forward to Management",
"type": "n8n-nodes-base.gmail",
"position": [
2288,
1056
],
"parameters": {
"sendTo": " user@example.com",
"message": "=Neue Sonderfrage an Gesch\u00e4ftsleitung von {{ $('Format Tally Data').item.json.kundenname }}: Anliegen: {{ $('Format Tally Data').item.json.sonderanliegen }} Email: {{ $('Tally Trigger').item.json.question_E1zP1B.value }} Telefon: {{ $('Tally Trigger').item.json.question_rKylK2.value }} Adresse: {{ $('Tally Trigger').item.json.question_4kX2kA.value }}",
"options": {},
"subject": "=Sonderanfrage \u2013 R\u00fcckruf erforderlich \u2013 {{ $('Format Tally Data').item.json.kundenname }} "
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "251a0328-7427-4ef9-923c-3797479470d5",
"name": "Gmail: On-Site Appointment Notification",
"type": "n8n-nodes-base.gmail",
"position": [
2288,
1440
],
"parameters": {
"sendTo": " user@example.com",
"message": "=Neuer Vorort-Termin von {{ $('Format Tally Data').item.json.kundenname }}: Materialwahl: {{ $('Format Tally Data').item.json.materialwahl }} Besichtigung: {{ $('Format Tally Data').item.json.vorortBesichtigung }} Telefon: {{ $('Tally Trigger').item.json.question_rKylK2.value }} Email: {{ $('Tally Trigger').item.json.question_E1zP1B.value }} Adresse: {{ $('Tally Trigger').item.json.question_4kX2kA.value }}",
"options": {},
"subject": "=Neuer Vorort-Termin von {{ $('Format Tally Data').item.json.kundenname }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "c15e1429-d89f-4fcc-a2f6-9b95ccea231f",
"name": "Gmail: Emergency Notification",
"type": "n8n-nodes-base.gmail",
"position": [
2288,
1248
],
"parameters": {
"sendTo": "=your-business-email@example.com",
"message": "=Neuer Notfall/ Akutschaden von {{ $('Tally Trigger').item.json.question_1KPrDW.value }}: {{ $('Format Tally Data').item.json.schadensbeschreibung }} Telefon: {{ $('Tally Trigger').item.json.question_MOKAvX.value }}",
"options": {},
"subject": "=Neuer Notfall/ Akutschaden von {{ $('Tally Trigger').item.json.question_1KPrDW.value }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "ad04f750-ebb7-4694-950f-66c6e9e0beb1",
"name": "Gmail: Special Request Notification",
"type": "n8n-nodes-base.gmail",
"position": [
2288,
1632
],
"parameters": {
"sendTo": "user@example.com",
"message": "=Neues Sonderanliegen von {{ $('Format Tally Data').item.json.kundenname }}: {{ $('Format Tally Data').item.json.sonderanliegen }}",
"options": {},
"subject": "=Neues Sonderanliegen von {{ $('Format Tally Data').item.json.kundenname }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "22d0ee24-9f4c-48a1-ba26-ed802826fe6a",
"name": "Webhook: Alternative Intake",
"type": "n8n-nodes-base.webhook",
"position": [
112,
1504
],
"parameters": {
"path": "your-webhook-path-uuid",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "91579be6-ae64-47f8-8532-6f4ca3acdd50",
"name": "Map Webhook Fields",
"type": "n8n-nodes-base.set",
"position": [
480,
1344
],
"parameters": {
"mode": "raw",
"options": {},
"jsonOutput": "={\n \"kundenname\": \"={{ $json.body.call.call_analysis.custom_analysis_data.vorname }} {{ $json.body.call.call_analysis.custom_analysis_data.nachname }}\",\n \"email\": \"={{ $json.body.call.call_analysis.custom_analysis_data.email }}\",\n \"telefonnummer\": \"={{ $json.body.call.call_analysis.custom_analysis_data.telefon }}\",\n \"adresse\": \"={{ $json.body.call.call_analysis.custom_analysis_data.adresse }}\",\n \"gebaudetyp\": \"={{ $json.body.call.call_analysis.custom_analysis_data.gebaeudetyp }}\",\n \"reinigungsservice\": \"={{ $json.body.call.call_analysis.custom_analysis_data.reinigungsservice }}\",\n \"service\": \"\",\n \"quadratmeter\": \"={{ $json.body.call.call_analysis.custom_analysis_data.quadratmeter }}\",\n \"reparaturbeschreibung\": \"\",\n \"materialwahl\": \"\",\n \"vorortBesichtigung\": \"\",\n \"schadensbeschreibung\": \"\"\n}"
},
"typeVersion": 3.4
},
{
"id": "40008728-8da3-4a8b-9fa1-3755afc32f5a",
"name": "Check Webhook Payload Valid",
"type": "n8n-nodes-base.if",
"position": [
336,
1504
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "85c20fc4-9e8b-4c4b-82c2-55cbb7cbbcca",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body.event }}",
"rightValue": "call_analyzed"
}
]
},
"looseTypeValidation": "={{ false }}"
},
"typeVersion": 2.3
},
{
"id": "9a6500ca-17f5-4ef3-aa11-ae9c0fe6a19a",
"name": "Parse Category from AI Response",
"type": "n8n-nodes-base.code",
"position": [
992,
1184
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const openAiOutput = ($input.item.json.output?.[0]?.content?.[0]?.text ?? $input.item.json.text ?? \"\").trim();\n\n// Hole Kundendaten aus dem richtigen vorherigen Node\nlet customerData = {};\n\ntry {\n customerData = $('Format Tally Data').item.json;\n} catch(e) {\n try {\n customerData = $('Edit Fields1').item.json;\n } catch(e2) {\n customerData = {};\n }\n}\n\nreturn {\n kategorie: openAiOutput,\n kundenname: (customerData.kundenname ?? \"\").replace(/^=/, \"\"),\n email: (customerData.email ?? \"\").replace(/^=/, \"\"),\n telefonnummer: (customerData.telefonnummer ?? \"\").replace(/^=/, \"\"),\n adresse: (customerData.adresse ?? \"\").replace(/^=/, \"\"),\n gebaudetyp: (customerData.gebaudetyp ?? \"\").replace(/^=/, \"\"),\n reinigungsservice: (customerData.reinigungsservice ?? \"\").replace(/^=/, \"\"),\n quadratmeter: (customerData.quadratmeter ?? \"\").replace(/^=/, \"\"),\n service: (customerData.service ?? \"\").replace(/^=/, \"\")\n};"
},
"typeVersion": 2
},
{
"id": "fd27f69e-9e02-4e8d-8532-a1e04566a915",
"name": "Sticky Note - Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-896,
448
],
"parameters": {
"width": 900,
"height": 892,
"content": "# \ud83c\udfe0 Automated Quote Generation via PDF for Service Businesses with AI Classification Engine, Telegram Approval Bot and Automated Gmail Delivery\n\n## Who's it for\nService businesses such as trade contractors (roofers, plumbers, electricians, cleaners, facility management) who want to send out customer quotes automatically as PDFs \u2014 either triggered by a **Tally form** embedded on their website or by a **Voice AI agent** webhook request. The business owner wants to delegate the operational work without giving up control, so every quote passes through an **approval instance via Telegram** before reaching the customer.\n\n## What it does\n1. **Intake** \u2014 Tally form OR direct webhook (e.g. AI Voice Agent summary)\n2. **AI classification** \u2014 GPT-4.1-mini categorizes the request into 6 buckets:\n - `ANGEBOT_DACHREINIGUNG_EFH` \u2192 auto-generate PDF quote (single-family) + Telegram approval \u2192 email customer\n - `ANGEBOT_DACHREINIGUNG_MFH` \u2192 auto-generate PDF quote (multi-family) + Telegram approval \u2192 email customer\n - `EMAIL_GESCHAEFTSLEITUNG` \u2192 notify management\n - `NOTFALL_AKUTSCHADEN` \u2192 emergency alert\n - `TERMIN_VOR_ORT` \u2192 on-site appointment request\n - `SONSTIGES` \u2192 special request fallback\n3. **Approval-gated quoting** \u2014 quotes are previewed via Telegram `sendAndWait` before any email goes to the customer\n4. **Direct notifications** \u2014 non-quote categories trigger Telegram + Gmail alerts to the team\n\n## How to set up\nEstimated **30-45 min**. See setup sticky on the bottom \u2192\n\n## Requirements\n- OpenAI (GPT-4.1-mini or any chat model)\n- Tally account with form\n- Telegram Bot (chat ID + token)\n- Gmail OAuth2\n- PDFMonkey account with 2 templates (EFH + MFH)\n\n## Customization\n- Change AI categories in the **Classify Request** node prompt\n- Swap GPT for any chat model\n- Replace Telegram with Slack `sendAndWait`\n- Skip approval gate for low-risk categories\n"
},
"typeVersion": 1
},
{
"id": "eed86955-7cfd-4abb-99ac-34c4eda27224",
"name": "Sticky Note - Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
-880,
1360
],
"parameters": {
"width": 620,
"height": 652,
"content": "## \u2699\ufe0f Setup Steps\n\n**1. Credentials** \u2014 connect:\n- OpenAI (any chat model node compatible)\n- Tally API\n- Telegram Bot (get token from @BotFather)\n- Gmail OAuth2\n- PDFMonkey API\n\n**2. Tally Form**\n- Replace `YOUR_TALLY_FORM_ID` in the Tally Trigger node\n- Map your form fields to: `gebaudetyp`, `reinigungsservice`, `kundenname`, `email`, `telefonnummer`, `adresse`, `quadratmeter`, `reparaturbeschreibung`, `materialwahl`, `vorortBesichtigung`, `schadensbeschreibung`, `sonderanliegen`, `service`\n\n**3. Telegram**\n- Replace ALL `YOUR_TELEGRAM_CHAT_ID` placeholders (6 telegram nodes)\n- Different chat IDs per category? Set per-node\n\n**4. Gmail**\n- Replace ALL `your-business-email@example.com` placeholders (4 Gmail nodes)\n\n**5. PDFMonkey**\n- Create 2 templates: one for single-family, one for multi-family quotes\n- Replace `YOUR_PDFMONKEY_TEMPLATE_ID_EFH` and `_MFH`\n\n**6. AI Prompt**\n- Open **Classify Request** node, adapt categories and field names to your business\n\n**7. Test**\n- Submit a test entry per category through Tally\n- Verify each branch fires correctly"
},
"typeVersion": 1
},
{
"id": "8f6962e1-50f4-40d5-bf88-056ee14ab99e",
"name": "Sticky Note - Intake",
"type": "n8n-nodes-base.stickyNote",
"position": [
32,
976
],
"parameters": {
"color": 7,
"width": 568,
"height": 664,
"content": "## Intake\nTally form OR direct webhook \u2192 field mapping"
},
"typeVersion": 1
},
{
"id": "73e1cab5-8a38-4c53-9f83-bbe836eb00be",
"name": "Sticky Note - AI Classification",
"type": "n8n-nodes-base.stickyNote",
"position": [
608,
1040
],
"parameters": {
"color": 7,
"width": 664,
"height": 344,
"content": "## AI Classification\nGPT-4.1-mini assigns one of 6 categories, then JS parses it"
},
"typeVersion": 1
},
{
"id": "c7ff7dbc-bfdd-4113-a1cb-164454a4a637",
"name": "Sticky Note - Routing",
"type": "n8n-nodes-base.stickyNote",
"position": [
1296,
1104
],
"parameters": {
"color": 7,
"width": 360,
"height": 440,
"content": "## Routing\nSwitch directs to the right branch"
},
"typeVersion": 1
},
{
"id": "70877649-f6d8-4c94-a6b3-62e8a25563a5",
"name": "Sticky Note - Quote Generation (EFH & MFH)",
"type": "n8n-nodes-base.stickyNote",
"position": [
2016,
480
],
"parameters": {
"color": 7,
"width": 1528,
"height": 472,
"content": "## Quote Generation + Approval\nPDFMonkey \u2192 Telegram sendAndWait \u2192 If approved \u2192 Gmail to customer"
},
"typeVersion": 1
},
{
"id": "dd4a1700-f726-4642-b320-c1994edb84cf",
"name": "Sticky Note - Direct Notifications",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
976
],
"parameters": {
"color": 7,
"width": 568,
"height": 856,
"content": "## Direct Notifications\nManagement / Emergency / On-Site / Special"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "13014c38-b92c-459b-9f79-37002e6ade04",
"connections": {
"Map Webhook Fields": {
"main": [
[
{
"node": "Classify Request with GPT-4.1-mini",
"type": "main",
"index": 0
}
]
]
},
"If Approval Approved EFH": {
"main": [
[
{
"node": "Gmail: Send Approved Quote EFH",
"type": "main",
"index": 0
}
]
]
},
"If Approval Approved MFH": {
"main": [
[
{
"node": "Gmail: Send Approved Quote MFH",
"type": "main",
"index": 0
}
]
]
},
"Route by Request Category": {
"main": [
[
{
"node": "Set Quote Variables (EFH/MFH)",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram: Notify Management",
"type": "main",
"index": 0
}
],
[
{
"node": "Set Quote Variables (EFH/MFH)",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram: Emergency Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram: On-Site Appointment Request",
"type": "main",
"index": 0
}
],
[
{
"node": "Telegram: Special Request",
"type": "main",
"index": 0
}
]
]
},
"Telegram: Emergency Alert": {
"main": [
[
{
"node": "Gmail: Emergency Notification",
"type": "main",
"index": 0
}
]
]
},
"Telegram: Special Request": {
"main": [
[
{
"node": "Gmail: Special Request Notification",
"type": "main",
"index": 0
}
]
]
},
"Map Tally Fields to Schema": {
"main": [
[
{
"node": "Classify Request with GPT-4.1-mini",
"type": "main",
"index": 0
}
]
]
},
"Check Webhook Payload Valid": {
"main": [
[
{
"node": "Map Webhook Fields",
"type": "main",
"index": 0
}
]
]
},
"Telegram: Notify Management": {
"main": [
[
{
"node": "Gmail: Forward to Management",
"type": "main",
"index": 0
}
]
]
},
"Webhook: Alternative Intake": {
"main": [
[
{
"node": "Check Webhook Payload Valid",
"type": "main",
"index": 0
}
]
]
},
"Set Quote Variables (EFH/MFH)": {
"main": [
[
{
"node": "Route by Building Type (EFH vs MFH)",
"type": "main",
"index": 0
}
]
]
},
"Telegram: Approval Request EFH": {
"main": [
[
{
"node": "If Approval Approved EFH",
"type": "main",
"index": 0
}
]
]
},
"Telegram: Approval Request MFH": {
"main": [
[
{
"node": "If Approval Approved MFH",
"type": "main",
"index": 0
}
]
]
},
"Parse Category from AI Response": {
"main": [
[
{
"node": "Route by Request Category",
"type": "main",
"index": 0
}
]
]
},
"Classify Request with GPT-4.1-mini": {
"main": [
[
{
"node": "Parse Category from AI Response",
"type": "main",
"index": 0
}
]
]
},
"Tally Trigger: New Form Submission": {
"main": [
[
{
"node": "Map Tally Fields to Schema",
"type": "main",
"index": 0
}
]
]
},
"Route by Building Type (EFH vs MFH)": {
"main": [
[
{
"node": "Generate Quote PDF: Multi-Family Home",
"type": "main",
"index": 0
}
],
[
{
"node": "Generate Quote PDF: Single-Family Home",
"type": "main",
"index": 0
}
]
]
},
"Generate Quote PDF: Multi-Family Home": {
"main": [
[
{
"node": "Telegram: Approval Request MFH",
"type": "main",
"index": 0
}
]
]
},
"Telegram: On-Site Appointment Request": {
"main": [
[
{
"node": "Gmail: On-Site Appointment Notification",
"type": "main",
"index": 0
}
]
]
},
"Generate Quote PDF: Single-Family Home": {
"main": [
[
{
"node": "Telegram: Approval Request EFH",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2openAiApipdfMonkeyApitallyApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Service businesses such as trade contractors (roofers, plumbers, electricians, cleaners, facility management) who want to send out customer quotes automatically as PDFs — either triggered by a Tally form embedded on their website or by a Voice AI agent webhook request. The…
Source: https://n8n.io/workflows/15676/ — 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.
Auto-generated offering for service based business. Uses telegram, n8n-nodes-tallyforms, openAi, n8n-nodes-pdfmonkey. Event-driven trigger; 33 nodes.
Send a target niche and location via Telegram message Workflow discovers businesses via Google Maps API AI enriches contacts with email and LinkedIn data via Serper GPT-4o scores and qualifies each le
Tags: Logistics, Supply Chain, Warehouse Operations, Paperless processes, Quality Management
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.
💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.