Dev Life
Transaktions-E-Mail-Workflows für das Zurücksetzen von Passwörtern mit der Mailgun-API erstellen
Transaktions-E-Mails sind automatisierte E-Mails, die durch Nutzeraktionen auf einer Website, in einer App oder bei einem Service ausgelöst werden. Im Gegensatz zu Marketing-E-Mails, die Produkte oder Dienstleistungen bewerben, liefern Transaktions-E-Mails wichtige Informationen, oft in Echtzeit.
Transaktions-E-Mail-Workflows gehen noch einen Schritt weiter, indem sie eine Abfolge von E-Mails basierend auf Nutzeraktionen automatisieren, um eine zeitnahe Kommunikation und ein reibungsloses Nutzererlebnis zu gewährleisten. Unternehmen verlassen sich auf Dienste wie Mailgun für Transaktions-E-Mails, da diese umgehend, relevant und durch unmittelbare Nutzeraktionen ausgelöst werden. So ermöglicht der Workflow beispielsweise einem Nutzer, sein Passwort schnell zurückzusetzen und wieder Zugriff auf sein Konto zu erhalten.
In diesem Tutorial erfahren Sie, wie Sie einen Transaktions-E-Mail-Workflow für das Zurücksetzen von Passwörtern mit der Mailgun-API erstellen.
Einrichten eines Mailgun-Kontos
Wenn Sie noch kein Mailgun-Konto haben, müssen Sie als Erstes eines erstellen. Prüfen Sie unbedingt die mit Ihrem Mailgun-Konto verknüpfte E-Mail-Adresse und verifizieren Sie Ihr Konto:

Geben Sie anschließend Ihre Telefonnummer und den bereitgestellten Autorisierungscode ein, um Ihr Konto zu aktivieren:

Sobald Ihr Mailgun-Konto eingerichtet ist, müssen Sie einen API-Schlüssel abrufen, um den Dienst nutzen zu können.
Einen API-Schlüssel abrufen
Damit Ihre Anwendung mit den Diensten von Mailgun interagieren kann, muss sie über einen API-Schlüssel authentifiziert werden. Um Ihren API-Schlüssel zu erhalten, navigieren Sie zum Mailgun-Dashboard und wählen Sie links Erste Schritte aus, um den Leitfaden für die ersten Schritte anzuzeigen:

Klicken Sie auf die Schaltfläche Erste Schritte unter API-Schlüssel erstellen. Geben Sie anschließend eine Beschreibung ein, die den Hauptzweck der API passend beschreibt. Wenn der API-Schlüssel beispielsweise für Prozesse zur Nutzerauthentifizierung gedacht ist, nennen Sie ihn etwa user_authentication und klicken Sie auf Schlüssel erstellen:

Stellen Sie sicher, dass Sie diesen Schlüssel kopieren und sicher aufbewahren, da der Schlüssel nur dieses eine Mal angezeigt wird:

