vb.netemailpop3

How To Download Emails From Junk Folder Using POP3


POP Servers allow for the LIST command that returns a list of all of the emails in the mail box. Unfortunately it does not return ALL of the emails, it only returns the emails from the Inbox. So if an email lands in a junk folder it cannot find it.

Is it possible to download emails from the junk folder using POP?

This is the current class(s) that I am using:

Option Strict On
Option Explicit On
Imports System.Net, System.Text
Public Class POP3
    Inherits Sockets.TcpClient

    Dim Stream As Sockets.NetworkStream
    Dim UsesSSL As Boolean = False
    Dim SslStream As Security.SslStream
    Dim SslStreamDisposed As Boolean = False
    Public LastLineRead As String = vbNullString

    Public Overloads Sub Connect(ByVal Server As String, ByVal Username As String, ByVal Password As String, Optional ByVal InPort As Integer = 110,Optional ByVal UseSSL As Boolean = False)
        If Connected Then Disconnect()
        UsesSSL = UseSSL
        MyBase.Connect(Server, InPort)
        Stream = MyBase.GetStream
        If UsesSSL Then
            SslStream = New Security.SslStream(Stream)
            SslStream.AuthenticateAsClient(Server)
        End If

        If Not CheckResponse() Then Exit Sub

        If CBool(Len(Username)) Then
            Me.Submit("USER " & Username & vbCrLf)
            If Not CheckResponse() Then Exit Sub
        End If

        If CBool(Len(Password)) Then
            Me.Submit("PASS " & Password & vbCrLf)
            If Not CheckResponse() Then Exit Sub
        End If
    End Sub

    Public Function CheckResponse() As Boolean
        If Not IsConnected() Then Return False
        LastLineRead = Me.Response
        If (Left(LastLineRead, 3) <> "+OK") Then
            Throw New POP3Exception(LastLineRead)
            Return False
        End If
        Return True
    End Function

    Public Function IsConnected() As Boolean
        If Not Connected Then
            Throw New POP3Exception("Not Connected to an POP3 Server.")
            Return False
        End If
        Return True
    End Function


    Public Function Response(Optional ByVal dataSize As Integer = 1) As String
        Dim enc As New ASCIIEncoding
        Dim ServerBufr() As Byte
        Dim Index As Integer = 0
        If dataSize > 1 Then

            ReDim ServerBufr(dataSize - 1)
            Dim dtsz As Integer = dataSize
            Dim sz As Integer
            Do While Index < dataSize
                If UsesSSL Then
                    sz = SslStream.Read(ServerBufr, Index, dtsz)
                Else
                    sz = Stream.Read(ServerBufr, Index, dtsz)
                End If
                If sz = 0 Then Return vbNullString
                Index += sz
                dtsz -= sz
            Loop
        Else
            ReDim ServerBufr(255)
            Do
                If UsesSSL Then
                    ServerBufr(Index) = CByte(SslStream.ReadByte)
                Else
                    ServerBufr(Index) = CByte(Stream.ReadByte)
                End If
                If ServerBufr(Index) = -1 Then Exit Do
                Index += 1
                If ServerBufr(Index - 1) = 10 Then Exit Do
                If Index > UBound(ServerBufr) Then
                    ReDim Preserve ServerBufr(Index + 255)
                End If
            Loop
        End If
        Return enc.GetString(ServerBufr, 0, Index)
    End Function

    Public Sub Submit(ByVal message As String)
        Dim enc As New ASCIIEncoding
        Dim WriteBuffer() As Byte = enc.GetBytes(message)
        If UsesSSL Then
            SslStream.Write(WriteBuffer, 0, WriteBuffer.Length)
        Else
            Stream.Write(WriteBuffer, 0, WriteBuffer.Length)
        End If
    End Sub

    Public Sub Disconnect()
        Me.Submit("QUIT" & vbCrLf)
        CheckResponse()
        If UsesSSL Then
            SslStream.Dispose()
            SslStreamDisposed = True
        End If
    End Sub

    '*******************************************************************************
    ' Function Name : List
    ' Purpose       : Get the drop listing from the maildrop
    '               :
    ' Returns       : Any Arraylist of POP3Message objects
    '               :
    ' Typical telNet I/O:
    'LIST            (submit)
    '+OK Mailbox scan listing follows
    '1 2532          (record index and size in bytes)
    '2 1610
    '3 12345
    '.               (end of records terminator)
    '*******************************************************************************
    Public Function List() As ArrayList
        If Not IsConnected() Then Return Nothing 'exit if not in TRANSACTION mode

        Me.Submit("LIST" & vbCrLf)                          'submit List request
        If Not CheckResponse() Then Return Nothing 'check for a response, but if an error, return nothing
        '
        'get a list of emails waiting on the server for the authenticated user
        '
        Dim retval As New ArrayList                         'set aside message list storage
        Do
            Dim response As String = Me.Response            'check response
            If (response = "." & vbCrLf) Then               'done with list?
                Exit Do                                     'yes
            End If
            Dim msg As New POP3Message                      'establish a new message
            Dim msgInfo() As String = Split(response, " "c) 'separate by spaces, which divide its fields
            msg.MailID = Integer.Parse(msgInfo(0))          'get the list item number
            msg.ByteCount = Integer.Parse(msgInfo(1))           'get the size of the email message
            msg.Retrieved = False                           'indicate its message body is not yet retreived
            retval.Add(msg)                                 'add a new entry into the retrieval list
        Loop
        Return retval                                       'return the list
    End Function


    Public Function GetHeader(ByRef msg As POP3Message, Optional ByVal BodyLines As Integer = 0) As POP3Message
        If Not IsConnected() Then Return Nothing
        Me.Submit("TOP " & msg.MailID.ToString & " " & BodyLines.ToString & vbCrLf)
        If Not CheckResponse() Then Return Nothing
        msg.Message = vbNullString
        Do
            Dim response As String = Me.Response
            If response = "." & vbCrLf Then
                Exit Do
            End If
            msg.Message &= response
        Loop
        Return msg
    End Function

    Public Function Retrieve(ByRef msg As POP3Message) As POP3Message
        If Not IsConnected() Then Return Nothing
        Me.Submit("RETR " & msg.MailID.ToString & vbCrLf)
        If Not CheckResponse() Then Return Nothing
        msg.Message = Me.Response(msg.ByteCount)
        Do
            Dim S As String = Response()
            If S = "." & vbCrLf Then
                Exit Do
            End If
            msg.Message &= S
        Loop
        msg.ByteCount = Len(msg.Message)
        Return msg
    End Function

    Public Sub Delete(ByVal msgHdr As POP3Message)
        If Not IsConnected() Then Exit Sub
        Me.Submit("DELE " & msgHdr.MailID.ToString & vbCrLf)
        CheckResponse()
    End Sub

    Public Sub Reset()
        If Not IsConnected() Then Exit Sub
        Me.Submit("RSET" & vbCrLf)
        CheckResponse()
    End Sub

    Public Function NOOP() As Boolean
        If Not IsConnected() Then Return False
        Me.Submit("NOOP")
        Return CheckResponse()
    End Function

    Protected Overrides Sub Finalize()
        If Not SslStreamDisposed Then
            SslStream.Dispose()
        End If
        MyBase.Finalize()
    End Sub
End Class

Public Class POP3Message
    Public MailID As Integer = 0
    Public ByteCount As Integer = 0
    Public Retrieved As Boolean = False
    Public Message As String = vbNullString

    Public Overrides Function ToString() As String
        Return Message
    End Function
End Class

Public Class POP3Exception
    Inherits ApplicationException

    Public Sub New(ByVal str As String)
        MyBase.New(str)
    End Sub
End Class

Solution

  • As per the comments, the POP3 standard only allows for downloading from the "Inbox". It's not designed for anything more advanced.

    The ideal solution would be to use IMAP4, if the mail server supports it.

    IMAP4 allows you to save, flag, copy and delete messages, as well as allowing folders and subfolders and it does not require exclusive access.