diff --git a/App/EmailProfiler.Common/Data/MailContainer.vb b/App/EmailProfiler.Common/Data/MailContainer.vb index eb6f318..54ff854 100644 --- a/App/EmailProfiler.Common/Data/MailContainer.vb +++ b/App/EmailProfiler.Common/Data/MailContainer.vb @@ -22,14 +22,11 @@ Public Class MailContainer ''' ''' The new MessageID, which is generated by hashing the original MessageID ''' - Public ReadOnly Property MessageId As String + Public Property MessageId As String - ''' - ''' Eine zweite MessageID, in der das Mail-Datum berücksichtigt wird. - ''' Wird verwendet wenn MessageId bereits existiert. - ''' - ''' - Public ReadOnly Property MessageId2 As String + Public ReadOnly Property EMailDate As Date + + Public ReadOnly Property MessageIDHashSet As HashSet(Of String) = New HashSet(Of String) ''' ''' The subject, truncated to SUBJECT_MAX_LENGTH characters @@ -48,13 +45,39 @@ Public Class MailContainer MessageIdOriginal = pMail.MessageID MessageId = StringEx.GetShortHash(pMail.MessageID) - MessageId2 = StringEx.GetShortHash(pMail.MessageID + pMail.Date.ToString()) Subject = ObjectEx.NotNull(pMail.Subject.Truncate(SUBJECT_MAX_LENGTH), String.Empty) SubjectOriginal = ObjectEx.NotNull(pMail.Subject, String.Empty) SenderAddress = GetSenderAddress(pMail) SenderDomain = GetSenderDomain(pMail) + + EMailDate = GetEmailDate(pMail) + End Sub + + ''' + ''' Erzeugt eine Liste von n unterschiedlichen MessageIDs + ''' Dabei verwenden wir den vorherigen Wert, um daraus einen neuen zu erzeugen + ''' + Public Sub InitializeHashsetOfMessageIDs() + MessageIDHashSet.Clear() + + Dim nextMessageID As String + + If String.IsNullOrEmpty(MessageIdOriginal) = True Then + nextMessageID = "1234567890ABCDEFGHIJKLMNOPQRSTUV" ' irgendwelche 32 Zeichen + Else + nextMessageID = MessageIdOriginal + End If + + For index = 1 To 10 + Dim zeitMitMs As String = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + nextMessageID = nextMessageID + "_" + index.ToString + "_" + zeitMitMs + nextMessageID = StringEx.GetShortHash(nextMessageID) + + MessageIDHashSet.Add(nextMessageID) + Next + End Sub Private Function GetSenderAddress(pMail As IMail) @@ -67,4 +90,16 @@ Public Class MailContainer Return oMailBox.DomainPart End Function + Public Sub SetMessageID(pMessageID As String) + MessageId = pMessageID + End Sub + + Private Function GetEmailDate(pMail As IMail) As Date + If pMail.Date IsNot Nothing Then + Return pMail.Date + Else + Return Date.MinValue + End If + End Function + End Class diff --git a/App/EmailProfiler.Common/Enum/EmailStrings.vb b/App/EmailProfiler.Common/Enum/EmailStrings.vb index b1c8a64..428d8d7 100644 --- a/App/EmailProfiler.Common/Enum/EmailStrings.vb +++ b/App/EmailProfiler.Common/Enum/EmailStrings.vb @@ -6,6 +6,12 @@ Public Const EMAIL_SUBJECT_REJECTED = "Beleg abgelehnt" + Public Const EMAIL_WRAPPING_TEXT_DUPLICATE_MESSAGEID = "Sehr geehrte Damen und Herren,

+ für die Email {0} konnte keine eindeutige EMail MessageID erzeugt werden.
Bitte prüfen sie die Logs des E-Mail Profilers." + Public Const EMAIL_SUBJECT_DUPLICATE_MESSAGEID = "Fehler im EMail Profiler - Es konnte keine eindeutige messageID erzeugt werden!" + Public Const EMAIL_BODY_TEXT_DUPLICATE_MESSAGEID = "

messageID: {0} vom {1}

" + Public Const DUPLICATE_MESSAGEID_CODE = "DUPLICATE MESSAGEID" + Public Const EMAIL_NO_FERDS = "

Ihre Email enthielt keine Dokumente.