Erstellung der Anwendungsschnittstelle mit FastAPI
Um die Anwendungsschnittstelle zu erstellen, die den E-Mail-Workflow antreibt, müssen Sie als Erstes die erforderlichen Bibliotheken installieren. Erstellen Sie vorher ein Projektverzeichnis, indem Sie mkdir my_fastapi_app ausführen, und starten Sie ein virtuelle Umgebung in dem Verzeichnis.
Installieren Sie dann die erforderlichen Bibliotheken mit dem folgenden Befehl:
pip install fastapi jinja2 requests uvicorn python-multipart
Hier installieren Sie:
fastapi, das als primäres Backend-Framework dientjinja2, das Ihre Frontend-Vorlagen bereitstelltrequests, das HTTP-Anfragen an die Mailgun-API sendet
Obwohl FastAPI primär für die Erstellung von APIs gedacht ist, ermöglicht das Hinzufügen der Bibliothek jinja2 eine Full-Stack-Entwicklung – was jedoch eine korrekte Verzeichnisstruktur erfordert. Ihre Projektstruktur sollte folgendes Format haben:
my_fastapi_app/
│── main.py # Hauptdatei der FastAPI-Anwendung
│── users.json # JSON-Datei zum Speichern von Nutzerdaten
│── templates/ # Ordner für HTML-Vorlagen
│ ├── login.html # Anmeldeseite
│ ├── home.html # Startseite
│ ├── passwordReset.html # Seite zum Zurücksetzen des Passworts
│── static/ # Ordner für statische Dateien
│ ├── styles.css # Stile für die Dateien login.html und passwordReset.html
Sie finden den gesamten Code für dieses Tutorial in diesem GitHub-Repository.
Sobald Ihre Projektstruktur steht, kopieren Sie den Code entweder und fügen ihn in die entsprechenden Dateien ein oder klonen das obige GitHub-Repository mit dem folgenden Befehl:
git clone https://github.com/EphraimX/building-transactional-email-workflows-for-password-resets-with-mailgun-api.git
Sehen wir uns den ersten Abschnitt der Datei main.py an. In dieser Datei geschieht die ganze Magie, da sie die Frontend- und Backend-Vorgänge miteinander verbindet:
import osrnimport jsonrnimport uuidrnimport requestsrnimport urllib.parsernfrom fastapi import FastAPI, Request, Formrnfrom pydantic import BaseModelrnfrom fastapi.responses import HTMLResponsernfrom fastapi.staticfiles import StaticFilesrnfrom fastapi.templating import Jinja2Templatesrnrnapp = FastAPI()rnapp.mount("/static", StaticFiles(directory="static"), name="static")rntemplates = Jinja2Templates(directory="templates")rnrnclass loginData(BaseModel):rn username: strrn password: strrnrn@app.get("/login", response_class=HTMLResponse)rnasync def login(request: Request):rn return templates.TemplateResponse("login.html", {"request": request, "message": ""})rnrn@app.get("/passwordResetView/", response_class=HTMLResponse)rnasync def password_reset_view(request: Request):rn return templates.TemplateResponse(rn "passwordReset.html", {"request": request, "message": ""}rn )rnrn@app.post("/home", response_class=HTMLResponse)rnasync def password_reset(rn request: Request, email_address: str = Form(...), password: str = Form(...)rn):rnrn # Open and read the JSON DB filern try:rn with open("users.json", "r") as file:rn users = json.load(file)rn except (FileNotFoundError, json.JSONDecodeError):rn users = []rnrn for user in users:rnrn if user["email_address"] == email_address and user["password"] == password:rn return templates.TemplateResponse("home.html", {"request": request})rnrn # If no match was found, return an error messagern return templates.TemplateResponse(rn "login.html",rn {rn "request": request,rn "message": "Email or Password Incorrect. If you cannot remember your password, kindly reset it.",rn },rn )rn
In diesem Code übernimmt die App die Authentifizierung, indem sie Seiten für die Anmeldung und das Zurücksetzen von Passwörtern bereitstellt und gleichzeitig die Anmeldeinformationen in der Datei users.json überprüft. Die App initialisiert FastAPI, konfiguriert Vorlagen und definiert ein loginData-Modell für die Validierung. Die Routen /login und /passwordResetView/ stellen ihre jeweiligen Seiten bereit, während /home die Anmeldeinformationen überprüft und gültige Nutzer weiterleitet oder Fehler anzeigt. Die Funktion zum Zurücksetzen von Passwörtern generiert mithilfe von uuid einen eindeutigen Link und sendet diesen über die Mailgun-API.
Um dies zu testen, öffnen Sie Ihre Behelfsdatenbank (users.json) und fügen Sie Folgendes ein:
[rn {rn "username" : "sinchy",rn "email_address" : "sinch@gmail.com",rn "password" : "sinch12345"rn },rn {rn "username" : "grinchy",rn "email_address" : "rinch@gmail.com",rn "password" : "grinch67890"rn }rn]
Sie sollten zudem die Autorisierung für diese E-Mail-Adressen über das Mailgun-Dashboard vornehmen, falls Sie eine Sandbox-Domain verwenden.
Starten Sie Ihre Anwendung, indem Sie den Befehl uvicorn main:app –reload ausführen. Gehen Sie dann zu http://localhost:8000/login, wo Sie Folgendes sehen sollten:

Wenn Sie versuchen, sich mit den Anmeldeinformationen in der Datei users.json anzumelden, werden Sie zur Startseite weitergeleitet:

Wenn Sie die falschen Anmeldeinformationen eingeben, sehen Sie Folgendes:

