52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Mail sender via SMTP (Mailhog in dev)."""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from email.message import EmailMessage
|
|
|
|
import aiosmtplib
|
|
from fastapi import APIRouter
|
|
|
|
from core.config import settings
|
|
from core.di import register_service
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class MailService:
|
|
async def send(self, to: str, subject: str, body_html: str, body_text: str = "") -> None:
|
|
msg = EmailMessage()
|
|
msg["From"] = settings.MAIL_FROM
|
|
msg["To"] = to
|
|
msg["Subject"] = subject
|
|
if body_text:
|
|
msg.set_content(body_text)
|
|
msg.add_alternative(body_html, subtype="html")
|
|
else:
|
|
msg.set_content(body_html, subtype="html")
|
|
try:
|
|
await aiosmtplib.send(
|
|
msg,
|
|
hostname=settings.SMTP_HOST,
|
|
port=settings.SMTP_PORT,
|
|
start_tls=False,
|
|
)
|
|
except Exception as e: # noqa: BLE001
|
|
print(f"[mail] send error: {e}")
|
|
|
|
def send_sync(self, to: str, subject: str, body_html: str, body_text: str = "") -> None:
|
|
"""Blocking wrapper for event handlers."""
|
|
try:
|
|
asyncio.run(self.send(to, subject, body_html, body_text))
|
|
except RuntimeError:
|
|
# inside running loop (unlikely in sync event handlers, but just in case)
|
|
loop = asyncio.new_event_loop()
|
|
try:
|
|
loop.run_until_complete(self.send(to, subject, body_html, body_text))
|
|
finally:
|
|
loop.close()
|
|
|
|
|
|
def on_load() -> None:
|
|
register_service("MailService", MailService())
|