Sistema automático de gestión de gastos. Envías una factura por Telegram, la IA extrae los datos y aparecen publicados en tu panel web en tiempo real.
Repo: https://github.com/moestilos/facturasbot Bot demo: @facturasmobot
┌────────────┐ ┌────────────────┐ ┌──────────────┐
│ Telegram │─img──▶│ Backend TS │──API─▶│ Gemini 2.5 │
│ (usuario) │◀─txt──│ grammy + SIO │◀─JSON─│ Flash │
└────────────┘ │ SQLite │ └──────────────┘
└───────┬────────┘
│ WebSocket realtime
┌───────▼────────┐
│ Frontend │
│ Next.js 15 │
└────────────────┘
Para el detalle completo ver docs/ARCHITECTURE.md.
- Backend: Node 22+, TypeScript, Express, Socket.io,
grammy(Telegram),@google/generative-ai,node:sqlite. - Frontend: Next.js 15 (App Router), Tailwind 3, Framer Motion,
lucide-react,socket.io-client. - IA: Gemini 2.5 Flash (vision multimodal, JSON mode).
apps/expense-bot/
├── README.md ← este archivo
├── .gitignore
├── docs/ ← documentación viva
│ ├── ARCHITECTURE.md
│ ├── DECISIONS.md ← ADRs (por qué Telegram, Gemini, etc.)
│ ├── CHANGELOG.md
│ └── DEPLOY.md ← cómo poner esto en producción
├── backend/
│ ├── src/
│ │ ├── index.ts ← Express + Socket.io
│ │ ├── telegram.ts ← bot (grammy)
│ │ ├── gemini.ts ← extracción IA
│ │ ├── db.ts ← SQLite
│ │ └── types.ts
│ ├── package.json
│ ├── tsconfig.json
│ └── .env.example
├── frontend/
│ └── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx ← dashboard
│ │ └── globals.css
│ ├── components/
│ │ ├── qr-panel.tsx
│ │ ├── stats-cards.tsx
│ │ └── expense-table.tsx
│ └── lib/
│ ├── socket.ts
│ └── utils.ts
└── data/
└── uploads/ ← imágenes recibidas (gitignored)
- Node.js 22+ (24 recomendado, probado en 24.13).
- Bot de Telegram (token de @BotFather).
- API key de Gemini (gratis en https://aistudio.google.com/apikey).
Copia el ejemplo y edita:
cp backend/.env.example backend/.envPORT=3001
FRONTEND_ORIGIN=http://localhost:3000
GEMINI_API_KEY=tu_api_key
GEMINI_MODEL=gemini-2.5-flash
TELEGRAM_BOT_TOKEN=tu_token_bot
DB_PATH=./expenses.dbEn dos terminales separadas:
# terminal 1: backend
cd backend
npm install
npm run dev
# → http://localhost:3001# terminal 2: frontend
cd frontend
npm install
npm run dev
# → http://localhost:3000- Abre el panel en http://localhost:3000.
- Escanea el QR o toca Abrir en Telegram (abre el chat con el bot).
- Envía
/startal bot. - Manda una foto de un ticket/factura (o PDF).
- El bot responde
⏳ Procesando...y luego el resumen. - En paralelo aparece la fila nueva en la tabla del panel, con flash dorado.
| Método | Ruta | Descripción |
|---|---|---|
| GET | /api/health |
Estado general + conexión bot |
| GET | /api/status |
Solo estado de conexión |
| GET | /api/stats |
Totales (hoy/mes/acumulado/nº) |
| GET | /api/expenses |
Últimos 200 gastos |
| Evento | Payload |
|---|---|
status |
ConnectionStatus |
expenses:init |
Expense[] |
expense:new |
Expense |
stats |
Stats |
log |
string |
- docs/ARCHITECTURE.md — diagrama detallado, flujo, componentes, schema DB, variables de entorno.
- docs/DECISIONS.md — ADRs: por qué Telegram, por qué Gemini 2.5, por qué
node:sqlite. - docs/DEPLOY.md — guías de deploy en Railway, Fly.io + Vercel, VPS.
- docs/CHANGELOG.md — historial de versiones.
Hay 3 caminos según presupuesto y control:
| Opción | Coste | Setup |
|---|---|---|
| Railway | ~$5/mes | 15 min |
| Fly.io + Vercel | Gratis | 30 min |
| VPS | €4/mes | 1 h |
Detalle completo en docs/DEPLOY.md.
rm backend/expenses.db*
rm -rf data/uploads/*- Nunca committees
.env,expenses.dbnidata/uploads/(ya gitignored). - Si se filtra el token de Telegram → rotar desde @BotFather.
- Si se filtra la API key de Gemini → revocar en https://aistudio.google.com/apikey.
Privado. Uso interno del proyecto.