Eine Verbindung zu Mailgun einrichten
Um E-Mails über Mailgun zu versenden, müssen Sie eine Verbindung zwischen Ihrer Anwendung und dem E-Mail-Service von Mailgun herstellen.
Öffnen Sie dazu die Datei main.py und fügen Sie den folgenden Code ein. Ersetzen Sie dabei , und durch gültige Werte:
def send_simple_message(API_KEY):rn response = requests.post(rn "https://api.mailgun.net/v3/<SANDBOX_URL>/messages",rn auth=("api", f"{API_KEY}"),rn data={"from": "Mailgun Sandbox <postmaster@<SANDBOX_URL>>",rn "to": "<RECIPIENT_NAME> <RECIPIENT_EMAIL>",rn "subject": "Hello <RECIPIENT_NAME>",rn "text": "Congratulations <RECIPIENT_NAME>, you just sent an email with Mailgun! You are truly awesome!"rn }rn )rnrn print(response.json())rn return responsern
Übergeben Sie zu Testzwecken Ihren API-Schlüssel direkt beim Aufruf der Funktion:
send_simple_message("your-api-key-here")
Führen Sie das Skript mit folgendem Befehl aus:
python main.py
Wenn dies erfolgreich war, gibt die Funktion eine Antwort ähnlich wie diese aus:
{
"id": "",
"message": "Queued. Thank you."
}
Dies bestätigt, dass die E-Mail-Anfrage erfolgreich von Mailgun in die Warteschlange eingereiht wurde.
E-Mail-Vorlage entwerfen und einrichten
Um an der Logik zum Zurücksetzen von Passwörtern zu arbeiten, müssen Sie die Vorlage für die E-Mail entwerfen, die an den Nutzer gesendet wird. Mit Mailgun gibt es zwei Möglichkeiten, eine E-Mail zu entwerfen: mit HTML oder mit dem Drag-and-Drop-Vorlagen-Builder von Mailgun. Hier verwenden Sie den HTML-Ansatz.
Um mit dem Entwurf zu beginnen, gehen Sie in Ihr Mailgun-Dashboard und navigieren Sie zu Senden > Versand > Vorlagen:

Klicken Sie als Nächstes auf Nachrichtenvorlage erstellen, wählen Sie die Option für die Programmierung in HTML und klicken Sie auf die Vorlage Leer:

Füllen Sie das Formular für die Vorlage mit dem Namen, der Beschreibung und den Details der E-Mail aus:

Scrollen Sie dann nach unten zum Tab Editor und kopieren Sie den Code aus der Datei email_template.html Datei:

Wenn Sie den Tab Testdaten auswählen, sehen Sie zwei dynamische Variablen: username und reset_link.
Wählen Sie den Tab Vorschau, um die Vorlage zu sehen:

