versione 1.0
This commit is contained in:
78
backend/app/services/mailer.py
Normal file
78
backend/app/services/mailer.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from email.message import EmailMessage
|
||||
import smtplib
|
||||
|
||||
from app.config import settings
|
||||
from app.schemas.booking import BookingRequestCreate
|
||||
|
||||
|
||||
class MailConfigurationError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def _build_booking_subject(payload: BookingRequestCreate) -> str:
|
||||
return f"{settings.booking_email_subject_prefix} Nuova richiesta visita - {payload.name}"
|
||||
|
||||
|
||||
def _build_booking_html(payload: BookingRequestCreate) -> str:
|
||||
submitted_at = datetime.now().strftime("%d/%m/%Y %H:%M")
|
||||
return f"""
|
||||
<html>
|
||||
<body style="font-family: Arial, sans-serif; color: #1f2937; line-height: 1.6;">
|
||||
<h2 style="color: #1B4F72;">Nuova richiesta di prenotazione visita</h2>
|
||||
<p>È stata inviata una nuova richiesta di prenotazione non vincolante dal sito web.</p>
|
||||
<table cellpadding="8" cellspacing="0" border="0" style="border-collapse: collapse;">
|
||||
<tr><td><strong>Nome e cognome</strong></td><td>{payload.name}</td></tr>
|
||||
<tr><td><strong>Telefono</strong></td><td>{payload.phone}</td></tr>
|
||||
<tr><td><strong>Nome animale</strong></td><td>{payload.pet_name or "-"}</td></tr>
|
||||
<tr><td><strong>Tipo animale</strong></td><td>{payload.pet_type}</td></tr>
|
||||
<tr><td><strong>Tipo di visita</strong></td><td>{payload.service}</td></tr>
|
||||
<tr><td><strong>Data preferita</strong></td><td>{payload.date}</td></tr>
|
||||
<tr><td><strong>Orario preferito</strong></td><td>{payload.time or "Qualsiasi orario"}</td></tr>
|
||||
<tr><td><strong>Note</strong></td><td>{payload.notes or "-"}</td></tr>
|
||||
<tr><td><strong>Inviata il</strong></td><td>{submitted_at}</td></tr>
|
||||
</table>
|
||||
<p style="margin-top: 20px;">
|
||||
Questa richiesta <strong>non costituisce conferma automatica dell'appuntamento</strong> e richiede
|
||||
presa in carico da parte dello staff.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def _build_booking_text(payload: BookingRequestCreate) -> str:
|
||||
submitted_at = datetime.now().strftime("%d/%m/%Y %H:%M")
|
||||
return (
|
||||
"Nuova richiesta di prenotazione visita\n\n"
|
||||
f"Nome e cognome: {payload.name}\n"
|
||||
f"Telefono: {payload.phone}\n"
|
||||
f"Nome animale: {payload.pet_name or '-'}\n"
|
||||
f"Tipo animale: {payload.pet_type}\n"
|
||||
f"Tipo di visita: {payload.service}\n"
|
||||
f"Data preferita: {payload.date}\n"
|
||||
f"Orario preferito: {payload.time or 'Qualsiasi orario'}\n"
|
||||
f"Note: {payload.notes or '-'}\n"
|
||||
f"Inviata il: {submitted_at}\n\n"
|
||||
"La richiesta non costituisce conferma automatica dell'appuntamento."
|
||||
)
|
||||
|
||||
|
||||
def send_booking_request_email(payload: BookingRequestCreate) -> None:
|
||||
if not settings.booking_mail_enabled:
|
||||
raise MailConfigurationError("Configurazione SMTP incompleta.")
|
||||
|
||||
message = EmailMessage()
|
||||
message["Subject"] = _build_booking_subject(payload)
|
||||
message["From"] = settings.booking_email_from
|
||||
message["To"] = settings.booking_email_to
|
||||
message.set_content(_build_booking_text(payload))
|
||||
message.add_alternative(_build_booking_html(payload), subtype="html")
|
||||
|
||||
with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=30) as server:
|
||||
if settings.smtp_use_tls:
|
||||
server.starttls()
|
||||
server.login(settings.smtp_username, settings.smtp_password)
|
||||
server.send_message(message)
|
||||
Reference in New Issue
Block a user