Feedback

VB - Email über POP3 abfrufen

Veröffentlicht von am 1/24/2008
(3 Bewertungen)
Eine Klasse um Emails von einem POP3 Server zu lesen. Habe mal alles was ich so gefunden haben in einer Klasse zusammen gebaut. Es gibt bestimmt noch einiges zu verbessern aber Mails lassen sich ohne Probleme abrufen. Für konstruktive Kritik bin ich immer dankbar.


Beispielaufruf:

Dim pop As New POP3.Client
pop.Connect("pop.test.de", "xyz", "test0815")

'Liste der auf dem Server vorhanden Nachrichten abrufen
pop.GetMessageList()
Dim MessageList As New List(Of POP3.Client.MessageList)
' gibt eine List mit ID und Groesse der Mails zurück
MessageList = pop.GetMessageList()

' Hier wird z.B. die Mail mit ID Nr. 1 abgerufen
Dim m() As String = pop.GetMessage(1).Split(vbCrLf)
For i As Integer = 0 To m.Length - 1
debug.print(m(i))
Next
pop.Disconnect()

Public Class Client

    Private Client As New Net.Sockets.TcpClient
    Private POP3Stream As Net.Sockets.NetworkStream
    Private Connected As Boolean = False

    '''<summary>
    '''Verbindungssatus abfragen.
    '''</summary>
    Public ReadOnly Property ConnectionEstablished() As Boolean

        Get
            Return Connected
        End Get

    End Property

    '''<summary>
    '''Nachrichten Klasse
    '''</summary>
    Public Class MessageList

        Public ID As Int64
        Public Size As Int64

    End Class

    '''<summary>
    '''Verfügbarer POP3 Befehlssatz.
    '''</summary>
    Private Class Commands

        Public Const Delete As String = "DELE "
        Public Const GetMessage As String = "RETR "
        Public Const List As String = "LIST"
        Public Const Password As String = "PASS "
        Public Const Quit As String = "QUIT"
        Public Const ServerConfirm As String = "+OK"
        Public Const ServerNoMoreData As String = "."
        Public Const User As String = "USER "

    End Class

    '''<summary>
    '''Stellt die Verbindung zum POP3-Server her.
    '''</summary>
    '''<param name="Server">Servername (subdomain.domain.tld)</param>
    '''<param name="User">Benutzername</param>
    '''<param name="Password">Passwort</param>
    Public Sub Connect(ByVal Server As String, ByVal User As String, ByVal Password As String)

        If Connected = True Then Me.Disconnect()
        Try
            Me.Client.Connect(Server, 110)
            Me.POP3Stream = Me.Client.GetStream
            Me.CheckResponse(Me.GetResponse)
            Me.Send(Commands.User + User)
            Me.CheckResponse(Me.GetResponse)
            Me.Send(Commands.Password + Password)
            Me.CheckResponse(Me.GetResponse)
            Me.Connected = True
        Catch ex As Exception
            Me.Disconnect()
            Throw New ApplicationException(ex.Message, ex)
        End Try

    End Sub

    '''<summary>
    '''Trennt die Verbindung zum POP3-Server her.
    '''</summary>
    Public Sub Disconnect()

        If Connected = True Then
            Me.Send(Commands.Quit)
            Me.CheckResponse(Me.GetResponse())
            Me.Connected = False
            Me.Client.Close()
        End If

    End Sub

    '''<summary>
    '''Sendet POP3 Befehl zum Server.
    '''</summary>
    '''<param name="Command">POP3 Befehl</param>
    Private Sub Send(ByVal Command As String)

        Dim data As [Byte]() = Text.Encoding.ASCII.GetBytes(Command & vbCrLf)
        Me.POP3Stream.Write(data, 0, data.Length)

    End Sub

    '''<summary>
    '''Empfängt Antwort auf Send-Befehl vom Server.
    '''</summary>
    Private Function GetResponse() As String

        Dim SR As New IO.StreamReader(Me.POP3Stream)
        Dim SBuilder As New Text.StringBuilder
        Do While SR.Peek > -1
            SBuilder.Append(SR.ReadLine + vbCr)
        Loop
        Return SBuilder.ToString

    End Function

    '''<summary>
    '''Prüft ob die erhalten Antwort von GetResponse gültig ist.
    '''</summary>
    '''<param name="Response">Antort von GetResponse</param>
    Private Sub CheckResponse(ByVal Response As String)

        If Not String.Compare(Response.Substring(0, 3), Commands.ServerConfirm, False, Globalization.CultureInfo.CurrentCulture) = 0 Then
            Me.Client.Close()
            Me.Connected = False
            Throw New ApplicationException("Response " + Response + " not expected.")
        End If

    End Sub

    '''<summary>
    '''Gibt eine List(of POP3Message) der verfügbaren Nachrichten zurück.
    '''</summary>
    Public Function GetMessageList() As List(Of MessageList)

        If Me.Connected = False Then
            Throw New InvalidOperationException("Not connected!")
        End If
        Dim Pop3l As New List(Of MessageList)
        Me.Send(Commands.List)
        Dim Response() As String = Me.GetResponse.Split(vbCrLf)
        CheckResponse(Response(0))

        For i As Integer = 1 To Response.Length - 3
            Dim POP3m As New MessageList
            POP3m.ID = i
            POP3m.Size = Convert.ToInt64(Response(i).Split(" ")(1))
            Pop3l.Add(POP3m)
        Next

        Return Pop3l

    End Function

    '''<summary>
    '''Nachricht mit angebener Nummer vom Server lesen
    '''</summary>
    '''<param name="MessageID">MessageID</param>
    Public Function GetMessage(ByVal MessageID As Integer) As String

        If Me.Connected = False Then
            Throw New InvalidOperationException("Not connected!")
        End If
        Me.Send(Commands.GetMessage & MessageID)
        Me.CheckResponse(Me.GetResponse)
        Dim Response As String = Me.GetResponse
        Return Response

    End Function

End Class
Abgelegt unter POP3, Email, VB.NET.

5 Kommentare zum Snippet

Thomas Reimelt schrieb am 3/4/2008:
Das ist ein Super Snippet, aber was jetzt eigentlich noch fehlt, ist ein Snippet, dass aus dieser Email String am Ende ein Emailobjekt wie zum Beispiel das MailMessage Objekt aus dem .net framework macht. Kennt jemand das vielleicht?

Gruß

Thomas
David Struthers schrieb am 3/6/2008:
Da wart ich auch drauf :)
Jan Welker schrieb am 3/6/2008:
Vielleicht sollte ich eine Snippet-Wish-List einbauen. :-)
Volker Steitz schrieb am 3/7/2008:
Zum Thema MailMessage Objekt - mal sehen was sich machen lässt.
Aber - wozu soll das MailMessage Objekt denn verwendet werden, was soll damit gemacht werden?
Volker
Thomas Reimelt schrieb am 3/10/2008:
Hallo,

so ein Objekt gibt es schon. Ich habe es hier gefunden: http://www.lumisoft.ee/lswww/download/downloads/Net/

Dem Objekt übergibt man in der Mime.Parse Funktion die Nachricht und kann dannach beqeum damit arbeiten. Zum Beispiel direkt auf die Attachments zugreifen, den Absender auswerten usw.

Gruß

Thomas
 

Logge dich ein, um hier zu kommentieren!