VB.NET - Mit Lotus Notes E-Mails versenden

Vor etwas mehr als zwei Jahre (wie die Zeit vergeht :-() habe ich hier einen Artikel namens "VB .NET - Mit Lotus Notes E-Mails und Dateianhängen arbeiten" veröffentlicht, der beschreibt, wie man mit Lotus Notes E-Mails aus der Inbox arbeiten kann.

Heute musste ich nun etwas ähnliches bewerkstellen, und zwar E-Mails über unseren Domino Server versenden. Im Prinzip benötigt man dazu keine COM-Verweis auf das Domino Mail Objekt, da man (sofern SMTP auf dem Domino Server freigegegeben ist) das ganze auch schön mit .NET Bordmitteln, sprich Net.Mail.MailMessage usw. lösen kann.

Doch wir wollten auch Faxe über Lotus Notes versenden, und dazu benötigt der Domino Server eine Authentifizierung, was man theoretisch über die .NET Credentials lösen könnte. Leider bekam ich beim Faxversenden immer wieder den Fehler, dass die Benutzerrechte nicht korrekt sein.

Laut Rechereche im Internet hat das auch noch keiner hinbekommen, also blieb mir nichts anderes übrig, als wieder auf das Domino COM-Objekt zu verweisen und damit zu arbeiten.

Herausgekommen dabei sind einige Klassen, mit denen man relativ einfach E-Mails und Faxe über den Server verschicken kann.

Zuerst einmal die Helfer-Klassen:

Hier die Anhangs-Klasse für Dateianhänge:

Public Class LotusNotesMailAttachment
 
  Public FullFilename As String
  Public DisplayName As String
 
  Public Sub New()
  End Sub
 
  Public Sub New(ByVal aFullFilename As String)
    Me.FullFilename = aFullFilename
  End Sub
 
  Public Sub New(ByVal aFullFilename As String, ByVal aDisplayName As String)
    Me.FullFilename = aFullFilename
    Me.Displayname = aDisplayName
  End Sub
 
End Class

Die Liste der Anhänge:

Public Class LotusNotesMailAttachmentList
 
  Inherits List(Of LotusNotesMailAttachment)
 
End Class

Die Klase LotusNotesMailData enthält einfach nur Absender, Empfänger, Betreff usw.
Diese Daten werden später an die Factory zum Versenden weitergereicht.

Public Class LotusNotesMailData
 
  Public Subject As String
 
  Private _To As List(Of String)
  Public Property [To]() As List(Of String)
    Get
      If _To Is Nothing Then
        _To = New List(Of String)
      End If
      Return _To
    End Get
    Set(ByVal value As List(Of String))
      _To = value
    End Set
  End Property
 
  Public From As String
 
  Private _CC As List(Of String)
  Public Property CC() As List(Of String)
    Get
      If _CC Is Nothing Then
        _CC = New List(Of String)
      End If
      Return _CC
    End Get
    Set(ByVal value As List(Of String))
      _CC = value
    End Set
  End Property
  Public Body As String
 
  Private _Attachments As LotusNotesMailAttachmentList
  Public Property Attachments() As LotusNotesMailAttachmentList
    Get
      If _Attachments Is Nothing Then
        _Attachments = New LotusNotesMailAttachmentList
      End If
      Return _Attachments
    End Get
    Set(ByVal value As LotusNotesMailAttachmentList)
      _Attachments = value
    End Set
  End Property
 
End Class

Die folgende Klasse "MailAccount" beinhaltet einfach die "Login-Daten" für den Domino-Server und Infos über das Postfach, das zum Senden verwendet werden soll.

Klasse Mailaccount:

Public Class MailAccount
 
  ''' <summary>
  ''' Hostname of the Domino Server
  ''' </summary>
  ''' <remarks></remarks>
  Public Host As String
 
  ''' <summary>
  ''' Filename with Path of the Notes Mail File
  ''' </summary>
  ''' <remarks>e.g. 'mail\user.nsf'</remarks>
  Public DatabaseFilename As String
 
  Public Password As String
 
  Public Sub New()
  End Sub
 
  Public Sub New(ByVal aHost As String, ByVal aDatabaseFilename As String, ByVal aPassword As String)
    Me.Host = aHost
    Me.DatabaseFilename = aDatabaseFilename
    Me.Password = aPassword
  End Sub
 
End Class

Hier nun meine Notes Factory, die das eigentliche Versenden der E-Mails und Faxe bewerkstelligt. Faxe werden dabei wie E-Mails gehandhabt. Bei unserer Fax-Software für Domino (Ferrari-Fax (übrigens sehr zu empfehlen)) wird statt der E-Mail Adresse einfach die Faxnummer mit dem Zusatz "@Fax" angegeben. Die Faxsoftware wandelt daraufhin alle Anhänge in TIFF um und sendet diese als Fax an den/die Empfänger.

Man erhält zudem das versendete Fax in Form einer E-Mail im "Gesendet" Ordner von Lotus Notes.

Public Class LotusNotesMailFactory
 
  Public Shared Function SendMail(ByVal aMailAccount As MailAccount, ByVal aMaildata As LotusNotesMailData) As Boolean
 
    ' Die Session starten
    Dim Session As New Domino.NotesSession
    Session.Initialize(aMailAccount.Password)
 
    ' Datenbank öffnen
    Dim MailDB As Domino.NotesDatabase
    Dim MailServer As String = Session.GetEnvironmentString("MailServer", True)
    MailDB = Session.GetDatabase(MailServer, aMailAccount.DatabaseFilename)
 
    If Not MailDB.IsOpen Then
      MailDB.Open()
    End If
 
    Dim MailDoc As Domino.NotesDocument = MailDB.CreateDocument
    Dim Body As Domino.NotesRichTextItem = MailDoc.CreateRichTextItem("Body")
 
    MailDoc.ReplaceItemValue("Form", "Memo")
 
    For Each toadr As String In aMaildata.To
      MailDoc.ReplaceItemValue("SendTo", toadr)
      'MailDoc.AppendItemValue("SendTo", aMaildata.To)
    Next
 
    MailDoc.ReplaceItemValue("Subject", aMaildata.Subject)
    'MailDoc.AppendItemValue("Subject", aMaildata.Subject)

    ' CC (Carbon Copy)
    For Each ccadr As String In aMaildata.CC
      MailDoc.AppendItemValue("CopyTo", ccadr)
    Next
 
    ' Create and set the Body content
    Body.AppendText(String.Empty)
    Body.AppendText(aMaildata.Body)
 
    ' Attachment
    For Each lnma As LotusNotesMailAttachment In aMaildata.Attachments
      Body.AddNewLine(2)
      Body.EmbedObject(1454, String.Empty, lnma.FullFilename, lnma.DisplayName)
    Next
 
    ' Example to save the message (optional)
    MailDoc.SaveMessageOnSend = True
 
    ' Send the document
    ' Gets the mail to appear in the Sent items folder
    MailDoc.ReplaceItemValue("PostedDate", Now)
    MailDoc.Send(False)
 
    ' Clean Up
    MailDB = Nothing
    MailDoc = Nothing
    Body = Nothing
    Session = Nothing
 
    Return True
 
  End Function
 
End Class

Wer Verbesserungen hat, oder gar weiß, wie man über die .NET Bordmittel das ganze bewerkstellingen kann, ist herzlich eingeladen, zu kommentieren.

Sollte ich dazukommen, werde ich das ganze noch etwas besser dokumentieren, aufräumen und verbessern.

Herald

Herald ist ein kleines Tool für Apple's Mail Programm. Herald zeigt eingehende E-Mails in einem netten Vorschaufenster auf dem Desktop an. Der Autor Erik Hinterbichler vertreibt das Programm kostenlos.

Das einzig blöde ist, dass es Mac OS X 10.6 oder höher voraussetzt, aber das kostet ja nur 29,- Euro ;-)

