Skip to content

Mit Python emails verschicken

Neulich bin ich auf die Idee gekommen, dass ich als Teil eines in geschriebenen Compile&Deploy-Skripts Statusmeldungen per email verschicken könnte. Das sollte natürlich auch per geschehen und eigentlich leicht machbar sein. Erste Recherchen brachten mich zum Modul smtplib, das standardmäßig bei Python mitgeliefert wird (Batteries included).

Dessen Verwendung allerdings für einen Quick’n’Dirty-Hack kompliziert war – vor allem, weil ich es nicht sofort zum Laufen brachte. Ich konnte keine Verbindung zum wohl von zur Verfügung gestellten SMTP-Servers (oder so) herstellen. Also habe ich mich nach einer anderen Lösung umgesehen. Da man in einer Business-Umgebung ziemlich viel über -Servern erledigt (und ich darin noch relativ unerfahren bin), habe ich mich auf die Suche nach einer entsprechenden Lösung gemacht. Wie alle Microsoft-Office-Anwendungen (?) stellt auch Outlook eine -Schnittstelle zur Verfügung. Unter [Python-de] Outlook Attachment fand ich eine denkbar einfache Lösung diese Schnittstelle zu bedienen.

Ein gutes Beispiel dafür, wie leicht die Verwendung von COM-Objekten mit Python ist:

import win32com.client

def send_mail_via_com(text, subject, recipient, profilename="Outlook2003"):
    s = win32com.client.Dispatch("Mapi.Session")
    o = win32com.client.Dispatch("Outlook.Application")
    s.Logon(profilename)
    
    Msg = o.CreateItem(0)
    Msg.To = recipient
    
    Msg.CC = "WeitereAdressaten"
    Msg.BCC = "Mailadresse"
    
    Msg.Subject = subject
    Msg.Body = text
    
    Anhang1 = "Pfad zum Anhang1"
    Anhang2 = "Pfad zum Anhang2"
    Msg.Attachments.Add(Anhang1)
    Msg.Attachments.Add(Anhang2)
 
    Msg.Send()

Dieser Code schickt tatsächlich eine email an beliebige Adressen. Ich verwende zwar zur Zeit noch keine Anhänge, aber diese wären auch ganz einfach zu handhaben.

Nach kleineren Veränderungen – zum Beispiel dem tatsächlich Aufruf der Funktion 😉 – sollte der Schnipsel laufen.

Auf der Wiki-Seite PythonWindowsProgramming finden sich weitere COM+Python-Links mit hilfreichem Code. Unter SomeOfMyPythonScripts sammle ich lokal nützliche Schnipsel.

{ 5 } Comments

  1. Emerentia | 2006/12/18 at 12:44 | Permalink

    Wie sieht es bei Python mit der Sicherheit aus? Bei PHP sind ja z.B. einige „Sicherheitslücken“ im Emailversand bekannt – aber auch deren Gegenmaßnahmen, etwa die „escape-string“-Funktion. Gibt’s sowas auch bei Python? Nicht dass ein Spammer über ein solches Email-Skript Spam verschickt…

  2. Steffen | 2006/12/19 at 12:03 | Permalink

    Ich kenne die Sicherheitslücke in PHP nicht, die du ansprichst. Geht es dabei aber nicht eher darum, dass die Funktionalität nicht geschützt ist und daher von außen missbraucht werden kann?

    Wie dem auch sei, mein Codebeispiel verwendet COM-Objekte. Es ist also nichts Python-spezifisches. Wenn es ein Sicherheitsproblem gibt, dann ist das – in diesem Beispiel – nicht die Schuld von Python.

    Ich habe es nicht ausprobiert, aber ich denke – zumindest auf meinem Arbeitsplatzrechner – kann diese COM-Funktionalität nur ein authentifizierter und autorisierter Benutzer verwenden.

  3. Emerentia | 2006/12/21 at 11:24 | Permalink

    Hmm, stimmt, war ungenau formuliert. Also nochmal genauer: in php gibt es eine Funktion mail($to, $subject, $message, $headers), der man die Email-relevanten Daten übergibt. Passt man nun in seinem Formuar nicht auf, d.h. läßt man Sonderzeichen wie das kleiner-Zeichen zu, so kann sich ein Angreifer durch geschickte Falscheingaben im Formular die mail-Funktionalität zu eigen machen, etwa durch ... </script><script>...mein_böses_Skript...<script> .... Mit escape-string() werden solche Sonderzeichen etwa durch deren HTML-Entitäten ersetzt und dieser Teil der Gefahr ist gebannt.

    Und nun wollte ich halt wissen, wie das in python gelöst wird. Gibt es da auch eine solche Ersetzungsfunktionen, die den programmierer beim Absichern des Skripts helfen?

  4. Steffen | 2007/1/5 at 05:25 | Permalink

    Ah – du sprichst also vom Verschicken böswilligen HTMLs.

    Über die Bibliothek, die bei der Installation von Python mitgeliefert wird, sage man auch Batteries Included. Nach kurzem Suchen bin ich dort auch fündig geworden:

    In [1]: import cgi
    
    In [2]: cgi.escape("<script>...mein_böses_Skript...</script>")
    Out[2]: '&lt;script&gt;...mein_b\x94ses_Skript...&lt;/script&gt;'

    (Für diese HTML-Ansicht musste ich den escapten String als original-String nehmen und die Ampersands im resultierenden eigentlichen escapten String mit &amp; ersetzen. Falls das kompliziert klingt – einfach vergessen.)

    Beantwortet der Codeschnipsel deine Frage?

  5. Emerentia | 2007/1/7 at 02:33 | Permalink

    Ja, ziemlich. Danke!

    P.S.: Es war an dem Tag nicht glatt auf der Straße…

Post a Comment

Your email is never published nor shared. Required fields are marked *