Email sender worker class as a windows service isn't working .net core c#

31 Views Asked by At

Trying to do background service that sends email for subs. I'll share all the files. Here is the worker.cs;

using Npgsql;
using Newtonsoft.Json;
using System.Net.Mail;


namespace WorkerServiceEmailExample
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        int delayMinutes;
        const int notifyminutes = (9 * 60) + 30;
        bool workOnStart = false;
        const string emailBody = "The subscription of our institution named {0} for the product {1} is about to expire on {2}.";
        private readonly string _connectionString;
        private readonly SmtpClient _smtpClient;


        public Worker(ILogger<Worker> logger, IConfiguration configuration)
        {
            _connectionString = configuration["ConnectionString"];
            _smtpClient = new SmtpClient(configuration["SmtpServer"], Convert.ToInt32(configuration["587"]));
            _smtpClient.Credentials = new System.Net.NetworkCredential(configuration["SmtpUsername"], configuration["SmtpPassword"]);

            _logger = logger;
            var minutes = DateTime.Now.Hour * 60 + DateTime.Now.Minute;
            if(minutes < notifyminutes)
                delayMinutes = notifyminutes - minutes;
            else if(minutes >= notifyminutes)
                delayMinutes = (24 * 60) - (minutes - notifyminutes);
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    if (workOnStart)
                    {
                        delayMinutes = 24 * 60;
                        GetClosestSubs();
                    }
                    else
                        workOnStart = true;
                    await Task.Delay(TimeSpan.FromMinutes(delayMinutes), stoppingToken);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Hata oluştu!");
                }
            }
        }

        void GetClosestSubs()
        {
            
            try
            {
                using(var npgsqlConnection = new NpgsqlConnection("Server = 127.0.0.1; Database = infoSub; User Id = ####; Password = ####;"))
                {
                    npgsqlConnection.Open();
                    string query = "SELECT getclosestsubs(@date1, @date2)";
                    NpgsqlCommand command = new NpgsqlCommand(query, npgsqlConnection);
                    command.Parameters.AddWithValue("@date1", DateTime.Today);
                    command.Parameters.AddWithValue("@date2", DateTime.Today.AddMonths(3));

                    string? JsonB = (command.ExecuteScalar()?.ToString());
                    if (JsonB != null)
                    {

                        List<Subscription> subscriptions = JsonConvert.DeserializeObject<List<Subscription>>(JsonB);
                        foreach (Subscription sub in subscriptions)
                        {
                            SendEmail(sub); 
                        }
                    }
                    else
                    {
                        Console.WriteLine("No subs found.");
                    }
                };                

            }
            catch(Exception ex)
            {
                Console.WriteLine("Error: {0}", ex.Message);
            }
            
        }

        void SendEmail(Subscription sub)
        {
            var body = string.Format(emailBody, sub.CompanyName, sub.ProductName, sub.ExpireDateTime.ToString("0:dd/MM/yyyy"));

            try
            {
                using (SmtpClient client = new SmtpClient("smtp.example.com"))
                {
                    client.UseDefaultCredentials = false;
                    client.Credentials = new System.Net.NetworkCredential("####", "####");
                    client.Port = 587;
                    client.EnableSsl = true;

                    using (MailMessage mailMessage = new MailMessage())
                    {
                        mailMessage.From = new MailAddress("####");
                        mailMessage.To.Add(sub.Email);
                        mailMessage.Subject = "Subs notif";
                        mailMessage.Body = body;

                        client.Send(mailMessage);
                        Console.WriteLine("Email sent: {0}", body);
                    }
                }
            }

            catch (Exception ex)
            {
                Console.WriteLine("Error accured sending e-mail: {0}", ex.Message);
            }

        }


        void UpdateLastNotifyDateTime(string subscriptionId)
        {
            try
            {
                string connString = "Server=127.0.0.1;Database=####;User Id=postgres;Password=####;";
                using (NpgsqlConnection npgsqlConnection = new NpgsqlConnection(connString))
                {
                    npgsqlConnection.Open();
                    using (NpgsqlCommand command = new NpgsqlCommand("UPDATE Subscription SET LastNotifyDateTime = @now WHERE Id = @id", npgsqlConnection))
                    {
                        command.Parameters.AddWithValue("@now", DateTime.Now);
                        command.Parameters.AddWithValue("@id", subscriptionId);
                        command.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error!");
            }


        }

    }
}

program.cs;

using WorkerServiceEmailExample;


IHost host = Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    .ConfigureServices(services =>
    {
        services.AddHostedService<Worker>();
        services.AddSingleton<Subscription>();
        
    })
    .Build();

await host.RunAsync();

subscription.cs;

namespace WorkerServiceEmailExample
{
    public class Subscription
    {
        public string Id { get; set; }
        public short Flags { get; set; }
        public DateTime ExpireDateTime { get; set; }
        public DateTime StartDateTime { get; set; }
        public string Email { get; set; }
        public string CompanyName { get; set; }
        public string ProductName { get; set; }
        public DateTime LastNotifyDateTime { get; set; }


    }
}

The aim of this program is to execute the getclosestsubs function located in Postgresql every day at 9:30 and to send emails to members whose subscriptions are approaching expiration by serializing the Json data obtained from there. In the UpdateLastNotifyDateTime class, it needs to update the column found in Postgre. I want to use the Worker class as a Windows service.

0

There are 0 best solutions below