Skip to main content

Overview

SpendWisely George consists of multiple components that can be installed independently based on your needs:
  • Frontend PWA (Required): The web interface
  • Google Apps Script (Required): Data storage and AI processing
  • Python Backend (Optional): Bank sync and portfolio features
  • Unfold CLI (Optional): Fold Money integration
You can start with just the frontend and Google Apps Script for basic expense tracking, then add the backend later for advanced features.

System Requirements

For Basic Setup (Frontend + Google Apps Script)

  • Modern web browser (Chrome, Firefox, Safari, Edge)
  • Google account
  • Gemini API key (free tier available)

For Full Setup (With Backend)

  • Python 3.8 or higher
  • pip (Python package manager)
  • Git (for cloning the repository)
  • Go 1.19+ (if building Unfold from source)

Installation Methods

Best for: Testing and personal useThis method uses GitHub Pages for the frontend and Google Apps Script for the backend.

Part 1: Frontend Installation

Clone the Repository

git clone https://github.com/georgejohnsonoff-business/spendwiselygeorge.git
cd spendwiselygeorge

Configure the Frontend

1

Update Script URL

Open index.html and locate line 306:
index.html
const SCRIPT_URL = "https://script.google.com/macros/s/YOUR_DEPLOYMENT_ID/exec";
You’ll update this after deploying Google Apps Script.
2

Customize Branding (Optional)

Update the manifest for PWA installation:
manifest.json
{
  "name": "George Finance",
  "short_name": "George AI",
  "start_url": ".",
  "display": "standalone",
  "background_color": "#f8fafc",
  "theme_color": "#ffffff",
  "orientation": "portrait"
}
3

Test Locally

Open index.html in your browser or use a simple HTTP server:
# Using Python
python -m http.server 8000

# Using Node.js
npx http-server
Visit http://localhost:8000 to see the app.

Part 2: Google Apps Script Setup

Create the Google Sheet

1

Create New Sheet

  1. Go to Google Sheets
  2. Create a new blank spreadsheet
  3. Add headers in the first row:
ABCDE
DateDescriptionAmountCategoryType
2

Copy Sheet ID

From the URL:
https://docs.google.com/spreadsheets/d/1u8avtUDehdZYSDDbIv0hoVyhBorUDptZDFh3ngp1gLo/edit
Your Sheet ID is: 1u8avtUDehdZYSDDbIv0hoVyhBorUDptZDFh3ngp1gLo

Deploy the Apps Script

1

Open Apps Script Editor

In your Google Sheet:
  • Click ExtensionsApps Script
2

Add the Script Code

Copy the entire contents of google_script.js and paste it into the editor.
Critical: Update line 14 with your Sheet ID:
google_script.js
const SHEET_ID = "YOUR_ACTUAL_SHEET_ID_HERE";
3

Deploy as Web App

  1. Click DeployNew deployment
  2. Select type: Web app
  3. Configuration:
    • Description: “George Finance API”
    • Execute as: Me (your email)
    • Who has access: Anyone
  4. Click Deploy
  5. Authorize the required permissions
  6. Copy the deployment URL
4

Update Frontend with URL

Return to index.html and update line 306 with your deployment URL:
index.html
const SCRIPT_URL = "https://script.google.com/macros/s/AKfycbzTLu.../exec";

Configure Google Apps Script

The script handles three types of operations:
Returns current balance, expenses, budget, and privacy settings:
google_script.js
function doGet() {
    const sheet = getTargetSheet();
    const balance = calculateBalance(sheet);
    const budget = SCRIPT_PROP.getProperty("DAILY_BUDGET") || 350;
    const privacy = SCRIPT_PROP.getProperty("PRIVACY_MODE");
    
    return ContentService.createTextOutput(JSON.stringify({
        balance: balance,
        expenses: expenses,
        budget: budget,
        privacy: privacy
    })).setMimeType(ContentService.MimeType.JSON);
}
Handles multiple actions:
  • save_settings: Updates budget, privacy mode, and Gemini API key
  • delete: Removes a transaction from the sheet
  • add: Adds a basic transaction
  • process_text: AI-powered expense processing
