Email mit Azure Functions senden

Azure Functions eignen sich hervorragend, um eine ausgelagerte Routine zum Versand von Email im Web zu erstellen. Die Funktion selbst kann, universell anlegt, in diversen eigenen Applikationen verwendet werden.

Der zentrale Ansatz sorgt dabei dafür, dass die Funktion einfach skalierbar bleibt und notwendige Stammdaten wie z.B. Zugangsdaten und Serveradressen leicht und zentral ausgetauscht werden können.

Im Folgenden beschrieben wir, wie eine derartige Funktion mit Microsoft Azure Functions-App angelegt werden kann.

Erstellung der Functions-App

azure_functions_erstellen

Zunächst erstellen wir eine neue Functions-App.
Diese finden wir unter Neu -> Compute -> Functions-App

Als nächstes müssen die notwendigen Grunddaten für die Erstellung angegeben bzw. ausgewählt werden:

azure_functions_konfig

Die verschiedenen Einstellungen wie Name, Abonnement/Subscription und Standort können dabei entsprechend den individuellen Anforderungen ausgewählt werden.

Nach einem Klick auf „Erstellen“ wird die Functions-App entsprechend den eingestellten Daten erzeugt. Die Erstellung dauert im Normalfall nur wenige Sekunden, dann steht die App in der ausgewählten Ressourcengruppe zur Verfügung.

Code zur App hinzufügen

Im nächsten Schritt bringen wir den Inhalt in die Functions-App. Auf der Startseite der App werden hierbei verschiedene Möglichkeiten angeboten, auf denen die Funktion aufbauen kann. Im Wesentlichen geht es dabei um den Auslösemechanismus (Trigger), der die App startet. Azure unterstützt dabei verschiedene Trigger:

  • Timer, ähnlich einem CRON-Job
  • Änderungen in einem Speicherkonto (BLOB-Container)
  • Azure Queues
  • Service-Bus-Nachrichten
  • HTTP-Trigger

In diesem Beispiel verwenden wir „eigene benutzerdefinierte Funktion erstellen“, was sich auf der Startseite ganz unten findet, damit unsere Funktion über HTTP aufgerufen werden kann. Hierfür stehen uns die Programmiersprachen C# und NodeJS zur Verfügung.

Azure unterstützt folgende Programmiersprachen:

  • C# .NET
  • NodeJS
  • Python
  • PHP

Für dieses Beispiel verwenden wir als HTTP-Trigger in Verbindung mit C#.NET den „GenericWebHook-CSharp“ als Ausgangsvorlage.

azure_functions_vorlage

Anschließend wird unten noch ein Name für die Funktion vergeben. Hiermit ist die Funktion mit einem Grundgerüst auch schon erstellt.

azure_functions_code

Einige Anmerkungen zur Code-Ansicht:

  1. Funktions-URL: Über diesen URL wird die Funktion später aufgerufen
  2. Code: der eigentliche Code der Funktion
  3. Logs: Ausgaben und Rückmeldungen der Funktion
  4. Ausführen: manueller Start der Funktion mit der Möglichkeit, manuelle Testdaten an den Funktionsaufruf zu senden

Beim Code selbst handelt es sich um Standard-C#-ASP-.NET-Code, der selbstverständlich modifiziert werden kann.

Emails senden

In unserem Fall möchten wir, dass die Funktion Emails sendet. Hierfür werden einige dynamische Parameter benötigt:

  1. from-Email: Emailadresse des Absenders
  2. to-Email: Emailadresse des Empfängers
  3. subjekt: Betreffzeile
  4. message: Inhalt der Email
  5. is-important: Priorität „hoch“ ja/nein

Da die Funktion diese Parameter im JSON-Format erwartet, hier ein Beispiel für einige Muster-Parameter:

{
"fromEmail": "muster@absender.com",
"toEmail": "max.mustermann@empfaenger.com",
"subject": "Beispiel-Email",
"message": "Hallo Welt, das ist eine Test-Email.",
"isImportant": true
}

Diese Parameter sind natürlich nur Beispiele – sie können Sie für Ihre Tests jederzeit anpassen.

Der eigentliche Programmcode, den Sie hier kopieren können, sieht folgendermaßen aus:

#r "Newtonsoft.Json"

using System;
using System.Net;
using Newtonsoft.Json;
using System.Net.Mail;

public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Verbose($"Webhook was triggered!");

    string jsonContent = await req.Content.ReadAsStringAsync();
    dynamic data = JsonConvert.DeserializeObject(jsonContent);
    
    // do some data validation... skipped this for demo purpose only.
    // if validation failes -> HttpStatusCode.BadRequest should be returned as HTTP Status
    
    bool isImportantEmail = bool.Parse(data.isImportant.ToString());
    string fromEmail = data.fromEmail;
    string toEmail = data.toEmail;
    int smtpPort = 587;
    bool smtpEnableSsl = true;
    string smtpHost = ""; // your smtp host
    string smtpUser = ""; // your smtp user
    string smtpPass = ""; // your smtp password
    string subject = data.subject;
    string message = data.message;
    
    MailMessage mail = new MailMessage(fromEmail, toEmail);
    SmtpClient client = new SmtpClient();
    client.Port = smtpPort;
    client.EnableSsl = smtpEnableSsl;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false;
    client.Host = smtpHost;
    client.Credentials = new System.Net.NetworkCredential(smtpUser, smtpPass);
    mail.Subject = message;
    
    if (isImportantEmail) {
      mail.Priority = MailPriority.High;
    }
    
    mail.Body = message;
    try {
      client.Send(mail);
      log.Verbose("Email sent.");
      return req.CreateResponse(HttpStatusCode.OK, new {
            status = true,
            message = string.Empty
        });
    }
    catch (Exception ex) {
      log.Verbose(ex.ToString());
      return req.CreateResponse(HttpStatusCode.InternalServerError, new {
            status = false,
            message = "Message has not been sent. Check Azure Function Logs for more information."
        });
    }
}

In den Zeilen 23-25 müssen Sie selbstverständlich Ihre eigenen Daten für SMTP-Server und Authentifizierung eintragen. Wenn Sie danach auf „Speichern“ klicken, wird der Code automatisch in Microsoft Azure gespeichert und kompiliert. Im Log-Bereich erscheinen entsprechende Informationen, ob das Kompilieren erfolgreich war.

Anschließend können Sie einen Testlauf machen, indem Sie Muster-Parameter an die Funktion übergeben und diese ausführen.

Wenn alles geklappt hat, erhalten Sie nach wenigen Sekunden eine Email im angegebenen Empfänger-Postfach.

Zusammenfassung

Functions-Apps sind eine praktische Bereicherung des Azure Portfolios. Zu akzeptablen Preisen können Sie hier einfach Code „in die Cloud“ auslagern und wiederverwendbaren Code für Ihre Applikationen bilden.

Wie man ein HTML-Formular als JSON an die Azure-Functions-App sendet, erfahren Sie im nächsten Beitrag.

Schreibe einen Kommentar