{ "id": "7Pw91QNT4UGeNmL5", "meta": { "instanceId": "workflow-3f366611", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:45.546025", "updatedAt": "2025-09-29T07:07:45.546042", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "name": "Customer and Sales Support", "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "nodes": [ { "id": "trigger-8b53c26a", "name": "Manual Trigger", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ 100, 100 ], "parameters": {} }, { "id": "99d711a1-2341-493b-ba56-e40e76e07d97", "name": "When chat message received", "type": "n8n-nodes-base.noOp", "position": [ -360, -120 ], "webhookId": "1de1a4dd-cea5-4c95-b489-6004601ff727", "parameters": { "public": true, "options": { "responseMode": "lastNode", "loadPreviousSession": "memory" }, "initialMessages": "Hi! I’m Babish from Apple Case. How can I help?”" }, "typeVersion": 1.1, "notes": "This chatTrigger node performs automated tasks as part of the workflow." }, { "id": "ab809cbb-0456-4a6f-b078-8a6f7bdbd4d0", "name": "OpenAI Chat Model", "type": "n8n-nodes-base.noOp", "position": [ 60, 260 ], "parameters": { "model": { "__rl": true, "mode": "list", "value": "gpt-4.1", "cachedResultName": "gpt-4.1" }, "options": { "maxTokens": "YOUR_TOKEN_HERE", "temperature": 0.3 } }, "credentials": { "openAiApi": { "id": "zqONgMf7CM0LERga", "name": "OpenAi DPL 2" } }, "typeVersion": 1.2, "notes": "This lmChatOpenAi node performs automated tasks as part of the workflow." }, { "id": "e74bc18b-3058-4658-83fd-85f9a45d3537", "name": "Simple Memory", "type": "n8n-nodes-base.noOp", "position": [ -220, 240 ], "parameters": {}, "typeVersion": 1.3, "notes": "This memoryBufferWindow node performs automated tasks as part of the workflow." }, { "id": "008d806b-e56d-4c37-b64d-2eb6792eefb5", "name": "Place order", "type": "n8n-nodes-base.googleSheetsTool", "position": [ 540, 240 ], "parameters": { "columns": { "value": { "Address": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Address', ``, 'string') }}", "Case ID": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Case_ID', ``, 'string') }}", "Quantity": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Quantity', ``, 'string') }}", "Case Name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Case_Name', ``, 'string') }}", "Timestamp": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Timestamp', ``, 'string') }}", "Phone Model": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Phone_Model', ``, 'string') }}", "Phone Number": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Phone_Number', ``, 'string') }}", "Customer Name": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Customer_Name', ``, 'string') }}" }, "schema": [ { "id": "Timestamp", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Timestamp", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Case ID", "type": "string", "display": true, "required": false, "displayName": "Case ID", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Case Name", "type": "string", "display": true, "required": false, "displayName": "Case Name", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Phone Model", "type": "string", "display": true, "required": false, "displayName": "Phone Model", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Customer Name", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Customer Name", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Phone Number", "type": "string", "display": true, "required": false, "displayName": "Phone Number", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Address", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Address", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Quantity", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Quantity", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": false }, "options": {}, "operation": "append", "sheetName": { "__rl": true, "mode": "list", "value": 622166849, "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Order placed" }, "documentId": { "__rl": true, "mode": "list", "value": "1btXGPudVDrG64coe5mIlw0Nd8r6YzOnNQ3wp7OVUffc", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Apple Case Stock" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "r16nFPNT77oA4BPq", "name": "Google Sheets account" } }, "typeVersion": 4.5, "notes": "This googleSheetsTool node performs automated tasks as part of the workflow." }, { "id": "9f1d892a-ad76-47ce-815f-1a7cc7a46cf8", "name": "Update Stock", "type": "n8n-nodes-base.googleSheetsTool", "position": [ 660, 240 ], "parameters": { "columns": { "value": { "Sold": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sold', ``, 'string') }}", "Case ID": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Case_ID__using_to_match_', ``, 'string') }}", "Updated ISO": "={{ $now.toISO() }}", "Quantity Available": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Quantity_Available', ``, 'string') }}" }, "schema": [ { "id": "Case ID", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Case ID", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Phone Model", "type": "string", "display": true, "removed": true, "required": false, "displayName": "Phone Model", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Case Name", "type": "string", "display": true, "removed": true, "required": false, "displayName": "Case Name", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Case Type", "type": "string", "display": true, "removed": true, "required": false, "displayName": "Case Type", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Quantity Available", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Quantity Available", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Initial Inventory,", "type": "string", "display": true, "removed": true, "required": false, "displayName": "Initial Inventory,", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Sold", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Sold", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "Updated ISO", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Updated ISO", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "row_number", "type": "string", "display": true, "removed": true, "readOnly": true, "required": false, "displayName": "row_number", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [ "Case ID" ], "attemptToConvertTypes": false, "convertFieldsToString": false }, "options": {}, "operation": "update", "sheetName": { "__rl": true, "mode": "list", "value": 2019723207, "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Inventory" }, "documentId": { "__rl": true, "mode": "list", "value": "1btXGPudVDrG64coe5mIlw0Nd8r6YzOnNQ3wp7OVUffc", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Apple Case Stock" } }, "credentials": { "googleSheetsOAuth2Api": { "id": "r16nFPNT77oA4BPq", "name": "Google Sheets account" } }, "typeVersion": 4.5, "notes": "This googleSheetsTool node performs automated tasks as part of the workflow." }, { "id": "7f0e6e31-6bdb-4901-9c07-4fb6fa4734f0", "name": "Support Agent", "type": "n8n-nodes-base.noOp", "position": [ 120, -120 ], "parameters": { "options": { "systemMessage": "=SYSTEM\nYou are the customer-support agent for “My Apple Case”.\n\nTOOLS\n• GetStock { \"phone_model\": string }\n • Returns: [{ \"case_id\": int, \"case_name\": string,\n \"quantity_available\": int, \"sold\": int,\n \"image_url\": string, ... }]\n• PlaceOrder { \"case_id\": int,\n \"case_name\": string,\n \"phone_model\": string,\n \"customer_name\": string,\n \"phone_number\": string,\n \"address\": string,\n \"quantity\": int }\n• UpdateStock { \"case_id\": int,\n \"quantity_sold\": int,\n \"quantity_available\": int,\n \"sold\": int }\n• The \"case_id\" you send to PlaceOrder or UpdateStock must be the one that\n appears **in the same row as the chosen case_name** from the latest\n GetStock response. Do not invent or modify it.\nRULES\n1. Begin every user-visible reply with: **Welcome to My Apple Case.**\n2. Speak English or Roman-Nepali, matching the customer.\n3. ONE tool call per turn. \n4. If GetStock returns an **image_url**, embed it after the text line using\n Markdown: \n `![]()`\n5. Legal case_ids set\n • The only valid case_id values are the ones you just received from\n GetStock in this conversation turn.\n6. Guard clause\n • If you do not have a valid case_id for the customer’s chosen case,\n ask follow-up questions or run GetStock again. DO NOT guess.\n7.Picking the correct case_id\n a. After GetStock returns, keep its rows in memory.\n b. When the customer names a case_name you just showed, locate the row\n whose case_name matches **exactly** (case-insensitive) and copy that\n row’s case_id.\n c. If more than one row shares the same case_name, ask which “Option #”\n or show a numbered list so they can pick. Never guess.\n\nWORKFLOW\na. If you don’t yet know stock data, call **GetStock** with the phone model. \nb. From GetStock output read:\n qa = quantity_available\n sold = sold\n img = image_url \n • Show the case_id, case_name, qa and (if img exists) the image. \nc. If qa < requested quantity → apologize, no PlaceOrder. \nd. Determine the correct case_id:\n • EXACT match: one row → use that row’s case_id.\n • Multiple matches: show a numbered list and ask the customer to\n choose (e.g. “Type 1 or 2”). Run no tools until they choose.\n Then call PlaceOrder using that exact case_id.\ne. Else collect missing customer fields → call **PlaceOrder**. \nf. After PlaceOrder succeeds, compute:\n qa_new = qa - quantity\n sold_new = sold + quantity\n then call **UpdateStock** with:\n { \"case_id\": ..., \"quantity_sold\": quantity,\n \"quantity_available\": qa_new, \"sold\": sold_new }\ng. After UpdateStock returns, thank the customer and show qa_new.\n\nEXAMPLES\n### Check stock with image\nUser: iPhone 12 ko cover cha? \nAssistant → tool: \n{ \"tool\": \"GetStock\", \"args\": { \"phone_model\": \"iPhone 12\" } }\n\n(GetStock output example) \n[\n {\n \"case_id\": 312,\n \"case_name\": \"Clear MagSafe Case\",\n \"quantity_available\": 25,\n \"sold\": 75,\n \"image_url\": \"{{ $env.WEBHOOK_URL }}\"\n }\n]\n\n### Two rows same name\n(GetStock output)\n1. case_id 101 \"Leather Flip\" qty 3\n2. case_id 202 \"Leather Flip\" qty 10\n\nUser: I want the Leather Flip case.\nAssistant: Welcome to My Apple Case. I have two “Leather Flip” options:\n(1) case_id 101 – 3 in stock\n(2) case_id 202 – 10 in stock\nWhich one would you like? Please reply 1 or 2.\n\nMy Apple Case ma swagatam. **Clear MagSafe Case** – 25 stock cha. \n![Clear MagSafe Case]({{ $env.WEBHOOK_URL }}\n", "returnIntermediateSteps": true } }, "retryOnFail": true, "typeVersion": 1.8, "notes": "This agent node performs automated tasks as part of the workflow." }, { "id": "03153a59-4971-49db-86c2-5fd245b36d28", "name": "GetStock", "type": "n8n-nodes-base.googleSheetsTool", "position": [ 400, 240 ], "parameters": { "options": {}, "filtersUI": { "values": [ { "lookupValue": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Value', ``, 'string') }}", "lookupColumn": "Phone Model" } ] }, "sheetName": { "__rl": true, "mode": "list", "value": 2019723207, "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Inventory" }, "documentId": { "__rl": true, "mode": "list", "value": "1btXGPudVDrG64coe5mIlw0Nd8r6YzOnNQ3wp7OVUffc", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "Apple Case Stock" }, "combineFilters": "OR" }, "credentials": { "googleSheetsOAuth2Api": { "id": "r16nFPNT77oA4BPq", "name": "Google Sheets account" } }, "typeVersion": 4.5, "notes": "This googleSheetsTool node performs automated tasks as part of the workflow." }, { "id": "error-b105595a", "name": "Error Handler", "type": "n8n-nodes-base.stopAndError", "typeVersion": 1, "position": [ 1000, 400 ], "parameters": { "message": "Workflow execution error", "options": {} } } ], "active": false, "pinData": {}, "settings": { "executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000 }, "versionId": "6f49665c-583f-456e-9ea9-bb95b172cac1", "connections": { "ab809cbb-0456-4a6f-b078-8a6f7bdbd4d0": { "main": [ [ { "node": "error-handler-ab809cbb-0456-4a6f-b078-8a6f7bdbd4d0-0241fb38", "type": "main", "index": 0 } ] ] }, "008d806b-e56d-4c37-b64d-2eb6792eefb5": { "main": [ [ { "node": "error-handler-008d806b-e56d-4c37-b64d-2eb6792eefb5-81922d15", "type": "main", "index": 0 } ] ] }, "9f1d892a-ad76-47ce-815f-1a7cc7a46cf8": { "main": [ [ { "node": "error-handler-9f1d892a-ad76-47ce-815f-1a7cc7a46cf8-b238cedc", "type": "main", "index": 0 } ] ] }, "03153a59-4971-49db-86c2-5fd245b36d28": { "main": [ [ { "node": "error-handler-03153a59-4971-49db-86c2-5fd245b36d28-3c627b01", "type": "main", "index": 0 } ] ] } }, "description": "Automated workflow: Customer and Sales Support. This workflow processes data and performs automated tasks.", "notes": "Excellent quality workflow: Customer and Sales Support. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }