diff --git a/GUIs.Test.TestGUI/frmEmail.vb b/GUIs.Test.TestGUI/frmEmail.vb
index af9c10d4..26568cf3 100644
--- a/GUIs.Test.TestGUI/frmEmail.vb
+++ b/GUIs.Test.TestGUI/frmEmail.vb
@@ -7,28 +7,34 @@ Public Class frmEmail
Private Email As Email2
Private Sub frmEmail_Load(sender As Object, e As EventArgs) Handles Me.Load
- Logconfig = New LogConfig(LogConfig.PathType.Temp)
+ Logconfig = New LogConfig(LogConfig.PathType.Temp, ProductName:="TestGUI.IMAP")
+ Logconfig.Debug = True
Email = New Email2(Logconfig)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
- Dim oResult = Email.Test_Login(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS)
+ Using oClient = Email.New_IMAPConnection(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL)
+ Dim oResult = Email.Test_IMAPLogin(oClient, "Inbox")
- If oResult = True Then
- AddLog($"Connection to {txtServer.Text} successful.")
- Else
- AddLog($"Connection to {txtServer.Text} failed!")
- End If
+ If oResult = True Then
+ AddLog($"Connection to {txtServer.Text} successful.")
+ Else
+ AddLog($"Connection to {txtServer.Text} failed!")
+ End If
+ End Using
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
- Dim oMessages = Email.Get_Messages(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS, "Inbox")
- AddLog($"Found {oMessages.Count} Messages!")
- For Each oMessage In oMessages
- AddLog(oMessage.MessageID)
- Next
+ Using oClient = Email.New_IMAPConnection(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL)
+ Dim oMessages = Email.Get_IMAPMessages(oClient, "Inbox")
+ AddLog($"Found {oMessages.Count} Messages!")
+
+ For Each oMessage In oMessages
+ AddLog(oMessage.MessageID)
+ Next
+ End Using
End Sub
Private Sub AddLog(pMessage)
@@ -36,22 +42,24 @@ Public Class frmEmail
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
- Dim oMessageId As String = txtMessageID.Text
- Dim oMail As IMail = Email.Get_Message(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS, oMessageId, "Inbox")
- Dim oFilename As String = IO.Path.GetTempFileName
- oMail.Save(oFilename)
+ Using oClient = Email.New_IMAPConnection(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL)
+ Dim oMessageId As String = txtMessageID.Text
+ Dim oMail As IMail = Email.Get_IMAPMessage(oClient, oMessageId, "Inbox")
+ Dim oFilename As String = IO.Path.GetTempFileName
+ oMail.Save(oFilename)
- AddLog($"Mail saved to {oFilename}")
+ AddLog($"Mail saved to {oFilename}")
- Dim oEmailTempPath = Email.Remove_AttachmentsFromEmail(oFilename)
+ Dim oEmailTempPath = Email.Remove_AttachmentsFromEmail(oFilename)
- AddLog($"Mail without attachments saved to {oEmailTempPath}")
+ AddLog($"Mail without attachments saved to {oEmailTempPath}")
- Dim oAttachments As List(Of String) = Email.Save_AttachmentsToDisk(oFilename)
+ Dim oAttachments As List(Of String) = Email.Save_AttachmentsToDisk(oFilename)
- For Each oAttachment In oAttachments
- AddLog($"Attachmen saved to {oAttachment}")
- Next
+ For Each oAttachment In oAttachments
+ AddLog($"Attachmen saved to {oAttachment}")
+ Next
+ End Using
End Sub
Private Sub ListBox1_SelectedValueChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedValueChanged
diff --git a/Modules.Messaging/Email2.vb b/Modules.Messaging/Email2.vb
index 6a29ccb9..f3bc043d 100644
--- a/Modules.Messaging/Email2.vb
+++ b/Modules.Messaging/Email2.vb
@@ -1,168 +1,238 @@
-Imports DigitalData.Modules.Logging
+Imports System.IO
+Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Imports Limilabs.Mail
-Imports Limilabs.Client.IMAP
Imports Limilabs.Mail.MIME
-Imports System.IO
Imports Limilabs.Mail.MSG
+Imports Limilabs.Client.IMAP
+Imports Limilabs.Client.SMTP
+Imports Limilabs.Client
Public Class Email2
Private ReadOnly Logger As Logger
+ Private ReadOnly LoggerMail As Logger
Private ReadOnly LogConfig As LogConfig
Private ReadOnly FileEx As Filesystem.File
Private ReadOnly MailBuilder As New MailBuilder()
+ Private DisableExcessiveLogging As Boolean = False
+
Public Sub New(pLogConfig As LogConfig)
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger()
+ LoggerMail = pLogConfig.GetLogger("Limilabs.Mail")
FileEx = New Filesystem.File(pLogConfig)
+
+ ' Turn on internal Mail.dll logging
+ Limilabs.Mail.Log.Enabled = True
+
+ AddHandler Limilabs.Mail.Log.WriteLine, AddressOf ProcessMailLog
End Sub
Public Enum EmailSecurity
- SSLTLS
- STARTTLS
+ SSL
+ START_TLS
End Enum
- Private Function Get_PortForSecurityOption(pSecurity As EmailSecurity) As Integer
- If pSecurity = EmailSecurity.STARTTLS Then
- Return 143
- Else ' EmailSecurity.SSL
- Return 993
+ Private Sub ProcessMailLog(pMessage As String)
+ If DisableExcessiveLogging = False Then
+ LoggerMail.Debug(pMessage)
End If
- End Function
+ End Sub
- Private Function New_Connection(pIMAP As Imap, pServer As String, pUsername As String, pPassword As String, pPort As Integer, pSecurity As EmailSecurity) As Boolean
+ Public Function New_SMTPConnection(pSMTP As Smtp, pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pPort As Integer = 0) As Smtp
Try
- Logger.Debug("Connecting to IMAP server [{0}]", pServer)
+ Logger.Info("Connecting to SMTP server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
+
+ Dim oPort As Integer
+ If pPort = 0 Then
+ If pSecurity = EmailSecurity.SSL Then
+ oPort = Smtp.DefaultSSLPort
+
+ Else
+ oPort = Smtp.DefaultPort
+
+ End If
+
+ Else
+ oPort = pPort
- Dim oPort As Integer = pPort
- If oPort = 0 Then
- oPort = Get_PortForSecurityOption(pSecurity)
End If
Logger.Debug("Using Port [{0}] for connection", oPort)
- If pSecurity = EmailSecurity.STARTTLS Then
- Logger.Debug("Using STARTTLS as Security Option")
- pIMAP.Connect(pServer, oPort)
- pIMAP.StartTLS()
- Else
+ If pSecurity = EmailSecurity.SSL Then
Logger.Debug("Using SSL/TLS as Security Option")
- pIMAP.ConnectSSL(pServer, oPort)
+ pSMTP.ConnectSSL(pServer, oPort)
+ Else
+ Logger.Debug("Using STARTTLS as Security Option")
+ pSMTP.Connect(pServer, oPort)
+ pSMTP.StartTLS()
End If
- Logger.Debug("Connection to IMAP Server [{0}] established!", pServer)
+ Logger.Debug("Connection to SMTP Server [{0}] established!", pServer)
Logger.Debug("Logging in with user [{0}]", pUsername)
- pIMAP.UseBestLogin(pUsername, pPassword)
+ pSMTP.UseBestLogin(pUsername, pPassword)
- Return True
+ Return pSMTP
Catch ex As Exception
Logger.Warn("Could not connect to server [{0}] with user [{1}]", pServer, pUsername)
Logger.Error(ex)
- Return False
+ Return pSMTP
End Try
End Function
- Public Function Test_Login(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As Boolean
- Logger.Debug("Testing Login to Server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
-
+ Public Function New_IMAPConnection(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pPort As Integer = 0) As Imap
Try
- Using oClient As New Imap()
- If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
- Logger.Debug("Fetching Inbox")
- Dim oStatus As FolderStatus = oClient.SelectInbox()
+ Logger.Info("Connecting to IMAP server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
- Logger.Debug("Test finished!")
- oClient.Close()
+ Dim oIMAP As New Imap()
+ Dim oPort As Integer
+ If pPort = 0 Then
+ If pSecurity = EmailSecurity.SSL Then
+ oPort = Imap.DefaultSSLPort
+
+ Else
+ oPort = Imap.DefaultPort
End If
- End Using
+ Else
+ oPort = pPort
+
+ End If
+ Logger.Debug("Using Port [{0}] for connection", oPort)
+
+ If pSecurity = EmailSecurity.SSL Then
+ Logger.Debug("Using SSL/TLS as Security Option")
+ oIMAP.ConnectSSL(pServer, oPort)
+ Else
+ Logger.Debug("Using STARTTLS as Security Option")
+ oIMAP.Connect(pServer, oPort)
+ oIMAP.StartTLS()
+ End If
+ Logger.Debug("Connection to IMAP Server [{0}] established!", pServer)
+
+ Logger.Debug("Logging in with user [{0}]", pUsername)
+ oIMAP.UseBestLogin(pUsername, pPassword)
+
+ Return oIMAP
+
+ Catch ex As Exception
+ Logger.Warn("Could not connect to server [{0}] with user [{1}]", pServer, pUsername)
+ Logger.Error(ex)
+ Throw ex
+
+ End Try
+ End Function
+
+ Public Function Test_IMAPLogin(pClient As Imap, Optional pFolder As String = "Inbox") As Boolean
+ Logger.Info("Testing Login to IMAP Server")
+
+ Try
+ Logger.Debug("Fetching Inbox")
+ Dim oStatus As FolderStatus = pClient.SelectInbox()
+
+ Logger.Debug("Test succeeded!")
Return True
Catch ex As Exception
- Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
+ Logger.Warn("Login failed for IMAP server!")
Logger.Error(ex)
Return False
End Try
End Function
- Public Function Get_Messages(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As List(Of IMail)
- Logger.Debug("Fetching Messages from Server [{0}:{1}] with user [{2}]", pServer, pPort, pUsername)
+ Public Function Test_SMTPLogin(pClient As Smtp) As Boolean
+ Logger.Info("Testing Login to IMAP Server")
+ Try
+ Dim oExtensions = pClient.SupportedExtensions()
+ Dim oExtensionArray = oExtensions.Select(Function(ex) ex.ToString).ToArray
+ Logger.Debug("Supported Extensions: ")
+ Logger.Debug(String.Join(", ", oExtensionArray))
+ Logger.Debug("Test succeeded!")
+
+ Return True
+ Catch ex As Exception
+ Logger.Warn("Login failed for SMTP server!")
+ Logger.Error(ex)
+
+ Return False
+ End Try
+ End Function
+
+ Public Function Get_IMAPMessages(pClient As Imap, Optional pFolder As String = "Inbox") As List(Of IMail)
+ Logger.Info("Fetching Messages in Folder [{0}]", pFolder)
Dim oMails As New List(Of IMail)
Try
- Using oClient As New Imap()
- If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
- Logger.Debug("Fetching Folder [{0}]", pFolder)
- Dim oStatus As FolderStatus = oClient.Select(pFolder)
+ Logger.Debug("Fetching Folder [{0}]", pFolder)
+ Dim oStatus As FolderStatus = pClient.Select(pFolder)
- Logger.Debug("Fetching Unseen UUIDs")
- Dim oUUIDs As List(Of Long) = oClient.Search(Flag.Unseen)
- Dim oMailBuilder As New MailBuilder()
+ Logger.Debug("Fetching Unseen UUIDs")
- Logger.Debug("Fetching Unseen Mails")
- For Each oUUID As Long In oUUIDs
- Dim oEmlFile As Byte() = oClient.GetMessageByUID(oUUID)
- Dim oEmail As IMail = oMailBuilder.CreateFromEml(oEmlFile)
- oMails.Add(oEmail)
+ DisableExcessiveLogging = True
+ Dim oUUIDs As List(Of Long) = pClient.Search(Flag.Unseen)
+ DisableExcessiveLogging = False
- Next
+ Logger.Debug("Fetching Unseen Mails")
+ For Each oUUID As Long In oUUIDs
+ DisableExcessiveLogging = True
+ Dim oEmlFile As Byte() = pClient.GetMessageByUID(oUUID)
+ DisableExcessiveLogging = False
- Logger.Debug("Emails fetched!")
- oClient.Close()
+ Dim oEmail As IMail = MailBuilder.CreateFromEml(oEmlFile)
+ oMails.Add(oEmail)
- End If
+ Next
- End Using
+ Logger.Debug("Emails fetched!")
Return oMails
Catch ex As Exception
- Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
+ Logger.Warn("Fetching messages for folder [{0}] failed!", pFolder)
Logger.Error(ex)
Return New List(Of IMail)
End Try
End Function
- Public Function Get_Message(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, pMessageId As String, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As IMail
- Logger.Debug("Fetching Message [{0}] from Server [{1}:{2}] with user [{3}]", pMessageId, pServer, pPort, pUsername)
+ Public Function Get_IMAPMessage(pClient As Imap, pMessageId As String, Optional pFolder As String = "Inbox") As IMail
+ Logger.Info("Fetching Message [{0}]", pMessageId)
Dim oMail As IMail = Nothing
Try
- Using oClient As New Imap()
- If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then
- Logger.Debug("Fetching Folder [{0}]", pFolder)
- Dim oStatus As FolderStatus = oClient.Select(pFolder)
+ Logger.Debug("Fetching Folder [{0}]", pFolder)
+ Dim oStatus As FolderStatus = pClient.Select(pFolder)
- Logger.Debug("Fetching UUIDs")
- Dim oUUIDs As List(Of Long) = oClient.Search(Flag.All)
- Logger.Debug("Fetching Mails")
- Dim oInfos As List(Of MessageInfo) = oClient.GetMessageInfoByUID(oUUIDs)
+ Logger.Debug("Fetching UUIDs")
+ Dim oUUIDs As List(Of Long) = pClient.Search(Flag.All)
+ Logger.Debug("Fetching Mails")
- Dim oMailInfo = oInfos.Where(Function(i) i.Envelope.MessageID = pMessageId).FirstOrDefault()
+ DisableExcessiveLogging = True
+ Dim oInfos As List(Of MessageInfo) = pClient.GetMessageInfoByUID(oUUIDs)
+ DisableExcessiveLogging = False
- If oMailInfo IsNot Nothing Then
- Dim oMailData As Byte() = oClient.GetMessageByUID(oMailInfo.UID)
- oMail = MailBuilder.CreateFromEml(oMailData)
- End If
+ Dim oMailInfo = oInfos.Where(Function(i) i.Envelope.MessageID = pMessageId).FirstOrDefault()
- Logger.Debug("Emails fetched!")
- oClient.Close()
+ If oMailInfo IsNot Nothing Then
+ DisableExcessiveLogging = True
+ Dim oMailData As Byte() = pClient.GetMessageByUID(oMailInfo.UID)
+ DisableExcessiveLogging = False
+ oMail = MailBuilder.CreateFromEml(oMailData)
+ End If
- End If
-
- End Using
+ Logger.Debug("Email fetched!")
Return oMail
Catch ex As Exception
- Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername)
+ Logger.Warn("Fetching message with MessageID [{0}] failed!", pMessageId)
Logger.Error(ex)
Return Nothing
@@ -170,15 +240,54 @@ Public Class Email2
End Try
End Function
+ Public Function Send_SMTPMessage(pClient As Smtp, pSender As String, pReceiver As String, pSubject As String, pBody As String) As Boolean
+ Logger.Info("Sending Message with Subject [{0}]", pSubject)
+
+ Try
+ Dim oBuilder As New MailBuilder()
+ oBuilder.From.Add(New Headers.MailBox(pSender))
+ oBuilder.To.Add(New Headers.MailBox(pReceiver))
+ oBuilder.Subject = pSubject
+ oBuilder.Text = pBody
+
+ Dim oMail As IMail = oBuilder.Create()
+ Dim oResult As ISendMessageResult = pClient.SendMessage(oMail)
+
+ If oResult.Status = SendMessageStatus.Success Then
+ Logger.Debug("Message sent successful!")
+ Return True
+
+ Else
+ Logger.Warn("Message sending failed. Status: [{0}]", oResult.Status)
+ Return False
+
+ End If
+
+ Catch ex As Exception
+ Logger.Warn("Message sending failed.")
+ Logger.Error(ex)
+ Return False
+
+ End Try
+ End Function
+
+ '''
+ ''' Removes all attachments from an EML file and saves it to a temporary file.
+ '''
+ ''' The EML file to process.
+ ''' The optional suffix to add to the original filename.
+ ''' The path of the new EML without attachments.
Public Function Remove_AttachmentsFromEmail(pFileName As String, Optional pSuffix As String = "") As String
Try
- Dim oTempFileName As String = Path.Combine(Path.GetTempPath(), AddFilenameSuffix(pFileName, pSuffix))
+ Dim oTempPath As String = Path.Combine(Path.GetTempPath(), Add_FilenameSuffix(pFileName, pSuffix))
+ Dim oCleanedPath As String = FileEx.GetCleanFilename(oTempPath)
+ Dim oVersionedPath As String = FileEx.GetVersionedFilename(oCleanedPath)
Dim oMail = MailBuilder.CreateFromEmlFile(pFileName)
oMail.RemoveAttachments()
- oMail.Save(oTempFileName)
+ oMail.Save(oVersionedPath)
- Return oTempFileName
+ Return oVersionedPath
Catch ex As Exception
Logger.Error(ex)
@@ -186,6 +295,10 @@ Public Class Email2
End Try
End Function
+ Public Function Load_Email(pFileName As String) As IMail
+ Return MailBuilder.CreateFromEmlFile(pFileName)
+ End Function
+
Public Function Save_AttachmentsToDisk(pFileName As String) As List(Of String)
Try
Dim oAttachmentPaths As New List(Of String)
@@ -212,7 +325,7 @@ Public Class Email2
End Try
End Function
- Public Function ConvertMsgToEml(pEmailFileName As String) As String
+ Public Function Convert_MsgToEml(pEmailFileName As String) As String
Dim oInfo As New FileInfo(pEmailFileName)
If oInfo.Extension.ToUpper = ".EML" Then
@@ -229,38 +342,35 @@ Public Class Email2
Private Function DoConvertMsgToEmlFile(pMsgFile As String) As String
Try
+ Dim oTempPath As String = IO.Path.GetTempPath()
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pMsgFile)
- Dim oEmlPath As String = $"{oFileNameWithoutExtension}.eml"
+ Dim oEmlPath As String = IO.Path.Combine(oTempPath, $"{oFileNameWithoutExtension}.eml")
+ Dim oVersionedPath As String = FileEx.GetVersionedFilename(oEmlPath)
Using oConverter As New MsgConverter(pMsgFile)
Dim oEmail As IMail = oConverter.CreateMessage()
Dim oData As Byte() = oEmail.Render()
- oEmail.Save(oEmlPath)
+ oEmail.Save(oVersionedPath)
+
End Using
- Return oEmlPath
+ Return oVersionedPath
Catch ex As Exception
- Return Nothing
+ Logger.Warn("Converting Msg to Eml file failed!")
+ Logger.Error(ex)
+ Return Nothing
End Try
End Function
- Private Function GetTempFileNameWithExtension(pExtension As String) As String
- Dim oTempFileName As String = IO.Path.GetTempFileName()
- Dim oInfo As New IO.FileInfo(oTempFileName)
- Dim oExtension As String = IIf(pExtension.StartsWith("."), pExtension, $".{pExtension}")
- Dim oNewFileName = IO.Path.Combine(oInfo.DirectoryName, oInfo.Name.Replace(oInfo.Extension, oExtension))
-
- Return oNewFileName
- End Function
-
- Private Function AddFilenameSuffix(pFilename As String, pSuffix As String)
+ Private Function Add_FilenameSuffix(pFilename As String, pSuffix As String)
Dim oFileInfo As New FileInfo(pFilename)
Dim oExtension As String = oFileInfo.Extension
Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pFilename)
Return $"{oFileNameWithoutExtension}{pSuffix}{oExtension}"
+
End Function
End Class