Overview
PisoTrack started from a simple annoyance: expense tracking apps ask you to open an app, and nobody actually does that consistently. The one app people already open, every day, without being reminded, is their messaging app. So the whole project is built on one idea: what if logging an expense was just texting a friend?
It ended up being a full self-hosted automation stack, running for free, with zero cloud bills and zero credit card on file anywhere. Message a Telegram bot with a plain sentence or a photo of a receipt, and it reads it, understands it, and saves it.
The Problem
Manual expense tracking dies the same way every time. Not from lack of discipline, but from friction. Open the app, tap the category, type the amount, tap save, repeat for every coffee and every grab ride. It takes fifteen seconds each time, and fifteen seconds is exactly long enough for most people to skip it "just this once," which becomes never again within a week.
The actual bottleneck was never math or categorization. It was the act of opening a separate app at all.
The Solution
PisoTrack removes the app entirely. You just text your Telegram bot the way you'd text anyone: "150 lunch with Tin" or "grab to office, 89 pesos." Or you skip typing altogether and just snap a photo of the receipt.
Behind that one message, Google Gemini reads the text or the image, pulls out the amount, currency, merchant, category, and date, and a self-hosted n8n workflow writes it straight into a Postgres database. The bot replies right away with what it logged, so there's instant confirmation instead of wondering if it worked.
On top of that, two scheduled workflows run in the background: one sends a spend-by-category summary every week, and another checks your budgets daily and pings you the moment any category creeps past 80 percent.
Workflow Architecture
User Input (Text / Receipt Photo)
│
▼
Telegram Bot
│
▼
ngrok Tunnel
│
▼
Self-Hosted n8n (Docker, running on a personal laptop)
│
▼
Google Gemini 2.5 Flash (text parsing or vision OCR)
│
▼
Expense Extraction + Categorization
│
▼
Supabase (Postgres)
│
▼
Confirmation Reply + Weekly Summaries + Budget Alerts (Telegram)
The text and photo paths split early and merge back together right before the data gets normalized and saved, so both entry methods end up writing to the exact same schema.
Core Features
Multi-Modal Input
Expenses can be logged as a plain text message or as a photo of a physical receipt. No fixed format, no slash commands, just natural language or a picture.
AI-Powered Extraction
Gemini handles both jobs: parsing free-text messages and reading receipt images through vision. Same model, same output shape, whether the input was typed or photographed.
Automatic Categorization
Every expense gets sorted into a category automatically, based on a fixed list the AI is instructed to choose from, so the data stays consistent enough to actually budget against.
Live Postgres Storage
Every expense lands in a Supabase Postgres database in real time, browsable and filterable through Supabase's own table editor, no separate spreadsheet sync required.
Weekly Spend Summaries
A scheduled workflow queries the last seven days of spending, grouped by category, and delivers it straight to Telegram every Monday morning.
Budget Alerts
A daily check compares this month's spending per category against user-defined limits and sends a Telegram alert the moment any category passes 80 percent of its budget.
Genuinely Zero Cost
Every single piece of this, the automation engine, the tunnel, the AI, and the database, runs on a free tier with no credit card entered anywhere. That constraint shaped a lot of the real decisions in the build.
Current Progress
Completed
- Telegram Bot integration, handling both text and photo messages
- Self-hosted n8n environment running in Docker on a personal machine
- ngrok tunnel with a permanent free dev domain for public webhook access
- Gemini AI integration for both text parsing and receipt vision
- Supabase Postgres database for expenses and budgets
- Automated end-to-end logging pipeline, confirmed working for both text and photo
- Weekly summary workflow, tested and confirmed
- Budget alert workflow, tested for both the silent and the firing case
- Durable startup: Docker and the ngrok tunnel both auto-launch on login, confirmed to survive a full laptop restart
In Progress
- Input validation, so a random non-expense message doesn't get force-parsed and saved as a junk row
- Real budget numbers tuned to actual monthly spending in PHP
Planned
- Undo command for the most recently logged expense
- Monthly summary variant alongside the weekly one
- Per-category spending charts sent as an image
- Multi-currency handling for expenses outside PHP
- Optional Google Sheets sync through an Apps Script webhook, avoiding the OAuth billing wall entirely
- Shared or household mode, splitting reports by Telegram user
Lessons Learned
Building this end to end, credential by credential, taught more about real infrastructure than any tutorial would. A few things stood out.
Free tiers are free, but they are not simple. Supabase's direct Postgres connection turned out to be IPv6-only, which silently fails on a lot of home networks, and the actual fix was switching to their session pooler with SSL set to allow, not something obvious from the first error message. Oracle Cloud and Google Cloud Console both gate you behind a card-verification step even for genuinely free usage, which pushed the whole hosting decision toward a local Docker setup with ngrok instead, a combination that turned out to be more reliable anyway.
AI models are not static infrastructure. Midway through testing, Gemini 2.0 Flash returned a quota of exactly zero, because Google had deprecated it days earlier. Anything built on a specific model name needs to be treated as replaceable, not permanent.
Automation platforms have their own quirks that only show up under real use. n8n's Code node had a real bug in how it exposed binary file data in this version, silently returning a filesystem reference string instead of the actual file bytes, which took a few rounds of debugging to catch. The fix ended up being simpler than the workaround: use the platform's dedicated binary conversion node instead of hand-rolled code.
And maybe the most important one: a working demo is not the same as a trustworthy system. Getting a confirmation reply on the first test felt like the finish line, but it took a direct question, whether nonsense messages would get ignored, to expose that the system had no real validation and would have logged garbage as if it were a real expense. Good automation needs guardrails for the inputs it wasn't designed for, not just the ones it was.
Future Roadmap
The next phase turns PisoTrack from a solid logger into something closer to a full personal finance assistant. That means closing the validation gap so junk messages get politely rejected instead of silently saved, adding monthly views alongside the weekly ones, and giving spending some visual shape through category charts instead of just text summaries.
Longer term, the goal is a system that doesn't just capture spending automatically, but actually helps make sense of it, without ever asking the user to open a separate app to do so.