A personal finance tracking bot for Telegram.
Record expenses and income directly into Google Sheets, with automated daily and monthly reports.
- Record expenses and income via a guided Telegram conversation
- Data stored in Google Sheets (Expenses, Income, Dashboard)
- Automated daily report at 18:00 with spending breakdown
- Automated monthly report on the last day of each month with month-over-month comparison
/summarycommand for on-demand monthly overview- Runs as a systemd service on Ubuntu
| Tool | |
|---|---|
| Language | Python 3.12 |
| Telegram | python-telegram-bot v21.9 |
| Sheets | gspread v6.x + Google Sheets API |
| Charts | matplotlib |
| Process | systemd |
finance-node-bot/
├── main.py # Entry point, logging setup, scheduled jobs
├── send_test_reports.py # Manual trigger — sends both reports using real data
├── requirements.txt # Pinned dependencies
├── src/
│ ├── bot.py # Telegram bot handlers and conversation flow
│ ├── sheets.py # Google Sheets read/write operations
│ ├── report.py # Chart generation (daily, monthly, summary)
│ └── config.py # Environment variable loading and startup validation
├── reports/ # Generated PNG reports (gitignored)
├── .env # Secrets (gitignored)
└── credentials.json # Google Service Account key (gitignored)
1. Google Service Account
- Go to Google Cloud Console
- Create a new project
- Enable Google Sheets API and Google Drive API
- Create a Service Account → download JSON key as
credentials.json - Share your Google Sheet with the service account email (Editor access)
2. Telegram Bot
- Open @BotFather on Telegram
/newbot→ follow prompts to get a bot token- Send any message to your bot, then fetch your chat ID:
python3 -c "
import asyncio
from telegram.ext import Application
async def get_id():
app = Application.builder().token('YOUR_BOT_TOKEN').build()
async with app:
updates = await app.bot.get_updates()
for u in updates:
print('Chat ID:', u.effective_chat.id)
asyncio.run(get_id())
"3. Environment Variables
Create a .env file:
TELEGRAM_BOT_TOKEN=your_bot_token
TELEGRAM_CHAT_ID=your_chat_id
GOOGLE_CREDENTIALS_PATH=/absolute/path/to/credentials.json
GOOGLE_SHEET_ID=your_google_sheet_id
GOOGLE_SHEET_NAME=Finance Node4. Install Dependencies
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt5. Run as systemd Service
Create /etc/systemd/system/finance-bot.service:
[Unit]
Description=Finance Node Telegram Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/finance-node-bot
ExecStart=/path/to/finance-node-bot/venv/bin/python3 main.py
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable finance-bot.service
sudo systemctl start finance-bot.service| Command | Description |
|---|---|
/add |
Record a new transaction (guided flow) |
/summary |
Monthly summary with donut chart (income vs expenses) |
/cancel |
Cancel the current flow |
Template: Finance Node — Google Sheet Template → Go to File → Make a copy to use it.
| Sheet | Columns |
|---|---|
| Expenses | Date, Vendor, Amount, Category, Note |
| Income | Date, Source, Amount, Category, Note |
| Dashboard | Auto-calculated summaries and recent transactions |
Daily — sent at 22:00 every day
- KPI cards: spent today, income today, monthly balance, transactions
- Monthly spend progress bar
- Spending breakdown by category with horizontal bars
Monthly — sent at 22:00 on the last day of each month
- KPI cards: income, expenses, saved, savings rate
- Daily spending bar chart (days 1–31) with average line
- Category breakdown donut chart with amounts and percentages
- Caption includes top spending category and total transaction count
Bot exits immediately on start
The config validates all required environment variables at startup. Check the error message — it will tell you exactly which variable is missing or which credentials file path is wrong.
[config] Missing required environment variables: GOOGLE_SHEET_ID
[config] Google credentials file not found: /path/to/credentials.json
Google Sheets API error after running a while
The Sheets client is cached per session. If the connection drops, it resets automatically on the next request. If errors persist, check that the service account still has Editor access to the sheet.
Reports not sending
Check the bot logs — file-not-found errors on report generation are now logged separately from other report errors.
sudo journalctl -u finance-bot.service -fMIT