" ''' diff --git a/App/EmailProfiler.Common/clsWorkEmail.vb b/App/EmailProfiler.Common/clsWorkEmail.vb index 49f131a..9885991 100644 --- a/App/EmailProfiler.Common/clsWorkEmail.vb +++ b/App/EmailProfiler.Common/clsWorkEmail.vb @@ -106,19 +106,28 @@ Public Class clsWorkEmail CURRENT_MAIL_FROM = m.Address Next - 'TODO: Move all of these CURRENT_MAIL vars into a business object of type mail container _CurrentMail = New MailContainer(pMailMessage, poUID) + 'ab hier, darf/sollte pMailMessage nicht mehr verwendet werden. - _Logger.Info($"Working on email from: [{_CurrentMail.SenderAddress}] ... Subject: [{_CurrentMail.SubjectOriginal}] ... MessageID: [{_CurrentMail.MessageId}]") + 'TODO: Move all of these CURRENT_MAIL vars into a business object of type mail container CURRENT_MAIL_BODY_ALL = "" CURRENT_MAIL_BODY_ANSWER1 = "" CURRENT_MAIL_BODY_Substr2 = "" CURRENT_MAIL_SUBJECT = "" - ' Dieser Eintrag wird weiter unten wieder überschrieben. Wenn Subject IS NULL --> Exception - 'CURRENT_MAIL_SUBJECT = pMailMessage.Subject.ToUpper.EscapeForSQL() + Dim oUniqueMessageID = GetUniqueMessagID() + If String.IsNullOrEmpty(oUniqueMessageID) = True Then + ' Im Fall, dass wir keine eindeutige MessageID haben, schicken wir uns eine E-Mail + _Logger.Error($"Could not process email [{_CurrentMail.SubjectOriginal}], no unique messageID found!") + SendDuplicateWarningMail() + Return False + Else + _CurrentMail.SetMessageID(oUniqueMessageID) + _Logger.Debug($"Unique messageID found [{oUniqueMessageID}] and in use [{_CurrentMail.MessageId}]") + End If CURRENT_MAIL_UID = poUID + _Logger.Info($"Working on email [{poUID}] from: [{_CurrentMail.SenderAddress}] ... Subject: [{_CurrentMail.SubjectOriginal}] ... MessageID: [{_CurrentMail.MessageId}]") If String.IsNullOrEmpty(_CurrentMail.SubjectOriginal) Then CURRENT_MAIL_SUBJECT = String.Empty @@ -128,24 +137,6 @@ Public Class clsWorkEmail _Logger.Debug("Fixed Subject: [{0}]", CURRENT_MAIL_SUBJECT) End If - ' Checking the messageID - could be a duplicate - _Logger.Debug($"messageID: '{_CurrentMail.MessageId}' - messageID2: '{_CurrentMail.MessageId2}'") - - Dim oSql = $"Select COALESCE(MAX(GUID),0) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{_CurrentMail.MessageId}'" - Dim oHistoryID = _DB_MSSQL.GetScalarValue(oSql) - - If oHistoryID > 0 And IS_LOCAL_TEST = False Then - _Logger.Warn("Found a MessageID already in use! Try MessageID2") - - oSql = $"Select COALESCE(MAX(GUID),0) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{_CurrentMail.MessageId2}'" - oHistoryID = _DB_MSSQL.GetScalarValue(oSql) - - If oHistoryID > 0 And IS_LOCAL_TEST = False Then - _Logger.Error("Found a MessageID2 already in use! Could not process email!") - Return False - End If - End If - Dim oTempMailExists As Boolean = Save2TempDirectory(_CurrentMail) 'Checking wether Mail can be opened @@ -269,6 +260,138 @@ Public Class clsWorkEmail End Try End Function + ''' + ''' Gibt die erste eindeutige messageID zurück, die generiert wurde. + ''' + ''' Wenn kein eindeutiger Schlüssel erzeugt werden konnte, gibt die + ''' Funktion Nothing / NULL zurück + ''' + ''' eindeutige messageID, oder nothing im Fehlerfall + Private Function GetUniqueMessagID() As String + + _Logger.Debug("GetUniqueMessagID() Start") + + If IS_LOCAL_TEST = True Then + ' Keine Prüfung im Test-Fall + Return _CurrentMail.MessageId + End If + + Try + + Dim oSql = $"SELECT COALESCE(MAX(GUID),0) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '" + Dim oTestSQL = oSql + _CurrentMail.MessageId + "';" + Dim oHistoryID = _DB_MSSQL.GetScalarValue(oTestSQL) + + If oHistoryID = 0 Then + _Logger.Info($"GetUniqueMessagID() unique messageID found from original messageID [{_CurrentMail.MessageId}]") + Return _CurrentMail.MessageId + + Else + ' Wenn ein Duplikat vorliegt, müssen wir weiter suchen + _Logger.Info($"GetUniqueMessagID() Activate Deep Search for unique messageID!") + _CurrentMail.InitializeHashsetOfMessageIDs() + For Each oMessageIDItem In _CurrentMail.MessageIDHashSet + + oTestSQL = oSql + oMessageIDItem + "';" + oHistoryID = _DB_MSSQL.GetScalarValue(oTestSQL) + If oHistoryID = 0 Then + _Logger.Info($"GetUniqueMessagID() unique messageID found [{oMessageIDItem}]") + Return oMessageIDItem + Else + _Logger.Warn($"GetUniqueMessagID() messageID [{oMessageIDItem}] already in use") + End If + + Next + End If + + ' Wenn wir bis hier her kommen, konnten wir keine eindeutige messageID finden + _Logger.Error($"GetUniqueMessagID() could not find unique messageID! ") + Return Nothing + + Catch ex As Exception + _Logger.Error(ex) + Return Nothing + End Try + + End Function + + Private Function SendDuplicateWarningMail() As Boolean + + Try + ' Gab es die Mail schon in den letzten 6 Stunden? + Dim oCheckSQL = $"SELECT COALESCE(MAX(GUID), 0) FROM DD_ECM.dbo.TBEMLP_EMAIL_OUT WHERE REFERENCE_STRING = '{_CurrentMail.MessageId}' AND COMMENT = '{EmailStrings.DUPLICATE_MESSAGEID_CODE}' AND DATEDIFF(hour, ADDED_WHEN, getdate()) < 6;" + Dim oOutHistoryID As Integer = _DB_MSSQL.GetScalarValue(oCheckSQL) + + If oOutHistoryID > 0 Then + _Logger.Warn($"Warning Mail already sent") + ' EMail ging bereits raus + Return True + End If + + Catch ex As Exception + _Logger.Error(ex) + Return False + End Try + + + Try + Dim oReference = _CurrentMail.MessageId + + Dim oAdressSQL = "SELECT TOP 1 COALESCE([CAT_STRING], '') FROM [IDB].[dbo].[TBIDB_CATALOG] WHERE CAT_TITLE = 'DD_SUPPORT_EMAIL';" + Dim configString = _DB_MSSQL.GetScalarValue(oAdressSQL) + Dim oEmailTo As String = "support-flow@digitaldata.works" + If String.IsNullOrEmpty(configString) = False Then + oEmailTo = configString + End If + + Dim oSubject = $"{SUBJECT_PRAFIX} - {EmailStrings.EMAIL_SUBJECT_DUPLICATE_MESSAGEID}" + Dim oCreatedWho = "DDEmailProfiler" + + Dim oMaskedBodyText = String.Format(EmailStrings.EMAIL_BODY_TEXT_DUPLICATE_MESSAGEID, _CurrentMail.MessageId, _CurrentMail.EMailDate) + Dim oSubjectBodyText = String.Format(EmailStrings.EMAIL_SUBJECT_TEXT, _CurrentMail.Subject) + Dim oCompleteBodyText = oMaskedBodyText + " - " + oSubjectBodyText + + Dim oFinalBodyText = String.Format(EmailStrings.EMAIL_WRAPPING_TEXT_DUPLICATE_MESSAGEID, oCompleteBodyText) + + _Logger.Debug("Trying to generate Email:") + _Logger.Debug("To: {0}", oEmailTo) + _Logger.Debug("Subject: {0}", oSubject) + _Logger.Debug("Body {0}", oFinalBodyText) + Dim osql = $"Select COALESCE(MAX(GUID), 0) FROM TBEMLP_HISTORY WHERE EMAIL_MSGID = '{_CurrentMail.MessageId}'" + Dim oHistoryID As Integer = _DB_MSSQL.GetScalarValue(osql) + + Dim oInsert = $"INSERT INTO [dbo].[TBEMLP_EMAIL_OUT] ( + [REMINDER_TYPE_ID] + ,[SENDING_PROFILE] + ,[REFERENCE_ID] + ,[REFERENCE_STRING] + ,[WF_ID] + ,[EMAIL_ADRESS] + ,[EMAIL_SUBJ] + ,[EMAIL_BODY] + ,[COMMENT] + ,[ADDED_WHO]) + VALUES + (77 + ,{_EmailAccountID} + ,{oHistoryID} + ,'{_CurrentMail.MessageId}' + ,77 + ,'{oEmailTo}' + ,'{oSubject}' + ,'{oFinalBodyText}' + ,'{EmailStrings.DUPLICATE_MESSAGEID_CODE}' + ,'{oCreatedWho}')" + Return _DB_MSSQL.ExecuteNonQuery(oInsert) + + Catch ex As Exception + _Logger.Error(ex) + Return False + End Try + + Return True + End Function + ''' ''' Wenn beim Herauslösen der Attachments festgestellt wurde, ''' das ein Teil der _normalen_ Attachments fehlerhaft war, wird der Absender hier diff --git a/App/EmailProfiler.Common/clsWorker.vb b/App/EmailProfiler.Common/clsWorker.vb index 29c7bfe..a84147d 100644 --- a/App/EmailProfiler.Common/clsWorker.vb +++ b/App/EmailProfiler.Common/clsWorker.vb @@ -221,6 +221,7 @@ Public Class clsWorker If LocalEmlFile = "" Then DeleteOrMoveEmailFile(oMailId) End If + _Logger.Info("Email with Id [{0}] was successfully worked.", oMailId) End If Else