Bot Telegram per monitorare i prezzi dei titoli della Borsa Italiana e inviare notifiche automatiche quando i prezzi superano o scendono al di sotto delle soglie target impostate dagli utenti.
- Monitoraggio prezzi in tempo reale dei titoli della Borsa Italiana
- Sistema di alert bidirezionali con notifiche Telegram per superamento e discesa delle soglie
- Interfaccia bot Telegram con menu comandi intuitivo
- Integrazione API sicura con Borsa Italiana
- Database MongoDB per persistenza dati
- CronJob automatico per controllo prezzi periodico
- Graceful shutdown con stop ordinato di bot, server, job e database
- Gestione utenti con profili personalizzati
- Logging strutturato con Pino
- Containerizzazione Docker per deployment semplificato
- Linguaggio: TypeScript (strict mode)
- Framework/Librerie:
- Database: MongoDB con Prisma
- Containerizzazione: Docker
- Pattern: Singleton, Separation of Concerns
- Node.js >= 18
- MongoDB (locale o cloud)
- Docker (opzionale, per setup containerizzato)
-
Clona il repository:
git clone https://github.com/tuousername/bot_borsa_italiana_alert.git cd bot_borsa_italiana_alert -
Installa le dipendenze:
npm install
-
Configura le variabili ambiente:
- Copia
.env.examplein.envnella root del progetto e compila i valori richiesti (vedi sotto)
- Copia
-
Avvia MongoDB:
- Localmente:
docker-compose up -d mongodb - Oppure usa la tua istanza MongoDB
- Localmente:
-
Esegui le migrazioni del database:
npx prisma generate npx prisma db push
-
Avvia il bot in sviluppo:
npm run dev
-
Oppure avvia con Docker:
docker-compose up -d
Crea un file .env nella root del progetto con le seguenti variabili:
# Bot Telegram
BOT_TOKEN=your_telegram_bot_token
# Database MongoDB
DATABASE_URL=mongodb://localhost:27017/borsa_italiana_alert
# API Borsa Italiana
BORSA_ITALIANA_API=your_borsa_italiana_api_endpoint
BORSA_ITALIANA_API_TAIL=your_borsa_italiana_api_tail_endpoint
BORSA_ITALIANA_JWT=your_borsa_italiana_jwt_token
# Express Server
PORT=3000
# Environment
NODE_ENV="development or production"npm run dev— Avvia il bot in modalità sviluppo (hot reload)npm start— Avvia il bot in modalità produzione
docker-compose up -d— Avvia bot e MongoDB in containerdocker-compose down— Ferma e rimuove i container
/start— Avvia il bot e registra l'utente/prezzo <ISIN>— Mostra il prezzo attuale di un titolo/alert <ISIN> <prezzo>— Crea un alert per un titolo/alerts_attivi— Lista tutti gli alert attivi dell'utente/elimina_alerts— Elimina tutti gli alert dell'utente
/prezzo IT0003128367
/alert IT0003128367 15.50
/alerts_attivi
Il bot monitora automaticamente i prezzi dei titoli configurati e invia notifiche intelligenti quando:
- 🟢 Prezzo supera la soglia target (condizione "above") - Notifica di opportunità di vendita
- 🔴 Prezzo scende sotto la soglia target (condizione "below") - Notifica di opportunità di acquisto
Il sistema utilizza una logica bidirezionale che distingue tra:
- Condizioni di superamento (prezzo > target)
- Condizioni di discesa (prezzo < target)
- Condizioni di equilibrio (prezzo = target) - Nessuna notifica
- Modalità Test: Controllo ogni minuto
- Modalità Produzione: Controllo ogni 2 minuti (lun-ven, 07:00-18:55)
├── src/
│ ├── handlers/ # Logica di business (bot, alert, api, database, error)
│ │ ├── bot/ # Gestione bot Telegram
│ │ ├── alert/ # Logica alert e notifiche
│ │ ├── api/ # Integrazione API esterne
│ │ ├── database/ # Operazioni database
│ │ ├── server # Express server
│ │ └── error/ # Gestione errori
│ ├── utils/ # Utility helpers (es. formattazione prezzi)
│ ├── types/ # Tipi TypeScript
│ ├── dto/ # Data Transfer Objects
│ ├── interfaces/ # Interfacce TypeScript
│ ├── enums/ # Enumerazioni
│ ├── consts/ # Costanti (API endpoints)
│ ├── jobs/ # CronJob e task schedulati
│ ├── lifecycle/ # Lifecycle app (es. graceful shutdown)
│ ├── logger/ # Configurazione logging
│ ├── schemas/ # Schemi Zod per validazione input
│ └── main.ts # Punto di ingresso
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD: deploy automatico su VPS al push su main
├── prisma/ # Schema database e migrazioni
├── docker-compose.yml # Configurazione Docker
├── package.json
├── tsconfig.json
└── README.md
Il repository include una pipeline CI/CD in /.github/workflows/deploy.yml che esegue il deploy automatico su VPS ad ogni push sul branch main.
- All'evento
pushsumain, la pipeline:- decodifica la chiave PEM in formato Base64 configurata nei Secrets
- si connette via SSH al VPS (es. istanza EC2) usando la chiave PEM
- fa
git pullnella cartella del progetto sul server - riavvia il container Docker solo se ci sono modifiche
Configura questi Secrets nel repository (Settings → Secrets and variables → Actions):
VPS_USER— utente SSH del server (es.ubuntuper macchine EC2 Ubuntu)VPS_PEM_BASE64— il contenuto della tua chiave privata.pemconvertita in Base64 (puoi generarlo concat tuachiave.pem | base64 -w 0da terminale Linux/Mac)VPS_HOST— host/IP pubblico del VPS (es.1.2.3.4)
La pipeline si aspetta che il progetto sul VPS sia in /home/ubuntu/BorsaItalianaAlert e che il server abbia Docker installato (se usi un utente diverso da ubuntu, ad esempio, potresti dover modificare il percorso nella Action).
- Singleton Pattern: Implementato in tutti gli handler per garantire istanze uniche
- Service Locator leggero: Le singleton vengono risolte tramite
getInstance()nei moduli di orchestrazione - Separation of Concerns: Ogni handler ha responsabilità specifiche
- Error Handler centralizzato per gestione uniforme degli errori
- Try-catch consistenti in tutti i metodi
- Logging strutturato con Pino per debugging
All'avvio dell'app il flusso è il seguente:
main.tsregistra gli handler di shutdown (SIGINT,SIGTERM) tramiteregisterProcessShutdownHandlers().- Viene avviato il server Express per l'endpoint health-check.
- Viene aperta la connessione al database MongoDB tramite Prisma.
- Viene avviato il bot Telegram e inizializzati comandi/menu.
- Parte il job di monitoraggio prezzi:
NODE_ENV=development→ job test (ogni minuto)NODE_ENV=production→ job produzione (lun-ven, 07:00-18:55, ogni 2 minuti)
Quando arriva un segnale di stop o un errore in startup:
- Viene attivato
shutdown(exitCode, reason). - Il job di monitoraggio viene fermato.
- In parallelo vengono chiusi:
- bot Telegram
- server Express
- connessione database
- L'app termina con
process.exit(exitCode):0su shutdown volontario (SIGINT,SIGTERM)1su errore di startup
- Interfacce TypeScript per tutte le strutture dati
- Type Guards per validazione runtime delle risposte API e opzioni Telegram
- Tipi centralizzati in
src/types/per riutilizzabilità - DTO pattern per trasferimento dati sicuro
- Validazione input con Zod: tutti gli input utente e parametri sono validati tramite schemi definiti in
src/schemas/
Gli input provenienti dagli utenti (comandi Telegram e parametri) sono validati con Zod. Questo garantisce formati coerenti, messaggi di errore chiari e tipizzazione inferita.
- Posizione schemi:
src/schemas/ - File principale:
src/schemas/input-validator.schema.ts
model User {
telegramId Int @id
name String
username String?
alerts Alert[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Alert {
id String @id @default(auto()) @map("_id")
isin String
label String
alertPrice Float
lastCondition Condition
lastCheckPrice Float
userTelegramId Int
user User @relation(fields: [userTelegramId], references: [telegramId])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userTelegramId])
@@index([userTelegramId, isin, alertPrice])
}
enum Condition {
above
below
equal
}- Endpoint: Integrazione con API ufficiali Borsa Italiana
- Autenticazione: Bearer token JWT
- Rate Limiting: Gestione automatica delle chiamate API
- Validazione: Type guards per risposte API; Zod per input utente
- Raggruppamento ISIN: Riduzione chiamate API duplicate
- Caching implicito: Riutilizzo prezzi per alert multipli
- Error handling: Gestione graceful degli errori API
- Concorrenza controllata: chiamate HTTP in parallelo con p-limit
- HTTP keep-alive: client Axios dedicato con
http/https.Agent(pool connessioni,timeout10 secondi)
Le pull request sono benvenute! Per modifiche importanti, apri prima un issue per discutere le modifiche proposte.
Questo progetto è sotto licenza MIT. Vedi il file LICENSE per i dettagli.
Nota: Questo bot è per uso educativo e personale. Assicurati di rispettare i termini di servizio delle API utilizzate.