Skip to content

Latest commit

 

History

History
114 lines (83 loc) · 4.09 KB

File metadata and controls

114 lines (83 loc) · 4.09 KB

Setup Guide

One-Time Setup for Emails

1. Create a Google Apps Script Project

Visit Google Apps Script and create a new project.

2. Add Script Files

Upload the script files in the following order (files are evaluated in order):

  1. constants (1-constants.gs)
  2. userConfig (2-sampleUserConfig.gs -- copy and customize for your setup)
  3. main (3-main.gs)
  4. utils (4-utils.gs)
  5. test (5-test.gs)

The files in GScript use the .gs extension but are plain JavaScript. You can rename to .js to work locally.

3. Add Moment.js Library

Follow this guide to add the Moment.js library to your GAS project.

4. Enable Gmail API

Configure the Gmail API as per Google's documentation.

5. Store Credentials

Use storeSecrets to save sensitive data securely in Script Properties:

const mySecrets = {
    EMAIL: "user1@example.com",
    SPREADSHEET_ID: "your-spreadsheet-id",
    ACCOUNT_ID_BANKA_SAVINGS: ["XX1234", "additional identifier"],
    ACCOUNT_ID_BANKA_CC: ["XX5678"],
};
storeSecrets(mySecrets);

After running storeSecrets once, delete the actual values from userConfig. The script reads them from Script Properties at runtime.

6. Prepare Spreadsheet

Import or create a Google Sheet for storing transactions, and set its ID in mySecrets.SPREADSHEET_ID.

A sample spreadsheet is available: Sample Sheet

7. Configure Regex Rules

Define regex patterns to extract transaction details from email content. Example for a credit card debit email:

Your BankA Credit Card XX1234 has been used for a transaction of INR 363.00 on Dec 06, 2024 at 01:18:50.
Info: SAMPLE SERVICE. The Available Credit Limit...

Corresponding rule:

"BankA-CC-Debit": {
    dateRegex: /\b([A-Za-z]{3}\s\d{2},\s\d{4})\s*at\s(\d{2}:\d{2}:\d{2})\b/,
    fromAccountRegex: /Credit Card\s([A-Za-z0-9]+)\s/,
    amountRegex: /transaction of\s[A-Za-z]+\s([\d,]+\.?\d*)/,
    merchantRegex: /Info:\s*(.+?)\. The Available Credit Limit/
}

Key patterns to know:

  • (?!) -- Never-match regex. Use when you want the field to fall back to defaults (e.g., use email date instead of extracting from body).
  • null -- No signal. Category/subcategory will be resolved by the keyword map.
  • Static strings (e.g., "Cash", "ATM Withdrawal") -- Used as literal values instead of regex extraction.

See 2-sampleUserConfig.gs for a full set of annotated examples covering different patterns.

8. Configure Categories

Set up categorySubcategoryKeywordMap with your expense and income categories. Keywords are matched case-insensitively against the transaction's merchant, category signal, and email body.

const categorySubcategoryKeywordMap = deepFreeze({
    expenses: {
        "Food": {
            subcategories: {
                "Eating Out": ["UBER EATS", "DOORDASH", "DOMINOS", "STARBUCKS"],
                "Groceries": ["WALMART", "COSTCO", "INSTACART"],
            },
        },
        "Misc Expense": {
            subcategories: {
                "Uncategorized Expense": [],
            },
        },
    },
    incomes: { ... }
});

9. Gmail Labels (Optional)

Create the following labels in Gmail and set up filters to tag transaction emails:

Label Purpose
Txs/[credit card emoji] All bank transaction emails
Txs/[speech bubble emoji] SMS forwarded as email (single) via SmsForwarder
Txs/[wifi emoji] Offline SMS batch forwarded later (legacy, only needed with the Automate app)
Txs/[test tube emoji] Emails for sanity test runs
Txs/[x emoji] Ignored/invalid emails (skipped)
Txs/[check emoji] Successfully processed emails
Txs/[wrench emoji] Emails needing regex fixes

Using Gmail API to label individual emails (not threads) means partially failed threads can be reprocessed. Enable "Conversation view off" in Gmail Settings to see per-email labels.