fix send mail with python script
This commit is contained in:
66
README.md
66
README.md
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
149
send_email.py
Normal 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
43
test_python.py
Normal 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())
|
||||
Reference in New Issue
Block a user