AutomationFlowsEmail & Gmail › Track Email Expenses From Gmail with Openai, Google Sheets, and Slack Alerts

Track Email Expenses From Gmail with Openai, Google Sheets, and Slack Alerts

ByWeblineIndia @weblineindia on n8n.io

This workflow monitors Gmail for invoice or receipt emails, uses OpenAI to extract an expense amount and category, logs the result to Google Sheets, and sends a Slack alert when an expense exceeds a defined threshold. Triggers every minute when a new email arrives in Gmail.…

Event trigger★★★★☆ complexityAI-powered17 nodesGmail TriggerOpenAIGoogle SheetsSlack
Email & Gmail Trigger: Event Nodes: 17 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Gmail Trigger → Google Sheets 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": "BqWjVPmA2OAX5kn5",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Expense Tracker",
  "tags": [],
  "nodes": [
    {
      "id": "40e6ae7e-c1d9-4498-bb86-571b4bba4291",
      "name": "Extract Email Data",
      "type": "n8n-nodes-base.set",
      "position": [
        432,
        -48
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"sender\": \"{{$json.From.match(/<(.+)>/)[1]}}\",\n  \"subject\": \"{{$json.Subject}}\",\n  \"date\": \"{{$json.internalDate}}\",\n  \"body\": \"{{$json.snippet}}\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "beb36ede-d12d-42ec-b7f4-a0b0ea586791",
      "name": "Parse AI Output",
      "type": "n8n-nodes-base.set",
      "position": [
        1232,
        -112
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"amount\": {{ JSON.parse($json.output[0].content[0].text.replace(/```json|```/g, '')).amount }},\n  \"category\": {{ JSON.parse($json.output[0].content[0].text.replace(/```json|```/g, '')).category }}\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "3565ba02-2c70-41c6-bd17-c5b667127b81",
      "name": "Check High Expense",
      "type": "n8n-nodes-base.if",
      "position": [
        2576,
        -48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b83bd06e-2e2e-4ebd-af99-e34af531e771",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json[\"Amount \"] }}",
              "rightValue": 5000
            }
          ]
        },
        "looseTypeValidation": "={{ true }}"
      },
      "typeVersion": 2.3
    },
    {
      "id": "e1732f60-f919-4f81-bad8-d766d6083007",
      "name": "Email Listener (Gmail Trigger)",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        0,
        -48
      ],
      "parameters": {
        "filters": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "e8e13a9a-c5cf-4099-9fd9-196c57c0772b",
      "name": "AI Expense Extractor",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        880,
        -128
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "GPT-4.1-MINI"
        },
        "options": {},
        "responses": {
          "values": [
            {
              "content": "=Extract the expense amount and category from this email:\n\n{{$json.body}}\n\nIMPORTANT:\n- Return ONLY pure JSON\n- Do NOT add text or explanation\n- Do NOT use markdown\n\nFormat:\n{\n  \"amount\": number,\n  \"category\": \"Software | Food | Travel | Office | Other\"\n}"
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.1
    },
    {
      "id": "33a5a78b-b94c-4850-8d22-501416791cb4",
      "name": "Merge Email + AI Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        1456,
        112
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "01d07645-dbe7-4f88-944b-50e107bce126",
      "name": "Format Expense Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        -48
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"sender\": \"{{$json.sender}}\",\n  \"subject\": \"{{$json.subject}}\",\n  \"date\": \"{{ new Date(Number($json.date)).toISOString().split('T')[0] }}\",\n  \"amount\": {{$json.amount}},\n  \"category\": \"{{$json.category}}\"\n\"status\": {{$json.amount > 5000 ? '\"High\"' : '\"Normal\"'}}\n\"priority\": {{$json.amount > 10000 ? '\"Critical\"' : ($json.amount > 5000 ? '\"Medium\"' : '\"Low\"')}}\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "759b0abc-bb93-4493-ba8f-dedf7e2c3086",
      "name": "Save to Expense Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2352,
        -48
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $('Format Expense Data').item.json.date }}",
            "Amount ": "={{ $('Format Expense Data').item.json.amount }}",
            "Sender ": "={{ $('Format Expense Data').item.json.sender }}",
            "Category": "={{ $('Format Expense Data').item.json.category }}",
            "Subject ": "={{ $('Format Expense Data').item.json.subject }}"
          },
          "schema": [
            {
              "id": "Sender ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Sender ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Subject ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Subject ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Amount ",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Amount ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category",
              "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/1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0/edit?usp=drivesdk",
          "cachedResultName": "Expenses"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "49ac0405-6d71-4f56-9889-af492bf5a46a",
      "name": "Slack Alert (High Expense)",
      "type": "n8n-nodes-base.slack",
      "position": [
        2800,
        -48
      ],
      "parameters": {
        "text": "= *High Expense Alert*\n\n *Amount:* \u20b9{{ $json[\"Amount \"] }}\n *Category:* {{ $json.Category }}\n *Sender:* {{ $json[\"Sender \"] }}\n *Date:* {{ $json.Date }}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0AQJMZQT4G",
          "cachedResultName": "all-expensetracker"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "311b7f7f-399b-472f-9140-eaaf2e279e73",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        -704
      ],
      "parameters": {
        "width": 528,
        "height": 528,
        "content": "## Smart Expense Tracker Automation\n\n### How it works:\nThis workflow monitors incoming emails in Gmail and identifies messages containing keywords such as \"Invoice\" or \"Receipt\". It extracts key details like sender, subject, date, and email content. The content is processed using an AI model to extract the expense amount and categorize it into Software, Food, Travel, Office, or Other. The processed data is then stored in Google Sheets. If the amount exceeds 5000, a Slack alert is triggered for real-time notification.\n\n### Setup:\n1. Connect Gmail OAuth2 credentials\n2. Configure OpenAI API key\n3. Connect Google Sheets (service account)\n4. Setup Slack bot and invite it to the channel"
      },
      "typeVersion": 1
    },
    {
      "id": "8250d664-2086-4dd5-ad0b-091ce9f4b49e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 912,
        "height": 432,
        "content": "## Email Processing\nCaptures incoming emails and filters relevant messages. Extracts sender, subject, date, and email content for further processing."
      },
      "typeVersion": 1
    },
    {
      "id": "e91bfc83-e2bb-43ad-8239-a817f93b0f65",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 992,
        "height": 544,
        "content": "## AI Processing\nAnalyzes email content to extract expense amount and category. Merges AI output with email data to create structured information."
      },
      "typeVersion": 1
    },
    {
      "id": "d32adfcf-c570-4b32-a7a9-7d2ce005c6c5",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1840,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 1152,
        "height": 544,
        "content": "## Storage & Alerting\nStores processed data in Google Sheets and triggers Slack alerts for high-value expenses based on defined conditions."
      },
      "typeVersion": 1
    },
    {
      "id": "d105252e-f0eb-4193-a035-c6a53fe7fa23",
      "name": "Filter Invoice/Receipt Emails",
      "type": "n8n-nodes-base.if",
      "position": [
        208,
        -48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "4a30230b-0aa5-4198-ad80-0bd0fd8b80ff",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Subject }}",
              "rightValue": "Invoice"
            },
            {
              "id": "acd15fa5-0368-4c19-951d-1ad7032e112c",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.Subject }}",
              "rightValue": "Receipt"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "0b70afe5-9b32-41a7-9cb7-c65af739a157",
      "name": "Validate Email Content",
      "type": "n8n-nodes-base.if",
      "position": [
        656,
        -112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "11dbe670-1157-447e-974b-b99dd166a4de",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{$json.body.length}}",
              "rightValue": 10
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "a4f3218b-79b4-47ff-937e-ae68f8ddfa19",
      "name": "Filter Duplicate Records",
      "type": "n8n-nodes-base.if",
      "position": [
        2080,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1a9096d6-9a5d-47af-a074-b554217b994e",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{Object.keys($json).length}}",
              "rightValue": 0
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "9b4695cd-8d19-4fde-a9cd-572b28868be0",
      "name": "Lookup Expense (Google Sheets)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1888,
        -32
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.subject }}",
              "lookupColumn": "Subject "
            },
            {
              "lookupValue": "={{ $json.date }}",
              "lookupColumn": "Date"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1RPXuajYVJ3sNCRM8ai4rR_aGVNRwh3xppW-w050_Zr0/edit?usp=drivesdk",
          "cachedResultName": "Expenses"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "b46a6c34-e7de-4b38-a323-39af970965d6",
  "connections": {
    "Parse AI Output": {
      "main": [
        [
          {
            "node": "Merge Email + AI Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Check High Expense": {
      "main": [
        [
          {
            "node": "Slack Alert (High Expense)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Email Data": {
      "main": [
        [
          {
            "node": "Merge Email + AI Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "Validate Email Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Expense Data": {
      "main": [
        [
          {
            "node": "Lookup Expense (Google Sheets)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Expense Extractor": {
      "main": [
        [
          {
            "node": "Parse AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Email + AI Data": {
      "main": [
        [
          {
            "node": "Format Expense Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save to Expense Sheet": {
      "main": [
        [
          {
            "node": "Check High Expense",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Email Content": {
      "main": [
        [
          {
            "node": "AI Expense Extractor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Duplicate Records": {
      "main": [
        [
          {
            "node": "Save to Expense Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Invoice/Receipt Emails": {
      "main": [
        [
          {
            "node": "Extract Email Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Listener (Gmail Trigger)": {
      "main": [
        [
          {
            "node": "Filter Invoice/Receipt Emails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Expense (Google Sheets)": {
      "main": [
        [
          {
            "node": "Filter Duplicate Records",
            "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 monitors Gmail for invoice or receipt emails, uses OpenAI to extract an expense amount and category, logs the result to Google Sheets, and sends a Slack alert when an expense exceeds a defined threshold. Triggers every minute when a new email arrives in Gmail.…

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

More Email & Gmail workflows → · Browse all categories →

Related workflows

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

Email & Gmail

Transform your Google Form into an intelligent customer support system that automatically analyzes, prioritizes, and responds to every inquiry with AI-powered personalization.

Google Sheets Trigger, OpenAI, Gmail +2
Email & Gmail

Support Ticket Triage. Uses gmailTrigger, googleSheets, slack, gmail. Event-driven trigger; 9 nodes.

Gmail Trigger, Google Sheets, Slack +3
Email & Gmail

Receive any business document via email. The attachment is automatically classified (Invoice, Contract, or Purchase Order) using easybits Extractor, then routed down the correct path where a second Ex

@Easybits/N8N Nodes Extractor, Gmail Trigger, Google Drive +2
Email & Gmail

Automatically convert Gmail emails and Slack messages into Zendesk support tickets with intelligent priority detection, comprehensive Google Sheets tracking, and real-time team notifications. Streamli

Slack Trigger, Zendesk, Slack +2
Email & Gmail

📘 Description

HTTP Request, Gmail Trigger, ClickUp +3