-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathemail_utils.py
More file actions
123 lines (106 loc) · 4.6 KB
/
Copy pathemail_utils.py
File metadata and controls
123 lines (106 loc) · 4.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import requests
from typing import Optional
import config
RESEND_EMAILS_URL = "https://api.resend.com/emails"
def _masked_recipient(to_email: str) -> str:
local, separator, domain = (to_email or "").strip().partition("@")
if not separator or not local or not domain:
return "invalid-recipient"
return f"{local[0]}***@{domain.casefold()}"
def _sender() -> str:
if config.EMAIL_FROM_NAME:
return f"{config.EMAIL_FROM_NAME} <{config.EMAIL_FROM}>"
return config.EMAIL_FROM
def _email_shell(headline: str, body_html: str, cta_text: str, cta_url: str) -> str:
return f"""<!doctype html>
<html>
<body style="margin:0;background:#0b0e14;color:#f8fafc;font-family:Arial,sans-serif;">
<div style="max-width:620px;margin:0 auto;padding:32px 20px;">
<div style="border:1px solid #2c3440;border-radius:18px;background:#171c24;padding:28px;">
<div style="color:#f59e0b;font-weight:800;font-size:14px;margin-bottom:18px;">>_ BashOps Radar</div>
<h1 style="font-size:28px;line-height:1.2;margin:0 0 14px;color:#f8fafc;">{headline}</h1>
<div style="font-size:16px;line-height:1.65;color:#cbd5e1;">{body_html}</div>
<p style="margin:26px 0;">
<a href="{cta_url}" style="display:inline-block;background:#f59e0b;color:#111827;text-decoration:none;font-weight:800;border-radius:10px;padding:12px 18px;">{cta_text}</a>
</p>
<p style="font-size:13px;line-height:1.6;color:#94a3b8;">If the button does not work, copy and paste this link into your browser:<br>
<a href="{cta_url}" style="color:#f59e0b;">{cta_url}</a></p>
<p style="font-size:13px;color:#94a3b8;margin-top:24px;">Need help? Contact support@bashops.site.</p>
</div>
</div>
</body>
</html>"""
def send_email(to_email: str, subject: str, body: str, html_body: Optional[str] = None) -> bool:
recipient = _masked_recipient(to_email)
if not config.email_configured:
print(f"[email disabled] subject={subject!r} recipient={recipient}")
return False
payload = {
"from": _sender(),
"to": [to_email],
"subject": subject,
"text": body,
}
if html_body:
payload["html"] = html_body
headers = {
"Authorization": f"Bearer {config.RESEND_API_KEY}",
"Content-Type": "application/json",
}
try:
response = requests.post(RESEND_EMAILS_URL, json=payload, headers=headers, timeout=10)
if response.status_code >= 400:
print(
f"[email send failed] subject={subject!r} recipient={recipient} "
f"resend_status={response.status_code}"
)
return False
return True
except Exception as exc:
print(
f"[email send failed] subject={subject!r} recipient={recipient} "
f"error={exc.__class__.__name__}"
)
return False
def send_verification_email(to_email: str, verification_link: str) -> bool:
body = (
"Welcome to BashOps Radar.\n\n"
"Verify your BashOps Radar account:\n"
f"{verification_link}\n\n"
"After verification you can analyze GitHub repositories, find high-probability issues, "
"track Proof-of-Work opportunities, and upgrade later for founder outreach.\n\n"
"Need help? Contact support@bashops.site.\n\n"
"If you did not create this account, you can ignore this email."
)
html_body = _email_shell(
"Verify your BashOps Radar account",
(
"<p>Confirm your email to activate your workspace.</p>"
"<ul>"
"<li>Analyze GitHub repositories</li>"
"<li>Find high-probability issues</li>"
"<li>Track Proof-of-Work opportunities</li>"
"<li>Upgrade later for founder outreach</li>"
"</ul>"
),
"Verify Email",
verification_link,
)
return send_email(to_email, "Verify your BashOps Radar account", body, html_body)
def send_password_reset_email(to_email: str, reset_link: str) -> bool:
body = (
"Use this link to reset your BashOps Radar password:\n"
f"{reset_link}\n\n"
"This link expires in 1 hour. If you did not request it, you can ignore this email."
)
html_body = _email_shell(
"Reset your BashOps Radar password",
(
"<p>Use the button below to set a new password.</p>"
"<p><strong>This link expires in 1 hour.</strong></p>"
"<p>If you did not request this, you can ignore this email.</p>"
),
"Reset Password",
reset_link,
)
return send_email(to_email, "Reset your BashOps Radar password", body, html_body)