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 Public Class Email2 Private ReadOnly Logger As Logger Private ReadOnly LogConfig As LogConfig Private ReadOnly FileEx As Filesystem.File Private ReadOnly MailBuilder As New MailBuilder() Public Sub New(pLogConfig As LogConfig) LogConfig = pLogConfig Logger = pLogConfig.GetLogger() FileEx = New Filesystem.File(pLogConfig) End Sub Public Enum EmailSecurity SSLTLS STARTTLS End Enum Private Function Get_PortForSecurityOption(pSecurity As EmailSecurity) As Integer If pSecurity = EmailSecurity.STARTTLS Then Return 143 Else ' EmailSecurity.SSL Return 993 End If End Function Private Function New_Connection(pIMAP As Imap, pServer As String, pUsername As String, pPassword As String, pPort As Integer, pSecurity As EmailSecurity) As Boolean Try Logger.Debug("Connecting to IMAP server [{0}]", pServer) 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 Logger.Debug("Using SSL/TLS as Security Option") pIMAP.ConnectSSL(pServer, oPort) End If Logger.Debug("Connection to IMAP Server [{0}] established!", pServer) Logger.Debug("Logging in with user [{0}]", pUsername) pIMAP.UseBestLogin(pUsername, pPassword) Return True Catch ex As Exception Logger.Warn("Could not connect to server [{0}] with user [{1}]", pServer, pUsername) Logger.Error(ex) Return False 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) 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.Debug("Test finished!") oClient.Close() End If End Using Return True Catch ex As Exception Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername) 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) 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 Unseen UUIDs") Dim oUUIDs As List(Of Long) = oClient.Search(Flag.Unseen) Dim oMailBuilder As New MailBuilder() 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) Next Logger.Debug("Emails fetched!") oClient.Close() End If End Using Return oMails Catch ex As Exception Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername) 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) 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 UUIDs") Dim oUUIDs As List(Of Long) = oClient.Search(Flag.All) Logger.Debug("Fetching Mails") Dim oInfos As List(Of MessageInfo) = oClient.GetMessageInfoByUID(oUUIDs) Dim oMailInfo = oInfos.Where(Function(i) i.Envelope.MessageID = pMessageId).FirstOrDefault() If oMailInfo IsNot Nothing Then Dim oMailData As Byte() = oClient.GetMessageByUID(oMailInfo.UID) oMail = MailBuilder.CreateFromEml(oMailData) End If Logger.Debug("Emails fetched!") oClient.Close() End If End Using Return oMail Catch ex As Exception Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername) Logger.Error(ex) Return Nothing End Try End Function 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 oMail = MailBuilder.CreateFromEmlFile(pFileName) oMail.RemoveAttachments() oMail.Save(oTempFileName) Return oTempFileName Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Function Save_AttachmentsToDisk(pFileName As String) As List(Of String) Try Dim oAttachmentPaths As New List(Of String) Dim oMail = MailBuilder.CreateFromEmlFile(pFileName) Dim oTempPath As String = IO.Path.GetTempPath() If oMail.Attachments.Count = 0 Then Return New List(Of String) End If For Each oAttachment As MimeData In oMail.Attachments Dim oPath As String = IO.Path.Combine(oTempPath, oAttachment.SafeFileName) Dim oVersionedPath As String = FileEx.GetVersionedFilename(oPath) oAttachment.Save(oVersionedPath) oAttachmentPaths.Add(oVersionedPath) Next Return oAttachmentPaths Catch ex As Exception Logger.Error(ex) Return New List(Of String) End Try End Function Public Function ConvertMsgToEml(pEmailFileName As String) As String Dim oInfo As New FileInfo(pEmailFileName) If oInfo.Extension.ToUpper = ".EML" Then Return pEmailFileName ElseIf oInfo.Extension.ToUpper = ".MSG" Then Return DoConvertMsgToEmlFile(pEmailFileName) Else Return Nothing End If End Function Private Function DoConvertMsgToEmlFile(pMsgFile As String) As String Try Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pMsgFile) Dim oEmlPath As String = $"{oFileNameWithoutExtension}.eml" Using oConverter As New MsgConverter(pMsgFile) Dim oEmail As IMail = oConverter.CreateMessage() Dim oData As Byte() = oEmail.Render() oEmail.Save(oEmlPath) End Using Return oEmlPath Catch ex As Exception 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) 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