VB .NET - E-Mails mit Indy empfangen und Anhänge abspeichern

Um in VB .NET E-Mails zu versenden, verwendet man am besten den Namespace Net.Mail.

Leider gibt es in VB .NET allerdings noch keine Möglichkeit, E-Mails zu empfangen um beispielsweise die Dateianhänge abzuspeichern.

Um dieses Problem zu beseitigen, zeige ich im Folgenden, wie man mit Hilfe von Indy eine E-Mail von einem POP3 Postfach herunterlädt und eventuelle Anhänge der E-Mails auf dem Dateisystem abspeichert.

Wichtig, zur Verwendung von Indy muss als Referenz die Indy.Sockets und Mono.Security DLL in das Projekt eingebunden werden.

Zu erst einmal eine kleine Hilfsklasse, in der wir die Konten-Informationen unseres POP3 Kontos ablegen:

Public Class MailAccount
 
  ''' <summary>
  ''' Hostname des E-Mail Servers
  ''' </summary>
  ''' <remarks></remarks>
  Public Host As String
 
  ''' <summary>
  ''' Benutzername des E-Mail Kontos
  ''' </summary>
  ''' <remarks></remarks>
  Public Username As String
 
  ''' <summary>
  ''' Benutzer-Passwort des E-Mail Kontos
  ''' </summary>
  ''' <remarks></remarks>
  Public Password As String
 
