This workflow corresponds to n8n.io template #7191 — we link there as the canonical source.
This workflow follows the Agent → Execute Workflow 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": "QiEoooyNMeJcvKKg",
"name": "Automating WhatsApp replies in Go High Level with Redis and Anthropic",
"tags": [
{
"id": "PnRGSMhEDCtkgPVA",
"name": "OJAUUMDev",
"createdAt": "2025-07-21T20:12:28.081Z",
"updatedAt": "2025-07-21T20:12:28.081Z"
}
],
"nodes": [
{
"id": "6290c10a-80ac-46b8-9d49-dcf5dff98125",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
-1380,
320
],
"parameters": {
"path": "fce352e8-8edf-447c-9b54-c2c2b6649ccc",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2
},
{
"id": "4f19d6b1-829c-4824-8e75-e0781caa59f3",
"name": "Switch1",
"type": "n8n-nodes-base.switch",
"position": [
-1220,
320
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "436fa76a-f948-4de3-86a1-9ed6e568430f",
"operator": {
"type": "string",
"operation": "notContains"
},
"leftValue": "={{ $json.body.message.body }}",
"rightValue": "type message: audio"
}
]
}
},
{
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a4574272-ebee-40a4-a1fb-9139e5f6112e",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.body.message.body }}",
"rightValue": "type message: audio"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3
},
{
"id": "2f44dc60-d93f-4ee0-8c5a-e481541d6486",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
460,
160
],
"parameters": {
"text": "={{ $('messages').first().json.menssage }}",
"options": {
"systemMessage": "=# Summary\n\nYou are the customer service assistant for **GlobalPoint Services**. Your task is to answer user questions **only using the information provided by the `ClientInfo` tool**, which contains accurate data about services, branches, locations, schedules, prices, and requirements.\n\n# Tools\n\n**ClientInfo** \u2192 Use this tool to obtain the exact information. Its content consists of a list of objects under the `\"response\"` field with the following structure:\n\n```json\n{\n \"response\": {\n \"Category\": \"Consulting\",\n \"Service\": \"Business Strategy Session\",\n \"Requirements\": \"Schedule at least 48 hours in advance\",\n \"Price (USD)\": 150\n }\n},\n{\n \"response\": {\n \"Branch\": \"GlobalPoint Downtown Office\",\n \"Location\": \"123 Main Street, Downtown, Springfield, USA\",\n \"Schedule\": \"Mon\u2013Fri: 9 a.m.\u20136 p.m.; Sat: 9 a.m.\u20131 p.m.; Sun: Closed\",\n \"Notes\": \"Walk-ins are welcome during business hours.\"\n }\n}\n```\n\n# Rules\n\n* When a user asks about branches, locations, schedules, services, prices, or requirements, **always use ClientInfo to find exact matches**, regardless of case sensitivity or minor typos.\n* You may accept partial matches or synonyms as long as they clearly refer to the exact service or branch listed in ClientInfo.\n* Always respond using the exact service or branch name **as it appears in ClientInfo**, and clarify:\n `The price for \"[exact name]\" is XX USD.`\n or\n `The branch \"[exact name]\" is located at [exact location]. Schedule: [schedule].`\n* **Never provide information that is not explicitly included in ClientInfo.**\n* If no clear match is found, respond with:\n `Sorry, we do not offer that service or have that branch in our records. Is there anything else I can help you with?`\n* Use a **friendly, clear, simple, and helpful** tone, always in the **same language as the user**.\n* If the question is generic or just a greeting, respond politely and invite them to ask.\n\n# Examples\n\n**1. Input:** Hello\n**Response:** Hi! Welcome to GlobalPoint Services. How can I assist you today?\n\n**2. Input:** I have a question\n**Response:** Sure, tell me more so I can help.\n\n**3. Input:** What services do you offer?\n**Action:** Read all items in ClientInfo.\n**Response:** At GlobalPoint Services, we offer options such as \\[brief list based on Category and Service].\n\n**4. Input:** How much is the Business Strategy Session?\n**Action:** Search \"Business Strategy Session\" in ClientInfo.\n**Response:** The price for the service \"Business Strategy Session\" is 150 USD. Requirements: Schedule at least 48 hours in advance.\n\n**5. Input:** Where is the Downtown Office?\n**Action:** Search \"Downtown Office\" in branches within ClientInfo.\n**Response:** Our branch \"GlobalPoint Downtown Office\" is located at 123 Main Street, Downtown, Springfield, USA. Schedule: Mon\u2013Fri: 9 a.m.\u20136 p.m. and Sat: 9 a.m.\u20131 p.m.\n\n# Final Reminders\n\n* **Never make up data, prices, or addresses.**\n* **Never answer from general knowledge**, only from ClientInfo.\n* **Always use the exact service or branch name when giving prices or requirements.**\n* **Do not give suggestions or recommendations not present in the data.**\n\n"
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "e60eaf2a-9c68-49bf-b237-d0bbd6bdd1c7",
"name": "Anthropic Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
380,
380
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-20250514",
"cachedResultName": "Claude Sonnet 4"
},
"options": {}
},
"typeVersion": 1.3
},
{
"id": "a29f6bab-4088-48f2-802a-c59f44d0d3f5",
"name": "Update Contact",
"type": "n8n-nodes-base.httpRequest",
"position": [
1280,
160
],
"parameters": {
"url": "=https://rest.gohighlevel.com/v1/contacts/{{ $('Webhook').item.json.body.contact_id }}",
"method": "PUT",
"options": {},
"jsonBody": "={\n \"customField\": {\n \"{{ $json.customFields.find(field => field.name === 'IA_answer').id }}\": \"{{ $('Sanitize and Format Message Output').item.json.output }}\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{}
]
}
},
"credentials": {
"httpBearerAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "ba1cfe67-f7ce-4f32-82a9-99557f4b6495",
"name": "GHL Custom fields",
"type": "n8n-nodes-base.httpRequest",
"position": [
1080,
160
],
"parameters": {
"url": "https://rest.gohighlevel.com/v1/custom-fields/",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "5ab4f7b8-ccf3-440b-a9ea-54e6d5e595f7",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
-500,
220
],
"parameters": {
"amount": 15
},
"typeVersion": 1.1
},
{
"id": "b081b133-b582-447e-bf52-8647d4c18e24",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-180,
220
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "41b0355b-7204-4e25-b74a-7bf70dea8a9c",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.messages.last() }}",
"rightValue": "={{ $('Sanitize and Format Message Body').item.json.text }}"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "1f6b0707-cd9d-4d93-ba39-757348beceb1",
"name": "No Operation, do nothing",
"type": "n8n-nodes-base.noOp",
"position": [
-20,
380
],
"parameters": {},
"typeVersion": 1
},
{
"id": "86cb66f8-0d79-40ee-88c6-48ac440a08cf",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
520,
380
],
"parameters": {
"sessionKey": "={{ $('Webhook').item.json.body.phone }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "27d0db94-0317-423f-8b58-8178211f8dfb",
"name": "Save message",
"type": "n8n-nodes-base.redis",
"position": [
-660,
220
],
"parameters": {
"list": "={{ $('Webhook').item.json.body.contact_id }}",
"tail": true,
"operation": "push",
"messageData": "={{ $json.text }}"
},
"typeVersion": 1
},
{
"id": "6c8b6cb0-7cd7-4e3d-90c4-4e117f3449eb",
"name": "Get messages",
"type": "n8n-nodes-base.redis",
"position": [
-340,
220
],
"parameters": {
"key": "={{ $('Webhook').item.json.body.contact_id }}",
"options": {},
"operation": "get",
"propertyName": "mensajes"
},
"typeVersion": 1
},
{
"id": "877a16b7-b461-439f-8501-9a4c418dc7d0",
"name": "Sanitize and Format Message Body",
"type": "n8n-nodes-base.code",
"position": [
-940,
220
],
"parameters": {
"jsCode": "return [{\n text: $input.first().json.body.message.body\n .replace(/\\\\+\"/g, '\"') // Fix incorrectly escaped double quotes\n .replace(/\\n/g, \"\\\\n\") // Properly escape line breaks\n .replace(/\\r/g, \"\\\\r\") // Escape carriage returns\n .replace(/\\t/g, \"\\\\t\") // Escape tab characters\n .trim() // Remove unnecessary whitespace\n}];"
},
"typeVersion": 2
},
{
"id": "8c8a0ce0-4fc3-4979-8f1a-331a0861bfe4",
"name": "Delete messages",
"type": "n8n-nodes-base.redis",
"position": [
120,
160
],
"parameters": {
"key": "={{ $('Webhook').item.json.body.contact_id }}",
"operation": "delete"
},
"typeVersion": 1
},
{
"id": "55e65c69-54ec-4df1-8197-0dd0b4f6f416",
"name": "messages",
"type": "n8n-nodes-base.set",
"position": [
-20,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "7bb3ef98-b766-4ad7-8343-b2885bd70225",
"name": "message",
"type": "string",
"value": "={{ $node[\"Get messages\"].json[\"messages\"].join(\"\\n\") }}"
},
{
"id": "62dfc214-fb40-4a59-81a4-b01c6c0860af",
"name": "id",
"type": "string",
"value": "={{ $('Webhook').item.json.body.contact_id }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "e65eca71-742f-4301-bbab-5130fe7e4d34",
"name": "When Executed by Another Workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"position": [
-600,
1140
],
"parameters": {
"inputSource": "passthrough"
},
"typeVersion": 1.1
},
{
"id": "22b16984-474c-488a-b012-17d6cc8f26c9",
"name": "Download file",
"type": "n8n-nodes-base.googleDrive",
"position": [
-440,
1140
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "list",
"value": "1Im72SvVQhzjLk_rVUidGK0du4s2zMZ3H",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Im72SvVQhzjLk_rVUidGK0du4s2zMZ3H/edit?usp=drivesdk&ouid=107080324345235325088&rtpof=true&sd=true",
"cachedResultName": "Examenes de Laboratorio Prueba Doctor Premier.xlsx"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "aabc26f2-36a2-469c-8c60-5a7b35030c16",
"name": "Success",
"type": "n8n-nodes-base.set",
"position": [
80,
1140
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "39c2f302-03be-4464-a17a-d7cc481d6d44",
"name": "=response",
"type": "object",
"value": "={{ $json }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ce02d432-ecca-44ff-ac7e-2f3d12f09185",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-60,
1140
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "e9836dfc-8a86-41be-ac81-5e706ce38a23",
"name": "Call n8n Workflow Tool",
"type": "@n8n/n8n-nodes-langchain.toolWorkflow",
"position": [
680,
380
],
"parameters": {
"workflowId": {
"__rl": true,
"mode": "list",
"value": "yVUPXPNCNlo5HkJs",
"cachedResultName": "My Sub-Workflow 1"
},
"workflowInputs": {
"value": {},
"schema": [],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
}
},
"typeVersion": 2.2
},
{
"id": "7a881605-ce1d-4ed4-9c61-36533b759286",
"name": "Extract Tests",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-240,
1060
],
"parameters": {
"options": {
"sheetName": "Tests"
},
"operation": "xlsx"
},
"typeVersion": 1
},
{
"id": "44d5d6c6-add6-424c-ad6c-0108435a1c1b",
"name": "Extract Sites",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-240,
1240
],
"parameters": {
"options": {
"sheetName": "Sites"
},
"operation": "xlsx",
"binaryPropertyName": "=data"
},
"typeVersion": 1
},
{
"id": "b8d3874e-ee58-4da7-bcf5-3b6b67071411",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-660,
580
],
"parameters": {
"color": 5,
"width": 900,
"height": 820,
"content": "# Google Drive Excel Merge Workflow\n\nThis is an **optional example** that should be created in a **separate workflow**. It demonstrates how to extract client information from an Excel file with two sheets, `tests` and `sites`, merge the data, and return it to an LLM.\n\n## 1. Setup and Download\n* Create Google OAuth 2.0 credentials in **Google Cloud Console** and enable the **Google Drive API**.\n* Authenticate and download the specified Excel file from Google Drive.\n---\n## 2. Extract Data from Excel\n* Read the Excel file.\n* Extract data from the **tests** sheet.\n* Extract data from the **sites** sheet.\n---\n## 3. Merge the Data\n* Combine the extracted data from both sheets into one dataset.\n* Ensure formatting and structure are consistent.\n* Return the merged dataset as the response to the LLM request.\n"
},
"typeVersion": 1
},
{
"id": "62d3abdc-7eac-4552-a064-23097d6ea7d6",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1400,
-300
],
"parameters": {
"width": 680,
"height": 860,
"content": "# GHL to n8n SMS Reply Bridge\n\n## 1. Requirements and Setup\n\n* Requires the **GoHighLevel sub-account API** (API key/token) where the chatbot will run.\n* In GoHighLevel, create an **Automation**: trigger on **Customer Replied (SMS)** and send the payload to your **n8n Webhook** URL.\n* Use the **Wazzap** plugin in GHL to receive WhatsApp replies into the same flow.\n* Cost-Saving Trick: Create a custom field in GHL, for example **IA_answer** and update with your bot\u2019s response instead of triggering extra paid automations on every inbound message.\n---\n\n## 2. Webhook and Filter\n\n* Receive the HTTP POST in **n8n Webhook**.\n* Add a filter/switch:\n * If the message is **audio** (Wazzap/GHL does not provide a downloadable file), **do not process**. Send a personalized fallback reply asking for text.\n * If the message is **text**, run a **Function/Code** node to **sanitize**:\n * Fix incorrectly escaped quotes.\n * Escape line breaks, carriage returns, and tabs.\n * Trim whitespace and remove invalid fields.\n\n"
},
"typeVersion": 1
},
{
"id": "20e82e23-0434-495e-9676-0cf6d91f1c5a",
"name": "Update Contact No audio",
"type": "n8n-nodes-base.httpRequest",
"position": [
-860,
400
],
"parameters": {
"url": "=https://rest.gohighlevel.com/v1/contacts/{{ $('Webhook').item.json.body.contact_id }}",
"method": "PUT",
"options": {},
"jsonBody": "={\n \"customField\": {\n \"{{ $json.customFields.find(field => field.name === 'IA_answer').id }}\": \"Sorry, I can\u2019t listen to voice notes at the moment. Could you please write your question or concern? Thank you very much.\"\n }\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth"
},
"credentials": {
"httpBearerAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "ad9f2916-0f90-4c4a-85eb-6b7dfc705fa8",
"name": "Get GHL Custom fields",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1060,
400
],
"parameters": {
"url": "https://rest.gohighlevel.com/v1/custom-fields/",
"options": {},
"sendHeaders": true,
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"credentials": {
"httpBearerAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "1cd6d85e-62e7-41d4-a4a8-5e6ded3140de",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-660,
-300
],
"parameters": {
"color": 6,
"width": 900,
"height": 860,
"content": "# Redis Message Buffer Workflow\n\n## 1. Purpose\n* Batch multiple user messages sent within a short window and pass a single merged text to the next step.\n---\n## 2. Setup\n* Configure a Redis database and set credentials/values in the Redis nodes (host, port, db index, password).\n* Use one Redis list per contact, keyed by the `contact_id` from the Webhook.\n---\n## 3. Flow\n* **Save message**: Push the sanitized text to the Redis list for `contact_id`.\n* **Wait**: Pause for a few seconds (e.g., 15) so the user can finish typing.\n* **Get messages**: Read all items from the Redis list into `messages`.\n* **If**: Compare `messages.last()` with the latest sanitized text; if equal proceed, if not do nothing.\n* **messages**: Join all collected items with newline into `message` and keep `id = contact_id`.\n* **Delete messages**: Delete the Redis key for that `contact_id` to clear the buffer.\n"
},
"typeVersion": 1
},
{
"id": "6949cf34-0086-4493-b281-2d8d200c7fcb",
"name": "Sanitize and Format Message Output",
"type": "n8n-nodes-base.code",
"position": [
800,
160
],
"parameters": {
"jsCode": "return [{\n output: $input.first().json.output\n .replace(/^\"{|}\"$/g, \"\") // Removes double quotes at the start and end if present\n .replace(/^{\"response\":\\s*\"/, '') // Removes '{\"response\":\"' at the beginning if present\n .replace(/\"}$/, '') // Removes '\"}' at the end if present\n .replace(/\\\\\"/g, '\"') // Converts escaped quotes \\\" into normal quotes \"\n .replace(/\\n/g, \"\\\\n\") // Escapes newlines correctly\n .replace(/\\r/g, \"\\\\r\") // Escapes carriage returns\n .replace(/\\t/g, \"\\\\t\") // Escapes tabs\n .replace(/^\"+|\"+$/g, \"\") // \ud83d\udd25 New line: Removes extra double quotes at the edges\n .replace(/\"/g, '\\\\\"') // Escapes internal double quotes for JSON\n .trim() // Removes unnecessary whitespace\n}];"
},
"typeVersion": 2
},
{
"id": "99f56ece-0c95-4148-938a-51e9d32d047f",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
340,
-300
],
"parameters": {
"color": 3,
"width": 660,
"height": 860,
"content": "# ClientInfo LLM Response Workflow\n\n## 1. AI Agent with ClientInfo Tool\n* Answers user questions **only** with data from **ClientInfo** (sub-workflow below), calling it through **Call n8n Workflow Tool**.\n * Uses **Anthropic (Claude Sonnet 4)** in this example but can work with any chat model by setting the API key.\n * The system prompt enforces answering only from ClientInfo, and can be tuned for your client\u2019s tone, style, or specificity based on available data.\n * Keeps short conversational context with **Simple Memory** using the user\u2019s phone as the session key.\n---\n## 2. Sanitize Output\n* After generating the response, a **Function/Code** node cleans it by fixing incorrectly escaped quotes, escaping line breaks, carriage returns, and tabs, trimming whitespace, and removing invalid fields before sending it downstream.\n"
},
"typeVersion": 1
},
{
"id": "3608f575-00cf-42a8-acd8-44771e584288",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1020,
-300
],
"parameters": {
"width": 460,
"height": 620,
"content": "# GHL Update Contact Workflow\n\n## 1. Get Custom Fields\n * Makes a **GET** request to the GoHighLevel API to retrieve all custom fields in the sub-account.\n * Finds the **IA_answer** field ID to be used in the update request.\n---\n## 2. Update Contact\n * Sends a **PUT** request to the GoHighLevel API to update the contact\u2019s **IA_answer** custom field with the sanitized AI response.\n * In GHL, create an **Automation** that triggers when **IA_answer** is updated and sends the value by SMS to the contact.\n"
},
"typeVersion": 1
},
{
"id": "996bfe66-4b59-4702-aa59-55da2c5282e3",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2600,
-300
],
"parameters": {
"color": 3,
"width": 1120,
"height": 1040,
"content": "# Automating WhatsApp replies in Go High Level with Redis and Anthropic\n## Description\n* Integrates GHL + Wazzap with Redis and an AI Agent using ClientInfo to process messages, generate accurate replies, and send them via a custom field trigger.\n---\n## Who\u2019s it for\n* This workflow is for businesses using **GoHighLevel (GHL)**, including the **Wazzap** plugin for WhatsApp, who want to automate inbound SMS/WhatsApp replies with AI. It\u2019s ideal for teams that need accurate, data-driven responses from a predefined **ClientInfo** source and want to send them back to customers without paying for extra inbound automations.\n---\n## How it works / What it does\n1. **Receive message** in n8n via Webhook from GHL (**Customer Replied (SMS)** automation). WhatsApp messages arrive the same way using the **Wazzap** plugin.\n2. **Filter message type**:\n * If audio \u2192 skip processing and send fallback asking for text.\n * If text \u2192 sanitize by fixing escaped quotes, escaping line breaks/carriage returns/tabs, and removing invalid fields.\n3. **Buffer messages** in Redis to group multiple messages sent in a short window.\n4. **Run AI Agent** using the **ClientInfo** tool to answer only with accurate service/branch data.\n5. **Sanitize AI output** before sending back.\n6. **Update GHL contact** custom field (**IA_answer**) with the AI\u2019s response.\n7. **Send SMS reply** automatically via GHL\u2019s outbound automation triggered by the updated custom field.\n---\n## How to set up\n1. In **GHL**, create:\n * **Inbound automation**: Trigger on *Customer Replied (SMS)* \u2192 Send to your n8n Webhook.\n * **Outbound automation**: Trigger when **IA_answer** is updated \u2192 Send SMS to the contact.\n * Create a custom field named **IA_answer**.\n2. Connect **Wazzap** in GHL to handle WhatsApp messages.\n3. Configure **Redis** in n8n (host, port, DB index, password).\n4. Add your **AI model** credentials (Anthropic, OpenAI, etc.) in n8n.\n5. (Optional) Set up the **Google Drive Excel Merge** sub-workflow to enrich ClientInfo with external data.\n---\n## Requirements\n* **GoHighLevel sub-account API key**.\n* **Anthropic (Claude)** API key or another supported LLM provider.\n* **Redis database** for temporary message storage.\n* **GHL automations**: one for inbound messages to n8n, one for outbound replies when **IA\\_answer** is updated.\n* **GHL custom field**: **IA\\_answer** to store and trigger replies.\n* **Wazzap plugin** in GHL for WhatsApp message handling.\n---\n## How to customize the workflow\n* Add more context or business-specific data to the **AI Agent prompt** so replies match your brand tone and policies.\n* Expand the **ClientInfo** dataset with additional services, branches, or product details.\n* Adjust the **Redis wait time** to control how long the workflow buffers messages before replying."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "7ff7549a-738b-4be0-8c59-bdd9f605edfa",
"connections": {
"If": {
"main": [
[
{
"node": "messages",
"type": "main",
"index": 0
}
],
[
{
"node": "No Operation, do nothing",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Get messages",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Success",
"type": "main",
"index": 0
}
]
]
},
"Switch1": {
"main": [
[
{
"node": "Sanitize and Format Message Body",
"type": "main",
"index": 0
}
],
[
{
"node": "Get GHL Custom fields",
"type": "main",
"index": 0
}
]
]
},
"Webhook": {
"main": [
[
{
"node": "Switch1",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Sanitize and Format Message Output",
"type": "main",
"index": 0
}
]
]
},
"messages": {
"main": [
[
{
"node": "Delete messages",
"type": "main",
"index": 0
}
]
]
},
"Get messages": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Save message": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Download file": {
"main": [
[
{
"node": "Extract Tests",
"type": "main",
"index": 0
},
{
"node": "Extract Sites",
"type": "main",
"index": 0
}
]
]
},
"Extract Sites": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Extract Tests": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Delete messages": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"GHL Custom fields": {
"main": [
[
{
"node": "Update Contact",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Get GHL Custom fields": {
"main": [
[
{
"node": "Update Contact No audio",
"type": "main",
"index": 0
}
]
]
},
"Call n8n Workflow Tool": {
"ai_tool": [
[
{
"node": "AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Sanitize and Format Message Body": {
"main": [
[
{
"node": "Save message",
"type": "main",
"index": 0
}
]
]
},
"When Executed by Another Workflow": {
"main": [
[
{
"node": "Download file",
"type": "main",
"index": 0
}
]
]
},
"Sanitize and Format Message Output": {
"main": [
[
{
"node": "GHL Custom fields",
"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.
googleDriveOAuth2ApihttpBearerAuth
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Integrates GHL + Wazzap with Redis and an AI Agent using ClientInfo to process messages, generate accurate replies, and send them via a custom field trigger.
Source: https://n8n.io/workflows/7191/ — 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.
🧠 Gwen – The AI Voice Marketing Agent Gwen is your intelligent voice-powered marketing assistant built in n8n. She combines the power of OpenAI, ElevenLabs, and automation workflows to handle content
L&D_AgentsAI_ATIVO. Uses httpRequest, agent, googleCalendarTool, toolSerpApi. Webhook trigger; 93 nodes.
Agente_DamaresEstetica. Uses postgres, agent, n8n-nodes-evolution-api, lmChatGoogleGemini. Webhook trigger; 87 nodes.
My workflow 7. Uses openAi, redis, httpRequest, agent. Webhook trigger; 77 nodes.
My workflow 7. Uses openAi, redis, httpRequest, agent. Webhook trigger; 77 nodes.