|
|
|
@ -90,22 +90,38 @@ def environment_callback(request): |
|
|
|
return [_("Production"), "primary"] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_email(recipient, code): |
|
|
|
import requests |
|
|
|
from django.conf import settings |
|
|
|
|
|
|
|
if not getattr(settings, "RESEND_API_KEY", None): |
|
|
|
api_key = getattr(settings, "RESEND_API_KEY", None) |
|
|
|
if not api_key: |
|
|
|
logger.warning("RESEND_API_KEY is not set in settings.") |
|
|
|
return False |
|
|
|
|
|
|
|
url = "https://api.resend.com/emails" |
|
|
|
headers = { |
|
|
|
"Authorization": f"Bearer {settings.RESEND_API_KEY}", |
|
|
|
"Authorization": f"Bearer {api_key}", |
|
|
|
"Content-Type": "application/json", |
|
|
|
} |
|
|
|
|
|
|
|
site_domain = getattr(settings, "SITE_DOMAIN", "https://dovodi.newhorizonco.uk/") |
|
|
|
# Normalize recipient into a clean list of email strings |
|
|
|
if isinstance(recipient, str): |
|
|
|
to_emails = [recipient.strip()] |
|
|
|
elif isinstance(recipient, (list, tuple, set)): |
|
|
|
to_emails = [str(r).strip() for r in recipient if r and str(r).strip()] |
|
|
|
else: |
|
|
|
to_emails = [str(recipient).strip()] |
|
|
|
|
|
|
|
if not to_emails: |
|
|
|
logger.error(f"Cannot send email: recipient list is empty ({recipient})") |
|
|
|
return False |
|
|
|
|
|
|
|
from_email = getattr(settings, "RESEND_FROM_EMAIL", "Dovodi <info@imamjavad.online>") |
|
|
|
if "<" not in from_email and "@" in from_email: |
|
|
|
from_email = f"Dovodi <{from_email}>" |
|
|
|
|
|
|
|
site_domain = getattr(settings, "SITE_DOMAIN", "https://dovodi.newhorizonco.uk/").rstrip('/') |
|
|
|
subject = "Код подтверждения | Verification Code" |
|
|
|
|
|
|
|
html_content = f""" |
|
|
|
@ -128,7 +144,7 @@ def send_email(recipient, code): |
|
|
|
<!-- Header with Logo --> |
|
|
|
<tr> |
|
|
|
<td style="padding: 32px 32px 20px 32px; text-align: center; background-color: #FAFAFC; border-bottom: 1px solid #F1F3F7;"> |
|
|
|
<img src="{site_domain}/static/images/dovoodi_logo.svg" alt="Dovodi Logo" style="height: 38px; width: auto; max-width: 160px; display: inline-block;" /> |
|
|
|
<img src="{site_domain}/static/images/dovoodi_logo.svg" alt="Dovodi" style="height: 38px; width: auto; max-width: 160px; display: inline-block;" /> |
|
|
|
</td> |
|
|
|
</tr> |
|
|
|
<!-- Main Body Section --> |
|
|
|
@ -148,7 +164,7 @@ def send_email(recipient, code): |
|
|
|
|
|
|
|
<!-- Intro Message --> |
|
|
|
<p style="margin: 0 0 24px 0; font-size: 14px; color: #646A75; text-align: center; line-height: 1.6;"> |
|
|
|
Используйте следующий одноразовый код для входа или подтверждения учетной записи в <strong>Dovodi</strong>: |
|
|
|
Используйте следующий одноразовый код для входа یا подтверждения учетной записи в <strong>Dovodi</strong>: |
|
|
|
</p> |
|
|
|
|
|
|
|
<!-- OTP Box --> |
|
|
|
@ -183,7 +199,7 @@ def send_email(recipient, code): |
|
|
|
<p style="margin: 0 0 12px 0; font-size: 12px; color: #646A75;"> |
|
|
|
<a href="https://dovodi.newhorizonco.uk/" style="color: #5172E1; text-decoration: none; font-weight: 600;">dovodi.newhorizonco.uk</a> |
|
|
|
• |
|
|
|
<a href="mailto:[EMAIL_ADDRESS]" style="color: #5172E1; text-decoration: none; font-weight: 600;">[EMAIL_ADDRESS]</a> |
|
|
|
<a href="mailto:info@imamjavad.online" style="color: #5172E1; text-decoration: none; font-weight: 600;">info@imamjavad.online</a> |
|
|
|
</p> |
|
|
|
<p style="margin: 0; font-size: 11px; color: #9AA0AC; line-height: 1.4;"> |
|
|
|
© 2026 Dovodi. Все права защищены. |
|
|
|
@ -197,20 +213,33 @@ def send_email(recipient, code): |
|
|
|
</body> |
|
|
|
</html> |
|
|
|
""" |
|
|
|
|
|
|
|
text_content = ( |
|
|
|
f"Код подтверждения Dovodi: {code}\n\n" |
|
|
|
f"Your Dovodi verification code is: {code}\n\n" |
|
|
|
f"Срок действия кода истекает через 5 минут. Если вы не запрашивали этот код, проигнорируйте это письмо.\n" |
|
|
|
f"Никому не передавайте этот код в целях безопасности вашего аккаунта." |
|
|
|
) |
|
|
|
|
|
|
|
payload = { |
|
|
|
"from": settings.RESEND_FROM_EMAIL, |
|
|
|
"to": recipient, |
|
|
|
"from": from_email, |
|
|
|
"to": to_emails, |
|
|
|
"subject": subject, |
|
|
|
"html": html_content, |
|
|
|
"text": text_content, |
|
|
|
} |
|
|
|
|
|
|
|
try: |
|
|
|
response = requests.post(url, headers=headers, json=payload) |
|
|
|
response.raise_for_status() |
|
|
|
response = requests.post(url, headers=headers, json=payload, timeout=15) |
|
|
|
if response.status_code >= 400: |
|
|
|
logger.error(f"Failed to send email via Resend: HTTP {response.status_code} - {response.text}") |
|
|
|
print(f"Failed to send email via Resend: HTTP {response.status_code} - {response.text}") |
|
|
|
return False |
|
|
|
logger.info(f"Email OTP sent successfully via Resend to {to_emails}") |
|
|
|
return True |
|
|
|
except Exception as e: |
|
|
|
logger.error(f"Failed to send email via Resend: {str(e)}") |
|
|
|
logger.error(f"Failed to send email via Resend: {str(e)}", exc_info=True) |
|
|
|
print(f"Failed to send email via Resend: {str(e)}") |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|