ExpenseBot

How to Automate Expense Tracking in Google Sheets (2026)

You can automate parts of Google Sheets expense tracking. Just not all of it — and knowing where the ceiling is will save you hours of frustrating Apps Script debugging.

This guide covers what's actually automatable in Sheets (Google Forms, IMPORTRANGE, Apps Script triggers), a working auto-categorization script you can copy, and an honest account of what Sheets simply cannot do regardless of how clever your script is.

What You Can Actually Automate in Google Sheets

Here's what's genuinely achievable without significant development effort:

✓ Google Forms → Sheet auto-appendFree form submission auto-creates a new row with timestamp. Mobile-friendly. No OCR — user still types the data.
✓ IMPORTRANGE consolidationPull data from multiple Sheets into one summary. Useful for multi-month or multi-category tracking across separate files. Auto-syncs.
✓ Conditional formatting alertsHighlight over-budget categories in red automatically. No script required — pure formula + formatting rules.
✓ Data validation dropdownsLock the Category column to a predefined list, preventing the typos that break SUMIF totals.
✓ Apps Script auto-categorizationScript reads the Merchant column on each new row and auto-assigns a category based on keyword matching. Requires writing ~20 lines of JavaScript.
✓ Apps Script scheduled summariesTime-based trigger emails you a weekly spending summary without opening the sheet. Requires ~30 lines of script.

Google Forms as a Receipt Entry Tool

Google Forms is the easiest automation win — no code required. Set up a form with five fields: Date, Merchant, Category (dropdown matching your Sheets list), Amount, and Notes. Link it to your expense sheet (Responses → Link to Sheets). Every form submission auto-appends a new row with a timestamp.

The mobile advantage: bookmark the form on your phone's home screen and you can log an expense in 20 seconds while still at the register. Faster than opening Sheets on mobile.

The limitation: Forms doesn't read receipt content. You're still manually typing the merchant name, amount, and category. It removes the "open the spreadsheet, find the right row, type carefully" friction — but not the mental overhead of logging every transaction.

For teams on Google Workspace (not personal Gmail), Forms supports file upload questions — employees can attach a receipt photo when submitting. The file lands in Drive automatically.

Apps Script: The Real Automation Layer

Google Apps Script is JavaScript that runs inside Google's infrastructure, triggered by events in your Sheet, on a schedule, or manually. For expense tracking, the practical use cases are:

  • Auto-categorize on form submit — runs when a new row arrives from Google Forms
  • Auto-categorize on edit — runs when you manually type in a row
  • Weekly summary email — time-based trigger, emails SUMIF totals every Monday
  • Budget alert — sends an email when a category exceeds a threshold
  • Exchange rate pull — fetches today's rate from an API and stores it in a cell (useful for multicurrency)

Quotas to know: Consumer Google accounts get 90 minutes/day of script execution time and 100 trigger slots. Google Workspace accounts get 6 hours/day. For expense tracking use cases, you'll use a tiny fraction of this — a categorization script running on form submit takes milliseconds.

Access Apps Script from your Sheet: Extensions → Apps Script. The editor opens in a new tab.

Apps Script Example: Auto-Categorize by Merchant

This script reads column B (Merchant) on each new row and writes a category to column C based on keyword matching. Paste it into the Apps Script editor, save, and set a trigger to run on form submit (or on edit for manual entry).

const CATEGORY_MAP = {
  'amazon':     'Office Supplies',
  'aws':        'Software & Subscriptions',
  'zoom':       'Software & Subscriptions',
  'starbucks':  'Meals (50%)',
  'uber':       'Auto & Travel',
  'lyft':       'Auto & Travel',
  'google ads': 'Advertising',
  'facebook':   'Advertising',
  'adobe':      'Software & Subscriptions',
};

function autoCategorizeLastRow() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet()
    .getSheetByName('Expenses');
  const lastRow = sheet.getLastRow();
  if (lastRow < 2) return; // no data yet

  const merchant = sheet.getRange(lastRow, 2).getValue()
    .toString().toLowerCase();
  const currentCategory = sheet.getRange(lastRow, 3).getValue();

  // Don't overwrite if user already set a category
  if (currentCategory) return;

  for (const [keyword, category] of Object.entries(CATEGORY_MAP)) {
    if (merchant.includes(keyword)) {
      sheet.getRange(lastRow, 3).setValue(category);
      return;
    }
  }
  // No match — leave blank for manual entry
}

Add new merchants to CATEGORY_MAP as you go. The script won't categorize merchants it doesn't recognize — those rows stay blank for manual review. After a month of use, most of your regular vendors will be covered.

What Google Sheets Can't Do

✗ Read email receipts automaticallyEven with the Gmail API available in Apps Script, parsing email receipts at scale requires significant custom development — handling HTML email bodies, inconsistent receipt formats across thousands of vendors, and OAuth token management. Not a 20-line script.
✗ OCR receipt photosSheets has no built-in image recognition. You could call Google Cloud Vision API from Apps Script, but that requires a paid GCP account, API key management, and custom parsing logic for each receipt format.
✗ Import bank transactionsNative bank feeds require Plaid or direct bank API integrations. Available via third-party tools (Tiller, $79/yr) but not natively in Sheets.
✗ Multi-user tracking with approval workflowsMultiple users can edit a Sheet simultaneously, but Sheets has no expense submission → manager approval → accounting workflow. You'd need to build this in Apps Script from scratch.
✗ Automatic deduplicationIf a receipt lands from both Gmail and a manual entry, Sheets won't flag it. Duplicate detection requires custom script logic.

The Ceiling Problem

Here's the honest ceiling: a well-configured Google Sheets tracker with Forms intake and an auto-categorization script handles about 30–60 receipts per month reasonably well. Past that, you'll spend more time maintaining the automation than you save.

The signals that you've hit the ceiling:

  • Your CATEGORY_MAP has dozens of entries and still misses 30% of your merchants
  • You have a backlog of uncategorized rows sitting blank for more than a week
  • Email receipts (Amazon, SaaS subscriptions, bank confirmations) are not in the Sheet at all
  • Tax season requires a full day of cleanup before you can hand the Sheet to your accountant
  • You've tried to add Gmail API integration and abandoned it mid-way

None of these mean Sheets is the wrong tool — they mean you've grown past what Sheets was designed to handle. The next step isn't a more complex script; it's a tool built specifically for this problem.

ExpenseBot: The Fully Automated Version

ExpenseBot's Google Sheets integration is what a "fully automated" Sheets expense tracker looks like: it scans your Gmail for receipts, runs OCR on attachments and email bodies, categorizes each expense to Schedule C, and writes a row to your Google Sheet — automatically, without a form submission or Apps Script.

The spreadsheet format is identical to what you'd build yourself. You still view, filter, and edit in Sheets. The difference is that the data entry happens in the background — your Sheet is current by morning without you touching it.

Skip the Apps Script entirely

Gmail auto-scan → OCR → Schedule C categorization → Google Sheet. No code, no maintenance.

See Automated Google Sheets Tracker →

Free 60-day trial · No credit card required

Also useful: automated expense reports — what's possible when you don't start from a spreadsheet at all. How to track business expenses — the broader process, beyond just the tool.

Share:

Track Mileage Automatically with ExpenseBot

Google Maps calculates your distances. Current IRS & CRA rates applied automatically. Tax-ready mileage log in seconds.

No credit card required · Deploys in 30 seconds