Klicken Sie abschließend auf die Schaltfläche Erstellen, um sie zu erstellen.
Implementierung der Funktion für den E-Mail-Versand
Sobald Ihre E-Mail-Vorlage fertig ist, können Sie die Funktion zum Versenden von E-Mails entwickeln. Öffnen Sie die Datei main.py und fügen Sie den folgenden Code ein:
@app.post("/resetPassword/")rnasync def reset_password(request: Request, email_address: str = Form(...)):rnrn # Open and read the JSON DB filern try:rn with open("users.json", "r") as file:rn users = json.load(file)rn except (FileNotFoundError, json.JSONDecodeError):rn users = []rnrn for user in users:rn if user["email_address"] == email_address:rnrn email_address = user["email_address"]rn username = user["username"]rn reset_link = await generate_password_reset_link(email_address)rnrn response = await send_password_reset_email(rn username, email_address, reset_linkrn )rnrn if response["success"]:rnrn return templates.TemplateResponse(rn "login.html",rn {rn "request": request,rn "message": "Kindly check your email to reset your password.",rn },rn )rnrn else:rnrn return templates.TemplateResponse(rn "passwordReset.html",rn {rn "request": request,rn "message": "Unfortunately, we ran into an error while trying to reset your password. Kindly try again, and if the issue persists, please contact support.",rn },rn )rnrn # If no match was found, return an error messagern return templates.TemplateResponse(rn "passwordReset.html",rn {rn "request": request,rn "message": "Unfortunately, we do not have a record of your email. Kindly reach out to the site administrator.",rn },rn )rnrnasync def send_password_reset_email(username, email_address, reset_link):rnrn API_KEY = os.getenv("API_KEY") # Fetch API key from environmentrnrn if not API_KEY:rn print("Error: API_KEY is not set!")rn return {"success": False, "error": "API key is missing"}rnrn try:rn response = requests.post(rn "https://api.mailgun.net/v3/<SANDBOX_URL>/messages",rn auth=("api", API_KEY),rn data={rn "from": "Mailgun Sandbox <postmaster@<SANDBOX_URL>>",rn "to": f"{username} <{email_address}>",rn "subject": f"Hello {username}",rn "template": "<EMAIL_TEMPLATE_NAME>",rn "h:X-Mailgun-Variables": json.dumps(rn {"reset_link": reset_link, "username": username}rn ),rn },rn )rnrn if response.status_code == 200:rn print(f"Password reset email sent successfully to {email_address}")rn return {"success": True, "message": "Email sent successfully"}rn else:rn print(rn f"Failed to send email. Status Code: {response.status_code}, Response: {response.text}"rn )rn return {"success": False, "error": response.text}rnrn except requests.exceptions.RequestException as e:rn print(f"Request failed: {str(e)}")rn return {"success": False, "error": str(e)}rnrnasync def generate_password_reset_link(rn email_address, base_url="https://mailgunny.com/reset-password"rn):rn token = uuid.uuid4()rn encoded_email = urllib.parse.quote(email_address)rn return f"{base_url}?email={encoded_email}&token={token}"rn
In diesem Code verarbeitet die Funktion reset_password (@app.post("/resetPassword/")) Anfragen zum Zurücksetzen von Passwörtern, indem sie überprüft, ob die übermittelte E-Mail in der Datenbank users.json vorhanden ist. Wenn sie gefunden wird, generiert sie mithilfe von generate_password_reset_link(email_address) einen eindeutigen Link zum Zurücksetzen und sendet die E-Mail zum Zurücksetzen über send_password_reset_email(username, email_address, reset_link). Anschließend gibt die Funktion eine Erfolgsmeldung zurück, wenn die E-Mail gesendet wurde, oder andernfalls eine Fehlermeldung aus. Falls keine passende E-Mail gefunden wird, wird eine entsprechende Fehlerantwort ausgegeben.
Hinweis: Ersetzen Sie die Variable API_KEY durch den Schlüssel für Ihr Mailgun-Konto.
Um die Implementierung zu testen, führen Sie uvicorn main:app –reload aus und öffnen Sie http://localhost:8000/login. Klicken Sie auf den Passwort vergessen? -Link:

Geben Sie eine in Ihrer Datei users.json vorhandene E-Mail-Adresse ein und klicken Sie auf Passwort zurücksetzen:

Wenn dies erfolgreich war, sollten Sie zurück zur Anmeldeseite geleitet werden, wo Sie angewiesen werden, Ihre E-Mails zu überprüfen. Sie sollten die folgende E-Mail im Posteingang des Empfängers sehen:

Integration mit Anwendungs-Events
Die Integration mit Anwendungsereignissen mithilfe von Webhooks ermöglicht es Ihrem System, automatisch auf Echtzeitaktualisierungen von externen Diensten zu reagieren.
Ein Webhook ist im Wesentlichen ein HTTP- Callback. Immer wenn ein bestimmtes Ereignis in einer externen Anwendung auftritt (z. B. eine Zahlungsbestätigung, eine Nutzerregistrierung oder eine Anfrage zum Zurücksetzen des Passworts), sendet der Dienst eine Anfrage an Ihre vordefinierte Webhook-URL. Dies ermöglicht eine nahtlose Automatisierung und reduziert den Bedarf an manuellen Eingriffen oder regelmäßigem Polling. Indem Sie Ihre Anwendung so konfigurieren, dass sie auf diese Webhook-Ereignisse reagiert, lösen Sie relevante Aktionen aus – etwa das Aktualisieren einer Datenbank, das Senden von Benachrichtigungen oder das Verarbeiten von Transaktionen –, sobald das Ereignis eintritt.
Um Webhooks in Mailgun zu integrieren, müssen Sie einen Endpunkt erstellen. Öffnen Sie dazu die Datei main.py und fügen Sie den folgenden Code am Ende ein:
@app.post("/webhooks/password-reset")rnasync def handle_webhook(request: Request):rn data = await request.json()rn print(f"Password reset email clicked: {data}")rn return {"status": "received", "status_code": 200}rn
Kehren Sie zum Dashboard zurück und gehen Sie zu Senden > Versand > Webhooks:

Klicken Sie in der oberen rechten Ecke auf Webhook hinzufügen. Wählen Sie in der Dropdown-Liste der Ereignistypen Zugestellte Nachrichten aus und geben Sie im Feld URL die Route zu Ihrer Webhook-URL ein. In diesem Fall ist es https:///webhooks/password-reset. Klicken Sie anschließend auf Webhook erstellen:

