1

Panoramica del progetto

Cosa fa e come funziona

Monitora Prezzi è una web app che gira su Raspberry Pi, sempre acceso, e monitora automaticamente i prezzi dei prodotti su Amazon, eBay e altri siti e-commerce.

Funzionalità principali

  • Aggiunta prodotti tramite URL (Amazon, eBay, siti generici)
  • Monitoraggio automatico ogni 15 minuti
  • Notifica email quando il prezzo scende o raggiunge l'obiettivo
  • Notifiche browser in tempo reale
  • Storico prezzi con grafico
  • Sistema multi-utente con login
  • Installabile come PWA (app) su telefono

Architettura

  • Backend: Node.js + Express
  • Scraping: Axios + Cheerio
  • Database: File JSON locale (prezzi.json)
  • Scheduler: node-cron
  • Email: Nodemailer + Gmail
  • Auth: JWT + bcryptjs
  • Web server: Apache con SSL (Let's Encrypt)
💡 Il Raspberry Pi è sempre acceso e controlla i prezzi in autonomia. Tu ricevi una email solo quando c'è una variazione interessante.
2

Struttura dei file

Organizzazione del progetto
monitora-prezzi/ ├── server.js # Server Express principale + scheduler ├── db.js # Gestione database JSON ├── scraper.js # Logica scraping prezzi ├── package.json # Dipendenze Node.js ├── config.json # Email Gmail + JWT secret (NON condividere!) ├── prezzi.json # Database (creato automaticamente) └── public/ ├── index.html # Interfaccia utente ├── style.css # Stili ├── app.js # JavaScript frontend ├── manifest.json # Configurazione PWA ├── sw.js # Service Worker (offline/PWA) ├── icon.png # Icona app (PWA + email) └── logo.png # Logo email
⚠️ config.json contiene le credenziali Gmail. Non condividerlo mai e non caricarlo su GitHub o servizi cloud.
3

Prerequisiti

Cosa serve prima di iniziare

Sul Raspberry Pi

  • Raspberry Pi con Raspberry OS (Debian)
  • Node.js v18 o superiore
  • Apache2 installato con certificato SSL (Let's Encrypt)
  • Accesso SSH attivo
  • IP statico locale (consigliato) o DHCP reservation

Sul PC

  • FileZilla (per trasferire i file via SFTP)
  • Un client SSH (es. PuTTY su Windows o terminale)

Account necessari

  • Account Gmail per l'invio notifiche email
  • App Password Gmail (non la password normale)
  • Dominio dinamico (es. sytes.net tramite No-IP)

Come ottenere la App Password Gmail

1

Vai su myaccount.google.comSicurezza

2

Attiva la Verifica in due passaggi se non è già attiva

3

Cerca "Password per le app" → App: Posta, Dispositivo: Altro → nome: monitora-prezzi

4

Clicca Genera → copia la password di 16 caratteri (tipo xxxx xxxx xxxx xxxx)

4

Trasferimento file con FileZilla

Come copiare i file dal PC al Raspberry
ℹ️ FileZilla usa il protocollo SFTP (SSH File Transfer Protocol) per trasferire file in modo sicuro al Raspberry Pi.

Connessione FileZilla

CampoValore
Hostsftp://tuodominio.sytes.net
Nome utentepi
Passwordpassword SSH del Raspberry
Porta22

Cosa trasferire

1

Nel pannello destro di FileZilla, naviga in /home/pi/ e crea la cartella monitora-prezzi

2

Trascina nella cartella questi file (dal PC):

  • server.js, db.js, scraper.js, package.json, package-lock.json
  • La cartella intera public/
🚫 Non caricare la cartella node_modules (è enorme e si reinstalla direttamente sul Raspberry) né il file prezzi.json.
5

Installazione dipendenze Node.js

npm install sul Raspberry

Connettiti via SSH al Raspberry e installa i pacchetti:

cd ~/monitora-prezzi
npm install
npm install cheerio@1.0.0    # versione compatibile con Node 18

Il comando scarica tutte le librerie definite in package.json. Puoi ignorare i WARN, gli errori importanti iniziano con npm error.

Dipendenze principali

PacchettoScopo
expressServer web
axiosRichieste HTTP per lo scraping
cheerioParsing HTML (come jQuery lato server)
node-cronScheduler per controlli automatici
nodemailerInvio email
bcryptjsHash delle password utenti
jsonwebtokenAutenticazione JWT
corsGestione CORS per le API
6

PM2 - Avvio automatico

Tieni l'app sempre attiva, anche dopo riavvii

PM2 è un process manager per Node.js. Tiene l'app in esecuzione 24/7 e la riavvia automaticamente se crasha o se il Raspberry viene riavviato.

# Installa PM2 globalmente
sudo npm install -g pm2

# Avvia l'app
pm2 start server.js --name monitora-prezzi

# Configura avvio automatico al boot
pm2 startup
# IMPORTANTE: esegui il comando che ti mostra (inizia con "sudo env PATH=...")

# Salva la configurazione
pm2 save

Comandi PM2 utili

ComandoCosa fa
pm2 statusMostra stato dell'app
pm2 restart monitora-prezziRiavvia (dopo aggiornamenti)
pm2 logs monitora-prezziVedi i log in tempo reale
pm2 logs monitora-prezzi --lines 50Ultimi 50 log
pm2 stop monitora-prezziFerma l'app
Dopo pm2 save, l'app si avvia automaticamente ad ogni accensione del Raspberry, senza intervento manuale.
7

Configurazione email Gmail

Per ricevere notifiche quando il prezzo scende

Crea il file config.json direttamente sul Raspberry via SSH:

nano ~/monitora-prezzi/config.json

Inserisci questo contenuto (con i tuoi dati):

{
  "email": {
    "from": "tuoemail@gmail.com",
    "to": "tuoemail@gmail.com",
    "password": "xxxx xxxx xxxx xxxx"
  }
}

Salva con CTRL+X → Y → Invio

  • from → il Gmail che invia le email
  • to → non più usato (le email vanno alla mail di ogni utente)
  • password → la App Password di 16 caratteri (non la password Gmail normale)

Test invio email

curl -X POST http://localhost:3000/api/settings/test-email \
  -H "Authorization: Bearer TUO_TOKEN_JWT"
⚠️ Se usi Gmail app su Android, vai su Impostazioni → tuo account → Immagini → Mostra sempre immagini esterne per vedere il logo nelle email.
8

Apache + HTTPS

Esponi l'app su internet con certificato SSL
💡 Apache fa da reverse proxy: riceve le richieste HTTPS sulla porta 3443 e le gira all'app Node.js sulla porta 3000 (locale). Così l'app è raggiungibile in HTTPS senza modificare il codice Node.js.

1. Abilita moduli Apache

sudo a2enmod proxy proxy_http ssl
sudo systemctl restart apache2

2. Crea configurazione

sudo nano /etc/apache2/sites-available/monitora-prezzi.conf

Incolla:

Listen 3443

<VirtualHost *:3443>
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/TUODOMINIO.sytes.net/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/TUODOMINIO.sytes.net/privkey.pem

    ProxyPreserveHost On
    ProxyPass / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/
</VirtualHost>

Sostituisci TUODOMINIO con il tuo dominio reale.

3. Attiva e riavvia

sudo a2ensite monitora-prezzi.conf
sudo systemctl restart apache2

L'app sarà accessibile su https://TUODOMINIO.sytes.net:3443

9

Port forwarding sul router

Rendi il Raspberry raggiungibile da internet
💡 Il port forwarding dice al router: "quando arriva una richiesta su questa porta, mandala al Raspberry Pi". Senza questa configurazione, il Raspberry è raggiungibile solo dalla rete di casa.

Trova l'IP locale del Raspberry

hostname -I

Prendi il primo indirizzo IPv4 (es. 192.168.1.180).

Regole da aggiungere sul router Vodafone

Accedi al pannello del router su 192.168.1.1Avanzate → NAT → Associazione porte

Porta pubblicaPorta localeIP localeProtocolloScopo
2222192.168.1.180TCPSSH
8080192.168.1.180TCPHTTP sito
443443192.168.1.180TCPHTTPS sito
34433443192.168.1.180TCPApp Monitora Prezzi
⚠️ Consigliato assegnare un IP statico locale al Raspberry nel router (DHCP reservation), altrimenti l'IP potrebbe cambiare e il port forwarding smetterebbe di funzionare.
10

PWA - Installa come app

Aggiungi l'app alla schermata Home del telefono
💡 Una PWA (Progressive Web App) si installa sul telefono come un'app nativa ma è in realtà una web app. Richiede HTTPS per funzionare.

I file necessari sono già inclusi nel progetto:

  • public/manifest.json → descrive l'app (nome, icona, colori)
  • public/sw.js → Service Worker per funzionamento offline
  • public/icon.png → icona che appare sulla home screen

Come installare su Android (Chrome)

1

Apri Chrome e vai su https://TUODOMINIO.sytes.net:3443

2

Tocca i 3 puntini in alto a destra → "Aggiungi a schermata Home"

3

Conferma → l'icona appare nella schermata Home come un'app normale

Come installare su iPhone (Safari)

1

Apri Safari (non Chrome) e vai sull'URL dell'app

2

Tocca il pulsante Condividi (quadrato con freccia) → "Aggiungi a schermata Home"

11

Sistema di login multi-utente

Gestione accessi e notifiche personalizzate

Creazione primo utente admin

La prima volta, nessun utente esiste. Crea l'admin con questo comando SSH:

curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"username":"giuseppe","password":"tuapassword","email":"tua@gmail.com"}'
Il primo utente creato diventa automaticamente admin. Gli admin successivi devono essere designati esplicitamente.

Gestione utenti dall'interfaccia

Accedi come admin → clicca sul tuo nome in alto a destra → Gestione Utenti:

  • Aggiungi utente → username, email, password, flag admin
  • Reset password → se un utente dimentica la password
  • Elimina utente → rimuove utente e tutti i suoi prodotti

Come funzionano le notifiche multi-utente

  • Ogni utente vede solo i propri prodotti
  • Le notifiche email vengono inviate alla mail del singolo utente
  • L'email è inviata dal Gmail configurato in config.json
  • Ogni utente può impostare il proprio prezzo obiettivo per ogni prodotto

Sicurezza

  • Le password sono salvate con hash bcrypt (non in chiaro)
  • L'autenticazione usa token JWT con scadenza 30 giorni
  • Ogni API richiede un token valido nell'header Authorization
12

Utilizzo quotidiano

Come usare l'app giorno per giorno

Aggiungere un prodotto

1

Apri la pagina prodotto su Amazon/eBay nel browser

2

Copia l'URL dalla barra degli indirizzi

3

Incollalo nel campo URL dell'app e (opzionale) inserisci il prezzo obiettivo

4

Clicca Aggiungi → l'app recupera subito il prezzo attuale

⚠️ Amazon usa sistemi anti-bot. Il prezzo potrebbe non essere rilevato al primo tentativo. In quel caso premi "Aggiorna" dopo qualche minuto.

Siti supportati

SitoAffidabilitàNote
Amazon IT/EU⭐⭐⭐Anti-bot attivo, a volte richiede più tentativi
eBay⭐⭐⭐⭐Selettori dedicati, funziona bene
MediaWorld⭐⭐⭐⭐⭐JSON-LD strutturato, molto affidabile
Unieuro⭐⭐⭐⭐JSON-LD strutturato
Euronics⭐⭐⭐⭐Selettori dedicati
Siti WooCommerce⭐⭐⭐⭐Selettori standard WooCommerce
Siti generici⭐⭐⭐Usa selettori comuni, variabile
💡 Se un sito mostra "Prezzo non rilevato", il sito potrebbe usare JavaScript per caricare il prezzo dinamicamente (non visibile allo scraper). In quel caso quel sito specifico non è supportato.

Quando ricevo le notifiche?

  • Quando aggiungi un prodotto e il prezzo è già sotto l'obiettivo
  • Quando il prezzo scende rispetto all'ultimo rilevamento
  • Quando il prezzo raggiunge l'obiettivo impostato

Frequenza controlli

L'app controlla i prezzi automaticamente ogni 15 minuti. Puoi forzare un controllo immediato con il pulsante "Aggiorna" sulla card del prodotto, o "Controlla tutti" per aggiornarli tutti.

13

Comandi utili SSH

Riferimento rapido per manutenzione

PM2

pm2 status                          # stato app
pm2 restart monitora-prezzi         # riavvia (dopo aggiornamenti file)
pm2 logs monitora-prezzi --lines 30 # ultimi 30 log
pm2 monit                           # monitor CPU/RAM in tempo reale

Aggiornare l'app (dopo modifiche file)

# 1. Carica i file aggiornati con FileZilla
# 2. Dal terminale SSH:
pm2 restart monitora-prezzi

Backup del database

Il file prezzi.json contiene tutto: utenti, prodotti, storico prezzi e notifiche. Fanne backup regolarmente!

Manuale (FileZilla): scarica /home/pi/monitora-prezzi/prezzi.json sul PC quando vuoi.

Automatico giornaliero: aggiungi un cron job che fa backup ogni notte alle 3:00 e mantiene solo gli ultimi 7 giorni:

crontab -e

Aggiungi in fondo al file:

0 3 * * * cp ~/monitora-prezzi/prezzi.json ~/backup-prezzi-$(date +\%Y\%m\%d).json && ls -t ~/backup-prezzi-*.json | tail -n +8 | xargs rm -f
⚠️ Se la scheda SD del Raspberry si corrompe senza backup, si perdono tutti i prodotti monitorati e gli utenti registrati.

Cambiare frequenza controllo prezzi

Modifica in server.js:

cron.schedule('*/15 * * * *', checkAllPrices);
//               ^^^
//               ogni 15 minuti (cambia questo numero)

Forzare controllo immediato di tutti i prodotti

Ottieni il token JWT dalla console del browser (F12 → Console):

localStorage.getItem('mp_token')

Poi esegui via SSH:

curl -X POST http://localhost:3000/api/check-all \
  -H "Authorization: Bearer TUO_TOKEN_JWT"
💡 In alternativa usa il pulsante "Controlla tutti" nell'app web — più semplice ma controlla solo i prodotti dell'utente loggato. Il comando SSH controlla i prodotti di tutti gli utenti.

Cambiare la password admin via SSH

# Ottieni prima il token JWT facendo login dall'app
# Poi usa il token per resettare la password di un utente (ID=1):
curl -X PATCH http://localhost:3000/api/users/1/password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TUO_TOKEN" \
  -d '{"password":"nuovapassword"}'

Riavvio completo del Raspberry

sudo reboot
# Dopo il riavvio PM2 farà ripartire l'app automaticamente
Dopo ogni modifica ai file ricordati sempre di eseguire pm2 restart monitora-prezzi per applicare le modifiche.