Generiertes Dokument per E-Mail versenden
Dieses Skript zeigt, wie ein generiertes Dokument nach der Erstellung automatisch per E-Mail versendet werden kann - wahlweise über klassisches SMTP mit Benutzername/Passwort oder über modernes OAuth2 (z.B. Microsoft 365).
Anwendungsfall
Nach der Erstellung eines Dokuments (z.B. Rechnung, Angebot, Serienbrief) soll dieses automatisch als Anhang per E-Mail an den Empfänger versendet werden ohne manuellen Umweg über ein E-Mail-Programm.
Konfiguration in PRINT+PLUS
- Exporter-Typ: Ein Dokument-Exporter (Word, Excel oder Text)
- Event:
AfterClosingDocument(das Dokument ist zu diesem Zeitpunkt fertig generiert, gespeichert und geschlossen)
Variante 1: SMTP mit Benutzername und Passwort
Die einfachste Variante für interne Mailserver oder ältere SMTP-Konfigurationen.
Vollständiges Skript
// Version 6
namespace Ruthardt.PrintPlus.Skripting
{
using System;
using System.Net;
using System.Net.Mail;
using Ruthardt.CobraBase.Functions.Access.Ado;
using Ruthardt.Common.Util;
using Ruthardt.PrintPlus.Model.Interfaces;
public class DokumentPerSMTP : IScriptAction
{
// --- Einstellungen (an Ihre Umgebung anpassen) ---
private const string SMTP_SERVER = "mail.meinefirma.de";
private const int SMTP_PORT = 587;
private const string SMTP_USER = "absender@meinefirma.de";
private const string SMTP_PASSWORT = "GeheimesPasswort";
private const string ABSENDER = "absender@meinefirma.de";
public void Execute(IPrintContext printContext, ICurrentContext currentContext, IChildContext childContext)
{
try
{
// Empfänger-Adresse aus dem Datensatz auslesen
var empfaengerMail = currentContext.Data.GetStringValue("E-Mail");
if (string.IsNullOrWhiteSpace(empfaengerMail))
{
printContext.Logger.Info($"Kein E-Mail-Empfänger für Datensatz {currentContext.Data.CurrentKey}. Versand wird übersprungen.");
return;
}
// E-Mail zusammenbauen
using (var nachricht = new MailMessage
{
Subject = "Ihr Dokument",
Body = "<p>Sehr geehrte Damen und Herren,</p><p>im Anhang finden Sie Ihr Dokument.</p><p>Mit freundlichen Grüßen</p>",
From = new MailAddress(ABSENDER),
IsBodyHtml = true
})
{
nachricht.To.Add(empfaengerMail);
nachricht.Attachments.Add(new Attachment(currentContext.DocumentFileName.FullName));
// Versand
using (var smtp = new SmtpClient(SMTP_SERVER)
{
Port = SMTP_PORT,
EnableSsl = true,
Credentials = new NetworkCredential(SMTP_USER, SMTP_PASSWORT)
})
{
// TLS 1.2 erzwingen (für ältere .NET-Konfigurationen)
var aktuellesProtokoll = (int)ServicePointManager.SecurityProtocol;
if (aktuellesProtokoll != 0)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
}
smtp.Send(nachricht);
}
}
printContext.Logger.Info($"E-Mail an '{empfaengerMail}' versendet mit Anhang: {currentContext.DocumentFileName.Name}");
}
catch (Exception ex)
{
printContext.Logger.Error(ex, "Fehler beim E-Mail-Versand.");
printContext.WaitFormManager?.ShowMessageBox("E-Mail-Versand fehlgeschlagen: " + ex.Message);
}
}
}
}
Variante 2: OAuth2 mit Microsoft 365
Für moderne Microsoft-365-Umgebungen, in denen klassische Authentifizierung deaktiviert ist.
Voraussetzungen
- Eine Azure App-Registrierung mit den Berechtigungen für SMTP-Versand
- Die folgenden DLLs als Referenz im Skript-Editor hinzufügen: Download: Mailversand_OAuth2_dlls.zip
Vollständiges Skript
// Version 6
namespace Ruthardt.PrintPlus.Skripting
{
using System;
using System.IO;
using MailKit.Net.Smtp;
using MailKit.Security;
using Microsoft.Identity.Client;
using MimeKit;
using Ruthardt.CobraBase.Functions.Access.Ado;
using Ruthardt.Common.Util;
using Ruthardt.PrintPlus.Model.Interfaces;
public class DokumentPerOAuth2 : IScriptAction
{
// --- Azure App-Einstellungen (an Ihre Umgebung anpassen) ---
private const string CLIENT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
private const string TENANT_ID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
private const string CLIENT_SECRET = "IhrClientSecret";
private const string ABSENDER_MAIL = "absender@meinefirma.de";
private const string SMTP_HOST = "smtp.office365.com";
private const int SMTP_PORT = 587;
public void Execute(IPrintContext printContext, ICurrentContext currentContext, IChildContext childContext)
{
// Empfänger aus dem Datensatz auslesen
var empfaengerMail = currentContext.Data.GetStringValue("E-Mail");
if (string.IsNullOrWhiteSpace(empfaengerMail))
{
printContext.Logger.Info($"Kein E-Mail-Empfänger. Versand wird übersprungen.");
return;
}
// Nachricht zusammenbauen
var nachricht = new MimeMessage();
nachricht.From.Add(InternetAddress.Parse(ABSENDER_MAIL));
nachricht.To.Add(InternetAddress.Parse(empfaengerMail));
nachricht.Subject = "Ihr Dokument";
var body = new BodyBuilder
{
HtmlBody = "<p>Sehr geehrte Damen und Herren,</p><p>im Anhang finden Sie Ihr Dokument.</p>",
TextBody = "Im Anhang finden Sie Ihr Dokument."
};
// Dokument als Anhang
body.Attachments.Add(currentContext.DocumentFileName.FullName);
nachricht.Body = body.ToMessageBody();
// OAuth2-Token holen
var app = ConfidentialClientApplicationBuilder.Create(CLIENT_ID)
.WithAuthority($"https://login.microsoftonline.com/{TENANT_ID}/v2.0")
.WithClientSecret(CLIENT_SECRET)
.Build();
var tokenTask = app.AcquireTokenForClient(new[] { "https://outlook.office365.com/.default" }).ExecuteAsync();
tokenTask.Wait();
var token = tokenTask.Result;
// Verbinden und versenden
var oauth2 = new SaslMechanismOAuth2(ABSENDER_MAIL, token.AccessToken);
using (var client = new SmtpClient())
{
client.Connect(SMTP_HOST, SMTP_PORT, SecureSocketOptions.StartTls);
client.Authenticate(oauth2);
client.Send(nachricht);
client.Disconnect(true);
}
printContext.Logger.Info($"E-Mail (OAuth2) an '{empfaengerMail}' versendet.");
}
}
}
Erklärung
| Aspekt | Variante 1 (SMTP) | Variante 2 (OAuth2) |
|---|---|---|
| Bibliothek | System.Net.Mail (in .NET enthalten) |
MailKit + Microsoft.Identity.Client (zusätzliche DLLs) |
| Authentifizierung | Benutzername + Passwort | Azure App mit Client-Secret |
| Geeignet für | Eigene Mailserver, ältere Exchange-Server | Microsoft 365, Umgebungen ohne Basic Auth |
| Zusätzliche Referenzen | Keine | OAuth2-DLLs herunterladen |
Tipps
- Personalisierter Mailtext: Verwenden Sie Werte aus dem Datensatz für Betreff und Text:
var vorname = currentContext.Data.GetStringValue("Vorname");
nachricht.Subject = $"Ihr Angebot, {vorname}";
-
Mehrere Empfänger: Fügen Sie weitere Adressen per
nachricht.To.Add(...)hinzu, z.B. aus einem CC-Feld. -
Fehlerbehandlung: Fangen Sie Ausnahmen immer ab, damit ein fehlgeschlagener Mailversand nicht den gesamten Export abbricht.
-
Task-Kompatibilität: Beide Varianten funktionieren auch im PRINT+PLUS Task (automatische Ausgabe ohne GUI). Der
WaitFormManagerist dort ein Dummy. Verwenden Sie für Fehler bevorzugt den Logger.