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 Imports System.Reflection.Emit Imports GdPicture14 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 Const SUCCESS_IMAP_FOLDER = "Verarbeitet" 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, pRejectionTemplateId As Integer, pInfoTemplateId As Integer, 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, pRejectionTemplateId, pInfoTemplateId) 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 &= $" AND GUID = {pProfileId}" End If Return Database.GetDatatable(oSQL) End Function Public Sub Start_WorkingProfiles(Optional LocalEmail As Boolean = False, Optional CallFromService As Boolean = False) Try DeleteTempFiles() IS_LOCAL_TEST = LocalEmail 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) Dim oSQLGDPicture = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE ACTIVE = 1" If CallFromService = True Then oSQLGDPicture = "SELECT LICENSE FROM TBDD_3RD_PARTY_MODULES WHERE NAME = 'GDPICTURE EMAIL_PROFILER'" End If GDPictureLicense = Database.GetScalarValue(oSQLGDPicture) 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) Dim oUID = String.Concat(Now.Month.ToString, Now.Day, Now.Hour, Now.Minute, Now.Second) ClassWorkMail.WorkEmailMessage(oEmail, oUID, 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 DeleteOrMoveEmailFile(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, New MailSession.MailSessionOptions() With { .EnableTls1_1 = True, .EnableTls1_2 = True }) 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 DeleteOrMoveEmailFile(pMailId As Integer) Try If MESSAGE_ERROR = True Then Logger.Warn("Did not delete or move Message with UID [{0}] as there was an MessageError!", pMailId) Return End If If IsNothing(Fetcher.Client) Then Logger.Warn("Did not delete or move Message with UID [{0}] as ImapClient is null", pMailId) Return End If If DeleteMail = True Then Fetcher.Client.DeleteMessageByUID(pMailId) Logger.Info("Email with Id [{0}] was deleted.", pMailId) Else If TestImapFolderExists(SUCCESS_IMAP_FOLDER) Then If Fetcher.Client.MoveByUID(pMailId, SUCCESS_IMAP_FOLDER) IsNot Nothing Then Logger.Info("Email with UID [{0}] was moved", pMailId) End If Else Logger.Warn("IMAP Folder [{0}] does not exist. Emails could not be moved!", SUCCESS_IMAP_FOLDER) End If End If Catch ex As Exception Logger.Error(ex) End Try End Sub Private Function TestImapFolderExists(pFolderName As String) As Boolean Try Return Fetcher.Client. GetFolders(). Where(Function(f) f.Name = pFolderName). Any() Catch ex As Exception Logger.Warn("Could not get IMAP folders. Returning False.") Logger.Error(ex) Return False End Try End Function End Class