Testen Sie den Webhook. Ihr Ergebnis sollte folgendermaßen aussehen:

Serverseitig sollten Sie die folgende Nachricht erhalten:
Password reset email clicked: {'signature': {'token': '41929b08bb287b8a0b157f7834844b6bc483b7b090692a2b15', 'timestamp': '1739785355', 'signature': '117f70dcf985c72df30c07b02898dd458d1cbbad29d0457ccee8c4497f89c5ac'}, 'event-data': {'id': 'CPgfbmQMTCKtHW6uIWtuVe', 'timestamp': 1521472262.908181, 'log-level': 'info', 'event': 'delivered', 'delivery-status': {'tls': True, 'mx-host': 'smtp-in.example.com', 'code': 250, 'description': '', 'session-seconds': 0.4331989288330078, 'utf8': True, 'attempt-no': 1, 'message': 'OK', 'certificate-verified': True}, 'flags': {'is-routed': False, 'is-authenticated': True, 'is-system-test': False, 'is-test-mode': False}, 'envelope': {'transport': 'smtp', 'sender': 'bob@sandbox9199067bcb654265aae9ce9e308b6150.mailgun.org', 'sending-ip': '209.61.154.250', 'targets': 'alice@example.com'}, 'message': {'headers': {'to': 'Alice ', 'message-id': '20130503182626.18666.16540@sandbox9199067bcb654265aae9ce9e308b6150.mailgun.org', 'from': 'Bob ', 'subject': 'Test delivered webhook'}, 'attachments': [], 'size': 111}, 'recipient': 'alice@example.com', 'recipient-domain': 'example.com', 'storage': {'url': 'https://se.api.mailgun.net/v3/domains/sandbox9199067bcb654265aae9ce9e308b6150.mailgun.org/messages/message_key', 'key': 'message_key'}, 'campaigns': [], 'tags': ['my_tag_1', 'my_tag_2'], 'user-variables': {'my_var_1': 'Mailgun Variable #1', 'my-var-2': 'awesome'}}}
Dies kann je nach gesendeter E-Mail variieren.
Überwachung und Verwaltung von E-Mails
Peter Drucker, ein berühmter Unternehmensberater, sagte einmal:
Was man nicht messen kann, kann man nicht verbessern.
In diesem Sinne bietet Mailgun Tools zur Überprüfung der Performance von gesendeten E-Mails. Die Seite Senden > Versand > Analysen hilft beispielsweise dabei zu messen, welcher Prozentsatz der E-Mails zugestellt, geöffnet und angeklickt wird:

Auf der Seite Senden > Berichte > Metriken erhalten Sie detaillierte Informationen zur Performance Ihrer E-Mails:

Wählen Sie zudem die Metriken aus, die Sie für einen bestimmten Zeitraum sehen möchten:

Mailgun stellt Ihnen zudem Protokolle zur Verfügung, falls Sie sich eingehender mit Zustellereignissen befassen und auftretende Fehler untersuchen möchten:

Schließlich bietet Mailgun eine Bounce-Klassifizierung, mit der Sie sehen, wie viele Ihrer E-Mails nicht durchgehen. Darin wird auch angezeigt, wie viele dieser Bounces kritisch sind:

Zusammenfassung
In diesem Tutorial haben Sie erfahren, wie Sie einen vollständigen Transaktions-E-Mail-Workflow für das Zurücksetzen von Passwörtern mit der Mailgun-API erstellen. Nachdem Sie ein Mailgun-Konto eingerichtet und einen API-Schlüssel abgerufen haben, haben Sie eine Anwendungsschnittstelle mit FastAPI erstellt. Anschließend haben Sie eine E-Mail-Vorlage entworfen und konfiguriert, die Funktion zum E-Mail-Versand implementiert und Webhooks für das Echtzeit-Ereignistracking integriert.
Transaktions-E-Mail-Prozesse sind entscheidend für ein nahtloses und sicheres Nutzererlebnis, insbesondere beim Zurücksetzen von Passwörtern. Mailgun hilft Ihnen bei der Automatisierung dieses Prozesses, verbessert die Sicherheit und Produktivität und macht gleichzeitig manuelle Eingriffe überflüssig. Die Implementierung dieses Ansatzes in Ihren Projekten wird nicht nur die Kundenzufriedenheit erhöhen, sondern auch zur Aufrechterhaltung eines zuverlässigen Authentifizierungssystems beitragen.