{
  "id": "iL5oeTgdrcA1avtP",
  "name": "AI Customer Support Email Agent with Gmail and Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "a34946c2-efe9-4c43-af40-571ec70da65e",
      "name": "Receive Customer Emails",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        160,
        208
      ],
      "parameters": {
        "simple": false,
        "filters": {},
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "8e95a8dd-eb83-4d0c-8daf-dde14f34afed",
      "name": "Filter Unwanted Emails",
      "type": "n8n-nodes-base.if",
      "position": [
        368,
        208
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond1",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.from.value[0].address }}",
              "rightValue": "user@example.com"
            },
            {
              "id": "c1",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.from.value[0].address }}",
              "rightValue": "noreply"
            },
            {
              "id": "c2",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.from.value[0].address }}",
              "rightValue": "no-reply"
            },
            {
              "id": "c3",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.from.value[0].address }}",
              "rightValue": "mailer-daemon"
            },
            {
              "id": "c4",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "out of office"
            },
            {
              "id": "c5",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "auto-reply"
            },
            {
              "id": "c6",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "automatic reply"
            },
            {
              "id": "c7",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "delivery notification"
            },
            {
              "id": "c8",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "undeliverable"
            },
            {
              "id": "c9",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "newsletter"
            },
            {
              "id": "c10",
              "operator": {
                "type": "string",
                "operation": "notContains"
              },
              "leftValue": "={{ $json.subject }}",
              "rightValue": "unsubscribe"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "05bc6007-08b2-4a16-838f-c1e40697bf9e",
      "name": "Draft AI Reply",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        624,
        192
      ],
      "parameters": {
        "text": "=From: {{ $('Receive Customer Emails').item.json.from }}\nSubject: {{ $('Receive Customer Emails').item.json.subject }}\n\n{{ $('Receive Customer Emails').item.json.text }}",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "message": "You are a support agent for Your Company Name Here\n\n## Company Documentation\nWe offer a 12-month warranty.\nCopy/paste your customer support info here.\n\n## Instructions\n- Read the customer's email carefully.\n- Identify their question or issue.\n- Draft a clear, helpful, professional reply that directly answers their question using the documentation above.\n- Do not make up information not in the documentation. If you don't know, say so politely and offer to escalate.\n- Sign off as \"Support Team\".\n- Output ONLY the email body text, no subject line."
            }
          ]
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "cbdf0ba9-5736-409c-9db1-16967f83def4",
      "name": "OpenRouter Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        624,
        400
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9a2050f3-3f2f-45e2-98a1-e09f80b483d5",
      "name": "Mark Email as Read",
      "type": "n8n-nodes-base.gmail",
      "position": [
        976,
        192
      ],
      "parameters": {
        "messageId": "={{ $('Receive Customer Emails').item.json.id }}",
        "operation": "markAsRead"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "74dcc027-fcdd-4f1e-9774-8ac3d751aca5",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1200,
        192
      ],
      "parameters": {
        "columns": {
          "value": {
            "Body": "={{ $('Receive Customer Emails').item.json.text }}",
            "From": "={{ $('Receive Customer Emails').item.json.from.value[0].address }}",
            "Reply": "={{ $('Draft AI Reply').item.json.text }}",
            "Subject": "={{ $('Receive Customer Emails').item.json.subject }}",
            "Message ID": "={{ $('Receive Customer Emails').item.json.id }}"
          },
          "schema": [
            {
              "id": "Message ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Message ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "From",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "From",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subject",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Body",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reply",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Reply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Send",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Send",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1P_loYpUly294lsvmBfJcMZJfMWX7kDWXnKwmUp1EKTc/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo/edit?usp=drivesdk",
          "cachedResultName": "Customer Support Emails"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "cd0b7884-435f-4a5b-98a5-9f7128924875",
      "name": "Check Pending Replies",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        176,
        736
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 1
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "dccb0769-54fe-4548-9051-413f90847f3d",
      "name": "Get Approved Replies",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        400,
        736
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "send",
              "lookupColumn": "Send"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo/edit?usp=drivesdk",
          "cachedResultName": "Customer Support Emails"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "d6c2381a-b6fe-4805-9db7-782594e84847",
      "name": "Send Reply to Customer",
      "type": "n8n-nodes-base.gmail",
      "position": [
        896,
        720
      ],
      "parameters": {
        "sendTo": "={{ $json.From }}",
        "message": "={{ $json.Reply.replace(/\\n/g, '<br>') }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Re: {{ $json.Subject }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "57e91e89-f103-4546-a250-c5221254e1d2",
      "name": "Update Status to Replied",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1168,
        720
      ],
      "parameters": {
        "columns": {
          "value": {
            "Send": "Replied",
            "Message ID": "={{ $('Is Approved to Send?').item.json['Message ID'] }}"
          },
          "schema": [
            {
              "id": "Message ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Message ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "From",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "From",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subject",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Subject",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Body",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Body",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reply",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Reply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Send",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Send",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Message ID"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1P_loYpUly294lsvmBfJcMZJfMWX7kDWXnKwmUp1EKTc/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Behqx-A6IROp22XJ92DDoDUP4SOEl6JZIq4OpnBWsBo/edit?usp=drivesdk",
          "cachedResultName": "Customer Support Emails"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "134d964e-705b-41d3-af41-9dca6852f59b",
      "name": "Is Approved to Send?",
      "type": "n8n-nodes-base.if",
      "position": [
        640,
        736
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "c1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Send }}",
              "rightValue": "send"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "3da05e07-7a32-48db-8a4f-42ea5f936ce4",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -784,
        -32
      ],
      "parameters": {
        "color": 5,
        "width": 796,
        "height": 1184,
        "content": "## \ud83d\udce7 AI Customer Support Email Agent\n\n**Automatically draft AI-powered replies to customer emails, let your team review them in Google Sheets, and send with a single word - keeping a human in the loop.**\n\n---\n\n### Who is this for\n- Small business owners handling customer support manually\n- Support teams that want AI assistance without losing human oversight\n- Freelancers and agencies managing client email inquiries\n\n---\n\n### How it works\n1. **Gmail** is monitored every minute for new incoming emails\n2. **Smart filtering** skips automated emails, newsletters, noreply senders, and out-of-office replies\n3. **AI (via OpenRouter)** drafts a reply using your company documentation as context\n4. The email and draft reply are **logged to Google Sheets** for review\n5. Your team **reviews the draft** - type \"send\" in the Send column to approve\n6. Every minute, the workflow **detects approved rows** and sends the reply via Gmail\n7. The row is **updated to \"Replied\"** to prevent duplicate sends\n\n---\n\n### Knowledge base\nYour company documentation is embedded **directly in the AI system prompt** - no vector database, no RAG pipeline, no extra infrastructure.\n\n**Advantages:**\n- Zero-setup knowledge base - paste your docs and go\n- Works with any OpenRouter model out of the box\n- Instant updates - edit the prompt, changes apply immediately\n- No hallucinations beyond what's in the prompt (the AI is instructed to escalate if unsure)\n\n**Practical limits:**\n- Up to ~10 pages (~3,000 words) works reliably with any model\n- Up to 50+ pages with large-context models (GPT-4 Turbo, Claude 3.5 Sonnet, Llama 3.1 70B and newer versions)\n- Beyond that, consider a RAG-based approach with a vector store\n\n---\n\n### Setup\n1. **Gmail** - Connect your Gmail OAuth2 account to the Receive Customer Emails, Mark Email as Read, and Send Reply to Customer nodes\n2. **OpenRouter** - Add your OpenRouter API key to the OpenRouter Model node\n3. **Google Sheets** - Connect your Google Sheets OAuth2 account to all sheet nodes; create a sheet with columns: Message ID, From, Subject, Body, Reply, Send\n4. In the **Draft AI Reply** node, update the system prompt with your own company documentation and business name\n5. In the **Filter Unwanted Emails** node, update the first condition to exclude your own email address\n6. Activate the workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "1e210314-18c0-4c9c-a03b-0e84dc06b34c",
      "name": "Section - Email Intake",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        64
      ],
      "parameters": {
        "color": 5,
        "width": 1380,
        "height": 476,
        "content": "## \u2460 Email Intake & AI Draft\nReceives incoming emails, filters noise, drafts AI replies, and logs everything to Google Sheets for review."
      },
      "typeVersion": 1
    },
    {
      "id": "680b871c-35de-4191-b6e9-d5fb8168c947",
      "name": "Section - Review and Send",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        624
      ],
      "parameters": {
        "color": 0,
        "width": 1320,
        "height": 268,
        "content": "## \u2461 Review & Send Approved Replies\nChecks Google Sheets every minute for rows marked \"send\" and delivers the approved reply to the customer."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "b567fb26-b0d4-4ddb-8df2-dfeb1b4e3ae4",
  "connections": {
    "Draft AI Reply": {
      "main": [
        [
          {
            "node": "Mark Email as Read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Model": {
      "ai_languageModel": [
        [
          {
            "node": "Draft AI Reply",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Mark Email as Read": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Approved Replies": {
      "main": [
        [
          {
            "node": "Is Approved to Send?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Approved to Send?": {
      "main": [
        [
          {
            "node": "Send Reply to Customer",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Check Pending Replies": {
      "main": [
        [
          {
            "node": "Get Approved Replies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Unwanted Emails": {
      "main": [
        [
          {
            "node": "Draft AI Reply",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Send Reply to Customer": {
      "main": [
        [
          {
            "node": "Update Status to Replied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Customer Emails": {
      "main": [
        [
          {
            "node": "Filter Unwanted Emails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}