laatzen/Common/PendingEmails/Program.cs
Stoyan Zlatev 00a873c174 Tls13
2025-06-04 08:31:17 +02:00

291 lines
10 KiB
C#

namespace PendingEmails
{
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
public static partial class Program
{
private static void Main()
{
try
{
var awaiter = new ManualResetEventSlim();
while (true)
{
if (!AppSettings.TryLoadExeConfiguration(out var errors))
{
WriteLine(new string('=', 50));
foreach (var error in errors)
{
WriteLine(error);
}
}
else
{
WriteLine(new string('=', 50));
using (var connection = new SqlConnection(AppSettings.MSSQLConnectionString))
{
OpenConnection(connection);
FindWarantyEmails(connection);
var messages = FindPendingEmails(connection);
if (messages.Count <= 0)
{
WriteLine($"Keine neue nachrichten gefunden.");
}
var invalidMessages = messages.Where(x => !x.IsValid).ToList();
if (invalidMessages.Count > 0)
{
WriteLine($"{invalidMessages.Count} von {messages.Count} ungültige nachrichten gefunden.");
var rowsAffected = SetOutDate(connection, invalidMessages.Select(x => x.Id));
WriteLine($"{rowsAffected} von {invalidMessages.Count} wurden als gesended markiert.");
}
else
{
WriteLine($"Keine neue ungültige nachrichten gefunden.");
}
var validMessages = messages
.Where(x => x.IsValid)
.ToList();
validMessages = new List<Message>
{
new Message(-1, AppSettings.Sender, "Just test", "It works!", "stoyan.zlatev@xylem.com", null)
};
if (validMessages.Count > 0)
{
WriteLine($"{validMessages.Count} von {messages.Count} gültige nachrichten gefunden.");
SendEmails(connection, validMessages);
}
}
}
awaiter.Wait(AppSettings.Interval);
awaiter.Reset();
}
}
catch (Exception e)
{
WriteLine(e.ToString());
}
}
private static void OpenConnection(SqlConnection connection)
{
connection.FireInfoMessageEventOnUserErrors = true;
connection.InfoMessage += (_, args) => WriteLine(args.Message);
connection.Open();
}
private static void SendEmails(SqlConnection connection, List<Message> messages)
{
var sentEmails = new List<int>();
var excludedRecipients = AppSettings
.ExcludeRecipients
.ToEmailList();
WriteLine($"Sender: {AppSettings.Sender}");
using (var smtpClient = new SmtpClient())
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
smtpClient.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
smtpClient.Connect(AppSettings.SMTPHost, AppSettings.SMTPPort, SecureSocketOptions.StartTls);
if (!string.IsNullOrWhiteSpace(AppSettings.SMTPUsername) && !string.IsNullOrWhiteSpace(AppSettings.SMTPPassword))
{
smtpClient.Authenticate(AppSettings.SMTPUsername, AppSettings.SMTPPassword);
}
foreach (var message in messages)
{
try
{
var recipients = message
.Recipients
.ToEmailList()
.Except(excludedRecipients)
.ToList();
if (recipients.Count <= 0)
{
break;
}
var recipientsCC = message
.RecipientsCC
.ToEmailList()
.Except(excludedRecipients)
.ToList();
var emailMessage = new MimeMessage
{
From = { new MailboxAddress("noreplay", AppSettings.Sender) },
Subject = message.Subject,
Body = new TextPart
{
Text = message.Body
}
};
recipients.ForEach(x => emailMessage.To.Add(new MailboxAddress(x, x)));
recipientsCC.ForEach(x => emailMessage.Cc.Add(new MailboxAddress(x, x)));
smtpClient.Send(emailMessage);
sentEmails.Add(message.Id);
WriteLine($"Nachricht: {message.Id} wurde gesendet.");
}
catch (Exception e)
{
WriteLine(e.ToString());
}
}
}
if (sentEmails.Count > 0)
{
WriteLine($"Gesendet {sentEmails.Count} von {messages.Count}");
var rowsAffected = SetOutDate(connection, sentEmails);
WriteLine($"{rowsAffected} von {messages.Count} wurden als gesended markiert.");
}
else
{
WriteLine($"Keine nachrichten gesendet.");
}
}
private static int SetOutDate(SqlConnection connection, IEnumerable<int> messageIds)
{
var rowsAffected = default(int);
using (var command = connection.CreateCommand())
{
command.CommandText = $@"
UPDATE Messages
SET OutDate = GETDATE()
WHERE Id IN ({string.Join(", ", messageIds)})";
rowsAffected = command.ExecuteNonQuery();
}
return rowsAffected;
}
private static List<Message> FindPendingEmails(SqlConnection connection)
{
var pendingMessages = new List<Message>();
using (var command = connection.CreateCommand())
{
command.CommandText = @"
SELECT Id
, Sender
, Subject
, Body
, Recipients
, CC
FROM Messages
WHERE OutDate IS NULL
ORDER BY InDate DESC";
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var messageId = reader.GetValue<int>(0);
var sender = reader.GetValue<string>(1);
var subject = reader.GetValue<string>(2);
var body = reader.GetValue<string>(3);
var recipients = reader.GetValue<string>(4);
var recipientsCC = reader.GetValue<string>(5);
pendingMessages.Add(new Message(messageId, sender, subject, body, recipients, recipientsCC));
}
}
}
return pendingMessages;
}
private static void FindWarantyEmails(SqlConnection connection)
{
using (var command = connection.CreateCommand())
{
command.CommandTimeout = 60000;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = @"SP_EMAILS_FUER_GARANTIESCHEINE_LADEN";
WriteLine($"E-Mails für Garantiescheine gefunden: {command.ExecuteNonQuery()}");
}
}
private static void WriteLine(object e)
{
var logFolder = AppSettings.LogFolder;
var logPath = Directory.CreateDirectory(logFolder).FullName;
var logFile = Path.Combine(logPath, $"{DateTime.Now:yyyy-MM-dd}.txt");
var message = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {e}{Environment.NewLine}";
File.AppendAllText(logFile, message);
Console.WriteLine(message.Trim());
}
private static T GetValue<T>(this SqlDataReader sqlDataReader, int index, T defaultValue = default(T))
{
var value = defaultValue;
if (0 <= index && index < sqlDataReader.FieldCount && !sqlDataReader.IsDBNull(index))
{
var sqlValue = sqlDataReader.GetValue(index);
var type = Nullable.GetUnderlyingType(typeof(T));
if (type is null)
{
type = typeof(T);
}
try
{
sqlValue = Convert.ChangeType(sqlValue, type);
if (sqlValue is T expectedValue)
{
value = expectedValue;
}
}
catch (Exception e)
{
WriteLine(e);
}
}
return value;
}
private static List<string> ToEmailList(this string value)
=> value
?.ToLower()
?.Split(new[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries)
?.Where(x => !string.IsNullOrWhiteSpace(x))
?.ToList()
?? new List<string>();
}
}