Die MIME-Klassen in LotusScript

15.09.2006 von Elmar Fuchs
Die Rich-Text-Klassen des LotusScript-Objektmodells ermöglichen die programmatische Erstellung und den Versand formatierter E-Mail. Bei einer Übertragung über das Internet gehen jedoch die Formate verloren, da Rich Text kein Internetstandard ist. Die Verwendung der MIME-Klassen löst dieses Problem.

Das Versenden von E-Mail ist eine der Kernfunktionalitäten von Lotus Notes/Domino. Die EMail- Erstellung kann nicht nur manuell vom Anwender mittels der Maildatenbank, sondern auch programmtechnisch erfolgen. Ein für diese Zwecke häufig eingesetztes Mittel ist die Erstellung eines LotusScript-Agenten, welcher periodisch oder beim Eintreten bestimmter Ereignisse die E-Mail erstellt und versendet. Dabei ist es durchaus möglich, dass nicht nur einfache textliche Informationen, sondern auch Tabellen, eingefügte Objekte und Anhänge versendet werden sollen. Die Gestaltung des Textes mittels der vielfältigen Möglichkeiten der Textformatierung ist eine ebenfalls auftretende Notwendigkeit.

LotusScript bietet in seinem Objektmodell über die seit der Version 6 neu hinzugekommenen Klassen zur Handhabung von Rich Text vielfältige Möglichkeiten, um entsprechende Wünsche umzusetzen.

In den Ausgaben 8, 9, 11 und 12/2004 von Expert ´s inside Lotus Notes/Domino wurde in mehreren Artikeln der Umgang und die Verwendung der LotusScript-Klassen zur Verarbeitung von Rich Text erklärt.

Der LotusScript-Agent

Listing 1 zeigt einen LotusScript-Agenten, der unter Verwendung verschiedener Eigenschaften und Methoden der Klassen NotesRichTextItem, NotesRichTextTable, NotesRichTextStyle Notes- RichTextNavigator eine E-Mail erstellt. Über die enthaltenen Kommentare können Sie die Funktion der einzelnen Programmzeilen leicht nachvollziehen. Der Empfänger der E-Mail wird im Dialog über eine InputBox vom Anwender bestimmt.

Sub Initialize
Dim se As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim rtItem As NotesRichTextItem
Dim rtStyle As NotesRichTextStyle 'Textformatierung
Dim rtnav As NotesRichTextNavigator 'Tabelle und T-zellen suchen
Dim rtt As NotesRichTextTable 'Tabelle formatieren
Dim farbe As NotesColorObject 'Farbe für Tabelle
Dim empfaenger As String
Dim datei As String
Dim zeilen As Integer, spalten As Integer
Set db = se.CurrentDatabase
'Neues Dokument erstellen
Set doc = New NotesDocument(db)
'Empfänger erfragen
empfaenger = Inputbox("Bitte geben Sie den Empfänger ein", "Senden an",
"Empfänger")
'Standardfelder setzen
Call doc.ReplaceItemValue("sendto", empfaenger)
Call doc.ReplaceItemValue("subject", "RichText-Nachricht aus LotusScript Agent")
'Feld Body erstellen
Set rtItem = New NotesRichTextItem(doc, "body")
'Schriftart Fett einstellen
Set rtStyle = se.CreateRichTextStyle
rtStyle.Bold = True
Call rtitem.AppendStyle(rtStyle)
'Text einfügen
Call rtItem.AppendText("Guten Tag")
'Schriftart Fett aufheben
rtStyle.Bold = False
'Zwei neue Zeilen einfügen
Call rtitem.AddNewline(2)
'Schriftart und -größe bestimmen, Text einfügen
'Textformate zurücksetzen, Weiteren Text ausgeben
rtstyle.FontSize = 24
rtstyle.NotesColor = 120
Call rtitem.AppendStyle(rtStyle)
Call rtitem.AppendText("Hier kommt Spam")
rtstyle.FontSize = 10
rtstyle.NotesColor = 0
Call rtitem.AppendStyle(rtStyle)
Call rtitem.AddNewline(2)
Call rtitem.AppendText("Zuerst ein Anhang")
Call rtitem.AddNewline(1)
'Anhang erstellen , weiteren Text ausgeben
datei = Dir("c:\windows\web\wallpaper\tulpen.jpg", 30)
If datei = "" Then
Msgbox "Anhang kann nicht erstellt werden"
Call rtitem.AppendText("Ohne Anhang")
Else
Call
rtitem.EmbedObject(EMBED_ATTACHMENT,"","c:\windows\web\wallpaper\tulpen.jpg")
End If
Call rtitem.AddNewline(1)
Call rtitem.AppendText("Und nun der Text in einer Tabelle:")
Call rtitem.AddNewline(1)
'Tabelle erstellen
zeilen = 2
spalten = 3
Call rtitem.AppendTable(zeilen, spalten)
'Mit Navigator auf Tabelle zugreifen
Set rtnav = rtitem.CreateNavigator
rtnav.FindFirstElement(RTELEM_TYPE_TABLE)
Set rtt = rtnav.GetElement
'Bereich für Format bestimmen - Solid = alle Zellen
rtt.Style = TABLESTYLE_SOLID
'Farbobjekt erstellen, Farbe setzen und Tabelle zuweisen
Set farbe = se.CreateColorObject
farbe.NotesColor = COLOR_RED
Call rtt.SetColor(farbe)
'Mit Navigator erste Tabellenzelle finden
rtnav.FindFirstElement(RTELEM_TYPE_TABLECELL)
'Alle Zellen durchlaufen, Text einfügen
Do
Call rtitem.BeginInsert(rtnav)
Call rtitem.AppendText("Spam...")
Call rtitem.EndInsert
Loop While rtnav.FindNextElement(RTELEM_TYPE_TABLECELL)
'Dokument senden
Call doc.Send(False)
End Sub

