@ -112,108 +112,64 @@ def send_email(recipient, code):
logger . error ( f " Cannot send email: recipient list is empty ({recipient}) " )
logger . error ( f " Cannot send email: recipient list is empty ({recipient}) " )
return False
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 "
from_email = getattr ( settings , " RESEND_FROM_EMAIL " , " onboarding@resend.dev " )
if " onboarding@resend.dev " in from_email :
from_email = " onboarding@resend.dev "
elif " < " not in from_email and " @ " in from_email :
from_email = f " Muslim Connect Hub <{from_email}> "
subject = f " Your Verification Code: {code} "
# Handle Resend sandbox restriction: onboarding@resend.dev can only deliver to the account owner's email
sandbox_redirect = getattr ( settings , " RESEND_SANDBOX_REDIRECT_TO " , " alisina.a.a50182@gmail.com " )
sandbox_notice_html = " "
sandbox_notice_text = " "
if " onboarding@resend.dev " in from_email and sandbox_redirect :
non_sandbox_recipients = [ r for r in to_emails if r . lower ( ) != sandbox_redirect . lower ( ) ]
if non_sandbox_recipients :
orig_str = " , " . join ( to_emails )
print ( f " [Resend Sandbox Mode] Notice: Resend sandbox only delivers to {sandbox_redirect}. " )
print ( f " [Resend Sandbox Mode] Redirecting test email intended for [{orig_str}] -> {sandbox_redirect} " )
subject = f " [Dev Test for {orig_str}] Your Verification Code: {code} "
sandbox_notice_html = f """
< div style = " background-color: #FEF3C7; border: 1px solid #F59E0B; border-radius: 8px; padding: 12px; margin-bottom: 20px; font-size: 13px; color: #92400E; text-align: left; " >
< strong > Sandbox Redirection Notice : < / strong > < br / >
This email was intended for < code > { orig_str } < / code > . Because Resend ' s free tier allows delivery only to the verified account email, it was routed to <code>{sandbox_redirect}</code> for testing.
< / div >
"""
sandbox_notice_text = f " [Notice: Resend test sandbox redirecting from {orig_str} to {sandbox_redirect}] \n \n "
to_emails = [ sandbox_redirect ]
html_content = f """
< ! DOCTYPE html >
< html lang = " ru " >
html_content = f """ <!DOCTYPE html>
< html >
< head >
< head >
< meta charset = " UTF-8 " >
< meta charset = " UTF-8 " >
< meta name = " viewport " content = " width=device-width, initial-scale=1.0 " >
< title > К о д п о д т в е р ж д е н и я | Verification Code < / title >
< title > Verification Code < / title >
< / head >
< / head >
< body style = " margin: 0; padding: 0; background-color: #F4F6F9; font-family: -apple-system, BlinkMacSystemFont, ' Segoe UI ' , Roboto, Helvetica, Arial, sans-serif; color: #15171C; -webkit-font-smoothing: antialiased; " >
< table border = " 0 " cellpadding = " 0 " cellspacing = " 0 " width = " 100 % " style = " table-layout: fixed; background-color: #F4F6F9; padding: 40px 16px; " >
< tr >
< td align = " center " valign = " top " >
< table border = " 0 " cellpadding = " 0 " cellspacing = " 0 " width = " 100 % " style = " max-width: 540px; background-color: #FFFFFF; border-radius: 16px; border: 1px solid #E2E8F0; box-shadow: 0 4px 20px -2px rgba(21, 23, 28, 0.06); overflow: hidden; " >
< ! - - Top Gradient Accent Line - - >
< tr >
< td style = " height: 4px; background: linear-gradient(90deg, #5172E1 0 % , #1C458C 100 % ); line-height: 4px; font-size: 4px; " > & nbsp ; < / td >
< / tr >
< ! - - 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 " style = " height: 38px; width: auto; max-width: 160px; display: inline-block; " / >
< / td >
< / tr >
< ! - - Main Body Section - - >
< tr >
< td style = " padding: 36px 36px 28px 36px; " >
< ! - - Security Badge - - >
< div style = " text-align: center; margin-bottom: 16px; " >
< span style = " display: inline-block; background-color: #EEF2FF; color: #3B66DE; border: 1px solid #D5DEFF; padding: 4px 12px; border-radius: 9999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; " >
Б е з о п а с н о с т ь / Security
< / span >
< / div >
< ! - - Main Title - - >
< h1 style = " margin: 0 0 12px 0; font-size: 22px; font-weight: 800; color: #15171C; text-align: center; line-height: 1.3; " >
К о д п о д т в е р ж д е н и я
< / h1 >
< ! - - Intro Message - - >
< p style = " margin: 0 0 24px 0; font-size: 14px; color: #646A75; text-align: center; line-height: 1.6; " >
И с п о л ь з у й т е с л е д у ю щ и й о д н о р а з о в ы й к о д д л я в х о д а ی ا п о д т в е р ж д е н и я у ч е т н о й з а п и с и в < strong > Dovodi < / strong > :
< body style = " margin: 0; padding: 40px 16px; background-color: #F8FAFC; font-family: -apple-system, BlinkMacSystemFont, ' Segoe UI ' , Roboto, Helvetica, Arial, sans-serif; color: #0F172A; " >
< div style = " max-width: 480px; margin: 0 auto; background: #FFFFFF; border-radius: 12px; border: 1px solid #E2E8F0; padding: 32px; text-align: center; box-shadow: 0 4px 6px -1px rgba(0,0,0,0.05); " >
{ sandbox_notice_html }
< h2 style = " margin: 0 0 16px; color: #1E293B; font-size: 22px; " > Muslim Connect Hub < / h2 >
< p style = " margin: 0 0 24px; color: #64748B; font-size: 15px; line-height: 1.5; " >
Use the following verification code to complete your registration :
< / p >
< / p >
< ! - - OTP Box - - >
< div style = " text-align: center; margin: 28px 0; padding: 22px; background-color: #F8FAFD; border: 1.5px dashed #5172E1; border-radius: 14px; " >
< span style = " font-family: ' SF Pro Mono ' , Monaco, Consolas, ' Liberation Mono ' , ' Courier New ' , monospace; font-size: 38px; font-weight: 800; color: #15171C; letter-spacing: 10px; display: inline-block; " >
< div style = " background-color: #F1F5F9; border-radius: 8px; padding: 18px 24px; margin: 24px 0; display: inline-block; " >
< span style = " font-family: monospace; font-size: 32px; font-weight: 700; letter-spacing: 6px; color: #0284C7; " >
{ code }
{ code }
< / span >
< / span >
< / div >
< / div >
< ! - - Expiry & Security Notice - - >
< div style = " background-color: #FFFBEB; border: 1px solid #FDE68A; border-radius: 10px; padding: 12px 16px; margin-bottom: 24px; " >
< table border = " 0 " cellpadding = " 0 " cellspacing = " 0 " width = " 100 % " >
< tr >
< td style = " font-size: 12px; color: #92400E; line-height: 1.5; " >
⏱ < strong > В н и м а н и е : < / strong > С р о к д е й с т в и я к о д а и с т е к а е т ч е р е з 5 м и н у т . Е с л и в ы н е з а п р а ш и в а л и э т о т к о д , п р о с т о п р о и г н о р и р у й т е э т о п и с ь м о .
< / td >
< / tr >
< / table >
< / div >
< p style = " margin: 0; font-size: 13px; color: #8C93A0; text-align: center; line-height: 1.5; " >
Н и к о м у н е п е р е д а в а й т е э т о т к о д в ц е л я х б е з о п а с н о с т и в а ш е г о а к к а у н т а .
< / p >
< / td >
< / tr >
< ! - - Footer Section - - >
< tr >
< td style = " padding: 24px 36px; background-color: #F8F9FB; border-top: 1px solid #EEF0F4; text-align: center; " >
< p style = " margin: 0 0 6px 0; font-size: 13px; font-weight: 700; color: #15171C; " >
Dovodi
< p style = " margin: 24px 0 0; color: #94A3B8; font-size: 13px; " >
This code will expire in 5 minutes . If you did not request this code , please ignore this email .
< / p >
< / p >
< 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 >
& nbsp ; • & nbsp ;
< 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 . В с е п р а в а з а щ и щ е н ы .
< / p >
< / td >
< / tr >
< / table >
< / td >
< / tr >
< / table >
< / div >
< / body >
< / body >
< / html >
"""
< / html > """
text_content = (
text_content = (
f " Код подтверждения Dovodi: {code} \n \n "
f " Your Dovodi verification code is: {code} \n \n "
f " Срок действия кода истекает через 5 минут. Если вы не запрашивали этот код, проигнорируйте это письмо. \n "
f " Никому не передавайте этот код в целях безопасности вашего аккаунта. "
f " {sandbox_notice_text} "
f " Muslim Connect Hub Verification Code: {code} \n \n "
f " This code will expire in 5 minutes. If you did not request this code, please ignore this email. "
)
)
payload = {
payload = {
@ -226,9 +182,9 @@ def send_email(recipient, code):
try :
try :
response = requests . post ( url , headers = headers , json = payload , timeout = 15 )
response = requests . post ( url , headers = headers , json = payload , timeout = 15 )
print ( f " [Resend API] status={response.status_code} response={response.text} " )
if response . status_code > = 400 :
if response . status_code > = 400 :
logger . error ( f " Failed to send email via Resend: HTTP {response.status_code} - {response.text} " )
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
return False
logger . info ( f " Email OTP sent successfully via Resend to {to_emails} " )
logger . info ( f " Email OTP sent successfully via Resend to {to_emails} " )
return True
return True