Files
Brancheneinstufung2/lead-engine/trading_twins/email_sender.py

86 lines
2.6 KiB
Python

import os
import msal
import requests
import base64
# Graph API Konfiguration (aus .env laden)
CLIENT_ID = os.getenv("AZURE_CLIENT_ID")
CLIENT_SECRET = os.getenv("AZURE_CLIENT_SECRET")
TENANT_ID = os.getenv("AZURE_TENANT_ID")
AUTHORITY = f"https://login.microsoftonline.com/{TENANT_ID}"
SCOPE = ["https://graph.microsoft.com/.default"]
SENDER_EMAIL = "info@robo-planet.de"
def get_access_token():
"""Holt ein Token für die Graph API."""
app = msal.ConfidentialClientApplication(
CLIENT_ID, authority=AUTHORITY, client_credential=CLIENT_SECRET
)
result = app.acquire_token_for_client(scopes=SCOPE)
if "access_token" in result:
return result["access_token"]
else:
raise Exception(f"Fehler beim Abrufen des Tokens: {result.get('error_description')}")
def send_email_via_graph(to_email, subject, body_html, banner_path=None):
"""
Sendet eine E-Mail über die Microsoft Graph API.
"""
token = get_access_token()
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
# E-Mail Struktur für Graph API
email_msg = {
"message": {
"subject": subject,
"body": {
"contentType": "HTML",
"content": body_html
},
"toRecipients": [
{
"emailAddress": {
"address": to_email
}
}
],
"from": {
"emailAddress": {
"address": SENDER_EMAIL
}
}
},
"saveToSentItems": "true"
}
# Optional: Banner-Bild als Inline-Attachment einfügen
if banner_path and os.path.exists(banner_path):
with open(banner_path, "rb") as f:
content_bytes = f.read()
content_b64 = base64.b64encode(content_bytes).decode("utf-8")
email_msg["message"]["attachments"] = [
{
"@odata.type": "#microsoft.graph.fileAttachment",
"name": "banner.png",
"contentBytes": content_b64,
"isInline": True,
"contentId": "banner_image"
}
]
endpoint = f"https://graph.microsoft.com/v1.0/users/{SENDER_EMAIL}/sendMail"
response = requests.post(endpoint, headers=headers, json=email_msg)
if response.status_code == 202:
print(f"E-Mail erfolgreich an {to_email} gesendet.")
return True
else:
print(f"Fehler beim Senden: {response.status_code} - {response.text}")
return False