This workflow corresponds to n8n.io template #5492 — we link there as the canonical source.
This workflow follows the Agent → Gmail 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": "B3xq3cGwsIbeSRGd",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Spare Parts Quote Generator",
"tags": [],
"nodes": [
{
"id": "a2278b8f-037c-4c94-a1cc-d5ab7df7351d",
"name": "Welcome & Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2500,
-600
],
"parameters": {
"color": 5,
"width": 400,
"height": 580,
"content": "# \ud83d\ude80 Automated Quote Generator Workflow\n\n## Overview\nThis workflow automatically:\n1. **Monitors Gmail** for spare parts requests\n2. **Identifies** requests using keyword detection\n3. **Generates** professional HTML quotes using AI\n4. **Replies** automatically with pricing\n\n## Setup Required:\n1. Configure Gmail OAuth2 credentials\n2. Set up Google Sheets with your data\n3. Configure Google Gemini API\n4. Update the sticky notes with your sheet IDs\n\n## Language Support:\nThe AI automatically detects and responds in the sender's language (Turkish, English, German, etc.)"
},
"typeVersion": 1
},
{
"id": "52c6ee3a-5a2f-48b8-8f44-26e58ffed046",
"name": "Google Sheets Structure",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2060,
0
],
"parameters": {
"color": 4,
"width": 400,
"height": 600,
"content": "## \ud83d\udcca Required Google Sheets Structure\n\n### Sheet 1: CRM Data\n**Columns Required:**\n- `Email` - Customer email addresses\n- `ProjectCode` - Project codes\n- `CustomerName` - Customer names\n- Other customer data as needed\n\n### Sheet 2: Bill of Materials (BoM)\n**Columns Required:**\n- `ProjectCode` - Project code\n- `PartCode` - Part code\n- `PartDescription` - Part description\n- `Quantity` - Quantity\n\n### Sheet 3: Pricing Data\n**Columns Required:**\n- `PartCode` - Part code\n- `UnitPriceEUR` - Unit price in EUR\n- `PartDescription` - Part description"
},
"typeVersion": 1
},
{
"id": "6100cf53-becc-46d5-b71b-40949c36db03",
"name": "Configuration Steps",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2060,
-600
],
"parameters": {
"color": 6,
"width": 400,
"height": 580,
"content": "## \u2699\ufe0f Configuration Steps\n\n### 1. Gmail OAuth2\n- Go to Google Cloud Console\n- Create OAuth2 credentials\n- Add Gmail API scopes\n- Configure in n8n Credentials\n\n### 2. Google Sheets OAuth2\n- Use same Google Cloud project\n- Add Sheets API scopes\n- Configure in n8n Credentials\n\n### 3. Google Gemini API\n- Get API key from Google AI Studio\n- Configure in n8n Credentials\n\n### 4. Update Sheet IDs\n- Replace placeholder IDs in:\n - CRM node\n - BoM node\n - Price node"
},
"typeVersion": 1
},
{
"id": "8c96701c-e2b6-4fcb-ba7d-1713f2a20581",
"name": "Keyword Detection Info",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1200,
-500
],
"parameters": {
"color": 3,
"width": 320,
"height": 580,
"content": "## \ud83d\udd0d Keyword Detection\n\nThis node checks for spare parts keywords:\n- **Turkish:** \"yedek par\u00e7a\"\n- **German:** \"Ersatzteile\", \"Ersatzteil\"\n- **English:** \"spare parts\"\n\nAdd more keywords as needed for your use case."
},
"typeVersion": 1
},
{
"id": "529c5508-ecac-458c-aaa4-4ca2a168ab69",
"name": "Email Reply Flow",
"type": "n8n-nodes-base.stickyNote",
"position": [
-160,
-500
],
"parameters": {
"width": 480,
"height": 520,
"content": "## \ud83d\udce7 Email Reply Flow\n\n1. **Gmail node** sends the HTML quote as a reply\n2. **Gmail2 node** marks the original email as read\n\nThis ensures clean inbox management and tracking."
},
"typeVersion": 1
},
{
"id": "9548c3df-9a99-432e-a7eb-caf2ffa7ef87",
"name": "IMPORTANT: Replace Sheet IDs",
"type": "n8n-nodes-base.stickyNote",
"position": [
-840,
320
],
"parameters": {
"color": 7,
"width": 600,
"height": 280,
"content": "## \ud83d\udccb Replace These IDs\n\n**CRM Sheet ID:**\n`YOUR_CRM_SHEET_ID_HERE`\n\n**BoM Sheet ID:**\n`YOUR_BOM_SHEET_ID_HERE`\n\n**Price Sheet ID:**\n`YOUR_PRICE_SHEET_ID_HERE`\n\nFind your Sheet ID in the URL:\n`docs.google.com/spreadsheets/d/[SHEET_ID]/edit`"
},
"typeVersion": 1
},
{
"id": "b8baf40e-d608-4bea-9545-98a8e864812f",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1560,
-100
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 1
}
]
}
},
"typeVersion": 1.2
},
{
"id": "0aae0d92-b5eb-4dee-be35-4af1f80a9d67",
"name": "Gmail - Get Latest Email",
"type": "n8n-nodes-base.gmail",
"position": [
-1360,
-100
],
"parameters": {
"limit": 1,
"filters": {},
"operation": "getAll"
},
"typeVersion": 2.1
},
{
"id": "37e455aa-3869-43de-848d-ef118537b75c",
"name": "Check Spare Parts Keywords",
"type": "n8n-nodes-base.if",
"position": [
-1060,
-100
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"id": "c1d2e3f4-a5b6-7c8d-9e0f-1a2b3c4d5e6f",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.snippet || $json.text || $json.html || '' }}",
"rightValue": "yedek par\u00e7a"
},
{
"id": "0d5115f9-1c10-4c00-a82f-a8a3de8a8152",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.snippet || $json.text || $json.html || '' }}",
"rightValue": "Ersatzteil"
},
{
"id": "91bfaac9-c400-4413-9a8e-a6613add9684",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.snippet || $json.text || $json.html || '' }}",
"rightValue": "spare parts"
},
{
"id": "1bca2708-9b93-4806-b379-1ef7f7b7b62d",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.snippet || $json.text || $json.html || '' }}",
"rightValue": "Ersatzteile"
}
]
}
},
"typeVersion": 2
},
{
"id": "23f8304b-b324-476b-a95b-f94d3bd2a862",
"name": "AI Agent - Quote Generator",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-780,
-240
],
"parameters": {
"text": "=Create a price quote based on the email below. Follow your primary goal and all rules.\n\nSender's Email: {{ $json.To }}\nSubject: {{ $json.Subject }}\nEmail Body: {{ $json.snippet }}\nDate: {{ $('Schedule Trigger').item.json['Readable date'] }}",
"options": {
"maxIterations": 100,
"systemMessage": "**PRIMARY GOAL:** Create a price quote as a complete HTML document, in the EXACT SAME language as the user's email.\n\n**RULES:**\n1. **DETECT LANGUAGE FIRST.** This is your first action.\n2. **RESPOND IN DETECTED LANGUAGE.** All text you generate (greetings, table headers, notes, etc.) MUST be in the detected language.\n3. **OUTPUT MUST BE HTML:** Your final output MUST be a complete HTML document, starting with `<!DOCTYPE html>` and ending with `</html>`. Use the provided HTML template below as a strict guide.\n4. **TOOLS ARE LANGUAGE-AGNOSTIC:** Your tools (`CRM`, `BoM`, `Price`) fetch data from sheets with English column names (`ProjectCode`, `PartCode`). The data itself may be in any language. **DO NOT TRANSLATE THE DATA** like part descriptions. Just display it as is.\n5. **CALCULATE EVERYTHING:** You must calculate sub-totals (Quantity * Unit Price) for each item and a final Grand Total. Do not forget this. Use Calculation Tool for every calculation needed!!\n6. **NO MARKDOWN:** Do not wrap your HTML output in Markdown code blocks like \\`\\`\\`html ... \\`\\`\\` . Your entire response must start DIRECTLY with <!DOCTYPE html>.\n7. **CRITICAL: DOUBLE-CHECK MATH:** You MUST calculate the sub-total for each line item (Quantity * Unit Price). Then, you MUST sum ALL sub-totals to get the final Grand Total. Verify your final sum before outputting the HTML. Mathematical accuracy is mandatory.\n8. **CRUCIAL: If mentioned project or Part code does not exist, do NOT provide any proposal. ONLY ask for the real Project Code or Part code!\n\n**EXECUTION FLOW:**\n1. Find the project code or part codes in the user's email.\n2. Use the `CRM`, `BoM`, and `Price` tools to get all necessary data.\n3. Assemble a complete and professional quote by filling in the placeholders in the HTML template below. The entire response must be this HTML.\n\n**HTML TEMPLATE (Use this structure):**\n\n<!DOCTYPE html>\n<html lang=\"[Language Code: tr, en, de]\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>[Quote Title - E.g.: Price Offer]</title>\n <style>\n body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }\n .container { width: 100%; max-width: 800px; margin: 20px auto; padding: 20px; border: 1px solid #ddd; border-radius: 8px; }\n .header { text-align: left; padding-bottom: 20px; border-bottom: 2px solid #005A9C; }\n .header h1 { color: #005A9C; margin: 0; }\n .quote-table { width: 100%; border-collapse: collapse; margin-top: 20px; }\n .quote-table th, .quote-table td { border: 1px solid #ddd; padding: 12px; text-align: left; }\n .quote-table th { background-color: #f2f2f2; font-weight: bold; }\n .quote-table tr:nth-child(even) { background-color: #f9f9f9; }\n .text-right { text-align: right; }\n .footer { margin-top: 30px; font-size: 0.9em; color: #777; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>[Quote Title]</h1>\n <p><strong>[Date Label]:</strong> {{ $('Schedule Trigger').item.json['Readable date'] }}</p>\n </div>\n\n <p>[Greeting]</p>\n <p>[Introduction paragraph about the quote]</p>\n\n <table class=\"quote-table\">\n <thead>\n <tr>\n <th>[Part Code Column]</th>\n <th>[Description Column]</th>\n <th class=\"text-right\">[Quantity Column]</th>\n <th class=\"text-right\">[Unit Price Column]</th>\n <th class=\"text-right\">[Total Price Column]</th>\n </tr>\n </thead>\n <tbody>\n <!-- REPEAT FOR EACH ITEM -->\n <tr>\n <td>[Part Code]</td>\n <td>[Part Description]</td>\n <td class=\"text-right\">[Quantity]</td>\n <td class=\"text-right\">[Unit Price] \u20ac</td>\n <td class=\"text-right\">[Total Price] \u20ac</td>\n </tr>\n </tbody>\n </table>\n\n <table style=\"width: 100%; margin-top: 20px;\">\n <tr>\n <td style=\"text-align: right; font-weight: bold; font-size: 1.2em;\">\n [Grand Total Label]: [Calculated Grand Total] \u20ac\n </td>\n </tr>\n </table>\n\n <div class=\"footer\">\n <p><strong>[Notes Title]:</strong></p>\n <ul>\n <li>[Validity period note]</li>\n <li>[Delivery time note]</li>\n <li>[Payment terms note]</li>\n </ul>\n <p>[Closing statement]<br>[Your Company Name]</p>\n </div>\n </div>\n</body>\n</html>"
},
"promptType": "define"
},
"typeVersion": 2
},
{
"id": "42c482fc-bfea-460a-aec1-acb8784521ec",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-820,
0
],
"parameters": {
"options": {
"temperature": 0.1,
"maxOutputTokens": 509600
},
"modelName": "models/gemini-2.0-flash-exp"
},
"typeVersion": 1
},
{
"id": "90ce437d-148b-4357-a60b-216386bf895f",
"name": "CRM - Customer Data",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
-600,
140
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "string",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "string",
"value": "YOUR_CRM_SHEET_ID_HERE"
},
"descriptionType": "manual",
"toolDescription": "Fetches customer data. Searches the sheet using a column named `Email` or a column named `ProjectCode`."
},
"typeVersion": 4.6
},
{
"id": "2ec1332d-ab34-481c-b142-16d6843495a2",
"name": "BoM - Bill of Materials",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
-480,
140
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "string",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "string",
"value": "YOUR_BOM_SHEET_ID_HERE"
},
"descriptionType": "manual",
"toolDescription": "Fetches a list of all parts for a given project. Searches the sheet using a column named `ProjectCode`. Input a project ID (e.g., \"PRJ-001\") to this tool."
},
"typeVersion": 4.6
},
{
"id": "91609c5b-55a1-4a9c-bb48-f1a239dd5d0d",
"name": "Price - Pricing Data",
"type": "n8n-nodes-base.googleSheetsTool",
"position": [
-360,
140
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "string",
"value": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "string",
"value": "YOUR_PRICE_SHEET_ID_HERE"
},
"descriptionType": "manual",
"toolDescription": "Fetches the price for a single part. Searches the sheet using a column named `PartCode` and returns the price from the `UnitPriceEUR` column. You must call this for every part."
},
"typeVersion": 4.6
},
{
"id": "a934e309-59d7-4c10-a522-6ef1daea4c08",
"name": "Calculator Tool",
"type": "@n8n/n8n-nodes-langchain.toolCalculator",
"position": [
-720,
160
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a5c22593-8079-4254-b1e3-a977412140b8",
"name": "Gmail - Send Reply",
"type": "n8n-nodes-base.gmail",
"position": [
-100,
-240
],
"parameters": {
"message": "={{ $json.output }}",
"options": {},
"messageId": "={{ $('Gmail - Get Latest Email').item.json.id }}",
"operation": "reply"
},
"typeVersion": 2.1
},
{
"id": "4033dcb4-31d7-403f-9f45-8adf6eeac8ac",
"name": "Gmail - Mark as Read",
"type": "n8n-nodes-base.gmail",
"position": [
120,
-240
],
"parameters": {
"messageId": "={{ $('Gmail - Get Latest Email').item.json.id }}",
"operation": "markAsRead"
},
"typeVersion": 2.1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "34a045ad-4fb3-48bd-b577-ac48959c92cd",
"connections": {
"Calculator Tool": {
"ai_tool": [
[
{
"node": "AI Agent - Quote Generator",
"type": "ai_tool",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Gmail - Get Latest Email",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Send Reply": {
"main": [
[
{
"node": "Gmail - Mark as Read",
"type": "main",
"index": 0
}
]
]
},
"CRM - Customer Data": {
"ai_tool": [
[
{
"node": "AI Agent - Quote Generator",
"type": "ai_tool",
"index": 0
}
]
]
},
"Price - Pricing Data": {
"ai_tool": [
[
{
"node": "AI Agent - Quote Generator",
"type": "ai_tool",
"index": 0
}
]
]
},
"BoM - Bill of Materials": {
"ai_tool": [
[
{
"node": "AI Agent - Quote Generator",
"type": "ai_tool",
"index": 0
}
]
]
},
"Gmail - Get Latest Email": {
"main": [
[
{
"node": "Check Spare Parts Keywords",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent - Quote Generator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"AI Agent - Quote Generator": {
"main": [
[
{
"node": "Gmail - Send Reply",
"type": "main",
"index": 0
}
]
]
},
"Check Spare Parts Keywords": {
"main": [
[
{
"node": "AI Agent - Quote Generator",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is perfect for sales teams, customer service departments, and businesses that frequently handle spare parts inquiries via email. It's especially valuable for companies managing multiple products with complex pricing structures who want to automate their quotation…
Source: https://n8n.io/workflows/5492/ — 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 implements an AI-powered WhatsApp booking assistant for a hair salon. The system allows customers to book, reschedule, or cancel appointments automatically via text or voice messages on
kisisel asistan. Uses toolWorkflow, toolHttpRequest, toolCalculator, toolThink. Scheduled trigger; 43 nodes.
This workflow automates end-to-end ESG (Environmental, Social, and Governance) sustainability reporting for enterprise sustainability teams, compliance officers, and green governance leads. It solves
This n8n workflow automates email triage and FAQ responses using Google Sheets and Gemini AI. It’s designed to: Automatically sort incoming emails into categories (e.g., FAQ, Billing, Tech Support). D
This workflow is perfect for individuals who want to maintain detailed financial records without the overhead of complex budgeting apps. If you prefer natural language over data entry forms and want a