2024-11-13 10:58:48 +01:00

369 lines
16 KiB
VB.net

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