Wird als Empfänger der Nachricht eine EMail- Adresse innerhalb der Notes-Domäne angegeben, erhält die ausgewählte Person eine E- Mail mit den im Programmcode festgelegten Formaten (Bild 1). Bei Auswahl einer InternetMailadresse jedoch werden die Textformate komplett unterdrückt (Bild 2). Der Anhang steht am Ende der Nachricht. Der inhaltliche Bezug zur ursprünglichen Position wird nur noch über den automatisch eingefügten Linktext hergestellt. Tabellen werden zwar erkannt und übertragen, tabellenspezifische Formatierungen gehen jedoch ebenfalls verloren.

Bild 1: Die Mail mit den im Programmcode festgelegten Formaten.
Bild 2: Die Mail mit unterdrückten MIME-Formaten.

Damit Formatierungen zur Gestaltung der Nachricht genutzt werden können, muss der Standard Multipurpose Internet Mail Extensions (MIME) beim Versand verwendet werden. Wie Sie mit LotusScript MIME-Nachrichten erstellen, wird nachfolgend gezeigt.

Multipurpose Internet Mail Extensions - MIME

Multipurpose Internet Mail Extensions (MIME) ist ein Kodierstandard. Er legt den Aufbau und die Struktur sowohl von E-Mails als auch von anderen Internetnachrichten fest. Die Beschreibung des Standards erfolgte im RFC 2045 (www.ietf.org/rfc/rfc2045.txt).

Bei Nutzung des MIME-Standards ist der Versand von Nicht-Text-Dokumenten in textbasierten Übertragungssystemen möglich. Der eigentliche Inhalt der MIME-Nachricht ist reiner Text. Bilder, Audio- und Videodaten und weitere Binärdateien werden vor dem Versand kodiert und nach Empfang wieder dekodiert. Dazu werden zwischen Sender und Empfänger nicht nur die eigentlichen Daten, sondern auch Informationen hinsichtlich des Typs der Daten sowie der Kodierungsform ausgetauscht. MIME-Nachrichten verfügen für diesen Zweck über (mindestens) einen Kopf, welcher in mehreren Feldern die Daten enthält, die die Informationen beschreiben. Tabelle 1 listet die möglichen Kopffelder auf.

Tabelle 1: Die möglichen Felder von MIME-Nachrichten, die im Header aufgenommen werden können

Name

Wert

MIME-Version

Das Kopffeld gibt die MIME-Version an, für welche die Nachricht gültig ist.

Content-type

Dieses Feld beschreibt den Typ und den Untertyp der im MIME-Knoten enthaltenen Daten. Mögliche Kombinationen sind zum Beispiel:

Typ

text

image

Application

Untertyp

text/html

text/plain

gif

jpeg

pdf

msword

Eine Beschreibung der Typen findet sich u. a. unter www.iana.org/assignments/mediatypes

Content-transfer-encoding

Dieses Kopffeld beschreibt die angewandte Kodierungsmethode. Typische Angaben sind 7-bit, 8-bit, binary, quoted-printable sowie base64.

Content-ID

Das optionale Feld Content-ID ordnet dem MIME-Knoten eine eindeutige ID zu.

Content-Desription

Ebenfalls optional ist die Angabe einer Beschreibung des Knoteninhalts mittels des Feldes Content-Description.

MIME-Nachrichten können mehrere Teile in Form einer Baumstruktur enthalten. Unterhalb des obersten Knotens können sich ein bzw. mehrere Unterknoten befinden. Unterhalb davon können wiederum weitere Unterknoten angeordnet sein. Jeder dieser Knoten kann seinen eigenen Kopf besitzen, welcher die Beschreibung für die Art der Daten und die zu verwendende Form der Umwandlung enthält. Die Trennung zwischen den einzelnen Bestandteilen einer MIME- Nachricht erfolgt durch Begrenzungslinien,so genannte Boundaries.

