This workflow follows the Agent → Chainllm 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 →
{
"nodes": [
{
"parameters": {
"jsCode": "const matches = / \\- (\\d+)/.exec($input.first().json.subject)\nreturn [{threadId: matches?.[1]}]"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-128,
-80
],
"id": "823b6634-3e1a-4fb3-acba-97554afe0f01",
"name": "Extract thread ID"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "d4e055e5-bdc4-4412-bc60-c9abbd242a71",
"name": "subject",
"value": "[PrestaShop Addons] You received a new message! : Dynamic Product Fields - 1157715",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-576,
-176
],
"id": "21176efa-72f4-448f-b144-5e095048c36c",
"name": "Set test subject"
},
{
"parameters": {},
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
-800,
-176
],
"id": "64078185-a289-4d46-a3c0-0135c91df531",
"name": "Trigger"
},
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {},
"options": {}
},
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.3,
"position": [
-576,
16
],
"id": "aeaa9acb-c3e6-474f-9773-e39f32959030",
"name": "Message Received",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "022724d7-c501-4c60-91fe-acc02fbcf7c5",
"leftValue": "={{ $json.subject }}",
"rightValue": "You received a new message! : Dynamic Product Fields",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.filter",
"typeVersion": 2.2,
"position": [
-352,
-80
],
"id": "3ab3ec70-8a80-4df1-b50e-6519a9463894",
"name": "Only keep Dynamic Product messages"
},
{
"parameters": {
"url": "=https://api.addons.prestashop.com/request/seller/threads/{{ $json.threadId }}/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "sort",
"value": "DESC"
},
{
"name": "limit",
"value": "5"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
320,
-80
],
"id": "df0e5486-3bf4-4e86-89af-4d0b77274b11",
"name": "HTTP Request",
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "let chatInput = \"\"\nfor (const item of $input.first().json.messages.data.reverse()) {\n chatInput += `${item.from}:\\n${item.message.replace(/\\<br[\\s\\/]*?\\>/g, \"\\n\").replace(/<[^>]*>/g, '')}\\n\\n`\n}\n\nreturn [{chatInput}]"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
544,
-80
],
"id": "92fbac8c-fadf-4c63-9697-9c2598e07785",
"name": "Code in JavaScript"
},
{
"parameters": {
"resource": "message",
"operation": "sendAndWait",
"guildId": {
"__rl": true,
"value": "1424094167579103354",
"mode": "list",
"cachedResultName": "tunisoft's server",
"cachedResultUrl": "https://discord.com/channels/1424094167579103354"
},
"channelId": {
"__rl": true,
"value": "1429191519771820246",
"mode": "list",
"cachedResultName": "support",
"cachedResultUrl": "https://discord.com/channels/1424094167579103354/1429191519771820246"
},
"message": "=A new support message was generated:\n\nContext:\n\n{{ $('Code in JavaScript').item.json.chatInput.replace(/customer/g, \"**Customer**\").replace(/seller/g, \"**Seller**\") }}\n\nResponse:\n\n{{ $json.output }}",
"options": {}
},
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
2320,
-80
],
"id": "114fe122-26b1-4245-92bb-03f569873a15",
"name": "Send message and wait for response",
"credentials": {
"discordBotApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.data.approved }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"id": "d9518b02-31a5-4415-9649-750669fbcde9"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Approved"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.3,
"position": [
2544,
-80
],
"id": "386f16b5-a712-4ab6-95d4-1baceb705220",
"name": "Switch"
},
{
"parameters": {
"prompt": "=Message:\n{{ $json.chatInput }} ",
"messages": {
"messageValues": [
{
"message": "Your task is to assess if the message requires a response. Return in JSON format true if it does, false otherwise."
}
]
}
},
"id": "cf7bc8fe-ddd3-40d0-b749-0a8f953b3673",
"name": "Assess if message needs a reply",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
768,
-80
],
"typeVersion": 1.3
},
{
"parameters": {
"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"needsReply\": {\n \"type\": \"boolean\"\n }\n },\n \"required\": [\"needsReply\"]\n}\n"
},
"id": "0093d66e-0b70-4977-b1ce-5a3d4b3ff6be",
"name": "JSON Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
904,
144
],
"typeVersion": 1
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "={{ $json.needsReply }}",
"rightValue": "",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"id": "d9518b02-31a5-4415-9649-750669fbcde9"
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "Needs reply"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.3,
"position": [
1120,
-80
],
"id": "c0a2614c-e02b-46b4-ad8d-18a246847dfa",
"name": "Switch1"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "945919b3-2f5a-44d4-9da7-ee14abe6f4ce",
"name": "chatInput",
"value": "={{ $('Code in JavaScript').item.json.chatInput }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1344,
-80
],
"id": "eadc2757-dd57-4275-9c56-21ef740dd70f",
"name": "Edit Fields"
},
{
"parameters": {
"method": "POST",
"url": "=https://api.addons.prestashop.com/request/seller/threads/{{ $('Extract thread ID').item.json.threadId }}/messages/add",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth",
"sendBody": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"name": "message",
"value": "={{ $json.message }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2992,
-80
],
"id": "8f6d6b7f-e35d-4f06-9bdb-d8153e7d3da1",
"name": "Respond to customer",
"credentials": {
"httpQueryAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"leftValue": "",
"rightValue": "",
"operator": {
"type": "string",
"operation": "equals"
},
"id": "45b0cbfe-d2a5-40e2-a31c-625efe5a9843"
}
],
"combinator": "and"
}
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.3,
"position": [
96,
-80
],
"id": "a32b9ff9-0d68-4df2-a32c-e613b7d9c821",
"name": "Check threadId"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
776,
144
],
"id": "e17a9f89-ad61-44ed-9da8-66671058da21",
"name": "Google Gemini Flash",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"modelName": "models/gemini-2.5-pro",
"options": {}
},
"id": "a32c839f-144b-47a0-b6a4-bd619e645c81",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Gemini 2.5 Flash",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"creator": "Lucas Peyrin",
"position": [
1568,
144
],
"typeVersion": 1,
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"notes": "\u00a9 2025 Lucas Peyrin"
},
{
"parameters": {},
"id": "7e4ffdee-fe74-4560-925a-485a3ecc1e13",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "Gemini Query Embedding",
"type": "@n8n/n8n-nodes-langchain.embeddingsGoogleGemini",
"creator": "Lucas Peyrin",
"position": [
1904,
352
],
"typeVersion": 1,
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"notes": "\u00a9 2025 Lucas Peyrin"
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.chatInput }}",
"options": {
"systemMessage": "=<role>\nYou are a specialized AI assistant, an expert in the Dynamic Product module documentation. Your sole mission is to help the Customer by providing accurate and factual information extracted exclusively from this documentation. You are meticulous, factual, and never deviate from your knowledge scope. Respond as if you are the seller.\n</role>\n\n<instructions>\n<goal>\nYour primary goal is to provide precise and factual answers to the Customer questions about the Dynamic product module, which is a module that supports many types of fields and makes dynamic calculations to calculate the price & weight of a product.\n\nYour job is to generate a response to the support thread to solve the Customer problem or to answer their question.\n</goal>\n\n<context>\nYou operate according to a RAG (Retrieval-Augmented Generation) model. For each user question, use the appropriate tool to retrieve the necessary information from the Dynamic product documentation's vector database.\n\n**Mandatory rules:**\n\n1. **Single source of truth:** Your answer MUST be entirely and solely derived from the information present in the provided documentation or the support messages provided. The support messages will be passed to you as coming from Seller and Customer. Respond as if you are the seller.\n2. **Accuracy and implicit citation:** Base your answer as literally as possible on the documentation text. Rephrase for clarity and conciseness, but do not add any information not found there. Act as if the documentation is your only knowledge in the world.\n3. **Do not mention the process:** Never mention your tool or the fact that you are a RAG system in your answer to the user. Respond as an expert who directly consults their documentation.\n4. **The seller IP:** To get the correct IP, you must run the HTTP request tool to get the current IP. Do not put the IP between quotes, place it in a new line to make it easier to copy it.\n</context>\n\n<output_format>\n* **Greeting** Greet the Customer using their name if provided.\n* **Inquiring** Ask for the product link if the Customer is having an issue with a specific product and did not provide a product link.\n* **Maintenance mode** If the Customer's shop is in maintenance mode, ask them to add my IP to the maintenance settings.\n* **Clarity:** Provide a clear, concise, and direct answer.\n* **Structuring:** If the context contains steps, lists, or code examples, use Markdown syntax to format them legibly (bullet points, numbered lists, code blocks for code snippets, JSON, etc.).\n* **Tone:** Adopt a professional, helpful, and confident tone, that of a technical Dynamic product expert. Conclude the message with kind words.\n* **Signature:** Add \"Dynamic Product Support\" at the end.\n</output_format>\n</instructions>"
}
},
"id": "4af2d430-db2c-44b0-94f7-8cbe0109e3a5",
"cid": "Ikx1Y2FzIFBleXJpbiI",
"name": "n8n Docs AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"creator": "Lucas Peyrin",
"position": [
1728,
-80
],
"typeVersion": 2.1,
"alwaysOutputData": false,
"executeOnce": false,
"notes": "\u00a9 2025 Lucas Peyrin"
},
{
"parameters": {
"mode": "retrieve-as-tool",
"toolDescription": "Get related chunks of the official Dynamic Product documentation.",
"qdrantCollection": {
"__rl": true,
"value": "dp-docs",
"mode": "list",
"cachedResultName": "dp-docs"
},
"topK": 10,
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.vectorStoreQdrant",
"typeVersion": 1.3,
"position": [
1824,
144
],
"id": "ef5e073e-4973-4616-9b0d-f35d9048ced2",
"name": "Qdrant Vector Store",
"credentials": {
"qdrantApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "={{ $('Extract thread ID').item.json.threadId }}"
},
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"typeVersion": 1.3,
"position": [
1696,
144
],
"id": "a0414d87-1af2-4b71-9f69-837685d4f1e3",
"name": "Simple Memory"
},
{
"parameters": {
"toolDescription": "Makes a HTTP request to get the current IP to be sent to the Customer. The IP will be used to allow the seller to view the shop in maintenance mode.",
"url": "http://ip-api.com/json/unlocomqx.duckdns.org",
"options": {},
"optimizeResponse": true,
"fieldsToInclude": "selected",
"fields": "query"
},
"type": "n8n-nodes-base.httpRequestTool",
"typeVersion": 4.2,
"position": [
2112,
144
],
"id": "c977d523-c246-4c8d-98ab-18442b1e56a8",
"name": "Get Seller current IP",
"notes": "Use this tool to get the current IP of the seller. The IP is useful to allow the seller to view the customer's shop when the shop is in maintenance mode."
},
{
"parameters": {
"mode": "markdownToHtml",
"markdown": "={{ $('n8n Docs AI Agent').item.json.output }}",
"destinationKey": "message",
"options": {}
},
"type": "n8n-nodes-base.markdown",
"typeVersion": 1,
"position": [
2768,
-80
],
"id": "b2afff4d-5389-42ad-89a3-8dae63d10021",
"name": "Markdown"
}
],
"connections": {
"Extract thread ID": {
"main": [
[
{
"node": "Check threadId",
"type": "main",
"index": 0
}
]
]
},
"Set test subject": {
"main": [
[
{
"node": "Only keep Dynamic Product messages",
"type": "main",
"index": 0
}
]
]
},
"Trigger": {
"main": [
[
{
"node": "Set test subject",
"type": "main",
"index": 0
}
]
]
},
"Message Received": {
"main": [
[
{
"node": "Only keep Dynamic Product messages",
"type": "main",
"index": 0
}
]
]
},
"Only keep Dynamic Product messages": {
"main": [
[
{
"node": "Extract thread ID",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Assess if message needs a reply",
"type": "main",
"index": 0
}
]
]
},
"Send message and wait for response": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "Markdown",
"type": "main",
"index": 0
}
]
]
},
"Assess if message needs a reply": {
"main": [
[
{
"node": "Switch1",
"type": "main",
"index": 0
}
]
]
},
"JSON Parser": {
"ai_outputParser": [
[
{
"node": "Assess if message needs a reply",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Switch1": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "n8n Docs AI Agent",
"type": "main",
"index": 0
}
]
]
},
"Check threadId": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Flash": {
"ai_languageModel": [
[
{
"node": "Assess if message needs a reply",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Gemini 2.5 Flash": {
"ai_languageModel": [
[
{
"node": "n8n Docs AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Gemini Query Embedding": {
"ai_embedding": [
[
{
"node": "Qdrant Vector Store",
"type": "ai_embedding",
"index": 0
}
]
]
},
"n8n Docs AI Agent": {
"main": [
[
{
"node": "Send message and wait for response",
"type": "main",
"index": 0
}
]
]
},
"Qdrant Vector Store": {
"ai_tool": [
[
{
"node": "n8n Docs AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "n8n Docs AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Get Seller current IP": {
"ai_tool": [
[
{
"node": "n8n Docs AI Agent",
"type": "ai_tool",
"index": 0
}
]
]
},
"Markdown": {
"main": [
[
{
"node": "Respond to customer",
"type": "main",
"index": 0
}
]
]
}
},
"meta": {
"templateCredsSetupCompleted": true
}
}
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.
discordBotApigmailOAuth2googlePalmApihttpQueryAuthqdrantApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Support-Bot. Uses gmailTrigger, httpRequest, discord, chainLlm. Event-driven trigger; 23 nodes.
Source: https://gist.github.com/unlocomqx/7e814484f8e73b8ea0a426fb8c675bfa — 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.
Alfred (funcional). Uses gmailTool, googleCalendarTool, gmail, embeddingsOpenAi. Event-driven trigger; 83 nodes.
The "WhatsApp Productivity Assistant with Memory and AI Imaging" is a comprehensive n8n workflow that transforms your WhatsApp into a powerful, multi-talented AI assistant. It's designed to handle a w
This simple philosophy changes the way we think about automated sales agents. Context changes everything. In this 4-part workflow, we start by creating a knowledge base that will act as context across
This workflow helps users find the most relevant n8n templates using AI.
Generate Exam Questions. Uses manualTrigger, vectorStoreQdrant, httpRequest, embeddingsOpenAi. Event-driven trigger; 37 nodes.