Imports EmailProfiler.Common.ClassCurrent Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Database Imports DigitalData.Modules.Base Imports DigitalData.Modules.Messaging.Mail Imports Limilabs.Mail Imports Limilabs.Mail.Headers Public Class clsWorker Private ReadOnly Logger As Logger Private ReadOnly Fetcher As MailFetcher Private ReadOnly Database As MSSQLServer Private ReadOnly UseWindream As Boolean = False Private ReadOnly ClassWindreamAllgemein As clsWindream_allgemein Private ReadOnly ClassWindreamIndex As clsWindream_Index Private ReadOnly ClassWorkMail As clsWorkEmail Private ReadOnly Encryption As clsEncryption Private ReadOnly ProfileId As Integer = 0D Private ReadOnly EmailLimitationSender As String = "" Private ReadOnly EmailLimitationEnabled As Boolean = False Private ReadOnly LocalEmlFile As String = "" Sub New(pLogConfig As LogConfig, pConnectionString As String, pWindreamConnectionString As String, pPollProfileId As Integer, pUseWindream As Boolean, pEmailAccountID As Integer, pEmailPrefix As String, pEmailLimitationSender As String, Optional pLocalEML As String = "") Logger = pLogConfig.GetLogger 'ClassEmailImap = New clsEmailIMAP(pLogConfig) Fetcher = New MailFetcher(pLogConfig) Database = New MSSQLServer(pLogConfig, pConnectionString) UseWindream = pUseWindream EmailLimitationSender = pEmailLimitationSender If EmailLimitationSender.Contains("@") Then Logger.Info("Email Sender Limitation active for address: [{0}]", EmailLimitationSender) EmailLimitationEnabled = True End If If UseWindream Then ClassWindreamAllgemein = New clsWindream_allgemein(pLogConfig) ClassWindreamIndex = New clsWindream_Index(pLogConfig) End If ClassWorkMail = New clsWorkEmail(pLogConfig, pConnectionString, pWindreamConnectionString, pUseWindream, pEmailAccountID, pEmailPrefix) Encryption = New clsEncryption("!35452didalog=", pLogConfig) ProfileId = pPollProfileId LocalEmlFile = pLocalEML End Sub Private Sub DeleteTempFiles() For Each _file In TEMP_FILES Logger.Debug("Trying to delete temp file: [{0}]", _file) If IO.File.Exists(_file) Then Try IO.File.Delete(_file) Catch ex As Exception Logger.Error(ex) Logger.Warn("Could not delete the tempfile from TEMP_FILES: [{0}]", _file) End Try End If Next TEMP_FILES.Clear() End Sub Private Function LoadEmailAccounts() As DataTable Return Database.GetDatatable("SELECT * FROM TBDD_EMAIL_ACCOUNT WHERE ACTIVE = 1") End Function Private Function LoadPollingProfiles(pProfileId As Integer) As DataTable Dim oSQL = "SELECT * FROM TBEMLP_POLL_PROFILES WHERE ACTIVE = 1" If ProfileId = 0 Then oSQL &= " ORDER BY SEQUENCE" Else oSQL &= $" WHERE GUID = {pProfileId}" End If Return Database.GetDatatable(oSQL) End Function Public Sub Start_WorkingProfiles(Optional LocalEmail As Boolean = False) Try DeleteTempFiles() If Database.DBInitialized = False Then Logger.Warn("Database is not initialized. Exiting.") Exit Sub End If Logger.Debug("now windream_init... ") If UseWindream Then If ClassWindreamAllgemein.Init = False Then Logger.Info("windream could not be initialized!!") Exit Sub Else Logger.Debug("windream_initialized!") End If End If Dim EmailAccountTable As DataTable = LoadEmailAccounts() Dim PollingProfileTable = LoadPollingProfiles(ProfileId) If IsNothing(PollingProfileTable) Then Logger.Warn("Error while fetching Polling Profiles. Exiting.") Exit Sub End If If PollingProfileTable.Rows.Count = 0 Then Logger.Warn("No active Polling Profiles found. Exiting.") Exit Sub End If Logger.Debug("Count of active profiles: " & PollingProfileTable.Rows.Count.ToString) For Each oProfile As DataRow In PollingProfileTable.Rows Dim oValidationSql = oProfile.ItemEx("VALIDATION_SQL", "") CURRENT_PROFILE_GUID = oProfile.Item("GUID") DT_POLL_PROCESS = Nothing Dim sql = String.Format("SELECT * FROM TBEMLP_POLL_PROCESS WHERE PROFILE_ID = {0} AND ACTIVE = 1", CURRENT_PROFILE_GUID) DT_POLL_PROCESS = Database.GetDatatable(sql) If Not IsNothing(DT_POLL_PROCESS) Then If DT_POLL_PROCESS.Rows.Count = 0 Then Logger.Info("No processes configured for this Email-Profile - " & sql) Continue For Else DT_STEPS = Nothing DT_STEPS = Database.GetDatatable($"SELECT T.* FROM TBEMLP_POLL_STEPS T,TBEMLP_POLL_PROCESS T1 WHERE T.PROCESS_ID = T1.GUID AND T1.PROFILE_ID = {CURRENT_PROFILE_GUID} AND T1.ACTIVE = 1") End If Else Logger.Warn("DT_POLL_PROCESS is nothing") Continue For End If CURRENT_EMAIL_GUID = 0 CURRENT_POLL_TYPE = oProfile.Item("POLL_TYPE") Logger.Debug(String.Format("Working on profile: ({0}-{1}-{2}) ", oProfile.Item("GUID"), oProfile.Item("PROFILE_NAME"), CURRENT_POLL_TYPE)) CURRENT_EMAIL_GUID = oProfile.Item("EMAIL_CONF_ID") Dim FilteredRows As List(Of DataRow) = EmailAccountTable. Select($"GUID = {CURRENT_EMAIL_GUID}"). ToList() Logger.Debug("FilteredRows: " & FilteredRows.Count) If FilteredRows.Count = 1 Then Dim oRow = FilteredRows(0) Dim oMailFrom = oRow("EMAIL_FROM") Dim oMailServer = oRow("EMAIL_SMTP") Dim oMailUser = oRow("EMAIL_USER") Dim oMailPassword = oRow("EMAIL_PW") Dim oMailPortIn = oRow("PORT_IN") Dim oMailboxName = "Inbox" Dim oMailArchiveFolder = oRow("ARCHIVE_FOLDER") Dim oMailAuthType = oRow("AUTH_TYPE") Logger.Debug("Mail Server: {0}", oMailServer) Logger.Debug("Mail From: {0}", oMailFrom) Dim PWPlain = Encryption.DecryptData(oMailPassword) If Not IsNothing(PWPlain) Then If PWPlain <> "" Then oMailPassword = PWPlain Else Logger.Warn("PWPlain is string.empty - Could not decrypt passwort") End If Else Logger.Warn("PWPlain is nothing - Could not decrypt passwort") End If CURRENT_WORKMAIL_UID_LIST.Clear() If oMailServer <> "" Then Dim oPollResult As Boolean = False If LocalEmail = True Then oPollResult = True Else Select Case CURRENT_POLL_TYPE Case "IMAP" ' We are using 'Archive Folder' as an additional field to save the Tenant-ID for O365-OAuth2 oPollResult = FetchMessages(oMailServer, oMailPortIn, oMailUser, oMailPassword, oMailAuthType, oMailArchiveFolder) Case Else Logger.Error("Poll Type [{0}] is not supported!", CURRENT_POLL_TYPE) oPollResult = False End Select End If If CURRENT_WORKMAIL_UID_LIST.Count() > 0 Or LocalEmail = True Then If LocalEmail Then Logger.Info("Working with local Mail") Dim oEmail As IMail = New MailBuilder().CreateFromEmlFile(LocalEmlFile) ClassWorkMail.WorkEmailMessage(oEmail, 123456789, oValidationSql) 'CURRENT_MAIL_MESSAGE = Nothing Else Try Logger.Info(String.Format("Pulled: [{0}] E-Mails", CURRENT_WORKMAIL_UID_LIST.Count())) For Each oMailId In CURRENT_WORKMAIL_UID_LIST Dim oEmail As IMail = Fetcher.FetchMail(oMailId) If Not IsNothing(oEmail) Then If EmailLimitationEnabled Then Dim oEmailFrom As String = "" For Each m As MailBox In oEmail.From oEmailFrom = m.Address Next If oEmailFrom <> EmailLimitationSender Then Logger.Debug($"Skipping email {oEmailFrom} ...Subject [{oEmail.Subject}]") Continue For End If End If If ClassWorkMail.WorkEmailMessage(oEmail, oMailId, oValidationSql) = True Then If LocalEmlFile = "" Then DeleteEmailFile(oMailId) End If End If Else Logger.Info("### oEmail was nothing ###") End If 'CURRENT_MAIL_MESSAGE = Nothing Next If CURRENT_POLL_TYPE = "IMAP" And CURRENT_WORKMAIL_UID_LIST.Count > 0 Then Fetcher.Disconnect() End If Catch ex As Exception Logger.Error(ex) Logger.Warn($"Unexpected Error working CURRENT_WORKMAIL_UID_LIST: {ex.Message} ") End Try End If Else Logger.Debug(String.Format("No emails for profile!")) End If Else Logger.Warn("For the Email-Profile ID " & CURRENT_EMAIL_GUID & " no record could be found!") End If Database.ExecuteNonQuery("UPDATE TBEMLP_POLL_PROFILES SET LAST_TICK = GETDATE() WHERE GUID = " & oProfile.Item("GUID").ToString) Else Logger.Warn("For the Email-Profile ID " & CURRENT_EMAIL_GUID & " no record could be found! Check wether Email-Profile is active!") End If Next DeleteTempFiles() Database.ExecuteNonQuery("UPDATE TBEMLP_CONFIG SET LAST_TICK = GETDATE() WHERE GUID = 1") Catch ex As Exception Logger.Error(ex) End Try End Sub Public Function FetchMessages(pServer As String, pPort As Integer, pUsername As String, pPassword As String, pAuthType As String, pArchiveFolder As String) As Boolean Try Dim oSession As MailSession.SessionInfo If pAuthType = MailSession.AUTH_OAUTH2 Then Dim oClientId As String = pServer Dim oClientSecret As String = pPassword Dim oTenantId As String = pArchiveFolder oSession = Fetcher.ConnectToO365(pUsername, oClientId, oTenantId, oClientSecret) Else oSession = Fetcher.Connect(pServer, pPort, pUsername, pPassword, pAuthType) End If If oSession.Connected = False AndAlso oSession.Error IsNot Nothing Then Logger.Warn("Connection to Mail Server failed!") Logger.Error(oSession.Error) Return False ElseIf oSession.Connected = False Then Logger.Warn("Connection to Mail Server failed!") Return False End If CURRENT_ImapObject = Fetcher.Client Dim oMailIds As List(Of Long) = Fetcher.ListAllMails() If oMailIds Is Nothing Then Logger.Warn("List of UIDs was Nothing. Exiting.") Return False End If If oMailIds.Count = 0 Then Logger.Debug("No Emails found.") Return True End If CURRENT_WORKMAIL_UID_LIST = oMailIds Return True Catch ex As Exception Logger.Error(ex) Return False End Try End Function Private Sub DeleteEmailFile(pMailId As Integer) Try If DeleteMail = True And MESSAGE_ERROR = False Then If IsNothing(Fetcher.Client) Then Logger.Warn("EMAIL_DELETE - CURRENT_ImapObject is nothing") End If Fetcher.Client.DeleteMessageByUID(pMailId) Logger.Info("Email with Id [{0}] was deleted.", pMailId) Else If MESSAGE_ERROR = True Then Logger.Warn("Did not delete Message with UID [{0}] as there was an MessageError!", pMailId) End If End If Catch ex As Exception Logger.Error(ex) End Try End Sub End Class