fix send mail with python script

This commit is contained in:
Francesco Picone
2025-12-09 17:35:40 +01:00
parent b79b31df69
commit 568a02251c
5 changed files with 296 additions and 13 deletions

View File

@@ -49,13 +49,10 @@ Piattaforma completa per vendere videolezioni e lezioni live di Pilates. Svilupp
### Requisiti
- **PHP** 7.4 o superiore (8.0+ raccomandato)
- **MySQL** 5.7 o superiore (o MariaDB 10.3+)
- **Python** 3.6 o superiore (per invio email SMTP)
- **Web Server** (Apache, Nginx, o PHP built-in server per sviluppo)
- **Account PayPal** Sandbox (per test) o Business (per produzione)
- **FFmpeg** (opzionale, per conversione automatica video in MP4)
- **PHP** 7.4 o superiore
- **MySQL** 5.7 o superiore (o MariaDB 10.3+)
- **Web Server** (Apache, Nginx, o PHP built-in server per sviluppo)
- **Account PayPal** Sandbox (per test) o Business (per produzione)
### Passo 1: Copia i File
```bash
@@ -115,7 +112,7 @@ define('SECRET_KEY', 'CAMBIA-QUESTA-CHIAVE-CON-STRINGA-CASUALE-LUNGA-E-SICURA');
```
#### Email SMTP con Gmail ⭐ **IMPORTANTE**
Per inviare email (recupero password), configura Gmail SMTP:
Per inviare email (recupero password, registrazione), configura Gmail SMTP:
1. **Abilita verifica 2 fattori** sul tuo account Gmail
2. Vai su [Password per le app](https://myaccount.google.com/apppasswords)
@@ -127,14 +124,30 @@ In `includes/config.php`:
```php
define('USE_SMTP', true); // Attiva SMTP
define('SMTP_HOST', 'smtp.gmail.com');
define('SMTP_PORT', 587);
define('SMTP_PORT', 587); // 587 per TLS, 465 per SSL
define('SMTP_USERNAME', 'tua-email@gmail.com'); // La tua Gmail
define('SMTP_PASSWORD', 'abcd efgh ijkl mnop'); // Password app (16 caratteri)
define('SMTP_ENCRYPTION', 'tls');
define('SMTP_ENCRYPTION', 'tls'); // tls (porta 587) o ssl (porta 465)
```
⚠️ **Non usare la password normale di Gmail**, usa solo la password applicazione!
**Sistema di invio email:**
- Le email vengono inviate tramite script Python (`send_email.py`)
- Python 3.6+ deve essere installato sul server
- Lo script legge automaticamente le credenziali da `config.php`
- Più affidabile e stabile rispetto a SMTP nativo PHP
Verifica installazione Python:
```bash
python3 --version
```
Se Python non è installato:
- **Ubuntu/Debian**: `sudo apt install python3`
- **CentOS/RHEL**: `sudo yum install python3`
- **Windows**: Scarica da [python.org](https://www.python.org/downloads/)
#### PayPal Sandbox (per Test)
1. Vai su [PayPal Developer](https://developer.paypal.com/)
2. Accedi con il tuo account PayPal
@@ -520,11 +533,39 @@ Crea `.htaccess` nella cartella `includes/`:
- La piattaforma è già aggiornata per gestire valori null
- Se vedi ancora warning, verifica che tutti i file siano aggiornati
### Reset Password non funziona
- Verifica che le email vengano inviate correttamente
- Configura SMTP in `config.php` se `mail()` non funziona
- Il token scade dopo 1 ora per sicurezza
- Controlla che la tabella `users` abbia i campi `reset_token` e `reset_expires`
### Reset Password / Email non funzionano
- Verifica che Python 3 sia installato: `python3 --version`
- Controlla credenziali SMTP in `config.php`
- Verifica che `send_email.py` abbia permessi esecuzione
- Testa invio dal profilo admin: pulsante "🧪 Testa Invio Email"
- Il token reset scade dopo 1 ora per sicurezza
- Controlla log errori PHP per dettagli (`error_log()`)
**Test manuale script Python:**
```bash
cd /path/to/pilates-platform
python3 send_email.py '{"to":"test@esempio.com","subject":"Test","html":"<p>Test email</p>"}'
```
**Errori comuni:**
- `python3: command not found` → Installa Python 3
- `Authentication failed` → Verifica password applicazione Gmail
- `Connection refused` → Controlla porta (587 per TLS, 465 per SSL)
- `Script not found` → Verifica che `send_email.py` esista nella root del progetto
- `Permission denied` → Su Linux: `chmod +x send_email.py`
- Il token reset scade dopo 1 ora per sicurezza
- Controlla log errori PHP per dettagli
**Test manuale script Python:**
```bash
cd /path/to/pilates-platform
python3 send_email.py '{"to":"test@esempio.com","subject":"Test","html":"<p>Test email</p>"}'
```
**Errori comuni:**
- `python3: command not found` → Installa Python 3
- `Authentication failed` → Verifica password applicazione Gmail
- `Connection refused` → Controlla porta (587 per TLS, 465 per SSL)
---
@@ -550,6 +591,7 @@ pilates-platform/
├── process_payment.php # Elabora pagamento PayPal
├── stream_video.php # Streaming protetto video (verifica permessi)
├── convert_videos.php # Conversione batch video in MP4 H.264
├── send_email.py # Script Python per invio email SMTP
├── test_password.php # Utility test hash password (debug)
├── test_email.php # Utility test invio email SMTP (debug)
└── README.md # Questo file

View File

@@ -74,7 +74,9 @@ define('MAIL_FROM_NAME', 'Pilates Studio');
define('USE_SMTP', true); // Imposta false per usare mail() PHP di base
// Impostazioni SMTP - Gmail
// NOTA: Le email vengono inviate tramite script Python (send_email.py) per maggiore affidabilità
// Per Gmail: usa password applicazione da https://myaccount.google.com/apppasswords
// Requisito: Python 3.6+ installato sul server (testa con: python3 --version)
define('SMTP_HOST', 'smtp.gmail.com');
define('SMTP_PORT', 587);
define('SMTP_USERNAME', 'pyco.networking@gmail.com'); // Inserisci la tua email Gmail

View File

@@ -433,7 +433,7 @@ function send_email($to, $subject, $message) {
}
/**
* Invia email tramite SMTP (Gmail)
* Invia email tramite script Python
*
* @param string $to Email destinatario
* @param string $subject Oggetto email
@@ -441,6 +441,53 @@ function send_email($to, $subject, $message) {
* @return bool True se inviata, false altrimenti
*/
function send_smtp_email($to, $subject, $message) {
try {
// Prepara dati JSON per lo script Python
$data = json_encode([
'to' => $to,
'subject' => $subject,
'html' => $message
], JSON_UNESCAPED_UNICODE);
// Percorso dello script Python
$script_path = __DIR__ . '/../send_email.py';
// Verifica che lo script esista
if (!file_exists($script_path)) {
error_log("Email Error: Script send_email.py non trovato");
return false;
}
// Esegui script Python
$command = 'python3 ' . escapeshellarg($script_path) . ' ' . escapeshellarg($data) . ' 2>&1';
exec($command, $output, $return_code);
// Parse risposta JSON
$result = json_decode(implode("\n", $output), true);
if ($return_code === 0 && isset($result['success']) && $result['success']) {
return true;
} else {
$error_msg = isset($result['error']) ? $result['error'] : 'Errore sconosciuto';
error_log("Email Error: " . $error_msg);
return false;
}
} catch (Exception $e) {
error_log("Email Error: " . $e->getMessage());
return false;
}
}
/**
* Invia email tramite SMTP PHP nativo (deprecato - usa send_smtp_email)
*
* @param string $to Email destinatario
* @param string $subject Oggetto email
* @param string $message Corpo email (HTML)
* @return bool True se inviata, false altrimenti
*/
function send_smtp_email_legacy($to, $subject, $message) {
try {
// Connessione al server SMTP con supporto SSL/TLS
$context = stream_context_create([

149
send_email.py Normal file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""
Script Python per invio email SMTP
Legge le credenziali da config.php e invia email tramite Gmail
"""
import sys
import json
import re
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from pathlib import Path
def parse_php_config(config_path):
"""Estrae le configurazioni SMTP dal file config.php"""
config = {}
try:
with open(config_path, 'r', encoding='utf-8') as f:
content = f.read()
# Estrai le define con regex
patterns = {
'SMTP_HOST': r"define\('SMTP_HOST',\s*'([^']+)'\)",
'SMTP_PORT': r"define\('SMTP_PORT',\s*(\d+)\)",
'SMTP_USERNAME': r"define\('SMTP_USERNAME',\s*'([^']+)'\)",
'SMTP_PASSWORD': r"define\('SMTP_PASSWORD',\s*'([^']+)'\)",
'SMTP_ENCRYPTION': r"define\('SMTP_ENCRYPTION',\s*'([^']+)'\)",
'MAIL_FROM': r"define\('MAIL_FROM',\s*'([^']+)'\)",
'MAIL_FROM_NAME': r"define\('MAIL_FROM_NAME',\s*'([^']+)'\)",
}
for key, pattern in patterns.items():
match = re.search(pattern, content)
if match:
value = match.group(1)
# Converti porta in intero
if key == 'SMTP_PORT':
config[key] = int(value)
else:
config[key] = value
return config
except Exception as e:
print(json.dumps({
'success': False,
'error': f'Errore lettura config.php: {str(e)}'
}))
sys.exit(1)
def send_email(to_email, subject, html_body, config):
"""Invia email tramite SMTP"""
try:
# Crea messaggio
msg = MIMEMultipart('alternative')
msg['From'] = f"{config['MAIL_FROM_NAME']} <{config['MAIL_FROM']}>"
msg['To'] = to_email
msg['Subject'] = subject
# Aggiungi corpo HTML
html_part = MIMEText(html_body, 'html', 'utf-8')
msg.attach(html_part)
# Connetti al server SMTP
if config['SMTP_ENCRYPTION'] == 'ssl':
# SSL diretto (porta 465)
server = smtplib.SMTP_SSL(config['SMTP_HOST'], config['SMTP_PORT'], timeout=30)
else:
# TLS con STARTTLS (porta 587)
server = smtplib.SMTP(config['SMTP_HOST'], config['SMTP_PORT'], timeout=30)
server.ehlo()
server.starttls()
server.ehlo()
# Login
server.login(config['SMTP_USERNAME'], config['SMTP_PASSWORD'])
# Invia email
server.send_message(msg)
server.quit()
return {
'success': True,
'message': f'Email inviata con successo a {to_email}'
}
except smtplib.SMTPAuthenticationError as e:
return {
'success': False,
'error': f'Autenticazione SMTP fallita: {str(e)}'
}
except smtplib.SMTPException as e:
return {
'success': False,
'error': f'Errore SMTP: {str(e)}'
}
except Exception as e:
return {
'success': False,
'error': f'Errore generico: {str(e)}'
}
def main():
"""Funzione principale"""
if len(sys.argv) < 2:
print(json.dumps({
'success': False,
'error': 'Uso: python send_email.py <json_data>'
}))
sys.exit(1)
try:
# Parse input JSON
data = json.loads(sys.argv[1])
if 'to' not in data or 'subject' not in data or 'html' not in data:
print(json.dumps({
'success': False,
'error': 'Parametri mancanti: to, subject, html sono obbligatori'
}))
sys.exit(1)
# Leggi configurazione
script_dir = Path(__file__).parent
config_path = script_dir / 'includes' / 'config.php'
config = parse_php_config(config_path)
# Invia email
result = send_email(data['to'], data['subject'], data['html'], config)
print(json.dumps(result))
sys.exit(0 if result['success'] else 1)
except json.JSONDecodeError as e:
print(json.dumps({
'success': False,
'error': f'JSON non valido: {str(e)}'
}))
sys.exit(1)
except Exception as e:
print(json.dumps({
'success': False,
'error': f'Errore: {str(e)}'
}))
sys.exit(1)
if __name__ == '__main__':
main()

43
test_python.py Normal file
View File

@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""
Test rapido per verificare che Python e le librerie necessarie siano installate
"""
import sys
def test_imports():
"""Verifica che tutte le librerie necessarie siano disponibili"""
required_modules = {
'smtplib': 'Libreria SMTP (built-in)',
'email': 'Libreria email (built-in)',
'json': 'Libreria JSON (built-in)',
're': 'Libreria regex (built-in)',
'pathlib': 'Libreria path (built-in)'
}
print("🐍 Test Python per Pilates Platform")
print(f" Python version: {sys.version}")
print()
all_ok = True
for module, description in required_modules.items():
try:
__import__(module)
print(f"{module:12} - {description}")
except ImportError:
print(f"{module:12} - MANCANTE!")
all_ok = False
print()
if all_ok:
print("✅ Tutte le librerie necessarie sono installate!")
print("✅ Python è pronto per inviare email.")
return 0
else:
print("❌ Alcune librerie sono mancanti. Installa Python 3.6+")
return 1
if __name__ == '__main__':
sys.exit(test_imports())