AutomationFlowsEmail & Gmail › Track and Analyze Google Sheets Expenses with Gemini and Gmail Alerts

Track and Analyze Google Sheets Expenses with Gemini and Gmail Alerts

ByWeblineIndia @weblineindia on n8n.io

Smart Expense Monitoring in Minutes

Event trigger★★★★☆ complexityAI-powered17 nodesGoogle SheetsGoogle GeminiGmail
Email & Gmail Trigger: Event Nodes: 17 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Gmail → Googlegemini 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": "CAUI5X0Bf5z2nnQx",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Expense Analyser",
  "tags": [],
  "nodes": [
    {
      "id": "0745df76-72dc-4a75-ad35-17ce63c3027b",
      "name": "Overview \u2014 Read This First",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1552,
        -448
      ],
      "parameters": {
        "width": 660,
        "height": 380,
        "content": "## Expense Analyser\n\n## How it works\nReads expense rows from Sheet1, cleans and categorises each row by keyword (Zomato, Uber, Netflix, etc.), summarises total spend per category, sends each to Gemini for a detailed financial advisory report, saves results to Sheet2 and emails an alert \u2014 High Expense or Normal Summary \u2014 based on a configurable threshold.\n\n## Setup steps\n1. Connect your Google Sheets OAuth2 credential\n2. Add your Google Gemini API key\n3. Add your Gmail OAuth2 credential\n4. In the Settings node, set your budget threshold, recipient email and sender name\n5. Confirm Sheet1 has columns: Date, Description, Amount\n6. Confirm Sheet2 has headers: Date, Category, Total Spent, AI Report, Status, Reviewed On"
      },
      "typeVersion": 1
    },
    {
      "id": "d87b419d-9625-40fc-9ef1-a028bb23f34e",
      "name": "Group \u2014 Data Ingestion",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1344,
        128
      ],
      "parameters": {
        "color": 7,
        "width": 780,
        "height": 364,
        "content": "## Data Ingestion\nFetches raw rows from Sheet1. Settings node holds all configurable values. Clean and Categorise assigns a category per row by matching keywords in the Description column. Summarise adds up totals per category."
      },
      "typeVersion": 1
    },
    {
      "id": "8620c0b1-c772-49b1-a2c2-cf5d1b38335b",
      "name": "Group \u2014 AI Analysis and Sheet Output",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        64
      ],
      "parameters": {
        "color": 7,
        "width": 824,
        "height": 396,
        "content": "## AI Analysis and Output\nBuild AI Prompt Fields prepares category, amount and status for the prompt. Gemini generates a full advisory report per category. Collect Report Fields gathers everything needed before writing to Sheet2."
      },
      "typeVersion": 1
    },
    {
      "id": "b34a0d72-3645-483a-ad06-1eeb8c7eedd0",
      "name": "Group \u2014 Email Notifications",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 664,
        "height": 508,
        "content": "## Email Alerts\nKeep Data Alive recovers all fields lost after the Sheets write node. Check Expense Level splits the flow \u2014 High Expense goes to an urgent alert email, Normal goes to a friendly summary email."
      },
      "typeVersion": 1
    },
    {
      "id": "e10cece5-20fc-463f-a365-508edbf46ec4",
      "name": "Click Here to Run",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1504,
        256
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "d62e07c1-6aaa-4088-a5cd-95bf937c4405",
      "name": "Read Expenses from Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1296,
        256
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1j-xbSU2cuJRgQUwoQS3mK8G1SPzeGesgl4g_71JrifE/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1j-xbSU2cuJRgQUwoQS3mK8G1SPzeGesgl4g_71JrifE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1j-xbSU2cuJRgQUwoQS3mK8G1SPzeGesgl4g_71JrifE/edit",
          "cachedResultName": "Expenses"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "66cbd010-4697-4720-ab39-7e4c0a304cb5",
      "name": "Settings \u2014 Change These Before Running",
      "type": "n8n-nodes-base.set",
      "position": [
        -1104,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-001",
              "name": "Budget Limit",
              "type": "number",
              "value": 1000
            },
            {
              "id": "cfg-002",
              "name": "Send Report To Email",
              "type": "string",
              "value": ""
            },
            {
              "id": "cfg-003",
              "name": "Email Sender Name",
              "type": "string",
              "value": "ARTHA Expense Tracker"
            },
            {
              "id": "cfg-004",
              "name": "Report Period",
              "type": "string",
              "value": "This Month"
            },
            {
              "id": "cfg-005",
              "name": "Currency Symbol",
              "type": "string",
              "value": "Rs."
            },
            {
              "id": "cfg-006",
              "name": "AI Model Name",
              "type": "string",
              "value": "models/gemini-2.5-flash"
            },
            {
              "id": "cfg-007",
              "name": "Food Keywords",
              "type": "string",
              "value": "zomato,swiggy,foodpanda,dunzo"
            },
            {
              "id": "cfg-008",
              "name": "Transport Keywords",
              "type": "string",
              "value": "uber,ola,rapido,irctc,redbus"
            },
            {
              "id": "cfg-009",
              "name": "Subscription Keywords",
              "type": "string",
              "value": "netflix,spotify,amazon prime,hotstar,youtube premium"
            },
            {
              "id": "cfg-010",
              "name": "Shopping Keywords",
              "type": "string",
              "value": "amazon,flipkart,myntra,meesho,ajio"
            },
            {
              "id": "cfg-011",
              "name": "Utilities Keywords",
              "type": "string",
              "value": "electricity,water,broadband,airtel,jio,bsnl"
            },
            {
              "id": "cfg-012",
              "name": "Health Keywords",
              "type": "string",
              "value": "pharmacy,hospital,clinic,medplus,apollo,1mg"
            },
            {
              "id": "cfg-013",
              "name": "High Expense Label",
              "type": "string",
              "value": "High Expense Detected"
            },
            {
              "id": "cfg-014",
              "name": "Normal Expense Label",
              "type": "string",
              "value": "Normal Expense"
            },
            {
              "id": "cfg-015",
              "name": "Output Sheet Name",
              "type": "string",
              "value": "Sheet2"
            },
            {
              "id": "cfg-016",
              "name": "Run Timestamp",
              "type": "string",
              "value": "={{ new Date().toLocaleString('en-IN') }}"
            },
            {
              "id": "cfg-017",
              "name": "Run Date",
              "type": "string",
              "value": "={{ new Date().toLocaleDateString('en-IN') }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "74324b4a-1962-4a36-ad65-d664cdeef4fb",
      "name": "Clean and Categorise Each Expense Row",
      "type": "n8n-nodes-base.set",
      "position": [
        -896,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "clean-001",
              "name": "Expense Amount",
              "type": "number",
              "value": "={{ $('Read Expenses from Google Sheet').item.json.Amount }}"
            },
            {
              "id": "clean-002",
              "name": "Description Lowercase",
              "type": "string",
              "value": "={{ $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().trim() }}"
            },
            {
              "id": "clean-003",
              "name": "Expense Date",
              "type": "string",
              "value": "={{ $('Read Expenses from Google Sheet').item.json.Date }}"
            },
            {
              "id": "clean-004",
              "name": "Category",
              "type": "string",
              "value": "={{\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"zomato\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"swiggy\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"foodpanda\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"dunzo\")\n? \"Food\"\n\n: $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"uber\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"ola\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"rapido\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"irctc\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"redbus\")\n? \"Transport\"\n\n: $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"netflix\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"spotify\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"amazon prime\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"hotstar\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"youtube premium\")\n? \"Subscription\"\n\n: $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"amazon\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"flipkart\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"myntra\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"meesho\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"ajio\")\n? \"Shopping\"\n\n: $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"electricity\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"broadband\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"airtel\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"jio\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"bsnl\")\n? \"Utilities\"\n\n: $('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"pharmacy\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"hospital\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"clinic\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"medplus\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"apollo\") ||\n$('Read Expenses from Google Sheet').item.json.Description.toLowerCase().includes(\"1mg\")\n? \"Health\"\n\n: \"Other\"\n}}"
            },
            {
              "id": "clean-005",
              "name": "Original Description",
              "type": "string",
              "value": "={{ $('Read Expenses from Google Sheet').item.json.Description }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "5648a384-c4b6-4a28-90e7-3a53b36dd5fc",
      "name": "Add Up Total Spent per Category",
      "type": "n8n-nodes-base.summarize",
      "position": [
        -704,
        256
      ],
      "parameters": {
        "options": {},
        "fieldsToSplitBy": "Category",
        "fieldsToSummarize": {
          "values": [
            {
              "field": "Expense Amount",
              "aggregation": "sum"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "31d83ab6-8dc4-4a8c-b0c3-e017d0fb862c",
      "name": "Build AI Prompt Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -496,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "ai-001",
              "name": "Category Name",
              "type": "string",
              "value": "={{ $json.Category }}"
            },
            {
              "id": "ai-002",
              "name": "Total Amount Spent",
              "type": "number",
              "value": "={{ $json.sum_Expense_Amount }}"
            },
            {
              "id": "ai-003",
              "name": "Expense Status",
              "type": "string",
              "value": "={{\n$json.sum_Expense_Amount >\n$('Settings \u2014 Change These Before Running').first().json['Budget Limit']\n\n? $('Settings \u2014 Change These Before Running').first().json['High Expense Label']\n\n: $('Settings \u2014 Change These Before Running').first().json['Normal Expense Label']\n}}"
            },
            {
              "id": "ai-004",
              "name": "Budget Limit",
              "type": "number",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Budget Limit'] }}"
            },
            {
              "id": "ai-005",
              "name": "Currency",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Currency Symbol'] }}"
            },
            {
              "id": "ai-006",
              "name": "Report Period",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Report Period'] }}"
            },
            {
              "id": "ai-007",
              "name": "Today Date",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Run Date'] }}"
            },
            {
              "id": "ai-008",
              "name": "Today Timestamp",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Run Timestamp'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "43d9f126-40e1-40ca-82d9-94af102f582e",
      "name": "Ask Gemini to Write Expense Report",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        -352,
        256
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash",
          "cachedResultName": "models/gemini-2.5-flash"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=You are ARTHA \u2014 a sharp, caring and honest personal financial advisor for Indians. Analyze the person's spending honestly and help them save money in practical ways.\n\nEXPENSE DATA:\nCategory: {{ $json['Category Name'] }}\nTotal Spent {{ $json['Report Period'] }}: {{ $json['Currency'] }}{{ $json['Total Amount Spent'] }}\nStatus: {{ $json['Expense Status'] }}\nBudget Limit: {{ $json['Currency'] }}{{ $json['Budget Limit'] }}\nReport Date: {{ $json['Today Date'] }}\n\nWrite a financial report using exactly these sections:\n\nEXPENSE REPORT \u2014 {{ $json['Category Name'].toUpperCase() }}\n\nWHY IS THIS DRAINING YOUR MONEY?\nIn 3 lines, explain why {{ $json['Category Name'] }} spending quietly gets expensive over time. Be specific and relatable to an Indian middle-class person.\n\nHONEST VERDICT\nPick one verdict:\n\"This spending is largely wasteful and can be reduced significantly.\"\n\"This is a necessary expense but can still be optimised.\"\n\"This is mixed \u2014 partly needed, partly habit-driven.\"\nExplain the verdict in 2 lines.\n\nTOP 3 WAYS TO CUT THIS EXPENSE\nTip 1: [action] \u2014 Save approx {{ $json['Currency'] }}[X] per month\nTip 2: [action] \u2014 Save approx {{ $json['Currency'] }}[X] per month\nTip 3: [action] \u2014 Save approx {{ $json['Currency'] }}[X] per month\n\nSMARTER ALTERNATIVES\nAlternative 1: [name] \u2014 [why it is better and cheaper]\nAlternative 2: [name] \u2014 [why it is better and cheaper]\n\nSPENDING HEALTH SCORE\nScore: [X] out of 10\nReason: [one line]\n\nMONTHLY SAVING POTENTIAL\nMinimum saving: {{ $json['Currency'] }}[X]\nMaximum saving: {{ $json['Currency'] }}[X]\nIn 1 year you could save: {{ $json['Currency'] }}[X]\n\nYOUR ACTION FOR THIS WEEK\nOne very specific action the person can take this week.\n\nCLOSING NOTE\nOne short, honest, emotionally resonant line \u2014 like advice from a trusted friend."
            }
          ]
        },
        "builtInTools": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "1be17846-37a3-4749-914f-b004288fc923",
      "name": "Collect Report Fields for Sheet and Email",
      "type": "n8n-nodes-base.set",
      "position": [
        -96,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fmt-001",
              "name": "AI Report Text",
              "type": "string",
              "value": "={{ $json.content.parts[0].text }}"
            },
            {
              "id": "fmt-002",
              "name": "Category Name",
              "type": "string",
              "value": "={{ $('Build AI Prompt Fields').item.json['Category Name'] }}"
            },
            {
              "id": "fmt-003",
              "name": "Total Amount Spent",
              "type": "number",
              "value": "={{ $('Build AI Prompt Fields').item.json['Total Amount Spent'] }}"
            },
            {
              "id": "fmt-004",
              "name": "Report Date",
              "type": "string",
              "value": "={{ $('Build AI Prompt Fields').item.json['Today Date'] }}"
            },
            {
              "id": "fmt-005",
              "name": "Expense Status",
              "type": "string",
              "value": "={{ $('Build AI Prompt Fields').item.json['Expense Status'] }}"
            },
            {
              "id": "fmt-006",
              "name": "Reviewed On",
              "type": "string",
              "value": "={{ $('Build AI Prompt Fields').item.json['Today Timestamp'] }}"
            },
            {
              "id": "fmt-007",
              "name": "Is High Expense",
              "type": "boolean",
              "value": "={{ $('Build AI Prompt Fields').item.json['Expense Status'] === $('Settings \u2014 Change These Before Running').first().json['High Expense Label'] }}"
            },
            {
              "id": "fmt-008",
              "name": "Recipient Email",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Send Report To Email'] }}"
            },
            {
              "id": "fmt-009",
              "name": "Sender Name",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Email Sender Name'] }}"
            },
            {
              "id": "fmt-010",
              "name": "Currency",
              "type": "string",
              "value": "={{ $('Settings \u2014 Change These Before Running').first().json['Currency Symbol'] }}"
            },
            {
              "id": "fmt-011",
              "name": "Report Period",
              "type": "string",
              "value": "={{ $('Build AI Prompt Fields').item.json['Report Period'] }}"
            },
            {
              "id": "fmt-012",
              "name": "Budget Limit",
              "type": "number",
              "value": "={{ $('Build AI Prompt Fields').item.json['Budget Limit'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "14b93413-b1af-4adc-856f-c4da48e5de03",
      "name": "Save Report to Sheet2",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        112,
        256
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json['Report Date'] }}",
            "Status": "={{ $json['Expense Status'] }}",
            "Category": "={{ $json['Category Name'] }}",
            "AI Report": "={{ $json['AI Report Text'] }}",
            "Reviewed On": "={{ $json['Reviewed On'] }}",
            "Total Spent": "={{ $json['Total Amount Spent'] }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Spent",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Spent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "AI Report",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AI Report",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reviewed On",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Reviewed On",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1j-xbSU2cuJRgQUwoQS3mK8G1SPzeGesgl4g_71JrifE",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1j-xbSU2cuJRgQUwoQS3mK8G1SPzeGesgl4g_71JrifE/edit?usp=drivesdk",
          "cachedResultName": "Expenses"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5d8c0358-cf83-48d7-87ab-4c763cec1bc0",
      "name": "Keep Data Alive After Sheet Write",
      "type": "n8n-nodes-base.set",
      "position": [
        368,
        256
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "pass-001",
              "name": "AI Report Text",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['AI Report Text'] }}"
            },
            {
              "id": "pass-002",
              "name": "Category Name",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Category Name'] }}"
            },
            {
              "id": "pass-003",
              "name": "Total Amount Spent",
              "type": "number",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Total Amount Spent'] }}"
            },
            {
              "id": "pass-004",
              "name": "Report Date",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Report Date'] }}"
            },
            {
              "id": "pass-005",
              "name": "Expense Status",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Expense Status'] }}"
            },
            {
              "id": "pass-006",
              "name": "Reviewed On",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Reviewed On'] }}"
            },
            {
              "id": "pass-007",
              "name": "Is High Expense",
              "type": "boolean",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Is High Expense'] }}"
            },
            {
              "id": "pass-008",
              "name": "Recipient Email",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Recipient Email'] }}"
            },
            {
              "id": "pass-009",
              "name": "Sender Name",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Sender Name'] }}"
            },
            {
              "id": "pass-010",
              "name": "Currency",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Currency'] }}"
            },
            {
              "id": "pass-011",
              "name": "Report Period",
              "type": "string",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Report Period'] }}"
            },
            {
              "id": "pass-012",
              "name": "Budget Limit",
              "type": "number",
              "value": "={{ $('Collect Report Fields for Sheet and Email').item.json['Budget Limit'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1787296b-7c5d-4f2a-a33d-575cf56cdf67",
      "name": "Check Expense Level \u2014 High or Normal?",
      "type": "n8n-nodes-base.if",
      "position": [
        576,
        256
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "if-cond-001",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $json['Is High Expense'] }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "b5dcedf5-49ec-4564-9038-e0eb08dfe08b",
      "name": "Send High Expense Alert Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        784,
        160
      ],
      "parameters": {
        "sendTo": "={{ $json['Recipient Email'] }}",
        "message": "=Hi,\n\nARTHA has flagged a HIGH EXPENSE in your {{ $json['Report Period'] }} report.\n\nCategory: {{ $json['Category Name'] }}\nTotal Spent: {{ $json['Currency'] }}{{ $json['Total Amount Spent'] }}\nBudget Limit: {{ $json['Currency'] }}{{ $json['Budget Limit'] }}\nStatus: {{ $json['Expense Status'] }}\nReviewed On: {{ $json['Reviewed On'] }}\n\n--- AI ADVISORY REPORT ---\n\n{{ $json['AI Report Text'] }}\n\n---\n\nThis report was auto-generated by {{ $json['Sender Name'] }}.\nCheck Sheet2 in your Expenses spreadsheet for the full record.",
        "options": {
          "senderName": "={{ $json['Sender Name'] }}"
        },
        "subject": "=Alert: High Expense Detected \u2014 {{ $json['Category Name'] }} ({{ $json['Currency'] }}{{ $json['Total Amount Spent'] }}) | {{ $json['Report Period'] }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "1fb680f7-cecd-475b-b577-5aec9737ea78",
      "name": "Send Normal Expense Summary Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        784,
        368
      ],
      "parameters": {
        "sendTo": "={{ $json['Recipient Email'] }}",
        "message": "=Hi,\n\nHere is your {{ $json['Report Period'] }} expense summary for {{ $json['Category Name'] }}.\n\nCategory: {{ $json['Category Name'] }}\nTotal Spent: {{ $json['Currency'] }}{{ $json['Total Amount Spent'] }}\nStatus: {{ $json['Expense Status'] }}\nReviewed On: {{ $json['Reviewed On'] }}\n\n--- AI ADVISORY REPORT ---\n\n{{ $json['AI Report Text'] }}\n\n---\n\nThis report was auto-generated by {{ $json['Sender Name'] }}.\nCheck Sheet2 in your Expenses spreadsheet for the full record.",
        "options": {
          "senderName": "={{ $json['Sender Name'] }}"
        },
        "subject": "=Expense Summary \u2014 {{ $json['Category Name'] }} ({{ $json['Currency'] }}{{ $json['Total Amount Spent'] }}) | {{ $json['Report Period'] }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "d3865d61-0023-4d26-9871-858aaba417f6",
  "connections": {
    "Click Here to Run": {
      "main": [
        [
          {
            "node": "Read Expenses from Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Report to Sheet2": {
      "main": [
        [
          {
            "node": "Keep Data Alive After Sheet Write",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Prompt Fields": {
      "main": [
        [
          {
            "node": "Ask Gemini to Write Expense Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Up Total Spent per Category": {
      "main": [
        [
          {
            "node": "Build AI Prompt Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Expenses from Google Sheet": {
      "main": [
        [
          {
            "node": "Settings \u2014 Change These Before Running",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Keep Data Alive After Sheet Write": {
      "main": [
        [
          {
            "node": "Check Expense Level \u2014 High or Normal?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask Gemini to Write Expense Report": {
      "main": [
        [
          {
            "node": "Collect Report Fields for Sheet and Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean and Categorise Each Expense Row": {
      "main": [
        [
          {
            "node": "Add Up Total Spent per Category",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Expense Level \u2014 High or Normal?": {
      "main": [
        [
          {
            "node": "Send High Expense Alert Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Normal Expense Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Settings \u2014 Change These Before Running": {
      "main": [
        [
          {
            "node": "Clean and Categorise Each Expense Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Collect Report Fields for Sheet and Email": {
      "main": [
        [
          {
            "node": "Save Report to Sheet2",
            "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

Smart Expense Monitoring in Minutes

Source: https://n8n.io/workflows/14901/ — 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

This template is ideal for HR teams, startup founders, operations leads, remote-first companies, and freelancers managing onboarding manually or across multiple tools.

Google Sheets Trigger, Jira, HubSpot Trigger +7
Email & Gmail

This template automates the complete hiring pipeline for digital agencies managing applications across multiple job roles. When a candidate submits a Google Form with their CV, the system scores it wi

OpenRouter Chat, Output Parser Structured, Google Sheets +6
Email & Gmail

Send A Chatgpt Email Reply And Save Responses To Google Sheets. Uses openAi, gmailTrigger, stickyNote, gmail. Event-driven trigger; 49 nodes.

OpenAI, Gmail Trigger, Gmail +2
Email & Gmail

Code. Uses openAi, gmailTrigger, stickyNote, gmail. Event-driven trigger; 49 nodes.

OpenAI, Gmail Trigger, Gmail +2
Email & Gmail

This workflow sends a OpenAI GPT reply when an email is received from specific email recipients. It then saves the initial email and the GPT response to an automatically generated Google spreadsheet.

OpenAI, Gmail Trigger, Gmail +2