AutomationFlowsAI & RAG › Power Your Website Chat with Openai Gpt-4o-mini and Session Memory

Power Your Website Chat with Openai Gpt-4o-mini and Session Memory

ByThomas Abraham @heyabt on n8n.io

This workflow exposes an n8n chat webhook that powers a website chatbot using an OpenAI chat model, with short-term session memory to keep recent conversation context. Receives a visitor message via the public n8n chat webhook trigger. Uses an AI agent with a custom system…

Chat trigger trigger★★★★☆ complexityAI-powered16 nodesChat TriggerAgentMemory Buffer WindowOpenAI ChatGoogle Sheets ToolSlack Tool
AI & RAG Trigger: Chat trigger Nodes: 16 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #17520 — we link there as the canonical source.

This workflow follows the Agent → Chat 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 →

Download .json
{
  "id": "c8mdGpnKDv26kkS6",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Website Chat Agent with Lead Capture and Human Handoff",
  "tags": [],
  "nodes": [
    {
      "id": "f52b90a3-06e2-4411-8b08-fee02fb92986",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -112,
        0
      ],
      "parameters": {
        "mode": "webhook",
        "public": true,
        "options": {}
      },
      "typeVersion": 1.1
    },
    {
      "id": "ac723a62-2049-402c-a774-fab0fa973373",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        240,
        0
      ],
      "parameters": {
        "options": {
          "systemMessage": "You are a helpful, intelligent website chatbot for "
        }
      },
      "typeVersion": 2
    },
    {
      "id": "8256a363-4755-4588-9b27-672eca2f7823",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        336,
        224
      ],
      "parameters": {
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "46bba34e-6620-4d44-9290-7e6c9633833c",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        112,
        224
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "97b47a3b-1136-4bc6-8b3d-f0a1d2a42828",
      "name": "Sticky Note - Main",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        -192
      ],
      "parameters": {
        "width": 400,
        "height": 544,
        "content": "## Website Chat Agent\nA drop-in AI chat agent for your website, powered by n8n's native chat trigger. Remembers the conversation within a session.\n\n## How it works\n1. Visitor sends a message through the chat widget\n2. AI Agent answers using the system prompt below, with short-term memory of the conversation\n3. Response streams back to the widget automatically\n\n## Setup\n- [ ] Connect OpenAI credentials in OpenAI Chat Model\n- [ ] Open AI Agent and replace the systemMessage placeholder with your own instructions (who you are, tone, what you can/can't help with)\n- [ ] Activate the workflow, then embed n8n's chat widget on your site pointing at this workflow's chat URL"
      },
      "typeVersion": 1
    },
    {
      "id": "8559e149-e72c-41b0-ab5f-19264eee2564",
      "name": "Sticky Note - Agent Core",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        -192
      ],
      "parameters": {
        "color": 7,
        "width": 872,
        "height": 588,
        "content": "## Agent Core\nModel + short-term memory feed the agent. Memory is scoped per chat session automatically."
      },
      "typeVersion": 1
    },
    {
      "id": "eb7a57d8-d250-49ad-ad87-f3e3bebbbdc7",
      "name": "Sticky Note - Conversation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 660,
        "height": 300,
        "content": "## Conversation\nChat comes in, the agent reasons over it with short-term memory of the session."
      },
      "typeVersion": 1
    },
    {
      "id": "eca35299-b2ee-48a7-b463-79c97645f58e",
      "name": "Sticky Note - Agent Tools",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        432
      ],
      "parameters": {
        "color": 7,
        "width": 1064,
        "height": 452,
        "content": "## Agent Tools\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nThe agent calls these itself when the conversation warrants it - capture a lead, flag a hot one, or hand off to a human."
      },
      "typeVersion": 1
    },
    {
      "id": "f5f2785f-15e2-49d6-8e46-df42984abbae",
      "name": "Sticky Note - Warning",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        576
      ],
      "parameters": {
        "color": 3,
        "width": 300,
        "height": 150,
        "content": "**Sheet columns must exist first.** Save Lead writes Name, Email, Interest, Notes, Captured At - create those headers before activating or the append silently misfires."
      },
      "typeVersion": 1
    },
    {
      "id": "f4669411-a52e-42c4-9801-19cec172a2b6",
      "name": "Website Chat Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1904,
        112
      ],
      "parameters": {
        "text": "={{ $json.chatInput }}",
        "options": {
          "systemMessage": "You are the assistant on the website of [YOUR COMPANY], which [WHAT YOU DO, e.g. builds custom automation systems for small businesses].\n\nHow to behave:\n- Answer questions about what we do in a friendly, concise way. Never invent pricing, features, timelines, or policies you weren't given - if you don't know, say so.\n- Keep replies short. This is a chat widget, not an email.\n\nWhen to use your tools:\n- Save Lead: once you have BOTH a name and an email address from the visitor, call this to record them. Summarise what they're interested in. Only call it once per conversation.\n- Notify Hot Lead: call this when the visitor shows real buying intent - asking about pricing, requesting a demo, describing a specific project, or asking to speak to someone. Include why you flagged them.\n- Escalate To Human: call this when you genuinely cannot answer, when the visitor asks for a human, or when they're frustrated or reporting a problem. Summarise the conversation so far so a person can pick it up cold.\n\nDon't announce that you're using a tool. Just do it and continue the conversation naturally. Never ask for an email more than twice - if they decline, keep helping them anyway."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "114f817a-4fde-4fc0-8b9c-7c177cdc3836",
      "name": "Window Buffer Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        1904,
        624
      ],
      "parameters": {
        "sessionKey": "={{ $('When chat message received').item.json.sessionId }}",
        "sessionIdType": "customKey",
        "contextWindowLength": 12
      },
      "typeVersion": 1.3
    },
    {
      "id": "25acc711-e2b2-4f0c-8b21-71710c8e96ea",
      "name": "Save Lead",
      "type": "n8n-nodes-base.googleSheetsTool",
      "onError": "continueRegularOutput",
      "position": [
        2112,
        624
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $fromAI('name', 'The visitor full name as they gave it', 'string') }}",
            "Email": "={{ $fromAI('email', 'The visitor email address', 'string') }}",
            "Notes": "={{ $fromAI('notes', 'Any other useful context from the conversation, such as company size, timeline, or budget hints', 'string') }}",
            "Interest": "={{ $fromAI('interest', 'One short line on what this visitor is looking for', 'string') }}",
            "Captured At": "={{ $now.format('yyyy-MM-dd HH:mm') }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultName": "Leads"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SPREADSHEET_ID",
          "cachedResultName": "Chat Leads"
        },
        "descriptionType": "manual",
        "toolDescription": "Save a website visitor as a lead. Call this only once you have both their name and their email address."
      },
      "typeVersion": 4.7
    },
    {
      "id": "08546fb3-9dab-4ad3-af68-9c024105f71a",
      "name": "Notify Hot Lead",
      "type": "n8n-nodes-base.slackTool",
      "onError": "continueRegularOutput",
      "position": [
        2304,
        624
      ],
      "parameters": {
        "text": "={{ $fromAI('message', 'A short alert for the sales team: who the visitor is, what they want, and why this is worth following up on now', 'string') }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_SALES_CHANNEL_ID",
          "cachedResultName": "sales-alerts"
        },
        "otherOptions": {},
        "descriptionType": "manual",
        "toolDescription": "Alert the sales team in Slack about a high-intent visitor. Call this when someone asks about pricing, requests a demo, describes a specific project, or asks to talk to a person."
      },
      "typeVersion": 2.3
    },
    {
      "id": "e9456bd6-c840-4883-b49f-91192d01b61f",
      "name": "Escalate To Human",
      "type": "n8n-nodes-base.slackTool",
      "onError": "continueRegularOutput",
      "position": [
        2512,
        624
      ],
      "parameters": {
        "text": "={{ $fromAI('summary', 'A handoff summary: what the visitor asked, what was already answered, and exactly what still needs a human. Include their contact details if known.', 'string') }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "REPLACE_WITH_SUPPORT_CHANNEL_ID",
          "cachedResultName": "support-escalations"
        },
        "otherOptions": {},
        "descriptionType": "manual",
        "toolDescription": "Hand this conversation to a human. Call this when you cannot answer the question, the visitor asks for a person, or they are frustrated or reporting a problem."
      },
      "typeVersion": 2.3
    },
    {
      "id": "5883a7e8-5901-4821-b980-3e60196d870c",
      "name": "Sticky Note - Main1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        -32
      ],
      "parameters": {
        "width": 460,
        "height": 896,
        "content": "## Website Chat Agent with Lead Capture & Human Handoff\nAn embeddable AI chat agent that answers visitor questions, saves qualified leads to Google Sheets on its own, and pulls in a human when it can't help.\n\n## How it works\n1. Visitor messages the chat widget on your site\n2. The agent answers using your system prompt, remembering the conversation\n3. When it collects a name + email, it calls the Save Lead tool and writes the lead to your sheet\n4. High-intent conversations (pricing, demo, buying signals) trigger a Slack alert\n5. Anything it can't answer gets escalated to Slack with the transcript so a human can take over\n\n## Setup\n- [ ] Connect OpenAI credentials in OpenAI Chat Model\n- [ ] Connect Google Sheets credentials in Save Lead, pick your spreadsheet + tab\n- [ ] Connect Slack credentials in both Slack tools, set the real channels\n- [ ] Replace the placeholder company details in the agent's system message\n- [ ] Activate, then point n8n's embeddable chat widget at this workflow's chat URL\n\n## Customize\nSwap the Slack tools for Gmail or Discord, or add another tool (Calendly, CRM) - the agent decides when to call each one based on its toolDescription."
      },
      "typeVersion": 1
    },
    {
      "id": "6f6ce76f-2961-41fd-87ca-5a33c297582d",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1712,
        624
      ],
      "parameters": {
        "model": "gpt-4o-mini",
        "options": {}
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "af1c438b-4288-429a-a8ea-f13d16e292e6",
  "nodeGroups": [],
  "connections": {
    "Save Lead": {
      "ai_tool": [
        [
          {
            "node": "Website Chat Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "AI Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Notify Hot Lead": {
      "ai_tool": [
        [
          {
            "node": "Website Chat Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Escalate To Human": {
      "ai_tool": [
        [
          {
            "node": "Website Chat Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Website Chat Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Window Buffer Memory": {
      "ai_memory": [
        [
          {
            "node": "Website Chat Agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "AI Agent",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow exposes an n8n chat webhook that powers a website chatbot using an OpenAI chat model, with short-term session memory to keep recent conversation context. Receives a visitor message via the public n8n chat webhook trigger. Uses an AI agent with a custom system…

Source: https://n8n.io/workflows/17520/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Who is this workflow for? This workflow is designed for SEO analysts, content creators, marketing agencies, and developers who need to index a website and then interact with its content as if it were

Agent, OpenAI Chat, Memory Buffer Window +10
AI & RAG

Enhance your data analysis by connecting an AI Agent to your dataset, using n8n tools.

Chat Trigger, Agent, OpenAI Chat +6
AI & RAG

Code Filter. Uses chatTrigger, agent, lmChatOpenAi, toolCalculator. Chat trigger; 30 nodes.

Chat Trigger, Agent, OpenAI Chat +6
AI & RAG

Workflow 3050. Uses chatTrigger, agent, lmChatOpenAi, toolCalculator. Chat trigger; 30 nodes.

Chat Trigger, Agent, OpenAI Chat +6
AI & RAG

Data Analyst. Uses chatTrigger, agent, lmChatOpenAi, toolCalculator. Chat trigger; 30 nodes.

Chat Trigger, Agent, OpenAI Chat +6