221 lines
9.7 KiB
Python
221 lines
9.7 KiB
Python
import logging
|
|
import base64
|
|
import os
|
|
import resend
|
|
from config import settings
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_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 = ""
|
|
|
|
|
|
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
|
|
|
|
|
|
_OPT_IN_URL = "https://play.google.com/apps/testing/com.bellsystems.vesper"
|
|
_APP_URL = "https://play.google.com/store/apps/details?id=com.bellsystems.vesper"
|
|
|
|
|
|
def send_device_assigned_email(
|
|
user_email: str,
|
|
serial_number: str,
|
|
device_name: str,
|
|
user_name: str | None = None,
|
|
) -> None:
|
|
"""
|
|
Notify a user that a BellSystems device has been assigned to their account,
|
|
with links to opt in to the Vesper beta programme and download the app.
|
|
"""
|
|
greeting = f"Dear {user_name}," if user_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 Is Ready</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;">Device Activation</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;">
|
|
Exciting news — your
|
|
<strong style="color:#c9d1d9;">BellSystems {device_name}</strong>
|
|
has been assigned to your account and is ready to use!
|
|
</p>
|
|
|
|
<p style="margin:0 0 28px; font-size:15px; color:#8b949e; line-height:1.75;">
|
|
To get started, join the <strong style="color:#c9d1d9;">Vesper</strong> programme
|
|
and download the companion app from the Google Play Store. The app gives you full
|
|
control over your device, including scheduling, customisation, and real-time
|
|
monitoring.
|
|
</p>
|
|
|
|
<!-- CTA buttons -->
|
|
<table cellpadding="0" cellspacing="0" width="100%" style="margin:0 0 32px;">
|
|
<tr>
|
|
<td align="center" style="padding-bottom:12px;">
|
|
<a href="{_OPT_IN_URL}"
|
|
style="display:inline-block; background-color:#238636; color:#ffffff;
|
|
text-decoration:none; padding:14px 32px; border-radius:8px;
|
|
font-size:14px; font-weight:700; letter-spacing:0.4px;
|
|
border:1px solid #2ea043; width:240px; text-align:center;">
|
|
Join the Vesper Programme
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td align="center">
|
|
<a href="{_APP_URL}"
|
|
style="display:inline-block; background-color:#1f6feb; color:#ffffff;
|
|
text-decoration:none; padding:14px 32px; border-radius:8px;
|
|
font-size:14px; font-weight:700; letter-spacing:0.4px;
|
|
border:1px solid #388bfd; width:240px; text-align:center;">
|
|
Download on Google Play
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<!-- Device info card -->
|
|
<table width="100%" cellpadding="0" cellspacing="0"
|
|
style="background:#0d1117; border:1px solid #30363d; border-radius:8px; margin-bottom:28px;">
|
|
<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>
|
|
|
|
<!-- How it works steps -->
|
|
<table width="100%" cellpadding="0" cellspacing="0"
|
|
style="background:#0d1117; border:1px solid #30363d; border-radius:8px; margin-bottom:28px;">
|
|
<tr>
|
|
<td style="padding:16px 20px; border-bottom:1px solid #21262d;">
|
|
<span style="font-size:11px; color:#8b949e; text-transform:uppercase;
|
|
letter-spacing:1.2px; font-weight:700;">Getting Started</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:14px 20px; border-bottom:1px solid #21262d;">
|
|
<span style="color:#58a6ff; font-weight:700; font-size:13px;">1 </span>
|
|
<span style="color:#8b949e; font-size:13px; line-height:1.6;">
|
|
Click <strong style="color:#c9d1d9;">Join the Vesper Programme</strong> above to opt in via the Google Play testing programme.
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:14px 20px; border-bottom:1px solid #21262d;">
|
|
<span style="color:#58a6ff; font-weight:700; font-size:13px;">2 </span>
|
|
<span style="color:#8b949e; font-size:13px; line-height:1.6;">
|
|
Download the <strong style="color:#c9d1d9;">Vesper</strong> app from the Google Play Store.
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding:14px 20px;">
|
|
<span style="color:#58a6ff; font-weight:700; font-size:13px;">3 </span>
|
|
<span style="color:#8b949e; font-size:13px; line-height:1.6;">
|
|
Sign in with your account and your device will appear automatically.
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p style="margin:0; font-size:14px; color:#6e7681; line-height:1.7;">
|
|
If you have any questions or need assistance with setup, our support team is
|
|
always happy to help.
|
|
</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=user_email,
|
|
subject=f"Your BellSystems {device_name} is ready — get started now!",
|
|
html=html,
|
|
)
|