Spaces:
Sleeping
Sleeping
Update main.py
Browse files
main.py
CHANGED
|
@@ -10,6 +10,7 @@ from flask_apscheduler import APScheduler
|
|
| 10 |
import firebase_admin
|
| 11 |
from firebase_admin import credentials, db, auth as firebase_auth
|
| 12 |
from resend import Emails
|
|
|
|
| 13 |
import logging
|
| 14 |
from logging.handlers import RotatingFileHandler
|
| 15 |
import time
|
|
@@ -61,27 +62,43 @@ Emails.api_key = RESEND_API_KEY
|
|
| 61 |
logger.info("Flask, APScheduler, and Resend initialized.")
|
| 62 |
|
| 63 |
|
|
|
|
| 64 |
def send_email(to, subject, html):
|
| 65 |
-
"""Sends an email and
|
| 66 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
response = Emails.send({
|
| 68 |
"from": "Admin <admin@resend.dev>",
|
| 69 |
-
"to":
|
| 70 |
"subject": subject,
|
| 71 |
"html": html
|
| 72 |
})
|
| 73 |
if response is None:
|
| 74 |
-
logger.warning(f"Email API returned None for recipient {
|
| 75 |
return None
|
| 76 |
-
logger.info(f"Email sent successfully to {
|
| 77 |
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
except Exception:
|
| 79 |
-
#
|
| 80 |
-
logger.error(f"
|
| 81 |
return None
|
| 82 |
|
|
|
|
| 83 |
def send_rotation_notification(job_id, shift_record):
|
| 84 |
-
"""Sends email notification for rotation to all admins
|
| 85 |
try:
|
| 86 |
job_ref = db.reference(f"jobs/{job_id}")
|
| 87 |
job_data = job_ref.get()
|
|
@@ -121,7 +138,7 @@ def send_rotation_notification(job_id, shift_record):
|
|
| 121 |
for admin_email in ADMIN_EMAILS:
|
| 122 |
logger.info(f"Sending rotation notification to {admin_email}...")
|
| 123 |
send_email(admin_email, subject, html_content)
|
| 124 |
-
time.sleep(1)
|
| 125 |
except Exception as e:
|
| 126 |
logger.error(f"Error building rotation notification for job {job_id}", exc_info=True)
|
| 127 |
|
|
|
|
| 10 |
import firebase_admin
|
| 11 |
from firebase_admin import credentials, db, auth as firebase_auth
|
| 12 |
from resend import Emails
|
| 13 |
+
from resend.exceptions import ResendError # <-- ADDED IMPORT
|
| 14 |
import logging
|
| 15 |
from logging.handlers import RotatingFileHandler
|
| 16 |
import time
|
|
|
|
| 62 |
logger.info("Flask, APScheduler, and Resend initialized.")
|
| 63 |
|
| 64 |
|
| 65 |
+
# === REFACTORED FUNCTION (send_email) ===
|
| 66 |
def send_email(to, subject, html):
|
| 67 |
+
"""Sends an email with sanitized input and detailed error logging."""
|
| 68 |
try:
|
| 69 |
+
# --- FIX: Sanitize the email address to remove leading/trailing whitespace ---
|
| 70 |
+
clean_to = to.strip()
|
| 71 |
+
if not clean_to:
|
| 72 |
+
logger.error("Attempted to send email to an empty address.")
|
| 73 |
+
return None
|
| 74 |
+
|
| 75 |
response = Emails.send({
|
| 76 |
"from": "Admin <admin@resend.dev>",
|
| 77 |
+
"to": clean_to, # Use the cleaned email address
|
| 78 |
"subject": subject,
|
| 79 |
"html": html
|
| 80 |
})
|
| 81 |
if response is None:
|
| 82 |
+
logger.warning(f"Email API returned None for recipient {clean_to}. Check Resend dashboard for suppression list.")
|
| 83 |
return None
|
| 84 |
+
logger.info(f"Email sent successfully to {clean_to}. Response ID: {response.get('id')}")
|
| 85 |
return response
|
| 86 |
+
# --- FIX: More specific error catching for Resend ---
|
| 87 |
+
except ResendError as e:
|
| 88 |
+
logger.error(
|
| 89 |
+
f"A Resend API error occurred for recipient '{to}': "
|
| 90 |
+
f"Code: {e.code}, Type: {e.error_type}, Message: {e.message}",
|
| 91 |
+
exc_info=True
|
| 92 |
+
)
|
| 93 |
+
return None
|
| 94 |
except Exception:
|
| 95 |
+
# Fallback for any other unexpected errors
|
| 96 |
+
logger.error(f"An unexpected exception occurred while sending email to '{to}'", exc_info=True)
|
| 97 |
return None
|
| 98 |
|
| 99 |
+
|
| 100 |
def send_rotation_notification(job_id, shift_record):
|
| 101 |
+
"""Sends email notification for rotation to all admins."""
|
| 102 |
try:
|
| 103 |
job_ref = db.reference(f"jobs/{job_id}")
|
| 104 |
job_data = job_ref.get()
|
|
|
|
| 138 |
for admin_email in ADMIN_EMAILS:
|
| 139 |
logger.info(f"Sending rotation notification to {admin_email}...")
|
| 140 |
send_email(admin_email, subject, html_content)
|
| 141 |
+
time.sleep(1) # Rate-limit prevention
|
| 142 |
except Exception as e:
|
| 143 |
logger.error(f"Error building rotation notification for job {job_id}", exc_info=True)
|
| 144 |
|