Felix Riesterer: E-Mail Parser zum Weiterversenden vorhandener E-Mails

Liebe Mitlesende,

ich suche nach einer PHP-Klasse, die mir eine E-Mail dahingehend parst, dass sie folgende Daten zuverlässig und in egal welcher Kodierung ermittelt:

* Absender
* Empfänger
* eigentliche Mail

Mit den Daten möchte ich erreichen, dass ich die Mail im Grunde unverändert (bis auf neuen Empfänger und Absender) weiterversenden kann, inklusive möglicher Attachments. Die bereits vorhandenen Header sind mir dabei sogar egal, Hauptsache der Inhalt der Mail bleibt erhalten.

Idealerweise möchte ich doch den Mailtext verändern können. Es geht um einen Bestätigungslink, der am Anfang der eigentlichen Nachricht einzufügen wäre - sowohl in text/plain als auch text/html. Das wäre allerdings sekundär.

Wie muss ich da vorgehen bzw. welche fertigen Tools sind dafür gut zu gebrauchen? Womit habt ihr gute Erfahrungen gemacht?

Liebe Grüße,

Felix Riesterer.

--
"Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
  1. Hallo Felix,

    ich suche nach einer PHP-Klasse, die mir eine E-Mail dahingehend parst, dass sie folgende Daten zuverlässig und in egal welcher Kodierung ermittelt:

    * Absender
    * Empfänger
    * eigentliche Mail

    ich kenne oder habe zwar nichts Fertiges, denke aber, dass das als Schnellschuss ein Feierabendprojekt wäre, mit ausführlichen Tests vielleicht ein Wochenendprojekt.
    Ganz grob sehe ich folgende Schritte:

    * explode an "\r\n\r\n", damit erhalte ich den Header-Block und den Content-Block
     * explode des Header-Blocks an "\r\n", dann erhalte ich aller Headerzeilen als Einzel-Elemente
       Achtung: Die mit Whitespace beginnenden müssen wieder dem vorhergehenden Element zugeordnet
       werden.
     * Empfänger und Absender stecken in den Header-Zeilen "To:" und "From:", dabei aufpassen, weil
       die Daten base64- oder Quoted-Printable codiert sein können

    Mit den Daten möchte ich erreichen, dass ich die Mail im Grunde unverändert (bis auf neuen Empfänger und Absender) weiterversenden kann, inklusive möglicher Attachments. Die bereits vorhandenen Header sind mir dabei sogar egal, Hauptsache der Inhalt der Mail bleibt erhalten.

    Bis hierher kein Problem. Die bisherigen Header müssen sogar zum Großteil wieder entfallen (etwa sämtliche Received- oder X-Felder).

    Idealerweise möchte ich doch den Mailtext verändern können. Es geht um einen Bestätigungslink, der am Anfang der eigentlichen Nachricht einzufügen wäre - sowohl in text/plain als auch text/html. Das wäre allerdings sekundär.

    Und es würde einen erheblichen Mehraufwand bedeuten, der beim reinen Weiterleiten nicht anfallen würde. Man müsste nämlich die ganze Struktur des Mail-Body analysieren, was andernfalls nicht nötig wäre.

    So long,
     Martin

    --
    Dieser Satz wurde in mühsamer Kleinstarbeit aus einzelnen Wörtern zusammengesetzt.
      (Hopsel)
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Lieber Der Martin,

      ich kenne oder habe zwar nichts Fertiges, denke aber, dass das als Schnellschuss ein Feierabendprojekt wäre, mit ausführlichen Tests vielleicht ein Wochenendprojekt.
      Ganz grob sehe ich folgende Schritte:

      dazu habe ich bereits eine fertige Lösung gefunden, die das und noch mehr kann. Damit kann ich relativ einfach Empfänger und Absender "ersetzen".

      Idealerweise möchte ich doch den Mailtext verändern können. Es geht um einen Bestätigungslink, der am Anfang der eigentlichen Nachricht einzufügen wäre - sowohl in text/plain als auch text/html. Das wäre allerdings sekundär.

      Und es würde einen erheblichen Mehraufwand bedeuten, der beim reinen Weiterleiten nicht anfallen würde. Man müsste nämlich die ganze Struktur des Mail-Body analysieren, was andernfalls nicht nötig wäre.

      Das kann obige Klasse auch. Wie aber baue ich eine multipart/alternative Mail (mit Attachment(s)) wieder zusammen, um sie mit meinen Veränderungen weiterzuleiten? Müsste ich die Mail wieder völlig neu zusammensetzen, oder würde es reichen, im originalen Quellcode der Mail die passenden Teile mit Stringersetzung anzupassen?

      Liebe Grüße,

      Felix Riesterer.

      --
      "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
      1. Hallo Felix,

        dazu habe ich bereits eine fertige Lösung gefunden, die das und noch mehr kann. Damit kann ich relativ einfach Empfänger und Absender "ersetzen".

        und ich red' mir hier einen Wolf ... ;-)

        Wie aber baue ich eine multipart/alternative Mail (mit Attachment(s)) wieder zusammen, um sie mit meinen Veränderungen weiterzuleiten? Müsste ich die Mail wieder völlig neu zusammensetzen, oder würde es reichen, im originalen Quellcode der Mail die passenden Teile mit Stringersetzung anzupassen?

        Der Quellcode von e-Mails ist technisch gesehen einfach nur Text. Es ist daher durchaus legitim, Passagen im Original-Quellcode einfach zu ändern (S&R), vorausgesetzt die Textstellen sind eindeutig identifizierbar. Dann muss man sich in der Tat nicht mit der verschachtelten MIME-Struktur befassen.

        Wenn aber die PHP-Bibliothek, die du da hast, quasi vollautomatisch die Mailstruktur aufdröselt ... dann frage ich mich, ob sie für den Zweck wirklich geeignet ist.

        Ciao,
         Martin

        --
        Früher habe ich mich vor der Arbeit gedrückt. Heute könnte ich stundenlang zusehen.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Lieber Der Martin,

          dazu habe ich bereits eine fertige Lösung gefunden

          und ich red' mir hier einen Wolf ... ;-)

          zu Deiner Ehrenrettung, den Fund habe ich erst nach dem Lesen Deiner Antwort gemacht, als ich dachte, dass ein Parsing der Mail unvermeidbar wäre.

          Der Quellcode von e-Mails ist technisch gesehen einfach nur Text. Es ist daher durchaus legitim, Passagen im Original-Quellcode einfach zu ändern (S&R), vorausgesetzt die Textstellen sind eindeutig identifizierbar. Dann muss man sich in der Tat nicht mit der verschachtelten MIME-Struktur befassen.

          Das ist offensichtlich unvermeidbar, denn in eine HTML-Mail einfach nur die Zeichenfolge einer URL einzufügen führt bei der Darstellung im Client nicht automatisch zu einem anklickbaren Link. Bei Plaintext-Mails ist das in fast allen Fällen umgekehrt, da muss ich die URL nicht in Markup verpacken.

          Wenn aber die PHP-Bibliothek, die du da hast, quasi vollautomatisch die Mailstruktur aufdröselt ... dann frage ich mich, ob sie für den Zweck wirklich geeignet ist.

          Wie wollte ich sonst herausfinden, ob der Mailtext text/plain oder text/html ist?

          Die Sache mit dem S&R klingt sehr verlockend! Ist sie aber von ihrem Konzept her ausreichend betriebssicher?

          Liebe Grüße,

          Felix Riesterer.

          --
          "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
      2. Wie aber baue ich eine multipart/alternative Mail (mit Attachment(s)) wieder zusammen, um sie mit meinen Veränderungen weiterzuleiten? Müsste ich die Mail wieder völlig neu zusammensetzen, oder würde es reichen, im originalen Quellcode der Mail die passenden Teile mit Stringersetzung anzupassen?

        Am einfachsten gar nicht.

        Du behandelts am billigsten die alte Mail als Dateianhang und baust ergo ein komplett neues Mail.

        Jörg Reinholz

        1. Lieber Jörg Reinholz,

          Am einfachsten gar nicht.

          dieses "Am einfachsten" wirft neue Probleme auf. Lasse ich die original-Mail unverändert als Anhang, dann öffnet DAU das Attachment, beantwortet es... >peng!< ... und sendet es womöglich an den ursprünglichen Adressaten, an den es gerade *nicht* mehr soll, nur weil er auf "allen antworten" geklickt hat.

          Außerdem ist der Zugang zur eigentlichen Information durch einen weiteren Arbeitsvorgang seitens des Users versperrt - kein Pluspunkt für Usability!

          Ich werde wohl einige Feldversuche mit echten Mails machen müssen, um alle (un)möglichen Kombinationen aus Anhängen, Enkodierungen und Dateigrößen auszuprobieren, damit ich meine Manipulationen präzisieren kann. Back to the drawing board. *soifz*

          Liebe Grüße,

          Felix Riesterer.

          --
          "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
          1. Moin!

            Am einfachsten gar nicht.
            dieses "Am einfachsten" wirft neue Probleme auf...

            Dann halten wir uns also an das alte Testament und machen erst einmal einen Plan.

            Wenn der steht wäre es übrigens immer noch sehr einfach wenn Du dann wie von Martin vorgeschlagen vorgehst.

            Jörg Reinholz

            1. Lieber Jörg Reinholz,

              Dann halten wir uns also an das alte Testament und machen erst einmal einen Plan.

              *LOL*

              Wenn der steht wäre es übrigens immer noch sehr einfach wenn Du dann wie von Martin vorgeschlagen vorgehst.

              Ich arbeite noch immer an Ideen, wie ich bei content-type="multipart/alternative" die passenden Einfügungen vornehmen muss, damit da ein anklickbarer Link im Client angezeigt wird - egal wie der User seinen Client konfiguriert hat.

              Nicht dass Du mich falsch verstehst, ich schätze Deine Impulse sehr! Vielen Dank dafür!

              Liebe Grüße,

              Felix Riesterer.

              --
              "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
              1. Hallo,

                Ich arbeite noch immer an Ideen, wie ich bei content-type="multipart/alternative" die passenden Einfügungen vornehmen muss, damit da ein anklickbarer Link im Client angezeigt wird - egal wie der User seinen Client konfiguriert hat.

                im HTML-Teil muss auch ein Link nach den Regeln von HTML notiert werden, also <a href="">...</a>. Im Plaintext-Teil wird dagegen von den bekannten Mailclients alles, was irgendwie nach URL aussieht, automatisch als anklickbarer Link dargestellt.
                Oder habe ich deine Unklarheiten falsch verstanden?

                Schönes Wochenende,
                 Martin

                --
                Um die Wahrheit zu erfahren, muss man den Menschen widersprechen.
                  (George Bernhard Shaw)
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                1. Lieber Der Martin,

                  Oder habe ich deine Unklarheiten falsch verstanden?

                  ich muss herausfinden, wo genau der Nachrichteninhalt der plaintext-Mail steht, um an dessen Anfang die Aufforderung und die URL einzufügen (inklusive Zeilenumbrüche). Und dann muss ich prüfen, ob es noch eine HTML-"Variante" dieser Mail gibt und wo da der <body> beginnt, um dort Code wie den folgenden als dessen erstes Kindelement einzufügen:

                  <p>  
                      Der Absender bittet um eine Bestätigung für den Empfang dieser Mail.  
                      Bitte klicken Sie dazu auf diesen Link:  
                      <a href="http://example.org/path?c=1234">http://example.org/path?c=1234</a>  
                  </p>
                  

                  Aktuell muss ich die geparsten Daten "verstehen", um multipart-Mails korrekt zu manipulieren. Das Prinzip habe ich verstanden, meinen Algorithmus leider noch nicht (deshalb tut er auch noch nicht)...

                  Liebe Grüße,

                  Felix Riesterer.

                  --
                  "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
                  1. wo genau der Nachrichteninhalt der plaintext-Mail steht, um an dessen Anfang ... einzufügen:

                    <p>

                    Der Absender bittet um eine Bestätigung für den Empfang dieser Mail.
                        Bitte klicken Sie dazu auf diesen Link:
                        <a href="http://example.org/path?c=1234">http://example.org/path?c=1234</a>
                    </p>

                      
                      
                    das hätte aber in einem Plaintext-Mail (content-type: text/plain vers. text/html nichts zu suchen.  
                      
                    Daran ändert auch nichts, wenn manche (also nicht alle) Mailprogramme dann automatisch annehmen, es handele sich um ein HTML-Mail dessen Inhalt nur fehlerhaft ausgezeichnet sei und beim Vorkommen von etwas, was auch wie html aussehen könnte automatisch den Anzeige-Modus von text/plain auf text/html wechseln.  
                      
                      
                    Jörg Reinholz  
                      
                    
                    
                    1. Lieber Jörg Reinholz,

                      das hätte aber in einem Plaintext-Mail (content-type: text/plain vers. text/html nichts zu suchen.

                      da stimme ich Dir vorbehaltlos zu.

                      Liebe Grüße,

                      Felix Riesterer.

                      --
                      "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
              2. Ich arbeite noch immer an Ideen, wie ich bei content-type="multipart/alternative" die passenden Einfügungen vornehmen muss, damit da ein anklickbarer Link im Client angezeigt wird - egal wie der User seinen Client konfiguriert hat.

                Das geht ganz einfach. Behaupte der Content-Typ sei "x-application/unkown". das hat aber einen "nicht ganz kleinen" Nachteil: Der Inhalt wird dann nämlich zwar zwingend als anklickbar dargestellt aber der Benutzer wird STETS gefragt, womit zum Teufel er das Zeug denn öffnen will.

                Sie Alternative ist den korrekten Content-Type zu verwenden. Dann bestimmt aber, im Rahmen des von dessen Mailprogramm erwart- und einstellbaren, stets der Benutzer ob er den Inhalt gleich sehen will oder ob ein Link gezeigt wird.

                Jörg Reinholz

                1. Aloha ;)

                  Das geht ganz einfach. Behaupte der Content-Typ sei "x-application/unkown". das hat aber einen "nicht ganz kleinen" Nachteil: Der Inhalt wird dann nämlich zwar zwingend als anklickbar dargestellt aber der Benutzer wird STETS gefragt, womit zum Teufel er das Zeug denn öffnen will.

                  Das ist, wie du schon richtig andeutest, eine Usability-Katastrophe.

                  Sie Alternative ist den korrekten Content-Type zu verwenden. Dann bestimmt aber, im Rahmen des von dessen Mailprogramm erwart- und einstellbaren, stets der Benutzer ob er den Inhalt gleich sehen will oder ob ein Link gezeigt wird.

                  Ist das nicht das, was der Fall sein sollte? Das hört sich irgendwie negativ besetzt an.

                  Grüße,

                  RIDER

                  --
                  Camping_RIDER a.k.a. Riders Flame a.k.a. Janosch Zoller
                  ch:? rl:| br:> n4:? ie:% mo:| va:) js:) de:> zu:) fl:( ss:| ls:[
                  1. Sie Alternative ist den korrekten Content-Type zu verwenden. Dann bestimmt aber, im Rahmen des von dessen Mailprogramm erwart- und einstellbaren, stets der Benutzer ob er den Inhalt gleich sehen will oder ob ein Link gezeigt wird.

                    Ist das nicht das, was der Fall sein sollte? Das hört sich irgendwie negativ besetzt an.

                    Felix wollte, so habe ich das jedenfalls verstanden, dieses Verhalten nicht haben.

                    Jörg Reinholz

                    1. Lieber Jörg Reinholz,

                      Sie Alternative ist den korrekten Content-Type zu verwenden.

                      ja, daran arbeite ich gerade. Bei multipart-Mails fummle ich sowohl im text/plain, als auch im text/html Messagebody herum, um da meinen Link einzubringen. Die verwendete Klasse ermöglicht mir eine relativ genaue Bestimmung des Beginns des Textinhalts in jedem Messagebody (muss nur jeweils bis zur Leerzeile vorspulen).

                      Auf diese Weise kann der User in egal welcher Ansicht den Link sehen:
                      1.) Bei erzwungener Plaintext-Ansicht (oder bei "echten" Plaintext-Mails) sieht er die pure URL als anklickbaren Link (dank dem Komfort durch den Mailclient).
                      2.) In der HTML-Ansicht sieht er den Link als anklickbaren Verweis, weil das injizierte Markup diesen entsprechend auszeichnet.

                      So langsam glabe ich, komme ich meinem Ziel tatsächlich näher!

                      Liebe Grüße,

                      Felix Riesterer.

                      --
                      "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
                      1. Hallo Ingrid,

                        das Parsing hat geklappt. Die verwendete Klasse war so nett, mir auch die Zeichen-Position für den Beginn eines Message-Bodies mit anzugeben, sodass ich meine Ersetzungen von vornherein relativ genau vornehmen konnte. Wenn's fertig ist, dann kann ich darauf verlinken.

                        Es ist mir nun möglich, in einem Message-Body einen Bestätigungslink an den Anfang "einzupflanzen", wobei beim content-type="text/html" richtiges Markup eingesetzt wird (auch die Zeilenlänge von 70 Zeichen wird je nach URL-Länge eingehalten), bei content-type="text/plain" dagegen die URL ohne Markup in den Text geschrieben wird. Dabei werden für die Mail sowieso nur maximal zwei Message-Bodies (die ersten, die entweder text/plain oder text/html sind) behandelt.

                        Mir ist aufgefallen, dass nicht alle Mailclients bei der Erstellung von HTML-Mails ein ganzes HTML-Dokument erstellen. Meine mit Squirrel-Mail erstellte Mail hatte nur Markup für Textauszeichnung (<hx>, <p>, ...) jedoch kein <html>, <head> oder <body> Element. Mit dem Thunderbird dagegen hatte die erstellte HTML-Mail ein vollständiges HTML-Gerüst - wenn auch ohne Doctype...

                        Liebe Grüße,

                        Felix Riesterer.

                        --
                        "Wäre die EU ein Staat, der die Aufnahme in die EU beantragen würde, müsste der Antrag zurückgewiesen werden - aus Mangel an demokratischer Substanz." (Martin Schulz, Präsident des EU-Parlamentes)
                        1. Meine mit Squirrel-Mail erstellte Mail hatte nur Markup für Textauszeichnung (<hx>, <p>, ...) jedoch kein <html>, <head> oder <body> Element.

                          Zumindest in den Spezifikationen bis html4x sind html, head, body als optional ausgezeichnet.

                          Mit dem Thunderbird dagegen hatte die erstellte HTML-Mail ein vollständiges HTML-Gerüst - wenn auch ohne Doctype...

                          Wenn Du Dich weiter damit beschäftigst wirst Du merken, dass die "WYSIWYG"-Editoren vieler Mailclients spätestens beim Beantworten von HTML-Mails noch mehr Mist bauen.

                          Jörg Reinholz