156 lines
6.4 KiB
Python
156 lines
6.4 KiB
Python
import logging
|
|
import base64
|
|
import os
|
|
import resend
|
|
from config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Embed logo as base64 so it works in any email client without a public URL
|
|
_LOGO_PATH = os.path.join(os.path.dirname(__file__), "assets", "bell_systems_horizontal_darkMode.png")
|
|
try:
|
|
with open(_LOGO_PATH, "rb") as _f:
|
|
_LOGO_B64 = base64.b64encode(_f.read()).decode()
|
|
_LOGO_SRC = f"data:image/png;base64,{_LOGO_B64}"
|
|
except Exception:
|
|
_LOGO_SRC = "" # fallback: image won't appear but email still sends
|
|
|
|
|
|
def send_email(to: str, subject: str, html: str) -> None:
|
|
"""Send a transactional email via Resend."""
|
|
try:
|
|
resend.api_key = settings.resend_api_key
|
|
resend.Emails.send({
|
|
"from": settings.email_from,
|
|
"to": to,
|
|
"subject": subject,
|
|
"html": html,
|
|
})
|
|
logger.info("Email sent to %s — subject: %s", to, subject)
|
|
except Exception as exc:
|
|
logger.error("Failed to send email to %s: %s", to, exc)
|
|
raise
|
|
|
|
|
|
def send_device_manufactured_email(
|
|
customer_email: str,
|
|
serial_number: str,
|
|
device_name: str,
|
|
customer_name: str | None = None,
|
|
) -> None:
|
|
"""
|
|
Notify a customer that their BellSystems device has been manufactured
|
|
and is being prepared for shipment.
|
|
"""
|
|
greeting = f"Dear {customer_name}," if customer_name else "Dear valued customer,"
|
|
|
|
html = f"""<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Your BellSystems Device Has Been Manufactured</title>
|
|
</head>
|
|
<body style="margin:0; padding:0; background-color:#0d1117; font-family:'Helvetica Neue', Helvetica, Arial, sans-serif;">
|
|
<table width="100%" cellpadding="0" cellspacing="0" style="background-color:#0d1117; padding:40px 16px;">
|
|
<tr>
|
|
<td align="center">
|
|
<table width="580" cellpadding="0" cellspacing="0"
|
|
style="background-color:#161b22; border-radius:12px; overflow:hidden;
|
|
box-shadow:0 4px 24px rgba(0,0,0,0.5); max-width:580px; width:100%;
|
|
border:1px solid #30363d;">
|
|
|
|
<!-- Header with logo -->
|
|
<tr>
|
|
<td style="background-color:#0f172a; padding:32px 40px 28px; text-align:center;
|
|
border-bottom:1px solid #21262d;">
|
|
{"<img src='" + _LOGO_SRC + "' alt='BellSystems' width='180' style='display:block; margin:0 auto; max-width:180px;'>" if _LOGO_SRC else "<h1 style='color:#ffffff; margin:0; font-size:22px; font-weight:700; letter-spacing:1px;'>BELLSYSTEMS</h1>"}
|
|
<p style="color:#64748b; margin:14px 0 0; font-size:11px; letter-spacing:2.5px;
|
|
text-transform:uppercase; font-weight:600;">Manufacturing Update</p>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Body -->
|
|
<tr>
|
|
<td style="padding:36px 40px 28px;">
|
|
|
|
<p style="margin:0 0 24px; font-size:16px; color:#c9d1d9; font-weight:500;">
|
|
{greeting}
|
|
</p>
|
|
|
|
<p style="margin:0 0 18px; font-size:15px; color:#8b949e; line-height:1.75;">
|
|
We are pleased to inform you that your
|
|
<strong style="color:#c9d1d9;">BellSystems {device_name}</strong>
|
|
has been successfully manufactured and has passed all quality checks.
|
|
</p>
|
|
|
|
<p style="margin:0 0 28px; font-size:15px; color:#8b949e; line-height:1.75;">
|
|
Your device is now being prepared for delivery. You will receive a separate
|
|
notification with tracking information once it has been dispatched.
|
|
</p>
|
|
|
|
<!-- Device info card -->
|
|
<table width="100%" cellpadding="0" cellspacing="0"
|
|
style="background:#0d1117; border:1px solid #30363d; border-radius:8px; margin-bottom:32px;">
|
|
<tr>
|
|
<td style="padding:16px 20px; border-bottom:1px solid #21262d;">
|
|
<span style="font-size:11px; color:#58a6ff; text-transform:uppercase;
|
|
letter-spacing:1.2px; font-weight:700;">Device Model</span><br>
|
|
<span style="font-size:15px; color:#c9d1d9; font-weight:600; margin-top:4px; display:block;">
|
|
BellSystems {device_name}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:16px 20px;">
|
|
<span style="font-size:11px; color:#58a6ff; text-transform:uppercase;
|
|
letter-spacing:1.2px; font-weight:700;">Serial Number</span><br>
|
|
<code style="font-size:14px; color:#79c0ff; background:#161b22;
|
|
padding:4px 10px; border-radius:4px; font-family:monospace;
|
|
border:1px solid #30363d; margin-top:6px; display:inline-block;">
|
|
{serial_number}
|
|
</code>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p style="margin:0 0 8px; font-size:14px; color:#6e7681; line-height:1.7;">
|
|
Thank you for choosing BellSystems. We take great pride in crafting each device
|
|
with care and precision, and we look forward to delivering an exceptional
|
|
experience to you.
|
|
</p>
|
|
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Footer -->
|
|
<tr>
|
|
<td style="background-color:#0d1117; border-top:1px solid #21262d;
|
|
padding:24px 40px; text-align:center;">
|
|
<p style="margin:0 0 6px; font-size:13px; color:#8b949e; font-weight:600;">
|
|
BellSystems.gr
|
|
</p>
|
|
<p style="margin:0; font-size:12px; color:#6e7681;">
|
|
Questions? Contact us at
|
|
<a href="mailto:support@bellsystems.gr"
|
|
style="color:#58a6ff; text-decoration:none;">support@bellsystems.gr</a>
|
|
</p>
|
|
<p style="margin:8px 0 0; font-size:11px; color:#484f58;">
|
|
If you did not expect this notification, please disregard this message.
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</body>
|
|
</html>"""
|
|
|
|
send_email(
|
|
to=customer_email,
|
|
subject=f"Your BellSystems {device_name} has been manufactured",
|
|
html=html,
|
|
)
|