This workflow corresponds to n8n.io template #12946 β we link there as the canonical source.
This workflow follows the Agent β Error Trigger 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": "w6VsYT1zZmiBub8C",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automate Guest Enquiry Classification & Replies with Base44 and GPT-4o",
"tags": [],
"nodes": [
{
"id": "f3a5e0ab-84fe-4751-810f-302bb31b2fb3",
"name": "Overview Sticky",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2304,
656
],
"parameters": {
"width": 656,
"height": 448,
"content": "## \ud83c\udfe8 Automate Guest Enquiry Classification & Replies with Base44 and GPT-4o\n### How it works\nThis workflow automates guest enquiry handling for hospitality businesses. When a guest submits an enquiry via webhook, an AI agent analyzes the message to detect intent (booking, pricing, availability, or policy), generates a personalized acknowledgment, and routes the enquiry to the appropriate team with SLA tracking. If the guest prefers email contact, an automated reply is sent. All enquiries are logged to Slack with full context for team follow-up.\n\n### Setup steps\n1. Configure the webhook URL in your booking form\n2. Connect Gmail OAuth2 credentials for email replies\n3. Add Slack workspace credentials for internal notifications\n4. Connect OpenAI API key for AI classification\n5. Update agent email addresses in assignment nodes\n6. Test with a sample enquiry to verify routing"
},
"typeVersion": 1
},
{
"id": "b5f5bb78-714d-4573-830f-237977501e34",
"name": "Section: Trigger & AI",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
1312
],
"parameters": {
"color": 7,
"width": 672,
"height": 784,
"content": "## \ud83d\udce5 Webhook Trigger & AI Classification\n\nReceives guest enquiry data via POST webhook and routes it to the AI agent for intent detection and reply generation."
},
"typeVersion": 1
},
{
"id": "0d793a02-3d82-4e96-af78-da33a3150657",
"name": "Section: Routing Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
-784,
1392
],
"parameters": {
"color": 7,
"width": 512,
"height": 464,
"content": "## \ud83e\udde0 Intent Detection & Assignment\n\nExtracts the detected category and routes enquiries to specialized teams based on intent: booking, pricing, availability, or policy questions."
},
"typeVersion": 1
},
{
"id": "a2cc319a-d0b4-4f34-80dc-a593cfd74a64",
"name": "Section: Assignment",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
1136
],
"parameters": {
"color": 7,
"width": 352,
"height": 928,
"content": "## \ud83d\udccb Team Assignment & SLA Configuration\n\nAssigns enquiries to specific agents with appropriate SLA timeframes based on urgency and category type."
},
"typeVersion": 1
},
{
"id": "01fff883-82bb-4c88-a00a-395b8017861b",
"name": "Section: Notifications",
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
1200
],
"parameters": {
"color": 7,
"width": 944,
"height": 832,
"content": "## \ud83d\udcec Guest Communication & Internal Alerts\n\nSends personalized email replies to guests who prefer email contact, and posts detailed enquiry summaries to Slack for team visibility and follow-up tracking."
},
"typeVersion": 1
},
{
"id": "0214ad46-12b2-4d6f-a9a4-449f566d4391",
"name": "Credentials & Security",
"type": "n8n-nodes-base.stickyNote",
"position": [
1424,
1760
],
"parameters": {
"color": 3,
"width": 352,
"height": 240,
"content": "## \ud83d\udd10 Required Credentials\n\n- **Gmail OAuth2**: For automated email replies\n- **Slack API**: For internal team notifications\n- **OpenAI API**: For AI intent classification\n\nReplace all email addresses and channel IDs with your own before deploying."
},
"typeVersion": 1
},
{
"id": "b531d9c3-e473-42ee-883b-f579ed75f646",
"name": "Extract Detected Category",
"type": "n8n-nodes-base.set",
"position": [
-736,
1584
],
"parameters": {
"values": {
"string": [
{
"name": "category",
"value": "={{ $json.output[0].intent_detected }}"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "cb927eca-6845-4fe8-b397-d09aade3fada",
"name": "Route by Intent Category",
"type": "n8n-nodes-base.switch",
"position": [
-528,
1552
],
"parameters": {
"rules": {
"rules": [
{
"value2": "booking"
},
{
"output": 1,
"value2": "pricing"
},
{
"output": 2,
"value2": "availability"
},
{
"output": 3,
"value2": "policy"
}
]
},
"value1": "={{ $json.category }}",
"dataType": "string",
"fallbackOutput": 3
},
"typeVersion": 1
},
{
"id": "5ba0d741-78d4-400f-b9a2-012180c04396",
"name": "Assign to Booking Team",
"type": "n8n-nodes-base.set",
"position": [
-80,
1312
],
"parameters": {
"values": {
"number": [
{
"name": "sla_minutes",
"value": 15
}
],
"string": [
{
"name": "assigned_agent",
"value": "user@example.com"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "6fd1f956-618b-4c9d-b41e-6aec997df67f",
"name": "Assign to Pricing Team",
"type": "n8n-nodes-base.set",
"position": [
-80,
1536
],
"parameters": {
"values": {
"number": [
{
"name": "sla_minutes",
"value": 15
}
],
"string": [
{
"name": "assigned_agent",
"value": "user@example.com"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "5112c56d-7d67-4d6d-bdb2-d734b86eb18d",
"name": "Assign to Availability Team",
"type": "n8n-nodes-base.set",
"position": [
-80,
1712
],
"parameters": {
"values": {
"number": [
{
"name": "sla_minutes",
"value": 30
}
],
"string": [
{
"name": "assigned_agent",
"value": "user@example.com"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "28c17d78-3872-441e-86e1-2ff7ffbcbfe8",
"name": "Assign to Policy Team",
"type": "n8n-nodes-base.set",
"position": [
-80,
1920
],
"parameters": {
"values": {
"number": [
{
"name": "sla_minutes",
"value": 60
}
],
"string": [
{
"name": "assigned_agent",
"value": "support@example.com"
}
]
},
"options": {}
},
"typeVersion": 1
},
{
"id": "b823b845-06cd-4ee2-a2c3-3dcd1ec846e5",
"name": "Send Email Reply to Guest",
"type": "n8n-nodes-base.gmail",
"position": [
656,
1312
],
"parameters": {
"sendTo": "={{ $('Webhook Trigger1').item.json.body.guest_email }}",
"message": "=\n{{ $json.output[0].reply_message }}\n\nBest regards,\nGuest Services Team\n\n",
"options": {},
"subject": "Re: Your Enquiry",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "93fab7ad-57b4-432f-a28f-55db17797cd3",
"name": "AI Agent: Classify Intent & Generate Reply",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1136,
1584
],
"parameters": {
"text": "=Guest enquiry details:\n\nGuest Name: {{ $json.body.guest_name }}\nGuest Email: {{ $json.body.guest_email }}\nPreferred Contact: {{ $json.body.preferred_contact }}\n\nEnquiry Type (user selected): {{ $json.body.enquiry_type }}\n\nMessage from Guest:\n\" {{ $json.body.guest_message }}\"\n\nCheck-in Date: {{ $json.body.check_in }}\nCheck-out Date: {{ $json.body.check_out }}\n\nTASK:\n1. Understand the guest's intent\n2. Generate a polite acknowledgement message\n3. Decide which internal team should handle this enquiry\n\nGenerate the response now.\n",
"options": {
"systemMessage": "=You are an AI Sales CRM decision engine for a hospitality business.\n\nYour job is to read a guest enquiry and generate a professional, friendly, and concise response on behalf of the business.\n\nRULES:\n- Be polite, warm, and human (not robotic)\n- Acknowledge the guest's request clearly\n- Do NOT invent prices or availability\n- Do NOT confirm bookings\n- If dates are provided, acknowledge them\n- Keep the response short (4\u20136 lines max)\n- End with a clear next-step sentence\n- Write as a hotel / property representative\n\nOUTPUT FORMAT:\nReturn ONLY valid JSON in this structure:\n\n{\n \"reply_message\": \"<final message to send to guest>\",\n \"intent_detected\": \"<booking | pricing | availability | policy>\",\n \"assigned_team\": \"<sales | frontdesk | support>\"\n}\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.1
},
{
"id": "becdc5c0-f877-498d-8eac-ac30769cf9b7",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-1232,
1808
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "f40057e5-a57b-4ed4-af20-630c1cb43d8c",
"name": "Check Guest Contact Preference",
"type": "n8n-nodes-base.if",
"position": [
320,
1584
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "8f35f570-e3f2-4aee-b956-402727befd27",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $('Webhook Trigger1').item.json.body.preferred_contact }}",
"rightValue": "Email"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "12845d04-d9dd-42f7-a07a-ef797945b1e8",
"name": "Post Enquiry Summary to Slack",
"type": "n8n-nodes-base.slack",
"position": [
960,
1568
],
"parameters": {
"text": "=\ud83d\udea8 *New Guest Enquiry Received*\n\n\ud83d\udc64 *Guest:* {{ $('Webhook Trigger1').item.json.body.guest_name }}\n\ud83d\udce7 *Email:* {{ $('Webhook Trigger1').item.json.body.guest_email }}\n\ud83d\udcde *Preferred Contact:* {{ $('Webhook Trigger1').item.json.body.guest_phone }}\n\n\ud83e\udde0 *Detected Intent:* *{{ $json.intent_detected || $json.category }}*\n\ud83d\udc65 *Assigned Team:* {{ $json.output[0].assigned_team }}\n\ud83c\udfaf *Assigned Agent:* {{ $json.assigned_agent || \"Unassigned\" }}\n\n\ud83d\udcc5 *Check-in:* \n\ud83d\udcc5 *Check-out:* \n\n\ud83d\udcac *Guest Message:*\n> {{ $('Webhook Trigger1').item.json.body.guest_message }}\n\n\u23f1\ufe0f *SLA:* {{ $json.sla_minutes }} minutes\n\n\u26a0\ufe0f Please follow up before SLA expires.\n",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09GNB90TED",
"cachedResultName": "general-information"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "e51485ee-b29e-47b4-a4cf-131069440fdc",
"name": "Log AI Reply to Slack",
"type": "n8n-nodes-base.slack",
"position": [
704,
1856
],
"parameters": {
"text": "={{ $json.output[0].reply_message }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09D7N4LGUV",
"cachedResultName": "all-vivek-workspace"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "c0946753-44ef-44bd-a79b-09e69c193dae",
"name": "Webhook Trigger1",
"type": "n8n-nodes-base.webhook",
"position": [
-1440,
1584
],
"parameters": {
"path": "guest-enquiry",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 1
},
{
"id": "26d1a483-43b4-4907-90fe-4e7b2a8bd23a",
"name": "Structured Output Parser1",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-960,
1824
],
"parameters": {
"jsonSchemaExample": "[{\n \"reply_message\": \"<final message to send to guest>\",\n \"intent_detected\": \"<booking | pricing | availability | policy>\",\n \"assigned_team\": \"<sales | frontdesk | support>\"\n}]"
},
"typeVersion": 1.3
},
{
"id": "efc4b764-0993-44ac-aed2-9796e055fdb4",
"name": "Error Handler Trigger",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-1504,
2480
],
"parameters": {},
"typeVersion": 1
},
{
"id": "722f321d-f5ec-44f4-b36d-62b912501338",
"name": "Slack: Send Error Alert",
"type": "n8n-nodes-base.slack",
"position": [
-1136,
2480
],
"parameters": {
"text": "=\u274c *Error in API Error Catalog Workflow* *Node:* {{ $json.node.name }} *Message:* {{ $json.error.message }} *Time:* {{ $json.timestamp }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09GNB90TED",
"cachedResultName": "general-information"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "6023367a-c592-4cf3-82e1-8773c2dc2b5c",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1600,
2320
],
"parameters": {
"color": 7,
"width": 672,
"height": 336,
"content": "## \ud83d\udea8 Error Handling \n\n \nCatches any workflow failure and posts an alert to Slack. \nIncludes node name, error message, and timestamp for quick debugging.\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "40c9897e-b123-413e-98c8-22718a12e468",
"connections": {
"Webhook Trigger1": {
"main": [
[
{
"node": "AI Agent: Classify Intent & Generate Reply",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent: Classify Intent & Generate Reply",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Assign to Policy Team": {
"main": [
[
{
"node": "Check Guest Contact Preference",
"type": "main",
"index": 0
}
]
]
},
"Error Handler Trigger": {
"main": [
[
{
"node": "Slack: Send Error Alert",
"type": "main",
"index": 0
}
]
]
},
"Assign to Booking Team": {
"main": [
[
{
"node": "Check Guest Contact Preference",
"type": "main",
"index": 0
}
]
]
},
"Assign to Pricing Team": {
"main": [
[
{
"node": "Check Guest Contact Preference",
"type": "main",
"index": 0
}
]
]
},
"Route by Intent Category": {
"main": [
[
{
"node": "Assign to Booking Team",
"type": "main",
"index": 0
}
],
[
{
"node": "Assign to Pricing Team",
"type": "main",
"index": 0
}
],
[
{
"node": "Assign to Availability Team",
"type": "main",
"index": 0
}
],
[
{
"node": "Assign to Policy Team",
"type": "main",
"index": 0
}
]
]
},
"Extract Detected Category": {
"main": [
[
{
"node": "Route by Intent Category",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser1": {
"ai_outputParser": [
[
{
"node": "AI Agent: Classify Intent & Generate Reply",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Assign to Availability Team": {
"main": [
[
{
"node": "Check Guest Contact Preference",
"type": "main",
"index": 0
}
]
]
},
"Check Guest Contact Preference": {
"main": [
[
{
"node": "Send Email Reply to Guest",
"type": "main",
"index": 0
},
{
"node": "Post Enquiry Summary to Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Log AI Reply to Slack",
"type": "main",
"index": 0
},
{
"node": "Post Enquiry Summary to Slack",
"type": "main",
"index": 0
}
]
]
},
"AI Agent: Classify Intent & Generate Reply": {
"main": [
[
{
"node": "Extract Detected Category",
"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.
gmailOAuth2openAiApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
π Description This workflow automates guest enquiry intake, intent classification, response generation, and internal routing for hospitality businesses using webhooks, GPT-4o, Gmail, and Slack. It converts raw guest enquiries into structured, actionable items while ensuring fastβ¦
Source: https://n8n.io/workflows/12946/ β 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 automates the entire process of taking a raw user-submitted script, rewriting it into a polished HeyGen-ready narration, generating a full avatar video, handling all processing checks, r
Enhance your support, onboarding, and internal knowledge workflows with an intelligent RAG-powered chatbot that responds using live data stored in Google Sheets. π€π Built for teams that rely on struct
This workflow automates enterprise resource planning (ERP) operations across Engineering, Finance, HR, and Admin departments for operations managers, ERP administrators, and business process owners wh
JoinDAn8n. Uses httpRequest, dataTable, emailReadImap, lmChatOpenAi. Webhook trigger; 37 nodes.
This workflow automates credit operations onboarding by running KYC verification, credit bureau checks, identity validation, and sanctions screening through a single AI-powered agent. Built for credit