In diesem Blogbeitrag beschreibe ich, wie man mit dem Paket blastula in R E-Mails verschicken kann. Dadurch ist es möglich, einen Ergebnisreport von einer Umfrage per E-Mail zu versenden und diesen Prozess auch zu automatisieren.

Die Herausforderung

In Evaluations- und Forschungsprojekten kommt es immer wieder vor, dass man einzelne Ergebnisse oder ganze Reports per E-Mail versenden muss. Dies ist beispielsweise dann der Fall, wenn man in der Phase der Datenerhebung ist und man den aktuellen Rücklauf dem Projektpartner mitteilen möchte. Da ich vor dieser Herausforderung in den letzten Wochen stand, habe ich mich gefragt, ob ich jetzt wirklich jeden Morgen die aktuellen Zahlen in eine E-Mail kopieren muss. Oder ob es nicht einfacher geht und nicht auch R diesen Prozess übernehmen kann?

blastuala Logo

Die Antwort auf diese Frage ist: Es geht! In R kann man das Versenden von E-Mails mit dem Paket blastula automatisieren. Arbeitet man dann noch mit einer Online-Befragungssoftware, die eine API-Schnittstelle zur Verfügung stellt, kann das R-Skript den aktuellen Datenstand aus der Umfrage beziehen, diesen aufbereiten und in einer E-Mail verschicken. Ich habe diesen Prozess bereits praktisch mit der API von Lamapoll ausprobiert und auch Limesurvey bietet diese Möglichkeit, wie ich in einem Blogbeitrag zuvor beschrieben haben. Nachfolgend werde ich darauf eingehen, wie der E-Mail-Versand mit R abläuft.

E-Mail-Nachricht in Markdown anlegen

In einem ersten Schritt muss die eigentliche E-Mail erstellt werden. Dies geschieht mit einer Markdown-Datei. Der einzige Unterschied zu einem normalen HTML-Output ist, dass als Output “blastula_email” ausgewählt wird. Aber auch bei diesem Output kann man ganz normal mit der Markdown-Datei arbeiten und Text, Tabellen, Grafiken und R-Code einfügen. In nachfolgendem Beispiel erstelle ich einen E-Mail-Text mit einer ggplot2-Grafik:

---
title: 'Das ist meine erste E-Mail aus R'
output: blastula::blastula_email
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = FALSE)
```

Sehr geehrte Damen und Herren,

hier die aktuelle Verteilung der erhobenen Daten (Beispieldatensatz penuguin)

```{r}
library(palmerpenguins)
library(ggplot2)
p <- ggplot(data = penguins, aes(x = species)) + geom_bar(stat="count")
p
```

Viele Grüße
Sebastian Ottmann
Code language: Markdown (markdown)

Es empfiehlt sich am Anfang im ersten Chunk das echo und die warning auf FALSE zu setzten, damit diese nicht in der späteren E-Mail ausgegeben werden. Wenn man wissen möchte, wie die E-Mail aussieht, kann man die Markdown-Datei ganz normal kniten. In R-Studio erscheint dann die Vorschau, die eigentlich E-Mail wird dabei noch nicht versendet, hierfür sind weitere Einstellungen nötig.

E-Mail-Server einrichten

Vor dem eigentlichen Versand muss noch der SMTP-Server über den die E-Mail verschickt wird eingerichtet werden. Dies geschieht mit der Funktion creat_smtp_creds_key() aus dem Paket blastula. Diese Funktion sieht wie folgt aus:

library(blastula)

create_smtp_creds_key(
  id = "meinmailserver",  # Vergeben einer eindeutigen ID die man später aufrufen kann
  user = "xxx",  # Benutzername (in den meisten Fälle die E-Mail-Adresse)
  host = "xxx",  # Adresse des SMTP-Server
  port = xxx,    # Port des SMTP-Server
  use_ssl = TRUE # Wenn beim Versand der E-Mail eine SSL-Verschlüsselung genutzt wird muss hier TRUE stehen
)Code language: R (r)

Die ID, die in der Funktion vergeben wird, muss eindeutig sein. Dies ist gerade dann wichtig, wenn man verschiedene Mailserver einrichten möchte. Führt man die Funktion aus, wird man nach dem Kennwort der E-Mail-Adresse gefragt. Wird dieses eingegeben, wird die Verbindung inkl. Kennwort gespeichert. Ab sofort kann dann die eingerichtete Verbindung mit der vergebenen ID verwendet werden. Daher muss diese Funktion auch nur einmal zur Einrichtung ausgeführt werden und nicht bei jedem E-Mail-Versand.

Die eigentliche E-Mail versenden

Der eigentliche Versand der E-Mail findet dann in einem eigenen R-Skript statt. In einem ersten Schritt wird der Text der zu versendeten E-Mail festgelegt. Dies geschieht durch die Funktion render_email() und den Verweis auf eine bestehende Markdown-Datei. Mit blastula ist es auch möglich, eine E-Mail zu versenden, ohne den Text davor in einer Markdown-Datei gespeichert zu haben. Wie dies genau funktioniert, kann in der Dokumentation nachgelesen werden. Ich finde aber das Arbeiten mit einer Markdown-Datei einfacher und man kann hier auch die E-Mail besser strukturieren und den benötigen R-Code besser integrieren. Wichtig ist hier nur, dass das Arbeitsverzeichnis klar gesetzt ist oder der Pfad zur Markdown-Datei den kompletten Pfad enthält. Wurde der E-Mail-Text gerendert, kann mit der Funktion smtp_send() der eigentliche Versandprozess angestoßen werden. Hier ein Beispiel:

library(blastula)

emailtext <- render_email("test_report_email.rmd") # Hier den Pfad zur Markdown-Datei einfügen

emailtext |>
  smtp_send(
    from = "xxx", # Hier den Absender einfügen, entweder nur die E-Mail-Adresse oder mit c("Absendername" = "E-Mail-Adresse")
    to = "xxx", # Hier die E-Mail-Adresse des Empfängers einfügen
    subject = "Aktueller Report aus R", # Betreff der E-Mail 
    credentials = creds_key("meinmailserver") # Hier die ID einfügen die zuvor bei der Einrichtung des Mailservers verwendet wurde
  )Code language: R (r)

Wurde alles in der Funktion richtig definiert und diese ausgeführt bekommt man kurz danach einen Hinweis, dass die E-Mail versendet wurde. Dieses sollte dann auch wenige Sekunden später im Posteingang auftauchen. Die oben definierte Markdown-Datei kommt bei mir dann wie folgt als E-Mail an:

Versendete E-Mail in Thunderbird

Innerhalb der Funktion smpt_send() können auch noch weitere Parameter definiert werden, wie ein CC- oder BCC-Empfänger.

Oder den Report doch lieber als Anhang?

In der bisherigen E-Mail haben wir die gewünschte Grafik direkt in die E-Mail integriert. Dies geht gut, wenn man nur einzelne Grafiken oder Tabellen verschicken muss. Ist es ein umfangreicherer Report, den man verschicken möchte, empfiehlt es sich, diesen als Anhang an die E-Mail zu versenden. Auch dies geht mit dem blastula-Paket. Hierzu erstellen wir als Erstes eine Markdown-Datei, die uns den Report als PDF-Datei erstellt:

---
title: "Testreport"
author: "Sebastian Ottmann"
date: "`r Sys.Date()`"
output: pdf_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(palmerpenguins)
library(ggplot2)
library(knitr)
```

Ein Beispiel mit dem penguin dataset

```{r}
kable(head(penguins))
```

Ein Plot mit der Variable species:

```{r}
p <- ggplot(data = penguins, aes(x = species)) + geom_bar(stat="count")
p
```Code language: Markdown (markdown)

Natürlich muss es nicht eine PDF-Datei sein. Mit Markdown in R ist es auch möglich, Word-Dateien zu erstellen. Wie dies geht, habe ich in einem früheren Blogbeitrag beschrieben.

Neben dem Anhang benötigen wir auch wieder einen E-Mail-Text. Hierzu erstellen wir eine kurze Markdown-Datei:

---
title: 'E-Mail mit Anhang'
output: blastula::blastula_email
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = FALSE)
```

Sehr geehrte Damen und Herren,
<br><p>

im Anhang der gewünschte Report.
<br><p>

Viele Grüße<br>
Sebastian OttmannCode language: Markdown (markdown)

In dem R-Skript für den Versand rendern wir in einem ersten Schritt die Markdown-Datei zu einer PDF-Datei. Der weitere Vorgang ist ähnlich wie der schon beschriebene. Es wird danach der eigentliche E-Mail-Text gerendert und danach der Versand der E-Mail durchgeführt. Eine Besonderheit ist hier, dass vor der Funktion smtp_send() mit der Funktion add_attachment() der Anhang zur E-Mail hinzugefügt wird. Hier der gesamte Code für den Versand:

library(blastula)
library(rmarkdown)
library(knitr)

# Erzeugen der PDF-Datei
render("test_report_email_pdf.rmd", output_format = "pdf_document")

# Erzeugen der E-Mail
emailtext <- render_email("test_report_email_anhang.rmd")

# Versand der E-Mail
emailtext |> 
  add_attachment("test_report_email_pdf.pdf") |> 
  smtp_send(
    from = "xxx", # Hier den Absender einfügen, entweder nur die E-Mail-Adresse oder mit c("Absendername" = "E-Mail-Adresse")
    to = "xxx", # Hier die E-Mail-Adresse des Empfängers einfügen
    subject = "Aktueller Report aus R", # Betreff der E-Mail 
    credentials = creds_key("meinmailserver") # Hier die ID einfügen die zuvor bei der Einrichtung des Mailservers verwendet wurde
  )Code language: R (r)

Nach dem Ausführen des R-Skripts kommt wenige Minuten später die E-Mail im Posteingang mit dem entsprechenden PDF-Anhang an:

Versendete E-Mail mit Anhang in Thunderbird

E-Mail-Versand in Windows automatisieren

Durch die dargestellte Vorgehensweise konnte der Versand der E-Mail schon vereinfacht werden. Es wird kein Kopieren von Zahlen, Tabellen und Grafiken mehr benötigt, sondern diese werden automatisch eingefügt und die E-Mail wird versendet. Lediglich das Ausführen des Skriptes bleibt als Aufgabe übrig. Aber kann man das nicht auch automatisieren? Kann man natürlich! 😉

Zum einen gibt es die Möglichkeit das Paket blastula mit RStudio Connect zu nutzen und hierdurch den Versand der E-Mail zu automatisieren. Wer keinen Zugang zu RStudio Connect hat, aber unter Windows arbeitet, kann den Vorgang des Versandes auch weiter automatisieren. Das Vorgehen habe ich in diesem Blogbeitrag gefunden. In einem ersten Schritt kann man eine sog. Batch-Datei anlegen. Führt man diese aus, wird das Skript zum Versand der E-Mail ausgeführt und die E-Mail versendet.

Weiterhin gibt es unter Windows eine Aufgabenplanung, in der man auch bestimmte Aufgaben terminieren kann. Wie man dies per Hand einstellt, wird in dem genannten Blogbeitrag beschrieben. Mit dem Paket taskscheduleR können solche Aufgaben auch automatisch aus R heraus angelegt werden. Eine Beschreibung des Paketes kann hier abgerufen werden. Zu beachten ist, dass die Windows Aufgabenplanung nur dann ausgeführt wird, wenn der Computer an ist. Insofern sollte man einen Zeitpunkt wählen, an dem sichergestellt ist, dass die Aufgabe auch ausgeführt werden kann.

Fazit

Mit dem hier beschriebenen Vorgehen, kann das Versenden von Ergebnissen und Reports per E-Mail automatisiert werden. Gerade bei der Überprüfung von Rückläufen während der Datenerhebung oder auch bei einer regelmäßigen Auswertung und Reporting ist dies eine Erleichterung. Kann man über eine API eine direkte Verbindung zur Online-Befragung herstellen, kann man den gesamten Prozess automatisieren und damit den Aufwand für die Erstellung und Versand der E-Mail enorm reduzieren.

Wer schon Erfahrungen mit dem Paket hat oder andere Pakete zum E-Mail-Versand in R genutzt hat, kann gerne einen Kommentar zu diesem Blogbeitrag hinterlassen.

Teile diesen Beitrag: