➿ E-Mail senden mit CURL

Begonnen von Torxgewinde, 17 Februar 2025, 20:31:24

Vorheriges Thema - Nächstes Thema

Remstäler

Kann ich eigentlich auch "längere" Texte mit Zeilenumbruch verschicken ?
Bzw. kann ich mit einem Kürzel im Text einen Zeilenumbruch machen ?

(derzeit wird trotz neuer Zeile im Auftrag alles "am Stück" geschrieben)

bertl

Zitat von: bertl am 26 Februar 2025, 15:59:12Ich wollte eine mehrzeilige Eingabe für den Message-Text machen und habe daher wie folgt ergänzt:
attr sendMail setList message:textField-long
Dann sollte dein Problem gelöst sein!

bertl

Zitat von: Remstäler am 23 Mai 2025, 18:23:03Ich bekomme zwar nach dem Senden den Status 250 gemeldet, aber es klappt alles.

Ich habe bei mir den HTTP Statuscode ausgewertet um gleich zu sehen, ob es sich um eine Info, einen Fehler oder was auch immer handelt.
Vielleicht ist es ja von Interesse, diese Auswertung generell zu übernehmen.

    $cmd .= "--write-out 'HTTP-Statuscode %{http_code}\n' ";;\    #Rückgabe über diese Funktion,\
    #anzeigen in dem reading dieses UserReadings:\
    if (!defined &sendMailfunc2) {\
        *sendMailfunc2 = sub ($) {\
            my ($result) = @_;;\
            my $hash = $defs{$name};;\
            $result = MIME::Base64::decode_base64($result);;\
            if(    $result =~ /HTTP-Statuscode 0[0-9]{2}/ )     { $result = "curl-ERROR: ".$result;; }\
            elsif( $result =~ /HTTP-Statuscode 1[0-9]{2}/ )     { $result = "INFO: ".$result;; }\
            elsif( $result =~ /HTTP-Statuscode 2[0-9]{2}/ )     { $result = "OK: ".$result;; }\
            elsif( $result =~ /HTTP-Statuscode 3[0-9]{2}/ )     { $result = "WARNING: ".$result;; }\
            elsif( $result =~ /HTTP-Statuscode [4-9][0-9]{2}/ ) { $result = "ERROR: ".$result;; }\
            readingsSingleUpdate($hash, $reading, $result, 1);;\
        }\
    }\

Torxgewinde

#63
Hi @bertl, das ist wie der Statuscode repräsentiert wird und deswegen würde ich es eher in dem Attribut stateFormat oder devStateIcon um-mappen auf den gewünschten Wert in der Darstellung. Ist aber eine Geschmacksfrage und deswegen IMHO optional zu behandeln.

im Kern:
...
attr sendMail stateFormat { \
    my $result = ReadingsVal($name, 'state', '???');;\
    \
    #modify result to your liking:\
    if(    $result =~ /Email sent with status 0[0-9]{2}/ )     { $result = "curl-ERROR: ".$result;; }\
    elsif( $result =~ /Email sent with status 1[0-9]{2}/ )     { $result = "INFO: ".$result;; }\
    elsif( $result =~ /Email sent with status 2[0-9]{2}/ )     { $result = "OK: ".$result;; }\
    elsif( $result =~ /Email sent with status 3[0-9]{2}/ )     { $result = "WARNING: ".$result;; }\
    elsif( $result =~ /Email sent with status [4-9][0-9]{2}/ ) { $result = "ERROR: ".$result;; }\
    \
    return $result;;\
}...

also komplett:
defmod sendMail dummy
attr sendMail readingList message password
attr sendMail setList message:textField-long password
attr sendMail stateFormat { \
    my $result = ReadingsVal($name, 'state', '???');;\
    \
    #modify result to your liking:\
    if(    $result =~ /Email sent with status 0[0-9]{2}/ )     { $result = "curl-ERROR: ".$result;; }\
    elsif( $result =~ /Email sent with status 1[0-9]{2}/ )     { $result = "INFO: ".$result;; }\
    elsif( $result =~ /Email sent with status 2[0-9]{2}/ )     { $result = "OK: ".$result;; }\
    elsif( $result =~ /Email sent with status 3[0-9]{2}/ )     { $result = "WARNING: ".$result;; }\
    elsif( $result =~ /Email sent with status [4-9][0-9]{2}/ ) { $result = "ERROR: ".$result;; }\
    \
    return $result;;\
}
attr sendMail userReadings state:message:[\s\S]* {\
    my $emailTo   = 'du@exmaple.com';;\
    my $emailFrom = 'fhem@example.de';;\
    my $emailServer = 'mail.your-server.de';;\
    \
    #erzeuge Datumsangabe konform zu RFC-5322:\
    my @emailDateArray = split(' ', strftime("%w %d %m %Y %H:%M:%S %z", localtime));;\
    $emailDateArray[0] = (qw[Sun Mon Tue Wed Thu Fri Sat])[$emailDateArray[0]] . ',';;\
    $emailDateArray[2] = (qw[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec])[$emailDateArray[2]-1];;\
    my $emailDate = join(' ', @emailDateArray);;\
    \
    # 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;;\
    }\
    \
    #Dateianhänge bestimmen\
    my @attachments;;\
    while ($message =~ s/(?:Attachment|Anhang)=["'](.*?)["']//) {\
        my $file = $1;;\
        return ">>$file<< not found, not sending email" unless (-e $file);;\
        push (@attachments, $file);;\
    }\
    \
    #der curl Befehl wird hier aufgebaut:\
    my $cmd = "curl -m 19 --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}' ";;\
    $cmd .= "-H 'Subject: $subject' ";;\
    $cmd .= "-H 'From: $emailFrom' ";;\
    $cmd .= "-H 'Date: $emailDate' ";;\
    \
    #multipart/alternative für Text und HTML EMail Body\
    $cmd .= "-F '=(;;type=multipart/alternative' ";;\
    \
    # Leerzeichen und <br> bzw <br \> am Anfang entfernen:\
    $message =~ s/^(\s|<br(?:[ \/]+)>)+//;;\
    # Leerzeichen und <br> bzw <br \> am Ende entfernen:\
    $message =~ s/(\s|<br(?:[ \/]+)>)+$//;;\
    \
    #Plaintext E-Mail Inhalt an cURL:\
    $cmd .= "-F \"=$message;;type=text/plain;; charset=UTF-8\" ";;\
    #ersetze \n bzw. \r\n durch ein HTML-tag <br />:\
    $message =~ s/\r?\n/<br \/>/g;;\
    \
    #HTML E-Mail Inhalt an cURL:\
    $cmd .= "-F '= <body>$message</body>;;type=text/html;; charset=UTF-8' ";;\
    $cmd .= "-F '=)' ";;\
    \
    #jetzt alle Attachments (0..N) anhängen:\
    foreach my $file (@attachments) {\
        $cmd .= "-F '=@".$file.";;encoder=base64' ";;\
    }\
    \
    #stderr auch mit in den output sammeln:\
    $cmd .= " 2>&1";;\
    \
    #Blockierender Aufruf von cURL in dieser Funktion via BlockingCall:\
    if (!defined &sendMailfunc1) {\
        *sendMailfunc1 = sub ($) {\
            my ($param) = @_;;\
            my $result;;\
            $result = qx/$param/;;\
            $result = MIME::Base64::encode_base64($result);;\
            $result =~ s/\n//g;;\
            return $result;;\
        }\
    }\
    \
    #Rückgabe über diese Funktion,\
    #anzeigen in dem reading dieses UserReadings:\
    if (!defined &sendMailfunc2) {\
        *sendMailfunc2 = sub ($) {\
            my ($result) = @_;;\
            my $hash = $defs{$name};;\
            $result = MIME::Base64::decode_base64($result);;\
            readingsSingleUpdate($hash, $reading, $result, 1);;\
        }\
    }\
    \
    #funktion falls BlockingCall abgebrochen wird:\
    if (!defined &sendMailfunc3) {\
        *sendMailfunc3 = sub ($) {\
            my ($result) = @_;;\
            my $hash = $defs{$name};;\
            readingsSingleUpdate($hash, $reading, $result, 1);;\
        }\
    }\
    \
    BlockingCall("sendMailfunc1", $cmd, "sendMailfunc2", 20, "sendMailfunc3", "Error: timeout");;\
    \
    return "started cURL command...";;\
},\
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";;\
}

Wie siehst du das?


Ich habe gerade auch nochmal die Doku dazu rausgekramt: https://everything.curl.dev/usingcurl/verbose/writeout.html