FireShadow commited on
Commit
ca3ce07
·
verified ·
1 Parent(s): b7dc123

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -13
app.py CHANGED
@@ -120,18 +120,33 @@ def _ok_html(text):
120
  return f"<div style='padding:10px;border:1px solid #2ea043;border-radius:5px;color:#2ea043;background-color:#333333;'>✅ {text}</div>"
121
 
122
  # --- Email support ---
123
- def send_email(recipient: str, subject: str, body_text: str, attachment_name: str = None, attachment_json: dict = None) -> str:
124
- """Returns '' on success, or error message string."""
125
- host = os.getenv("SMTP_HOST")
126
- port = int(os.getenv("SMTP_PORT", "587"))
127
- user = os.getenv("SMTP_USER")
128
- pwd = os.getenv("SMTP_PASS")
129
- from_addr = os.getenv("EMAIL_FROM")
130
 
131
- if not all([host, port, user, pwd, from_addr]):
132
- return "Email is not configured (set SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, EMAIL_FROM)."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
  try:
 
135
  msg = EmailMessage()
136
  msg["From"] = from_addr
137
  msg["To"] = recipient
@@ -142,10 +157,17 @@ def send_email(recipient: str, subject: str, body_text: str, attachment_name: st
142
  payload = json.dumps(attachment_json, indent=2).encode("utf-8")
143
  msg.add_attachment(payload, maintype="application", subtype="json", filename=attachment_name)
144
 
145
- with smtplib.SMTP(host, port, timeout=30) as s:
146
- s.starttls()
147
- s.login(user, pwd)
148
- s.send_message(msg)
 
 
 
 
 
 
 
149
  return ""
150
  except Exception as e:
151
  return f"Email send failed: {e}"
 
120
  return f"<div style='padding:10px;border:1px solid #2ea043;border-radius:5px;color:#2ea043;background-color:#333333;'>✅ {text}</div>"
121
 
122
  # --- Email support ---
123
+ import base64, json, requests
124
+ from email.message import EmailMessage
 
 
 
 
 
125
 
126
+ def _gmail_access_token() -> str:
127
+ token_url = "https://oauth2.googleapis.com/token"
128
+ data = {
129
+ "client_id": os.getenv("GMAIL_CLIENT_ID"),
130
+ "client_secret": os.getenv("GMAIL_CLIENT_SECRET"),
131
+ "refresh_token": os.getenv("GMAIL_REFRESH_TOKEN"),
132
+ "grant_type": "refresh_token",
133
+ }
134
+ r = requests.post(token_url, data=data, timeout=20)
135
+ r.raise_for_status()
136
+ return r.json()["access_token"]
137
+
138
+ def send_email(recipient: str, subject: str, body_text: str,
139
+ attachment_name: str = None, attachment_json: dict = None) -> str:
140
+ """
141
+ Sends via Gmail API. Returns '' on success, or an error string.
142
+ """
143
+ from_addr = os.getenv("EMAIL_FROM")
144
+ if not all([os.getenv("GMAIL_CLIENT_ID"), os.getenv("GMAIL_CLIENT_SECRET"),
145
+ os.getenv("GMAIL_REFRESH_TOKEN"), from_addr]):
146
+ return "Gmail API not configured (set GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, GMAIL_REFRESH_TOKEN, EMAIL_FROM)."
147
 
148
  try:
149
+ # Build MIME message
150
  msg = EmailMessage()
151
  msg["From"] = from_addr
152
  msg["To"] = recipient
 
157
  payload = json.dumps(attachment_json, indent=2).encode("utf-8")
158
  msg.add_attachment(payload, maintype="application", subtype="json", filename=attachment_name)
159
 
160
+ # Base64url encode the raw RFC822 message
161
+ raw = base64.urlsafe_b64encode(msg.as_bytes()).decode("utf-8")
162
+
163
+ # Get access token and send
164
+ access_token = _gmail_access_token()
165
+ api_url = "https://gmail.googleapis.com/gmail/v1/users/me/messages/send"
166
+ headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
167
+ r = requests.post(api_url, headers=headers, json={"raw": raw}, timeout=20)
168
+
169
+ if r.status_code >= 400:
170
+ return f"Gmail API error {r.status_code}: {r.text[:300]}"
171
  return ""
172
  except Exception as e:
173
  return f"Email send failed: {e}"