initial commit
This commit is contained in:
89
app/services/smtp_sender.py
Normal file
89
app/services/smtp_sender.py
Normal file
@@ -0,0 +1,89 @@
|
||||
import smtplib
|
||||
from datetime import datetime
|
||||
from email.mime.text import MIMEText
|
||||
from typing import Sequence
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.system import SendLog
|
||||
from app.services.config_store import get_config
|
||||
|
||||
|
||||
def get_smtp_settings(db: Session) -> dict[str, str]:
|
||||
return {
|
||||
"enabled": get_config(db, "smtp.enabled", "false"),
|
||||
"host": get_config(db, "smtp.host", ""),
|
||||
"port": get_config(db, "smtp.port", "587"),
|
||||
"username": get_config(db, "smtp.username", ""),
|
||||
"password": get_config(db, "smtp.password", ""),
|
||||
"from_email": get_config(db, "smtp.from_email", ""),
|
||||
"use_tls": get_config(db, "smtp.use_tls", "true"),
|
||||
"recipients": get_config(db, "smtp.recipients", ""),
|
||||
"schedule_time": get_config(db, "smtp.schedule_time", "08:00"),
|
||||
"last_scheduled_date": get_config(db, "smtp.last_scheduled_date", ""),
|
||||
}
|
||||
|
||||
|
||||
def send_newsletter(
|
||||
db: Session,
|
||||
subject: str,
|
||||
html_content: str,
|
||||
text_content: str,
|
||||
recipients: Sequence[str],
|
||||
scheduled: bool = False,
|
||||
) -> None:
|
||||
settings = get_smtp_settings(db)
|
||||
if settings["enabled"].lower() != "true":
|
||||
_log(db, subject, recipients, "skipped", "SMTP ist deaktiviert.", scheduled)
|
||||
return
|
||||
if not settings["host"] or not settings["from_email"] or not recipients:
|
||||
_log(db, subject, recipients, "failed", "SMTP unvollständig konfiguriert.", scheduled)
|
||||
return
|
||||
|
||||
msg = MIMEText(html_content, "html", "utf-8")
|
||||
msg["Subject"] = subject
|
||||
msg["From"] = settings["from_email"]
|
||||
msg["To"] = ", ".join(recipients)
|
||||
|
||||
try:
|
||||
port = int(settings["port"])
|
||||
with smtplib.SMTP(settings["host"], port, timeout=20) as server:
|
||||
if settings["use_tls"].lower() == "true":
|
||||
server.starttls()
|
||||
if settings["username"]:
|
||||
server.login(settings["username"], settings["password"])
|
||||
server.sendmail(settings["from_email"], list(recipients), msg.as_string())
|
||||
_log(db, subject, recipients, "sent", "Versand erfolgreich.", scheduled)
|
||||
except Exception as exc:
|
||||
_log(db, subject, recipients, "failed", f"Versandfehler: {exc}", scheduled)
|
||||
|
||||
|
||||
def run_scheduled_send_if_due(db: Session, subject: str, html_content: str, text_content: str) -> None:
|
||||
settings = get_smtp_settings(db)
|
||||
if settings["enabled"].lower() != "true":
|
||||
return
|
||||
now = datetime.now()
|
||||
schedule_time = settings["schedule_time"] or "08:00"
|
||||
if now.strftime("%H:%M") < schedule_time:
|
||||
return
|
||||
today = now.strftime("%Y-%m-%d")
|
||||
if settings["last_scheduled_date"] == today:
|
||||
return
|
||||
recipients = [r.strip() for r in settings["recipients"].split(",") if r.strip()]
|
||||
send_newsletter(db, subject, html_content, text_content, recipients, scheduled=True)
|
||||
from app.services.config_store import set_config
|
||||
|
||||
set_config(db, "smtp.last_scheduled_date", today)
|
||||
|
||||
|
||||
def _log(db: Session, subject: str, recipients: Sequence[str], status: str, detail: str, scheduled: bool) -> None:
|
||||
db.add(
|
||||
SendLog(
|
||||
subject=subject,
|
||||
recipients=", ".join(recipients) if recipients else "-",
|
||||
status=status,
|
||||
detail=detail,
|
||||
scheduled=scheduled,
|
||||
)
|
||||
)
|
||||
db.commit()
|
||||
Reference in New Issue
Block a user