Zentr¶
Personal finance management system controlled via Telegram bot, backed by Google Sheets per user.
Product Vision¶
"Your finances, in your Google Drive, controlled from Telegram"
- No black box — user owns their data in their own Google Drive
- Telegram as the quick interaction channel, Google Sheets as the power UI
- Future: mobile app consuming the same Worker API
Tech Stack¶
| Concern | Technology |
|---|---|
| Runtime | Cloudflare Workers |
| Framework | Hono (TypeScript) |
| Session / token cache | Cloudflare KV |
| User metadata | Cloudflare D1 (SQLite) |
| Financial data | Google Sheets API (per user, OAuth2) |
| Bot channel | Telegram Bot API (@ZentrFinanceBot) |
| AI analysis | Gemini API (gemini-2.5-flash) |
| Scheduled jobs | Cloudflare Cron Triggers |
| CI/CD | Strauss (internal) → wrangler deploy |
System Overview¶
User (Telegram)
│
▼
@ZentrFinanceBot
│ POST /webhook
▼
Cloudflare Worker (Hono)
│
┌────┼─────────────────┐
▼ ▼ ▼
KV D1 Gemini API
(tokens, (user metadata,
sessions) locale, plan)
│
Google OAuth2 (refresh token per user)
│
Google Sheets API
│
User's Sheet (in their own Drive)
Bot Commands¶
/expense AMOUNT DESCRIPTION [-c CATEGORY] [-a ACCOUNT] [-s STATUS]
/income AMOUNT DESCRIPTION [-c CATEGORY] [-a ACCOUNT] [-s STATUS]
/investment AMOUNT DESCRIPTION [-c CATEGORY] [-a ACCOUNT]
/retrieval AMOUNT DESCRIPTION [-a ACCOUNT]
/open List Pending / Scheduled / Planned / Deferred transactions
/settle UUID Mark transaction as Paid/Received, update date to today
/csv Send Transactions sheet as CSV file
/accounts List valid accounts
/concepts List valid categories (from user's Budgets sheet)
Examples:
/expense 25.50 Mercadona -c Comida -a Revolut
/income 2800 Salary -c Nómina -a Cuenta
/investment 500 Fondos -a Indexed
/expense 50 Dentista -s Pending
Automated Digests (Cron)¶
| Cron | Handler | Content |
|---|---|---|
0 8 * * * |
DailyDigestCron |
Yesterday's transactions, net balance, per-diem real vs ideal, days to payday |
0 8 * * 1 |
WeeklySummaryCron |
Last week summary by category + Gemini AI analysis |
0 7 * * * |
DeferredSettleCron |
Auto-settle deferred transactions whose date ≤ today |
Google Sheet Structure¶
Each user has their own Sheet (copy of the template).
| Sheet | Purpose |
|---|---|
Transactions |
Main data: Date, Description, Category, Type, Amount, Account, Status, Notes, _Year, _Month, _ID |
Dashboard |
SUMAPRODUCTO formulas, period selectors, payday, period start |
Budgets |
Budget vs actual by category (column A = valid category names) |
Savings & Invest |
Manual monthly net-worth snapshot |
Changelog |
Auto-generated daily snapshots |
_Cobros |
Hidden: payday dates, savings delta, savings absolute |
Accounts¶
| Account | Category | Notes |
|---|---|---|
Revolut |
Liquid | Default |
Cuenta |
Liquid | |
Ventus |
Liquid | |
Efectivo |
Liquid | Cash |
Joint |
Blocked (50%) | Shared with partner |
Indexed |
Blocked | Index fund investments |
Volatile |
Blocked (excluded) | Speculative investments |
Stable |
Blocked | Other stable capital |
Net Worth Philosophy¶
- Liquid: Revolut + Cuenta + Ventus + Efectivo
- Net worth base: Liquid + Joint (50%) + Indexed
- Excluded from per-diem: Volatile (speculative)
- Blocked capital: Joint + Indexed + Volatile
Commercialisation¶
- Google Workspace Marketplace add-on potential
- Single Telegram bot, multi-tenant via D1
- User owns their data in their own Google Drive
- Pricing: one-time setup fee or monthly subscription