132 lines
6.0 KiB
Python
Executable File
132 lines
6.0 KiB
Python
Executable File
import smtplib
|
|
import logging
|
|
from email.mime.text import MIMEText
|
|
from email.mime.multipart import MIMEMultipart
|
|
from typing import Optional
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from app.core.config import settings
|
|
from app.core.i18n import locale_manager
|
|
from app.services.config_service import config
|
|
from app.db.session import AsyncSessionLocal # Szükséges a beállítások lekéréséhez
|
|
|
|
logger = logging.getLogger("Email-Manager-2.0")
|
|
|
|
class EmailManager:
|
|
@staticmethod
|
|
def _get_html_template(template_key: str, variables: dict, lang: str = "hu") -> str:
|
|
"""HTML sablon generálása a fordítási fájlok alapján (Megmaradt az eredeti logika)."""
|
|
greeting = locale_manager.get(f"email.{template_key}_greeting", lang=lang, **variables)
|
|
body = locale_manager.get(f"email.{template_key}_body", lang=lang, **variables)
|
|
button_text = locale_manager.get(f"email.{template_key}_button", lang=lang)
|
|
footer = locale_manager.get(f"email.{template_key}_footer", lang=lang)
|
|
|
|
link_fallback_text = locale_manager.get("email.link_fallback", lang=lang)
|
|
|
|
return f"""
|
|
<html>
|
|
<body style="font-family: Arial, sans-serif; color: #333; line-height: 1.6;">
|
|
<div style="max-width: 600px; margin: 0 auto; border: 1px solid #ddd; padding: 30px; border-radius: 10px;">
|
|
<h2 style="color: #2c3e50;">{greeting}</h2>
|
|
<p>{body}</p>
|
|
<div style="text-align: center; margin: 40px 0;">
|
|
<a href="{variables.get('link', '#')}"
|
|
style="background-color: #3498db; color: white; padding: 15px 30px; text-decoration: none; border-radius: 5px; font-weight: bold; font-size: 16px;">
|
|
{button_text}
|
|
</a>
|
|
</div>
|
|
<p style="font-size: 0.85em; color: #777; word-break: break-all;">
|
|
{link_fallback_text}<br>
|
|
<a href="{variables.get('link')}" style="color: #3498db;">{variables.get('link')}</a>
|
|
</p>
|
|
<hr style="border: 0; border-top: 1px solid #eee; margin: 30px 0;">
|
|
<p style="font-size: 0.8em; color: #999; text-align: center;">{footer}</p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
@staticmethod
|
|
async def send_email(recipient: str, template_key: str, variables: dict, lang: str = "hu", db: Optional[AsyncSession] = None):
|
|
"""
|
|
E-mail küldése admin-vezérelt szolgáltatóval (SendGrid vagy SMTP).
|
|
"""
|
|
# 1. Belső session kezelés, ha kívülről nem kaptunk (pl. háttérfolyamatoknál)
|
|
session_internal = False
|
|
if db is None:
|
|
db = AsyncSessionLocal()
|
|
session_internal = True
|
|
|
|
try:
|
|
# 2. Dinamikus beállítások lekérése az adatbázisból (Admin 2.0)
|
|
provider = await config.get_setting(db, "email_provider", default="disabled")
|
|
from_email = await config.get_setting(db, "emails_from_email", default="noreply@profibot.hu")
|
|
from_name = await config.get_setting(db, "emails_from_name", default="Sentinel System")
|
|
|
|
if provider == "disabled":
|
|
logger.info(f"Email küldés letiltva (Admin config). Cél: {recipient}")
|
|
return
|
|
|
|
html = EmailManager._get_html_template(template_key, variables, lang)
|
|
subject = locale_manager.get(f"email.{template_key}_subject", lang=lang)
|
|
|
|
# 3. KÜLDÉSI LOGIKA VÁLASZTÁSA
|
|
if provider == "sendgrid":
|
|
api_key = await config.get_setting(db, "sendgrid_api_key")
|
|
if api_key:
|
|
return await EmailManager._send_via_sendgrid(api_key, from_email, from_name, recipient, subject, html)
|
|
logger.warning("SendGrid szolgáltató kiválasztva, de nincs API kulcs!")
|
|
|
|
# Fallback vagy közvetlen SMTP
|
|
smtp_cfg = await config.get_setting(db, "smtp_config", default={
|
|
"host": "localhost", "port": 587, "user": "", "pass": "", "tls": True
|
|
})
|
|
return await EmailManager._send_via_smtp(smtp_cfg, from_email, from_name, recipient, subject, html)
|
|
|
|
finally:
|
|
if session_internal:
|
|
await db.close()
|
|
|
|
@staticmethod
|
|
async def _send_via_sendgrid(api_key: str, from_email: str, from_name: str, recipient: str, subject: str, html: str):
|
|
try:
|
|
from sendgrid import SendGridAPIClient
|
|
from sendgrid.helpers.mail import Mail
|
|
|
|
message = Mail(
|
|
from_email=(from_email, from_name),
|
|
to_emails=recipient,
|
|
subject=subject,
|
|
html_content=html
|
|
)
|
|
sg = SendGridAPIClient(api_key)
|
|
response = sg.send(message)
|
|
logger.info(f"SendGrid siker: {response.status_code} -> {recipient}")
|
|
return {"status": "success", "provider": "sendgrid"}
|
|
except Exception as e:
|
|
logger.error(f"SendGrid hiba: {str(e)}")
|
|
return {"status": "error", "message": "SendGrid failed"}
|
|
|
|
@staticmethod
|
|
async def _send_via_smtp(cfg: dict, from_email: str, from_name: str, recipient: str, subject: str, html: str):
|
|
try:
|
|
msg = MIMEMultipart()
|
|
msg["From"] = f"{from_name} <{from_email}>"
|
|
msg["To"] = recipient
|
|
msg["Subject"] = subject
|
|
msg.attach(MIMEText(html, "html"))
|
|
|
|
with smtplib.SMTP(cfg["host"], cfg["port"], timeout=15) as server:
|
|
if cfg.get("tls", True):
|
|
server.starttls()
|
|
if cfg.get("user") and cfg.get("pass"):
|
|
server.login(cfg["user"], cfg["pass"])
|
|
server.send_message(msg)
|
|
|
|
logger.info(f"SMTP siker -> {recipient}")
|
|
return {"status": "success", "provider": "smtp"}
|
|
except Exception as e:
|
|
logger.error(f"SMTP hiba: {str(e)}")
|
|
return {"status": "error", "message": str(e)}
|
|
|
|
email_manager = EmailManager() |