MIME mit LotusScript nutzen

Das LotusScript-Objektmodell bietet zwei Klassen zum Umgang mit MIME-Objekten. Bereits sei der Version 5.0.2 gibt es die Klasse NotesMIMEEntity. Ein Objekt dieser Klasse steht für den MIME-Inhalt eines Dokuments. Dabei wird jeder Knoten innerhalb der MIME-Struktur von einem Objekt der Klasse NotesMIMEEntity repräsentiert. Die Klasse besitzt zehn Eigenschaften, deren Werte jeweils nur gelesen werden können.

Methoden der Klasse NotesMIMEEEntity

Die Methoden der Klasse NotesMIMEEntity können in mehrere Gruppen unterteilt werden.

Der Zugriff auf die Klasse erfolgt über ein Objektder Klassen NotesDocument oder NotesItem. Die zweite Klasse für den Umgang mit MIMEInformationen in Dokumenten ist NotesMIMEHeader. Diese Klasse existiert im LotusScript-Objektmodell seit der Version 6. Ein Objekt dieser Klasse repräsentiert den Kopf eines MIME-Dokuments.

Die Klasse besitzt die beiden Eigenschaften HeaderName und Parent. BeideWerte können nur gelesen werden. HeaderName liefert den Namen des Kopfs. Über Parent erhalten Sie die MIME-Entität mit dem Objekt der Klasse NotesMIMEHeader.

Die Methoden der Klasse ermöglichen das Lesen (GetHeaderVal, GetHeaderValAndParams und GetParamVal) und Schreiben (SetHeaderVal, SetHeaderValAndParams, SetParam- Val) der Kopfinformationen. Wie schon die Namen der Methoden andeuten, können dabei entweder nur der Inhalt, der Parameter oder beide gelesen bzw. geschrieben werden. Des Weiteren sind das Hinzufügen von Text zum Kopf mit AddValText sowie das Entfernen des Kopfs mittels der Methode(Remove) möglich.

Ein MIME-Mail erstellen

Nachdem wir uns mit den Grundlagen des MIME-Formats und den in LotusScript zu dessen Verarbeitung vorhandenen Klasen vertraut gemacht haben, können wir einen Agenten programmieren, der eine formatierte EMail in LotusScript erstellt, die sowohl beim Versand innerhalb der Notes-Domäne als auch über das Internet mit allen Formaten beim Empfänger angezeigt wird. Für die Textformatierung, die Erstellung der Tabelle sowie deren Formatierung können wir HTMLCode verwenden.

Listing 2 enthält den vollständigen Programmcode des Agenten. Im Deklarationsteil werden mehrere Variable der Klasse NotesMIMEEntity deklariert [1]. Das ist notwendig, da unsere E-Mail verschiedene Knoten (zwei Textteile und einen Anhang) enthalten soll. Für die Einbindung des Anhangs sind spezielle Kopfinformationen notwendig. Deshalb benötigen wir eine Variable der Klasse NotesMIMEHeader [2]. Die in den einzelnen Knoten aufzunehmenden Daten sollen in einem Objekt der Klasse NotesStream zwischengespeichert werden. Es wird deshalb eine Variable dieser Klasse deklariert [3].

