E-Mail senden: Unterschied zwischen den Versionen
(→Raspberry Pi: Anführungszeichen im Beispiel korrigiert und erläutert) |
K (cURL snippet auf BlockingCall umgestellt) |
||
(41 dazwischenliegende Versionen von 8 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
Um aus FHEM heraus | Um aus FHEM heraus E-Mails senden zu können, gibt es unterschiedliche Methoden, abhängig von der verwendeten Plattform. | ||
Lange Zeit war <code>sendemail</code> sehr beliebt. Da aber die Homepage des Projekts nicht mehr online ist und Probleme nur noch via erhöhtem Supportaufwand gelöst werden, sollte diese Option als veraltet betrachtet werden. | |||
Eine Liste mit ressourcensparenden E-Mails Clients findet man bei dem OpenWRT Projekt: https://openwrt.org/docs/guide-user/services/email/smtp.client | |||
MSGMail ist ein FHEM eigenes Modul zum Versenden, die Einrichtung ist allerdings nicht gänzlich einfach. Anfängern sei die cURL Methode empfohlen. | |||
=== | === MSGMail (Linux, Windows) === | ||
FHEM bringt ein eigenes Device zum Senden von E-Mails mit, welches in Perl implementiert ist: [https://fhem.de/commandref.html#MSGMail MSGMail, https://fhem.de/commandref.html#MSGMail] | |||
=== cURL (Linux, Windows) === | |||
[https://curl.se/ cURL] kann auf praktisch [https://curl.se/download.html jedem Betriebssystem] genutzt werden, [https://curl.se/windows/ selbst unter Windows]. Es kann direkt mit einem SMTP Server E-Mails versenden und stellt damit eine moderne, portable und sichere Option zum Versenden von E-Mails dar. | |||
In FHEM richtet man sich ein Device ein und passt die Details (<code>$emailTo, $emailFrom, $emailServer</code>) an. Das Programm cURL muss installiert sein (z.B. mit <code>apt install curl</code>, oder durch Herunterladen und Installieren von der [https://curl.se cURL-Webseite]).<syntaxhighlight lang="perl" line="1"> | |||
defmod sendMail dummy | |||
attr sendMail readingList message password | |||
attr sendMail setList message password | |||
attr sendMail userReadings state:message:.* {\ | |||
my $emailTo = 'you@example.com';;\ | |||
my $emailFrom = 'fhem@domain.com';;\ | |||
my $emailServer = 'mail.smtpserver.de';;\ | |||
\ | |||
# Passwort aus getKeyValue abrufen\ | |||
my ($err, $emailPass) = getKeyValue("${name}_password");;\ | |||
if ($err || !defined $emailPass) {\ | |||
return "Error retrieving password: $err";;\ | |||
}\ | |||
\ | |||
my $message = ReadingsVal($name, 'message', '???');;\ | |||
my $subject = "$name: FHEM Nachricht";;\ | |||
\ | |||
# Betreff extrahieren und aus der Nachricht entfernen\ | |||
if ($message =~ s/(?:Subject|Betreff)="(.*?)"//) {\ | |||
$subject = $1;;\ | |||
}\ | |||
\ | |||
# Empfänger extrahieren und aus der Nachricht entfernen\ | |||
if ($message =~ s/(?:To|An)="(.*?)"//) {\ | |||
$emailTo = $1;;\ | |||
}\ | |||
\ | |||
#my $cmd = "echo 'Subject: $subject\\nFrom: $emailFrom\\nTo: $emailTo\\n\\n$message' | ";;\ | |||
my $cmd = "echo 'Subject: $subject\\r\\n";;\ | |||
$cmd .= "From: $emailFrom\\r\\n";;\ | |||
$cmd .= "To: $emailTo\\r\\n";;\ | |||
$cmd .= "Content-Type: text/plain;; charset=UTF-8\\r\\n";;\ | |||
$cmd .= "\\r\\n";;\ | |||
$cmd .= "$message' | ";;\ | |||
\ | |||
$cmd .= "curl -m 4.8 --noproxy '*' --no-progress-meter --ssl-reqd smtps://$emailServer:465 ";;\ | |||
$cmd .= "--user '$emailFrom:$emailPass' --mail-from '$emailFrom' --mail-rcpt '$emailTo' ";;\ | |||
$cmd .= "--write-out 'Email sent with status %{http_code}\n' ";;\ | |||
$cmd .= "--upload-file - 2>&1";;\ | |||
\ | |||
#blocking function that is called from a forked process\ | |||
if (!defined &sendMailfunc1) {\ | |||
*sendMailfunc1 = sub ($) {\ | |||
my ($param) = @_;;\ | |||
my $result;;\ | |||
$result = qx/$param/;;\ | |||
$result = MIME::Base64::encode_base64($result);;\ | |||
$result =~ s/\n//g;;\ | |||
return $result;;\ | |||
}\ | |||
}\ | |||
\ | |||
#finish function that is called when blocking function is done\ | |||
if (!defined &sendMailfunc2) {\ | |||
*sendMailfunc2 = sub ($) {\ | |||
my ($result) = @_;;\ | |||
my $hash = $defs{$name};;\ | |||
$result = MIME::Base64::decode_base64($result);;\ | |||
readingsSingleUpdate($hash, $reading, $result, 1);;\ | |||
}\ | |||
}\ | |||
\ | |||
BlockingCall("sendMailfunc1", $cmd, "sendMailfunc2", 5);;\ | |||
\ | |||
return "started Job...";;\ | |||
},\ | |||
state:password:.* {\ | |||
# Passwort speichern\ | |||
my $ret = setKeyValue("${name}_password", ReadingsVal($name, 'password', undef)) // "password stored";;\ | |||
\ | |||
#password wieder aus der Variablen rausnehmen, soll nicht sichtbar bleiben:\ | |||
#\ | |||
# Hinweis: das Password taucht beim Setzen hierüber im Event-Log auf!\ | |||
# Alternativ: { setKeyValue("sendMail_password", "geheimesPasswort") }\ | |||
readingsBulkUpdate($hash, "password", "****");;\ | |||
\ | |||
return "$ret";;\ | |||
} | |||
</syntaxhighlight>Das Passwort setzt man mit: | |||
* <code>set sendMail password geheimesPasswort</code> | |||
* Alternativ, damit das Passwort nicht im Log auftaucht: <code>{ setKeyValue("sendMail_password", "geheimesPasswort") }</code> | |||
}</ | |||
E-Mails kann man dann Senden mit: | |||
: | |||
* <code>set sendMail message Mein Text</code> (es wird der Standardbetreff und Empfänger aus dem Snippet genutzt) | |||
* <code>set sendMail message Betreff="Mein Betreff" Mein Text</code>(es wird der Empfänger aus dem Snippet genutzt) | |||
* <code>set sendMail message Subject="Dies ist ein Test" Mein Text</code> | |||
* <code>set sendMail message To="jemand@example.com" Mein Text</code> | |||
* <code>set sendMail message An="jemand@example.com" Mein Text</code> | |||
* <code>set sendMail message An="jemand@example.com" Betreff="Mein Betreff" Mein Text</code> | |||
* <code>set sendMail message To="jemand@example.com" Subject="Mein Betreff" Mein Text</code> | |||
* <code>set sendMail message Subject="✅ Dies ist ein Test" Meldung mit Emoji ⚽ geht auch</code> | |||
=== | ==== Fehlersuche ==== | ||
Sollte cURL zwar installiert sein, aber keine E-Mails versenden, kann es sein, dass das Protokoll nicht einkompiliert wurde. Dies ist bei OpenWRT zum Beispiel der Fall. | |||
< | So sollte es aussehen (hier ein Ubuntu), relevant ist für diese Nutzung das Protokoll smtp und smtps, das braucht man:<syntaxhighlight lang="bash"> | ||
curl -V | |||
curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7 | |||
Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6 | |||
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp | |||
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd | |||
</syntaxhighlight>So sollte es nicht aussehen (hier ein OpenWRT):<syntaxhighlight lang="bash"> | |||
curl: (1) Protocol "smtps" not supported | |||
curl -V | |||
curl 8.10.1 (arm-openwrt-linux-gnu) libcurl/8.10.1 mbedTLS/3.6.2 nghttp2/1.63.0 | |||
Release-Date: 2024-09-18 | |||
Protocols: file ftp ftps http https ipfs ipns mqtt | |||
Features: alt-svc HSTS HTTP2 HTTPS-proxy IPv6 Largefile SSL threadsafe UnixSockets | |||
</syntaxhighlight>Hat man nur ein cURL ohne das Protokoll, so muss man sich das Paket leider anderweitig beschaffen (chroot, selbst kompilieren, statisch gelinkte Version, ...). | |||
==== Forumlink ==== | |||
https://forum.fhem.de/index.php?topic=140814.0 | |||
=== EXIM4 (Debian) === | |||
Eine Anleitung zum Versenden von E-Mails mit Exim ist als PDF verfügbar: [[Medium:Anleitung Exim4 Debian GMX.pdf|PDF]] | |||
=== SSMTP (OpenWRT, embedded Distros) === | |||
==== Installation ==== | |||
<syntaxhighlight lang="bash"> | |||
opkg update | opkg update | ||
opkg install ssmtp_2.64-4_mpc85xx.ipk | opkg install ssmtp_2.64-4_mpc85xx.ipk | ||
</ | </syntaxhighlight>Damit <code>ssmtp</code> funktioniert müssen die Dateien <code>/etc/ssmtp/ssmtp.conf</code> und <code>/etc/ssmtp/revaliases</code> angepasst werden. | ||
/etc/ssmtp/ssmtp.conf | /etc/ssmtp/ssmtp.conf | ||
<syntaxhighlight lang="text"> | |||
mailhub=mail.gmx.net:465 | root=arnold@gmx.net | ||
rewriteDomain=gmx.net | mailhub=mail.gmx.net:465 | ||
hostname=gmx.net | rewriteDomain=gmx.net | ||
FromLineOverride=YES | hostname=gmx.net | ||
UseTLS=YES | FromLineOverride=YES | ||
#UseSTARTTLS=YES | UseTLS=YES | ||
AuthUser=arnold@gmx.net | #UseSTARTTLS=YES | ||
AuthPass=Passwort_von_arnold@gmx.net | AuthUser=arnold@gmx.net | ||
</ | AuthPass=Passwort_von_arnold@gmx.net | ||
</syntaxhighlight> | |||
/etc/ssmtp/revaliases | /etc/ssmtp/revaliases | ||
<syntaxhighlight lang="text"> | |||
root:arnold@gmx.net:mail.gmx.net:465</ | root:arnold@gmx.net:mail.gmx.net:465 | ||
</syntaxhighlight> | |||
In der [[99_myUtils_anlegen|99_myUtils]] folgende Unterroutine einfügen: | |||
<syntaxhighlight lang="perl"> | |||
sub OpenWRTMail | |||
OpenWRTMail | |||
{ | { | ||
my $rcpt = shift; | my $rcpt = shift; | ||
Zeile 82: | Zeile 175: | ||
$ret =~ s,[\r\n]*,,g; # remove CR from return-string | $ret =~ s,[\r\n]*,,g; # remove CR from return-string | ||
Log 1, "sendEmail returned: $ret"; | Log 1, "sendEmail returned: $ret"; | ||
}</ | } | ||
</syntaxhighlight> | |||
=== PHP Mail Funktion (Synology DiskStation) === | |||
Beim DSM 3.2 funktioniert der <code>php-mail</code>-Befehl, so dass man mittels folgendem Modul E-Mails versenden kann: | |||
=== Synology DiskStation === | <syntaxhighlight lang="perl"> | ||
Beim DSM 3.2 | sub sendmail($$$) { | ||
my($empf, $subj, $nachricht) = @_; | my($empf, $subj, $nachricht) = @_; | ||
system( | system("php -r 'mail(\"$empf\",\"$subj\",\"$nachricht\");'"); | ||
} | |||
</syntaxhighlight> | |||
=== Sendemail (Veraltet, Debian-basierende Distros) === | |||
Es handelt sich um ein Perl Programm, dass man aus den Paketquellen installieren kann. | |||
Es gibt Probleme: | |||
* mit der TLS bzw STARTTLS Verschlüsselung (https://github.com/fhem/fhem-docker/issues/254, https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1915977.html) , | |||
* Mit der Webseite des Projekts (https://web.archive.org/web/20190906140125/http://caspian.dotconf.net/menu/Software/SendEmail); diese ist nicht mehr verfügbar und nur eine archivierte Kopie kann eingesehen werden, | |||
weswegen diese Lösung als technisch überholt gelten sollte. | |||
Die archivierte Doku zu <code>sendemail</code> befindet sich in der Änderungshistorie: https://wiki.fhem.de/w/index.php?title=E-Mail_senden&oldid=37524 | |||
[[Kategorie:E-Mail]] | |||
[[Kategorie: | |||
Aktuelle Version vom 21. Februar 2025, 08:15 Uhr
Um aus FHEM heraus E-Mails senden zu können, gibt es unterschiedliche Methoden, abhängig von der verwendeten Plattform.
Lange Zeit war sendemail
sehr beliebt. Da aber die Homepage des Projekts nicht mehr online ist und Probleme nur noch via erhöhtem Supportaufwand gelöst werden, sollte diese Option als veraltet betrachtet werden.
Eine Liste mit ressourcensparenden E-Mails Clients findet man bei dem OpenWRT Projekt: https://openwrt.org/docs/guide-user/services/email/smtp.client
MSGMail ist ein FHEM eigenes Modul zum Versenden, die Einrichtung ist allerdings nicht gänzlich einfach. Anfängern sei die cURL Methode empfohlen.
MSGMail (Linux, Windows)
FHEM bringt ein eigenes Device zum Senden von E-Mails mit, welches in Perl implementiert ist: MSGMail, https://fhem.de/commandref.html#MSGMail
cURL (Linux, Windows)
cURL kann auf praktisch jedem Betriebssystem genutzt werden, selbst unter Windows. Es kann direkt mit einem SMTP Server E-Mails versenden und stellt damit eine moderne, portable und sichere Option zum Versenden von E-Mails dar.
In FHEM richtet man sich ein Device ein und passt die Details ($emailTo, $emailFrom, $emailServer
) an. Das Programm cURL muss installiert sein (z.B. mit apt install curl
, oder durch Herunterladen und Installieren von der cURL-Webseite).
defmod sendMail dummy
attr sendMail readingList message password
attr sendMail setList message password
attr sendMail userReadings state:message:.* {\
my $emailTo = 'you@example.com';;\
my $emailFrom = 'fhem@domain.com';;\
my $emailServer = 'mail.smtpserver.de';;\
\
# Passwort aus getKeyValue abrufen\
my ($err, $emailPass) = getKeyValue("${name}_password");;\
if ($err || !defined $emailPass) {\
return "Error retrieving password: $err";;\
}\
\
my $message = ReadingsVal($name, 'message', '???');;\
my $subject = "$name: FHEM Nachricht";;\
\
# Betreff extrahieren und aus der Nachricht entfernen\
if ($message =~ s/(?:Subject|Betreff)="(.*?)"//) {\
$subject = $1;;\
}\
\
# Empfänger extrahieren und aus der Nachricht entfernen\
if ($message =~ s/(?:To|An)="(.*?)"//) {\
$emailTo = $1;;\
}\
\
#my $cmd = "echo 'Subject: $subject\\nFrom: $emailFrom\\nTo: $emailTo\\n\\n$message' | ";;\
my $cmd = "echo 'Subject: $subject\\r\\n";;\
$cmd .= "From: $emailFrom\\r\\n";;\
$cmd .= "To: $emailTo\\r\\n";;\
$cmd .= "Content-Type: text/plain;; charset=UTF-8\\r\\n";;\
$cmd .= "\\r\\n";;\
$cmd .= "$message' | ";;\
\
$cmd .= "curl -m 4.8 --noproxy '*' --no-progress-meter --ssl-reqd smtps://$emailServer:465 ";;\
$cmd .= "--user '$emailFrom:$emailPass' --mail-from '$emailFrom' --mail-rcpt '$emailTo' ";;\
$cmd .= "--write-out 'Email sent with status %{http_code}\n' ";;\
$cmd .= "--upload-file - 2>&1";;\
\
#blocking function that is called from a forked process\
if (!defined &sendMailfunc1) {\
*sendMailfunc1 = sub ($) {\
my ($param) = @_;;\
my $result;;\
$result = qx/$param/;;\
$result = MIME::Base64::encode_base64($result);;\
$result =~ s/\n//g;;\
return $result;;\
}\
}\
\
#finish function that is called when blocking function is done\
if (!defined &sendMailfunc2) {\
*sendMailfunc2 = sub ($) {\
my ($result) = @_;;\
my $hash = $defs{$name};;\
$result = MIME::Base64::decode_base64($result);;\
readingsSingleUpdate($hash, $reading, $result, 1);;\
}\
}\
\
BlockingCall("sendMailfunc1", $cmd, "sendMailfunc2", 5);;\
\
return "started Job...";;\
},\
state:password:.* {\
# Passwort speichern\
my $ret = setKeyValue("${name}_password", ReadingsVal($name, 'password', undef)) // "password stored";;\
\
#password wieder aus der Variablen rausnehmen, soll nicht sichtbar bleiben:\
#\
# Hinweis: das Password taucht beim Setzen hierüber im Event-Log auf!\
# Alternativ: { setKeyValue("sendMail_password", "geheimesPasswort") }\
readingsBulkUpdate($hash, "password", "****");;\
\
return "$ret";;\
}
Das Passwort setzt man mit:
set sendMail password geheimesPasswort
- Alternativ, damit das Passwort nicht im Log auftaucht:
{ setKeyValue("sendMail_password", "geheimesPasswort") }
E-Mails kann man dann Senden mit:
set sendMail message Mein Text
(es wird der Standardbetreff und Empfänger aus dem Snippet genutzt)set sendMail message Betreff="Mein Betreff" Mein Text
(es wird der Empfänger aus dem Snippet genutzt)set sendMail message Subject="Dies ist ein Test" Mein Text
set sendMail message To="jemand@example.com" Mein Text
set sendMail message An="jemand@example.com" Mein Text
set sendMail message An="jemand@example.com" Betreff="Mein Betreff" Mein Text
set sendMail message To="jemand@example.com" Subject="Mein Betreff" Mein Text
set sendMail message Subject="✅ Dies ist ein Test" Meldung mit Emoji ⚽ geht auch
Fehlersuche
Sollte cURL zwar installiert sein, aber keine E-Mails versenden, kann es sein, dass das Protokoll nicht einkompiliert wurde. Dies ist bei OpenWRT zum Beispiel der Fall.
So sollte es aussehen (hier ein Ubuntu), relevant ist für diese Nutzung das Protokoll smtp und smtps, das braucht man:
curl -V
curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.0.13 zlib/1.3 brotli/1.1.0 zstd/1.5.5 libidn2/2.3.7 libpsl/0.21.2 (+libidn2/2.3.7) libssh/0.10.6/openssl/zlib nghttp2/1.59.0 librtmp/2.3 OpenLDAP/2.6.7
Release-Date: 2023-12-06, security patched: 8.5.0-2ubuntu10.6
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
So sollte es nicht aussehen (hier ein OpenWRT):
curl: (1) Protocol "smtps" not supported
curl -V
curl 8.10.1 (arm-openwrt-linux-gnu) libcurl/8.10.1 mbedTLS/3.6.2 nghttp2/1.63.0
Release-Date: 2024-09-18
Protocols: file ftp ftps http https ipfs ipns mqtt
Features: alt-svc HSTS HTTP2 HTTPS-proxy IPv6 Largefile SSL threadsafe UnixSockets
Hat man nur ein cURL ohne das Protokoll, so muss man sich das Paket leider anderweitig beschaffen (chroot, selbst kompilieren, statisch gelinkte Version, ...).
Forumlink
https://forum.fhem.de/index.php?topic=140814.0
EXIM4 (Debian)
Eine Anleitung zum Versenden von E-Mails mit Exim ist als PDF verfügbar: PDF
SSMTP (OpenWRT, embedded Distros)
Installation
opkg update
opkg install ssmtp_2.64-4_mpc85xx.ipk
Damit ssmtp
funktioniert müssen die Dateien /etc/ssmtp/ssmtp.conf
und /etc/ssmtp/revaliases
angepasst werden.
/etc/ssmtp/ssmtp.conf
root=arnold@gmx.net
mailhub=mail.gmx.net:465
rewriteDomain=gmx.net
hostname=gmx.net
FromLineOverride=YES
UseTLS=YES
#UseSTARTTLS=YES
AuthUser=arnold@gmx.net
AuthPass=Passwort_von_arnold@gmx.net
/etc/ssmtp/revaliases
root:arnold@gmx.net:mail.gmx.net:465
In der 99_myUtils folgende Unterroutine einfügen:
sub OpenWRTMail
{
my $rcpt = shift;
my $subject = shift;
my $text = shift;
my $ret = "";
my $sender = "dockstar\@heye-tammo.de";
Log 1, "sendEmail RCP: $rcpt, Subject: $subject, Text: $text";
$ret .= qx(echo -e 'to:$rcpt\n from:$sender\nsubject:$subject\n$text\n' | ssmtp $rcpt);
$ret =~ s,[\r\n]*,,g; # remove CR from return-string
Log 1, "sendEmail returned: $ret";
}
PHP Mail Funktion (Synology DiskStation)
Beim DSM 3.2 funktioniert der php-mail
-Befehl, so dass man mittels folgendem Modul E-Mails versenden kann:
sub sendmail($$$) {
my($empf, $subj, $nachricht) = @_;
system("php -r 'mail(\"$empf\",\"$subj\",\"$nachricht\");'");
}
Sendemail (Veraltet, Debian-basierende Distros)
Es handelt sich um ein Perl Programm, dass man aus den Paketquellen installieren kann.
Es gibt Probleme:
- mit der TLS bzw STARTTLS Verschlüsselung (https://github.com/fhem/fhem-docker/issues/254, https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1915977.html) ,
- Mit der Webseite des Projekts (https://web.archive.org/web/20190906140125/http://caspian.dotconf.net/menu/Software/SendEmail); diese ist nicht mehr verfügbar und nur eine archivierte Kopie kann eingesehen werden,
weswegen diese Lösung als technisch überholt gelten sollte.
Die archivierte Doku zu sendemail
befindet sich in der Änderungshistorie: https://wiki.fhem.de/w/index.php?title=E-Mail_senden&oldid=37524