End Class

Nun der interessantere Teil. Die Methode SaveAllAttachments speichert vom übergebenen Mailkonto alle Anhänge aller E-Mails temporär auf der Festplatte lokal ab.

Hierfür verbinden wir uns erst mit dem Mailkonto, ermitteln dann die Menge aller E-Mails auf dem Postfach und iterieren dann durch jede einzelne E-Mail.

Eine E-Mail besteht aus mehreren sogenannten Messageparts. Ist ein Messagepart vom Typ Octet-Stream, handelt es sich um einen Dateianhang, den wir ja abspeichern wollen.

Public Class IndyTools
 
  ''' <summary>
  ''' Speichert alle Dateianhänge des Postfachs aAccount im Verzeichnis
  ''' </summary>
  ''' <param name="aAccount">Postfach Konto</param>
  ''' <remarks></remarks>
  Public Sub SaveAllAttachments(ByVal aAccount As MailAccount)
 
    Dim tempfilename As String
    Dim IsAttachment As Boolean
 
    Dim o As NewIndy.Sockets.TIdNetNativeComponent
    Dim p As NewIndy.Sockets.POP3(o)
    Dim att As Indy.Sockets.Attachment
 
    ' Verbindungsdaten an Indy übergeben
    With p
      .Host = aAccount.Host
      .Username = aAccount.Username
      .Password = aAccount.Password
    End With
 
    Try
 
      Try
        ' Verbinden und Mailmenge feststellen
        p.Connect()
 
        ' Anzahl der Mails auf dem Postfach ermitteln
        Dim Amount As Integer = p.CheckMessages
 
        ' Für alle Mails
        For i As Integer = 1 To Amount
 
          ' Mail abholen
          Dim msg As New Indy.Sockets.Message
          p.Retrieve(i, msg)
 
          ' Für jeden Messagepart
          For x As Integer = 1 To msg.MessageParts.Count - 1
 
            ' Ist dieser Messagepart ein Anhang?
            IsAttachment = msg.MessageParts.Items(x).ContentType = "application/octet-stream"
 
            If IsAttachment Then
 
              Try
                ' Anhang holen
                att = msg.MessageParts.Items(x)
 
                ' Anhang temporär speichern
                tempfilename = System.IO.Path.GetTempFileName
                att.SaveToFile(tempfilename)
 
              Catchex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)
              End Try
 
            End If
 
          Next
 
        Next
 
      Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)
      End Try
 
    Finally
      p.Disconnect()
      p.Dispose()
    End Try
 
  End Sub
 
End Class

Hier noch ein Modul mit einem kleinen Beispielaufruf obiger Klassen:

Module modTest
 
  Sub Main()
    Dim it As New IndyTools
    Dim ac As New MailAccount
 
    ac.Username = "frank.miller@gmx.net"
    ac.Password = "BestMovie300"
    ac.Host = "pop.gmx.de"
 
    it.SaveAllAttachments(ac)
  End Sub
 
End Module

Mail verschwunden

Wenn man von einem Kollegen gefragt wird, weshalb die E-Mail, die man gerade eben erhalten hat, plötzlich nicht mehr auffindbar ist, sollte man erstmal vorsichtig mit übereilten Vermutungen sein.

Klar, man prüft, ob die fragliche E-Mail nicht versehentlich in einen anderen Ordner verschoben oder als gelesen markiert wurde und das Mail Programm nur die ungelesenen Mails anzeigt.

Aber dass die Mail dann banalerweise schlicht und einfach gelöscht wurde, das ist schon etwas zu simpel um gleich drauf zu kommen.

Wobei, wenn man überlegt, dass die Entfernen und die Einfügen Taste (welche in Lotus Notes für das Markieren von E-Mails (gelesen/ungelesen) zuständig ist) ziemlich nah beieinander sind, dann wundert auch das nicht mehr.

Mozilla Thunderbird 2 - Erster Release Candidate verfuegbar

Mozilla Thunderbird

Seit gestern gibt es den ersten Release Candidate des neuen Mozilla Thunderbird offiziell zum Download. Was sich seit der letzten Beta so alles getan hat, kann man in den Release Notes bestaunen.

Hier eine kurze Zusammenfassung:

  • Mails können mit individuellen Tags versehen werden
  • Vor und Zurück Schaltflächen ermöglichen eine datum-basierte Navigation durch E-Mails
  • Neue Ordner-Ansicht: Ungelesene Mails, Favoriten, Letzte Ordner