Update main.py
Browse files
main.py
CHANGED
|
@@ -100,22 +100,64 @@ def _send_notification(user_id, user_email, message_content, send_email=False, e
|
|
| 100 |
logger.error("RESEND_API_KEY is not configured. Cannot send email.")
|
| 101 |
return False
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
headers = {
|
| 104 |
-
"Authorization": f"Bearer {
|
| 105 |
"Content-Type": "application/json"
|
| 106 |
}
|
| 107 |
payload = {
|
| 108 |
-
"from": "Sozo Business Studio <onboarding@sozofix.tech>",
|
| 109 |
"to": [user_email],
|
| 110 |
"subject": email_subject,
|
| 111 |
"html": email_body
|
| 112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
try:
|
| 114 |
-
response = requests.post("https://api.resend.com/emails", json=payload)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 115 |
response.raise_for_status()
|
| 116 |
-
|
|
|
|
|
|
|
| 117 |
except requests.exceptions.RequestException as e:
|
| 118 |
logger.error(f"Failed to send email to {user_email} via Resend: {e}")
|
|
|
|
|
|
|
|
|
|
| 119 |
return False
|
| 120 |
|
| 121 |
return True
|
|
|
|
| 100 |
logger.error("RESEND_API_KEY is not configured. Cannot send email.")
|
| 101 |
return False
|
| 102 |
|
| 103 |
+
# Clean the API key (remove any whitespace)
|
| 104 |
+
api_key = RESEND_API_KEY.strip()
|
| 105 |
+
|
| 106 |
+
# Debug logging (be careful in production)
|
| 107 |
+
logger.debug(f"API key format check - starts with 're_': {api_key.startswith('re_')}")
|
| 108 |
+
logger.debug(f"API key length: {len(api_key)}")
|
| 109 |
+
logger.debug(f"User email: {user_email}")
|
| 110 |
+
|
| 111 |
headers = {
|
| 112 |
+
"Authorization": f"Bearer {api_key}",
|
| 113 |
"Content-Type": "application/json"
|
| 114 |
}
|
| 115 |
payload = {
|
| 116 |
+
"from": "Sozo Business Studio <onboarding@sozofix.tech>",
|
| 117 |
"to": [user_email],
|
| 118 |
"subject": email_subject,
|
| 119 |
"html": email_body
|
| 120 |
}
|
| 121 |
+
|
| 122 |
+
# Log the request details (excluding sensitive info)
|
| 123 |
+
logger.debug(f"Request URL: https://api.resend.com/emails")
|
| 124 |
+
logger.debug(f"Request payload keys: {list(payload.keys())}")
|
| 125 |
+
logger.debug(f"From address: {payload['from']}")
|
| 126 |
+
logger.debug(f"To address: {payload['to']}")
|
| 127 |
+
|
| 128 |
try:
|
| 129 |
+
response = requests.post("https://api.resend.com/emails", headers=headers, json=payload)
|
| 130 |
+
|
| 131 |
+
# Log response details for debugging
|
| 132 |
+
logger.info(f"Resend API response status: {response.status_code}")
|
| 133 |
+
logger.debug(f"Response headers: {dict(response.headers)}")
|
| 134 |
+
logger.debug(f"Response content: {response.text}")
|
| 135 |
+
|
| 136 |
+
if response.status_code == 401:
|
| 137 |
+
logger.error("=== RESEND 401 UNAUTHORIZED DEBUG ===")
|
| 138 |
+
logger.error(f"API Key starts correctly: {api_key.startswith('re_')}")
|
| 139 |
+
logger.error(f"API Key length: {len(api_key)} (should be ~40 chars)")
|
| 140 |
+
logger.error(f"Authorization header: Bearer {api_key[:10]}...")
|
| 141 |
+
logger.error("Possible issues:")
|
| 142 |
+
logger.error("1. API key copied incorrectly (extra chars/spaces)")
|
| 143 |
+
logger.error("2. API key was regenerated in dashboard but not updated in env")
|
| 144 |
+
logger.error("3. API key permissions were changed")
|
| 145 |
+
logger.error("4. Account billing issue")
|
| 146 |
+
logger.error(f"Full response: {response.text}")
|
| 147 |
+
return False
|
| 148 |
+
elif response.status_code == 422:
|
| 149 |
+
logger.error(f"Resend API validation error (422): {response.text}")
|
| 150 |
+
return False
|
| 151 |
+
|
| 152 |
response.raise_for_status()
|
| 153 |
+
response_data = response.json()
|
| 154 |
+
logger.info(f"Successfully sent email to {user_email}. Email ID: {response_data.get('id')}")
|
| 155 |
+
|
| 156 |
except requests.exceptions.RequestException as e:
|
| 157 |
logger.error(f"Failed to send email to {user_email} via Resend: {e}")
|
| 158 |
+
if hasattr(e, 'response') and e.response is not None:
|
| 159 |
+
logger.error(f"Error response status: {e.response.status_code}")
|
| 160 |
+
logger.error(f"Error response content: {e.response.text}")
|
| 161 |
return False
|
| 162 |
|
| 163 |
return True
|