Imports Independentsoft.Email Imports Independentsoft.Email.Pop3 Imports Independentsoft.Email.Mime Imports Independentsoft.Email.Imap Imports System.Net.Mail Imports System.Net Imports System.Reflection Imports System.IO Public Class Email Private ReadOnly _logger As Logging.Logger Private ReadOnly _logConfig As Logging.LogConfig Public Err_Message As String Public _msg_Send As Boolean Public Sub New(LogConfig As Logging.LogConfig) _logger = LogConfig.GetLogger() _logConfig = LogConfig End Sub ''' ''' Tests connection to a given IMAP Server by connecting and doing a simple message query. ''' ''' IP-Address or Domainname of Server ''' IMAP-Port ''' IMAP-Username ''' IMAP-Password ''' The folder to fetch messages from. Defaults to `Inbox` ''' True if connection and query were successful. False otherwise. Public Function TestIMAPLogin(Server As String, Port As Integer, Username As String, Password As String, Optional Folder As String = "Inbox") As Boolean _logger.Debug("Testing Login to Server {0}:{1} with user {2}", Server, Port, Username) Try _logger.Debug("Connecting...") Using oClient As New S22.Imap.ImapClient(Server, Port, Username, Password, S22.Imap.AuthMethod.Login, True) If Not oClient.Authed Then _logger.Warn("Connected to server but authentication failed.") Return False End If _logger.Debug("Connection successful") _logger.Debug("Fetching MessageIds..") Dim oMessageIds As IEnumerable(Of UInteger) = oClient.Search(S22.Imap.SearchCondition.Unseen, Folder) _logger.Debug("Found {0} messages", oMessageIds.Count) _logger.Debug("Fetching messages...") Dim oMessages As IEnumerable(Of MailMessage) = oClient.GetMessages(oMessageIds, False, Folder) _logger.Debug("Messages fetched") oClient.Dispose() Return True End Using Catch ex As Exception _logger.Error(ex) Return False End Try End Function ''' ''' Connects to an IMAP Server with the given credentials and ''' fetches emails from the given folder. ''' Results can be filtered with `SearchCondition` ''' ''' IP-Address or Domainname of Server ''' IMAP-Port ''' IMAP-Username ''' IMAP-Password ''' The folder to fetch messages from ''' Filter the search command. Defaults to `All` ''' A list of Independentsoft.Email.Mime.Message objects Public Function FetchIMAPMessages(Server As String, Port As Integer, Username As String, Password As String, Folder As String) As List(Of Message) ', Optional SearchCondition As S22.Imap.SearchCondition = S22.Imap.SearchCondition.All Dim oMessages As New List(Of Message) _logger.Debug("Connecting to Server {0}:{1} with user {2}", Server, Port, Username) Try _logger.Debug("Connecting...") Using oClient As New S22.Imap.ImapClient(Server, Port, Username, Password, S22.Imap.AuthMethod.Login, True) If Not oClient.Authed Then _logger.Warn("Connected to server but authentication failed.") Return Nothing End If _logger.Debug("Connection successful") _logger.Debug("Fetching MessageIds..") Dim oMessageIds As IEnumerable(Of UInteger) = oClient.Search(S22.Imap.SearchCondition.Unseen, Folder) _logger.Debug("Found {0} messages", oMessageIds.Count) _logger.Debug("Fetching messages...") ' Since this needs to return a list of IndependentSoft Message objects, ' we 'convert' the .NET MailMessage objects that are fetched from the server ' by writing them temporarily to disk as an eml file and then reading them back into a Message object. ' This approach uses an unintended use of internal .NET APIs and may break in the future. For Each oMessageId As UInteger In oMessageIds Dim oMessage = oClient.GetMessage(oMessageId, False, Folder) Dim oTempPath = Path.GetTempFileName() Dim oResult = WriteMessageToFile(oMessage, oTempPath) Dim oMsg As New Message(oTempPath) oMessages.Add(oMsg) Try File.Delete(oTempPath) Catch ex As Exception _logger.Error(ex) _logger.Warn("Temp file could not be deleted") End Try Next _logger.Debug("{0} Messages fetched", oMessages.Count) End Using Return oMessages Catch ex As Exception _logger.Error(ex) Return Nothing End Try End Function ''' ''' Uses a private API from MailWriter to write a MailMessage to disk. ''' May break in future versions of .NET ''' Public Function WriteMessageToFile(Message As MailMessage, Filename As String) As Boolean Dim oAssembly As Assembly = GetType(System.Net.Mail.SmtpClient).Assembly Dim oMailWriterType As Type = oAssembly.[GetType]("System.Net.Mail.MailWriter") Try Using oStream As New FileStream(Filename, FileMode.Create) Dim oMailWriterConstructor As ConstructorInfo = oMailWriterType.GetConstructor( BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Type() {GetType(Stream)}, Nothing ) Dim oMailWriter As Object = oMailWriterConstructor.Invoke(New Object() {oStream}) Dim sendMethod As MethodInfo = GetType(MailMessage).GetMethod("Send", BindingFlags.Instance Or BindingFlags.NonPublic) sendMethod.Invoke(Message, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, {oMailWriter, True, True}, Nothing) End Using Return True Catch ex As Exception Return Nothing End Try End Function Public Function IMAP_COLLECT(INBOXNAME As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) Try Dim oMAIL_LIST As New ArrayList() _logger.Info(String.Format("Working on IMAP_COLLECT...")) Dim oClient As New ImapClient(MYMAIL_SERVER, MYMAIL_PORT) oClient.Connect() oClient.Login(MYMAIL_USER, MYMAIL_USER_PW) oClient.SelectFolder("Inbox") Dim oEnvelopes As Envelope() = oClient.ListMessages() For i As Integer = 0 To oEnvelopes.Length - 1 If Not IsNothing(oEnvelopes(i).Subject) Then 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then _logger.Info($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") Dim message As Mime.Message = oClient.GetMessage(oEnvelopes(i).UniqueID) If Not IsNothing(message) Then oMAIL_LIST.Add(message) End If 'End If End If Next oClient.Disconnect() _logger.Debug("IMAP_COLLECT finished!") Return oMAIL_LIST Catch ex As Exception _logger.Error(ex, "Unexpected Error in IMAP COLLECT:") Return Nothing End Try End Function Public Function TEST_IMAP_COLLECT(INBOXNAME As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) Try _logger.Info(String.Format("Working on TEST_IMAP_COLLECT.....")) Dim oClient As New ImapClient(MYMAIL_SERVER, MYMAIL_PORT) oClient.Connect() oClient.Login(MYMAIL_USER, MYMAIL_USER_PW) oClient.SelectFolder(INBOXNAME) Dim oEnvelopes As Envelope() = oClient.ListMessages() For i As Integer = 0 To oEnvelopes.Length - 1 If Not IsNothing(oEnvelopes(i).Subject) Then 'If envelopes(i).Subject.ToString.ToUpper.Contains("[PROCESSMANAGER]") Or envelopes(i).Subject.ToString.ToUpper.Contains("[ADDI]") Then MsgBox($"Working on email: UniqueID: {oEnvelopes(i).UniqueID} - Subject:{oEnvelopes(i).Subject} - Date {oEnvelopes(i).Date.ToString}") Dim message As Mime.Message = oClient.GetMessage(oEnvelopes(i).UniqueID) End If Next oClient.Disconnect() _logger.Info("TEST_IMAP_COLLECT finished!") Return True Catch ex As Exception _logger.Error(ex, "Unexpected Error in TEST_IMAP_COLLECT:") Return False End Try End Function Public Function POP3_COLLECT(MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) Try Dim oMAIL_LIST As New ArrayList() _logger.Debug(String.Format("Working on POP3_COLLECT.....")) Dim oClient As New Pop3Client(MYMAIL_SERVER, MYMAIL_PORT) oClient.ValidateRemoteCertificate = False oClient.Connect() _logger.Debug(String.Format("..connected!")) oClient.Login(MYMAIL_USER, MYMAIL_USER_PW) Dim oMessageInfo As MessageInfo() = oClient.List() For i As Integer = 0 To oMessageInfo.Length - 1 Dim message As Message = oClient.GetMessage(oMessageInfo(i).Index) oMAIL_LIST.Add(message) Try _logger.Debug(String.Format("Message [{0}] added", message.Subject)) Catch ex As Exception End Try Next oClient.Disconnect() _logger.Debug(String.Format(" POP3_COLLECT finished!")) Return oMAIL_LIST Catch ex As Exception _logger.Error(ex) Return Nothing End Try End Function Public Function TEST_POP3_COLLECT(MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) As Boolean Try _logger.Debug(String.Format("Working on TEST_POP3_COLLECT...")) Dim oClient As New Pop3Client(MYMAIL_SERVER, MYMAIL_PORT) oClient.ValidateRemoteCertificate = False oClient.Connect() _logger.Debug(String.Format("..connected!")) oClient.Login(MYMAIL_USER, MYMAIL_USER_PW) Dim messageInfo As MessageInfo() = oClient.List() For i As Integer = 0 To messageInfo.Length - 1 Dim message As Message = oClient.GetMessage(messageInfo(i).Index) MsgBox(String.Format("Message [{0}] added", message.Subject)) Next oClient.Disconnect() MsgBox(String.Format("TEST_POP3_COLLECT finished!")) Return True Catch ex As Exception _logger.Error(ex) Return False End Try End Function Public Function NewEmail(mailto As String, mailSubject As String, mailBody As String, mailfrom As String, mailsmtp As String, mailport As Integer, mailUser As String, mailPW As String, AUTH_TYPE As String, SENDER_INSTANCE As String, Optional attachmentString As String = "", Optional Test As Boolean = False) Dim myClient As Net.Mail.SmtpClient Dim myMesssage As New MailMessage Try Dim oError As Boolean = False Dim oReceipiants As String() If mailto.Contains(";") Then oReceipiants = mailto.Split(";") Else ReDim Preserve oReceipiants(0) oReceipiants(0) = mailto End If For Each oMailReceipiant As String In oReceipiants _logger.Debug($"oMailReceipiant [{oMailReceipiant}]") _logger.Debug($"mailsmtp [{mailsmtp}]") Try myClient = New Net.Mail.SmtpClient(mailsmtp, mailport) Catch ex As Exception _logger.Warn($"Could not create SMTP-Client: [{ex.Message}]") Return False End Try myClient.DeliveryMethod = SmtpDeliveryMethod.Network myClient.Port = mailport _logger.Debug($"mailport [{mailport}]") If AUTH_TYPE = "SSL" Then _logger.Debug("SSL = true") myClient.EnableSsl = True Else _logger.Debug("SSL = false") myClient.EnableSsl = False End If _logger.Debug($"mailUser [{mailUser}]") myClient.Credentials = New NetworkCredential(mailUser, mailPW) myClient.UseDefaultCredentials = False If Test = True Then myMesssage.Body = $"This is the body (text will be replaced within profile)!
mailsmtp: {mailsmtp}
mailport: {mailport}
mailUser: {mailUser}
mailPW: XXXX
AUTH_TYPE: {AUTH_TYPE}" Else myMesssage.Body = mailBody End If _logger.Debug($"mailBody [{mailBody}]") 'mymesssage.IsBodyHtml = True Dim htmlView As AlternateView = AlternateView.CreateAlternateViewFromString(myMesssage.Body) htmlView.ContentType = New System.Net.Mime.ContentType("text/html") myMesssage.AlternateViews.Add(htmlView) _logger.Debug($"attachmentString [{attachmentString}]") If attachmentString <> "" Then _logger.Info($"Attachment Path is: {attachmentString}") Dim oAttachment As New System.Net.Mail.Attachment(attachmentString) 'If attment.ToLower.EndsWith("pdf") Then ' oAttachment.ContentType = New Independentsoft.Email.Mime.ContentType("application", "pdf") 'ElseIf attment.ToLower.EndsWith("jpg") Then ' oAttachment.ContentType = New Independentsoft.Email.Mime.ContentType("application", "jpg") 'ElseIf attment.ToLower.EndsWith("docx") Then ' oAttachment.ContentType = New Independentsoft.Email.Mime.ContentType("application", "MS-word") 'End If myMesssage.Attachments.Add(oAttachment) Else _logger.Debug("No Attachment.") End If _logger.Debug($"mailfrom [{mailfrom}]") myMesssage.From = New MailAddress(mailfrom) _logger.Debug($"mailSubject [{mailSubject}]") myMesssage.Subject = mailSubject myMesssage.To.Add(New MailAddress(oMailReceipiant)) _logger.Debug($"Now Sending mail...") myClient.Send(myMesssage) _logger.Debug($"Mail has been sent!") _logger.Info("Message to " & oMailReceipiant & " has been send.") Next If oError = False Then Return True Else Return False End If Catch ex As Exception _logger.Error(ex) Try _logger.Info("Unexpected error in Sending smtp-Mail: ") If Not IsNothing(myClient) Then _logger.Info($"myClient.Host: {myClient.Host.ToString}") _logger.Info($"myClient.Port: {myClient.Port.ToString}") _logger.Info($"myClient.EnableSsl: {myClient.EnableSsl.ToString}") End If If Not IsNothing(myMesssage) Then _logger.Info($"myMesssage.Subject: {myMesssage.Subject.ToString}") _logger.Info($"myMesssage.Body: {myMesssage.Body.ToString}") _logger.Info($"myMesssage.From: {myMesssage.From.ToString}") End If Catch e1x As Exception End Try Return False End Try End Function Public Function New_EmailISoft(ByVal mailSubject As String, ByVal mailBody As String, mailto As String, from_mailaddress As String, from_name As String, mailsmtp As String, mailport As Integer, mailUser As String, mailPW As String, AUTH_TYPE As String, SENDER_INSTANCE As String, Optional attment As String = "") Try Err_Message = "" _msg_Send = False ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 _logger.Debug($"in Email_Send_Independentsoft..") Dim empfaenger As String() If mailto.Contains(";") Then empfaenger = mailto.Split(";") Else ReDim Preserve empfaenger(0) empfaenger(0) = mailto End If Dim _error As Boolean = False 'Für jeden Empfänger eine Neue Mail erzeugen For Each _mailempfaenger As String In empfaenger _logger.Debug($"Working on email for {_mailempfaenger}..") Try Dim oMessage As New Message() oMessage.From = New Mailbox(from_mailaddress, from_name) oMessage.[To].Add(New Mailbox(_mailempfaenger)) oMessage.Subject = mailSubject _logger.Debug($"Message created..") Dim textBodyPart As New BodyPart() textBodyPart.ContentType = New ContentType("text", "html", "utf-8") textBodyPart.ContentTransferEncoding = ContentTransferEncoding.QuotedPrintable textBodyPart.Body = mailBody oMessage.BodyParts.Add(textBodyPart) If attment <> String.Empty Then If System.IO.File.Exists(attment) Then Dim attachment1 As New Independentsoft.Email.Mime.Attachment(attment) If attment.ToLower.EndsWith("pdf") Then attachment1.ContentType = New ContentType("application", "pdf") ElseIf attment.ToLower.EndsWith("jpg") Then attachment1.ContentType = New ContentType("application", "jpg") ElseIf attment.ToLower.EndsWith("docx") Then attachment1.ContentType = New ContentType("application", "MS-word") End If oMessage.BodyParts.Add(attachment1) Else _logger.Warn($"Attachment {attment.ToString} is not existing!") End If End If Dim client As Independentsoft.Email.Smtp.SmtpClient Try client = New Independentsoft.Email.Smtp.SmtpClient(mailsmtp, mailport) Catch ex As Exception _logger.Warn("clsEmail.Create Client: " & ex.Message) _error = True Continue For End Try Try client.Connect() Catch ex As Exception _logger.Warn("clsEmail.Client.Connect1: " & ex.Message) _logger.Debug("Error in ClientConnect - but still trying to send") _error = True ' Continue For End Try _logger.Debug("Connected to Client!") If AUTH_TYPE = "SSL" Then client.EnableSsl = True 'client.ValidateRemoteCertificate = True _logger.Debug("Authentification via SSL.") ElseIf AUTH_TYPE = "TLS" Then ' client.ValidateRemoteCertificate = False client.StartTls() client.EnableSsl = False _logger.Debug("Authentification via TLS. SSL disabled") Else client.EnableSsl = False _logger.Debug("Authentification NONE. SSL disabled") End If Try client.Connect() Catch ex As Exception _logger.Warn("clsEmail.Client.Connect: " & ex.Message) Err_Message = "clsEmail.Client.Connect: " & ex.Message _error = True ' Continue For End Try Try If mailsmtp.Contains("office365.com") Then client.Login(mailUser, mailPW, AuthenticationType.None) Else client.Login(mailUser, mailPW) End If _logger.Debug("Logged in!") Catch ex As Exception Try If mailsmtp.Contains("office365.com") Then client.Login(mailUser, mailPW, AuthenticationType.Login) Else client.Login(mailUser, mailPW, AuthenticationType.Anonymous) End If Catch ex1 As Exception Try client.Login(mailUser, mailPW, AuthenticationType.Login) Catch ex2 As Exception _logger.Warn("clsEmail.Client.Login: " & ex.Message) _error = True client.Disconnect() Continue For End Try End Try End Try Try client.Send(oMessage) _logger.Info("Message to " & _mailempfaenger & " has been send.") _msg_Send = True _error = False Catch ex As Exception _logger.Warn("clsEmail.Client.Send: " & ex.Message) Err_Message = ex.Message _error = True client.Disconnect() Continue For End Try client.Disconnect() Catch ex As Exception Err_Message = ex.Message If _msg_Send = True Then _logger.Info($"Error Closing Connection [{ex.Message}]") Else _logger.Error(ex) End If _error = True End Try Next If _error = True Then Return False Else Return True End If Catch ex As Exception _logger.Error(ex) Err_Message = ex.Message Return False End Try End Function Public Function DELETE_EMAIL(POLLTYPE As String, msgid As String, MYMAIL_SERVER As String, MYMAIL_PORT As Integer, MYMAIL_USER As String, MYMAIL_USER_PW As String) Try If POLLTYPE = "POP" Then Dim oClient As New Pop3Client(MYMAIL_SERVER, MYMAIL_PORT) oClient.ValidateRemoteCertificate = False oClient.Connect() oClient.Login(MYMAIL_USER, MYMAIL_USER_PW) Dim oMessageInfo As MessageInfo() = oClient.List() For i As Integer = 0 To oMessageInfo.Length - 1 Dim message As Message = oClient.GetMessage(oMessageInfo(i).Index) If message.MessageID = msgid Then oClient.Delete(oMessageInfo(i).Index) _logger.Info(String.Format("Message [{0}] was deleted!", message.Subject)) Exit For End If Next oClient.Disconnect() Return True ElseIf POLLTYPE = "IMAP" Then Dim oIMAPClient As New ImapClient(MYMAIL_SERVER, MYMAIL_PORT) oIMAPClient.ValidateRemoteCertificate = False oIMAPClient.Connect() oIMAPClient.Login(MYMAIL_USER, MYMAIL_USER_PW) oIMAPClient.SelectFolder("Inbox") Dim envelopes As Envelope() = oIMAPClient.ListMessages() For i As Integer = 0 To envelopes.Length - 1 If envelopes(i).MessageID = msgid Then oIMAPClient.Delete(envelopes(i).UniqueID) 'mark as deleted End If Next oIMAPClient.Expunge() 'delete messages marked as deleted oIMAPClient.Disconnect() Return True End If Catch ex As Exception _logger.Error(ex) 'clsLogger.Add("Unexpected Error in DELETE_EMAIL: " & ex.Message) Return False End Try End Function End Class