Spaces:
Sleeping
Sleeping
| # File: backend/email_utils.py | |
| import httpx | |
| from pydantic import EmailStr | |
| import random | |
| import string | |
| import os | |
| # --- CONFIGURATION --- | |
| # Securely pull both keys from Hugging Face Settings | |
| MAILJET_API_KEY = os.getenv("MAILJET_API_KEY") | |
| MAILJET_SECRET_KEY = os.getenv("MAILJET_SECRET_KEY") | |
| # This MUST exactly match the email you registered in Mailjet | |
| SENDER_EMAIL = "docusortofficial@gmail.com" | |
| SENDER_NAME = "DocuSort" | |
| def generate_otp(length=6): | |
| return ''.join(random.choices(string.digits, k=length)) | |
| async def send_otp_email(email: EmailStr, otp: str, subject="DocuSort Verification"): | |
| # Fallback safety: If API keys are missing, print to logs instead of crashing | |
| if not MAILJET_API_KEY or not MAILJET_SECRET_KEY: | |
| print(f"\n{'='*40}") | |
| print(f" ⚠️ [MOCK EMAIL - NO API KEY] To: {email}") | |
| print(f" ⚠️ [MOCK EMAIL - NO API KEY] CODE: {otp}") | |
| print(f"{'='*40}\n") | |
| return | |
| url = "https://api.mailjet.com/v3.1/send" | |
| payload = { | |
| "Messages": [ | |
| { | |
| "From": {"Email": SENDER_EMAIL, "Name": SENDER_NAME}, | |
| "To": [{"Email": email}], | |
| "Subject": subject, | |
| "HTMLPart": f"<p>Your verification code is: <strong>{otp}</strong></p><p>This code expires in 10 minutes.</p>" | |
| } | |
| ] | |
| } | |
| async with httpx.AsyncClient() as client: | |
| try: | |
| response = await client.post( | |
| url, | |
| json=payload, | |
| auth=(MAILJET_API_KEY, MAILJET_SECRET_KEY) | |
| ) | |
| response.raise_for_status() | |
| except Exception as e: | |
| print(f"Mailjet API Error: {e}") | |
| async def send_alert_email(email: EmailStr, subject: str, body_content: str): | |
| if not MAILJET_API_KEY or not MAILJET_SECRET_KEY: | |
| clean_body = body_content.replace("<br>", "\n").replace("<b style='font-size:24px;'>", "").replace("</b>", "") | |
| print(f"\n{'='*40}") | |
| print(f" ⚠️ [MOCK ALERT - NO API KEY] To: {email}") | |
| print(f" ⚠️ [MOCK ALERT - NO API KEY] Body: \n{clean_body}") | |
| print(f"{'='*40}\n") | |
| return | |
| url = "https://api.mailjet.com/v3.1/send" | |
| html_body = f""" | |
| <div style="font-family: Arial, sans-serif; padding: 20px; color: #333; max-width: 600px; margin: 0 auto; border: 1px solid #e2e8f0; border-radius: 8px;"> | |
| <h2 style="color: #4f46e5; border-bottom: 2px solid #e0e7ff; padding-bottom: 10px;">DocuSort Notification</h2> | |
| <p style="font-size: 16px; line-height: 1.6;">{body_content}</p> | |
| <div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee; font-size: 12px; color: #94a3b8; text-align: center;"> | |
| This is an automated message from the DocuSort platform. Please do not reply directly to this email. | |
| </div> | |
| </div> | |
| """ | |
| payload = { | |
| "Messages": [ | |
| { | |
| "From": {"Email": SENDER_EMAIL, "Name": SENDER_NAME}, | |
| "To": [{"Email": email}], | |
| "Subject": subject, | |
| "HTMLPart": html_body | |
| } | |
| ] | |
| } | |
| async with httpx.AsyncClient() as client: | |
| try: | |
| response = await client.post( | |
| url, | |
| json=payload, | |
| auth=(MAILJET_API_KEY, MAILJET_SECRET_KEY) | |
| ) | |
| response.raise_for_status() | |
| except Exception as e: | |
| print(f"Mailjet API Error: {e}") |