115 lines
3.9 KiB
Python
115 lines
3.9 KiB
Python
"""Notifiche: email SMTP + WhatsApp via gateway XAB."""
|
|
import smtplib
|
|
import logging
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
from datetime import datetime
|
|
import httpx
|
|
from app.config import get_settings
|
|
|
|
log = logging.getLogger(__name__)
|
|
settings = get_settings()
|
|
|
|
|
|
async def send_wa_message(phone: str, text: str) -> bool:
|
|
"""Invia messaggio WhatsApp via gateway XAB su APP:18800."""
|
|
if not settings.wa_enabled:
|
|
log.info(f"WA disabled, skip: {phone}")
|
|
return False
|
|
try:
|
|
# Normalizza numero: +39 3xx -> 39 3xx
|
|
clean = phone.replace("+", "").replace(" ", "").replace("-", "")
|
|
if not clean.startswith("39"):
|
|
clean = "39" + clean
|
|
|
|
async with httpx.AsyncClient(timeout=10) as client:
|
|
r = await client.post(
|
|
settings.wa_gateway_url,
|
|
json={"to": clean, "text": text},
|
|
)
|
|
if r.status_code == 200:
|
|
log.info(f"WA sent to {clean}")
|
|
return True
|
|
else:
|
|
log.error(f"WA error {r.status_code}: {r.text}")
|
|
return False
|
|
except Exception as e:
|
|
log.error(f"WA exception: {e}")
|
|
return False
|
|
|
|
|
|
def send_email(to: str, subject: str, html_body: str) -> bool:
|
|
"""Invia email via SMTP."""
|
|
if not settings.smtp_user:
|
|
log.info(f"SMTP not configured, skip: {to}")
|
|
return False
|
|
try:
|
|
msg = MIMEMultipart("alternative")
|
|
msg["Subject"] = subject
|
|
msg["From"] = settings.smtp_from
|
|
msg["To"] = to
|
|
msg.attach(MIMEText(html_body, "html"))
|
|
|
|
with smtplib.SMTP(settings.smtp_host, settings.smtp_port) as server:
|
|
server.starttls()
|
|
server.login(settings.smtp_user, settings.smtp_pass)
|
|
server.sendmail(settings.smtp_from, to, msg.as_string())
|
|
log.info(f"Email sent to {to}")
|
|
return True
|
|
except Exception as e:
|
|
log.error(f"Email exception: {e}")
|
|
return False
|
|
|
|
|
|
async def notify_booking_confirmed(booking, service_name: str, provider_name: str):
|
|
"""Notifica al cliente: conferma prenotazione."""
|
|
dt = booking.start_at.strftime("%d/%m/%Y alle %H:%M")
|
|
# WhatsApp al cliente
|
|
wa_text = (
|
|
f"✅ Prenotazione confermata!\n\n"
|
|
f"Servizio: {service_name}\n"
|
|
f"Data: {dt}\n"
|
|
f"Operatore: {provider_name}\n\n"
|
|
f"Farmacia Ianni - Via Cassia 940, Roma\n"
|
|
f"Per cancellare, rispondi CANCELLA."
|
|
)
|
|
await send_wa_message(booking.customer_phone, wa_text)
|
|
|
|
# Email se fornita
|
|
if booking.customer_email:
|
|
html = f"""
|
|
<h2>Prenotazione confermata</h2>
|
|
<p><strong>Servizio:</strong> {service_name}</p>
|
|
<p><strong>Data:</strong> {dt}</p>
|
|
<p><strong>Operatore:</strong> {provider_name}</p>
|
|
<hr>
|
|
<p>Farmacia Ianni - Via Cassia 940, Roma</p>
|
|
"""
|
|
send_email(booking.customer_email, f"Prenotazione {service_name} - {dt}", html)
|
|
|
|
|
|
async def notify_operator(booking, service_name: str, provider_email: str):
|
|
"""Notifica all'operatore: nuova prenotazione."""
|
|
dt = booking.start_at.strftime("%d/%m/%Y alle %H:%M")
|
|
html = f"""
|
|
<h2>Nuova prenotazione</h2>
|
|
<p><strong>Cliente:</strong> {booking.customer_name}</p>
|
|
<p><strong>Telefono:</strong> {booking.customer_phone}</p>
|
|
<p><strong>Servizio:</strong> {service_name}</p>
|
|
<p><strong>Data:</strong> {dt}</p>
|
|
"""
|
|
if provider_email:
|
|
send_email(provider_email, f"Nuova prenotazione: {booking.customer_name} - {dt}", html)
|
|
|
|
|
|
async def send_reminder(booking, service_name: str):
|
|
"""Reminder 24h prima via WhatsApp."""
|
|
dt = booking.start_at.strftime("%d/%m/%Y alle %H:%M")
|
|
text = (
|
|
f"📅 Promemoria: domani hai un appuntamento\n\n"
|
|
f"Servizio: {service_name}\n"
|
|
f"Data: {dt}\n\n"
|
|
f"Farmacia Ianni - Via Cassia 940, Roma"
|
|
)
|
|
await send_wa_message(booking.customer_phone, text)
|