Sub Initialize
Dim se As New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument
Dim body As NotesMimeEntity [1]
Dim text1 As NotesMimeEntity [1]
Dim text2 As NotesMimeEntity [1]
Dim anhang As NotesMimeEntity [1]
Dim header As NotesMimeHeader [2]
Dim Inhalt As NotesStream [3]
Dim empfaenger As String
se.ConvertMime = False [4]
Set db = se.CurrentDatabase
Set doc = New NotesDocument(db) [5]
empfaenger = Inputbox("Bitte geben Sie den Empfänger ein", "Senden an", "Empfänger") [5]
Call doc.ReplaceItemValue("sendto", empfaenger) [5]
Call doc.ReplaceItemValue("subject", "MIME-Nachricht aus LotusScript Agent") [5]
Set inhalt = se.CreateStream [6]
Call inhalt.WriteText({<b>Guten Tag</b><br />}) [6]
Call inhalt.WriteText({<font size = "18" color = "blue">Hier kommt Spam</font><br />}) [6]
Call inhalt.WriteText({Zuerst ein Anhang<br />}) [6]
Set body = doc.CreateMIMEEntity("body") [7]
Set text1 = body.CreateChildEntity [8]
Call text1.SetContentFromText(inhalt, "Text/html",ENC_QUOTED_PRINTABLE) [9]
Call inhalt.Truncate [9]
Set inhalt = se.CreateStream [9]
If Not inhalt.Open("C:\windows\web\wallpaper\tulpen.jpg") Then [10]
Msgbox "Datei nicht gefunden"
se.ConvertMime = True [4]
Exit Sub
End If
Set anhang = body.CreateChildEntity [11]
Set header = anhang.CreateHeader("Content-Transfer-Encoding") [12]
Call header.SetHeaderVal("binary") [12]
Set header = anhang.CreateHeader("Content-Disposition") [12]
Call header.SetHeaderVal({attachment; filename="tulpen.jpg"}) [12]
Call anhang.SetContentFromBytes(inhalt, "image/jpeg", ENC_NONE) [13]
Call anhang.EncodeContent(ENC_BASE64) [13]
Call inhalt.close [14]
Set inhalt = se.CreateStream [14]
Call inhalt.WriteText({<br />Und nun der Text: <br />}) [15]
Call inhalt.WriteText({<table bgcolor="Red">}]; [15]
Call inhalt.WriteText({<tr><td>Spam...</td><td>Spam.../td><td>Spam...</td></tr>}) [15]
Call inhalt.WriteText({<tr><td>Spam...</td><td>Spam...</td><td>Spam...</td></tr></table>})[15]
Set text2 = body.CreateChildEntity [15]
Call text2.SetContentFromText(inhalt, "Text/html",ENC_QUOTED_PRINTABLE) [15]
Call doc.Send(False) [16]
Call inhalt.Close [16]
se.ConvertMime = True [4]
End Sub

Fortsetzung MIME-Mail erstellen

Da wir mit dem MIME-Format arbeiten wollen, muss als Erstes die automatische MIMEKonvertierung ausgeschaltet werden. Nach dem Beendigen des Agenten wird diese Einstellung wieder aufgehoben [4].

Analog zum RichText-Agent wird als Nächstes das Dokument erstellt, der Empfänger vom Anwender erfragt sowie den Standardfeldern Send- To und Subject der Inhalt zugewiesen [5].

Der erste Teil der Nachricht soll formatierten Text enthalten. Dazu wird das Objekt der Klasse NotesStream instanziert und anschließend über die Methode WriteText mit dem Text in Form von HTML-Code gefüllt [6].

Im nächsten Schritt wird der oberste Knoten mit dem Namen Body der Baumstruktur mittels der Methode CreateMIMEEntity des Objekts der Klasse NotesDocument erstellt. Diesem wird entsprechend der allgemeinen Struktur einer E-Mail der Feldname Body zugewiesen [7].

Danach kann der erste Unterknoten für den ersten Textteil unterhalb des Knotens Body mit CreateChildEntity definiert werden [8]. Der Inhalt des Streams wird in den Textteil unter Angabe des Typs Text, Subtype Text/html und der Kodierungsmethode ENC_QUOTED_PRINTABLE geschrieben. Anschließend wird der Stream zurückgesetzt [9].

Der zweite Teil der Nachricht soll als Anhang die Datei tulpen.jpg enthalten. Sie wird in den Stream eingelesen. Ist die Datei nicht vorhanden, wird der Agent unter Ausgabe einer Fehlermeldung beendet [10]. Für den Anhang wird ein zweiter Unterknoten unter dem Knoten Body erstellt [11].

Zur Kennzeichnung der Daten ist es bei einer Datei notwendig, einige Kopfinformationen zu setzen. In [12] werden die MIME-Kopffelder Content- Tranfer-Encoding und Content-Disposition gesetzt. Der Inhalt des Knotens kann nun geschrieben und kodiert werden. [13]. Im Anschluss wird erneut der Stream zur Vorbereitung der Erstellung des dritten Knotens zurückgesetzt [14].

Die Definition des dritten Unterknotens, das Zusammenbauen im Stream-Objekt sowie das Schreiben des Inhalts entsprechen der Vorgehensweise des ersten Textblocks [15]. Abschließend kann das Dokument gesendet und der Stream geschlossen werden [16]. Beim Empfänger wird die E-Mail mit allen Formaten angezeigt (Bild 3).

Bild 3: Die Internet-Mail mit den im MIME-Header definierten Formatierungen.

Zusammenfassung

Durch die Nutzung der LotusScript-Klassen NotesMIMEEntity und NotesMIMEHeader in Verbindung mit HTML-Code können formatierte EMail zum Versand über Internetverbindungen aus einer Notes-Domäne heraus automatisch erstellt werden. Obwohl die Möglichkeiten dabei über die im Beispiel gezeigten Ansätze hinausgehen, vermittelt dieses doch einen ersten Eindruck der Anwendung. Die im Artikel vorgestellten Agenten werden in einer Beispieldatenbank als Download zur Verfügung gestellt.