The script sends prompts to Gemini Flash:
google_script.js
const aiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-flash-latest:generateContent?key=${geminiKey}`;
const aiPayload = { 
    contents: [{ 
        parts: [{ text: prompt }] 
    }] 
};

Part 3: Backend Server (Optional)

The backend server is only required for:
  • Bank sync with Fold Money
  • Mutual fund portfolio tracking
  • Transaction history from banking APIs

Install Dependencies

pip install fastapi uvicorn pyyaml requests
Or use the requirements file:
pip install -r requirements.txt

Configure the Server

The server configuration is at the top of server.py:
server.py
# Configuration
UNFOLD_BINARY = "./unfold/unfold"
UNFOLD_CONFIG = "./unfold_config.yaml"
DB_PATH = "./unfold/db.sqlite"
HOLDINGS_FILE = "./holdings.json"
  • UNFOLD_BINARY: Path to the Unfold CLI executable
  • UNFOLD_CONFIG: YAML file storing Fold Money credentials
  • DB_PATH: SQLite database for cached transactions
  • HOLDINGS_FILE: JSON file storing mutual fund holdings

Start the Server

python server.py
By default, the server runs on http://localhost:8000.
For production deployment, set the PORT environment variable:
PORT=3000 python server.py

API Endpoints

The FastAPI server provides these endpoints:
@app.post("/api/fold/login")
def fold_login(req: LoginRequest):
    url = "https://api.fold.money/v1/auth/otp"
    phone = req.phone if req.phone.startswith("+") else "+91" + req.phone
    payload = {"phone": phone, "channel": "sms"}
    res = requests.post(url, json=payload)
    return {"status": "otp_sent"}

@app.post("/api/fold/verify")
def fold_verify(req: VerifyRequest):
    # Verify OTP and save tokens
    save_unfold_config(access, refresh, uuid)
    return {"status": "success"}

Part 4: Unfold CLI Setup

Unfold is a Go-based CLI tool for Fold Money integration. Pre-built binaries are not provided in the repository, so you’ll need to build from source or obtain a binary.

Directory Structure

Create the unfold directory:
mkdir unfold
cd unfold

Configuration File

The server creates unfold_config.yaml automatically when you log in via the UI:
unfold_config.yaml
token:
  access: "your_access_token"
  refresh: "your_refresh_token"
fold_user:
  uuid: "your_user_uuid"
device_hash: "python-client-abc123"
Never commit unfold_config.yaml to version control. It contains sensitive authentication tokens.

Using Unfold

Once configured, the backend automatically calls Unfold:
server.py
subprocess.run([
    UNFOLD_BINARY, 
    "transactions", 
    "--db",  # Save to SQLite
    "--config", UNFOLD_CONFIG
], check=True)
This creates/updates db.sqlite with transaction data.

Part 5: Environment Variables

For Local Development

Create a .env file (optional, for advanced configurations):
PORT=8000
UNFOLD_BINARY=./unfold/unfold
DB_PATH=./unfold/db.sqlite

For Production Deployment

Set these environment variables on your hosting platform:
VariableDescriptionExample
PORTServer port8000
GEMINI_KEYGoogle Gemini API keyAIza...
FOLD_PHONEPre-configured phone (optional)+919876543210

Verification Steps

1

Test Google Apps Script

Visit your Apps Script web app URL directly. You should see JSON output:
{
  "balance": 0,
  "expenses": [],
  "budget": 350,
  "privacy": true
}
2

Test Frontend Connection

Open the frontend and check the status indicator:
  • Should show “ONLINE” in green
  • Balance should display (or show ••••••)
3

Test Backend API (if installed)

Visit http://localhost:8000/docs for the interactive API documentation.
4

Add Test Transaction

  1. Type “Test 100” in the input
  2. Click ADD
  3. Check your Google Sheet—should see a new row
  4. Frontend should update immediately

Troubleshooting

Error: “Authorization required”
  • Solution: Re-deploy the script and grant all requested permissions
Error: “Sheet not found”
  • Solution: Verify the SHEET_ID constant matches your actual Sheet ID
Error: “Gemini API limit exceeded”
Error: ModuleNotFoundError: No module named 'fastapi'
  • Solution: Install dependencies: pip install -r requirements.txt
Error: “Unfold binary not found”
  • Solution: Verify UNFOLD_BINARY path is correct or skip bank sync features
Error: “CORS policy blocked”
  • Solution: The server allows all origins by default. Check browser console for specific errors.
Issue: Status stuck on “INITIALIZING…”
  • Check: Is SCRIPT_URL correct?
  • Check: Can you access the Apps Script URL directly?
  • Check: Browser console for JavaScript errors
Issue: Voice input not working
  • Requires: HTTPS or localhost
  • Requires: Microphone permissions granted
  • Supported: Chrome, Edge, Safari (limited)
Issue: Transactions not syncing
  • Verify: Backend server is running
  • Verify: Fold account is logged in (check /api/fold/status)
  • Check: unfold/db.sqlite file exists and has recent timestamp
Issue: Portfolio not showing
  • Verify: Holdings are saved via Settings → Mutual Fund Holdings
  • Check: Network access to api.mfapi.in
  • Check: Scheme codes are valid (6-digit numbers)

Security Considerations

Important Security Notes:
  1. Never commit sensitive files:
    • unfold_config.yaml (contains auth tokens)
    • .env files with API keys
    • holdings.json (personal financial data)
  2. Google Apps Script access:
    • “Anyone can access” means anyone with the URL
    • Consider using “Anyone with Google account” for better security
  3. Gemini API key:
    • Store in Google Apps Script properties, not in frontend code
    • Monitor usage to prevent quota exhaustion
  4. Backend CORS:
    • Current config allows all origins (allow_origins=["*"])
    • For production, restrict to your frontend domain

Next Steps

Deploy to Production

Learn how to deploy to Render, Railway, or Fly.io

Explore Features

Discover all the powerful features of SpendWisely George

API Reference

Explore all backend endpoints

Integrations

Set up bank sync and portfolio tracking
Join our community on GitHub Discussions to share tips, ask questions, and show off your customizations!

Build docs developers (and LLMs) love