291 lines
10 KiB
C#
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>();
|
|
}
|
|
}
|