An AI-powered Telegram bot that automatically extracts, categorizes, and logs personal expenses from natural language messages and receipt screenshots.
SpendSnap replaces manual expense logging with an instant chat interface. Users send transaction notes or photo receipts, and the bot parses key metadata into structured JSON records for personal financial tracking.
- Natural Language Parsing: Automatically identifies transaction amounts, dates, and items from conversational text.
- Receipt OCR: Extracts text from transaction screenshots and printed physical receipts using system OCR and Llama 3.3 70B.
- Automated Categorization: Classifies expenses into standardized categories (Food, Travel, Transportation, Utilities, Shopping, Entertainment, Healthcare, Education, Housing, Miscellaneous).
- Multi-Currency Support: Handles regional currency formats (USD, INR, EUR, etc.) and auto-formats monetary values.
- Structured Schema Validation: Enforces strict Pydantic JSON outputs for downstream database ingestion.
- Python 3.10+
- Tesseract OCR installed on system PATH
- Groq Cloud API Key
- Telegram Bot Token from @BotFather
git clone https://github.com/Kusagra9308/SpendSnap.git
cd SpendSnap
python -m venv venv
source venv/bin/activate # On Windows: .\venv\Scripts\Activate.ps1
pip install -r requirements.txtCreate a .env file in the root directory:
GROQ_API_KEY=your_groq_api_key
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
# Optional: Only needed if Tesseract binary is not on system PATH
# TESSERACT_CMD=/usr/bin/tesseract # Linux/macOS
# TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe # Windowspython bot/my_bot.pySend commands or messages to your bot on Telegram:
/start— View welcome message and instructions./summary— Request expense summary report.- Text Entry: Send any expense message (e.g.,
"Paid 450 INR for groceries"). - Photo Entry: Send a photo of a receipt or payment screenshot with an optional caption.
User: "Spent $35 on gas and $12 on lunch at Subway"
Bot Reply:
{
"amount": 47.0,
"category": "Transportation",
"transaction_date": "2026-08-02"
}
from backend.graph.workflow import first_graph
# Invoke graph directly
result = first_graph.invoke({
"input_type": "text",
"text": "Paid $45 for gas today",
"image_path": None
})
print(result["reply"][-1].content)
# Output: {"amount": 45.0, "category": "Transportation", "transaction_date": null}flowchart TD
User([Telegram User]) -->|Text / Photo Message| Bot[Telegram Bot Handler: bot/my_bot.py]
Bot -->|Invoke Graph State| Graph[LangGraph Workflow: backend/graph/workflow.py]
Graph -->|Conditional Routing| Route{Input Type?}
Route -->|Text Message| TextNode[Text Processing Node: welcome]
Route -->|Photo / Screenshot| OCRNode[Receipt OCR Node: welcome1 + Tesseract]
TextNode --> LLM[Groq Llama 3.3 70B + Pydantic Schema]
OCRNode --> LLM
LLM -->|Structured JSON Output| Bot
Bot -->|Formatted Reply| User
- Database Persistence: Currently outputs extracted JSON records without writing to a database.
- Dynamic Summary Queries:
/summarycommand is static pending database integration. - Groq Vision LLM: Upgrade OCR pipeline from Tesseract to native multi-modal vision LLMs (
llama-3.2-11b-vision).
Contributions, bug reports, and feature requests are welcome. Feel free to check the issues page or submit a pull request.
Distributed under the MIT License.