Complete subscription and newsletter tracking for new emails in Danish

Implemented subscription and newsletter tracking with support for new Danish emails. All emails are now delivered to the Primary tab in Gmail for improved visibility.
This commit is contained in:
Qaisyousuf 2025-08-06 14:23:37 +02:00
parent 13bf203fe4
commit 9bfed53e71
2 changed files with 151 additions and 279 deletions

View file

@ -112,74 +112,48 @@ namespace Web.Areas.Admin.Controllers
{ {
// Retrieve all subscribed users // Retrieve all subscribed users
var subscribedUsers = await _context.Subscriptions.Where(s => s.IsSubscribed).ToListAsync(); var subscribedUsers = await _context.Subscriptions.Where(s => s.IsSubscribed).ToListAsync();
string confirmationPath = _configuration["Email:unsubscribePath"]; string confirmationPath = _configuration["Email:unsubscribePath"];
// Send the newsletter email to each subscribed user // Send the newsletter email to each subscribed user
foreach (var user in subscribedUsers) foreach (var user in subscribedUsers)
{ {
string confirmationUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={user.Email}"; string unsubscribeUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={user.Email}";
string emailBody = $@"<head>
<meta charset=""UTF-8""> // This HTML version with proper line breaks works for primary inbox
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0""> string emailBody = $@"<!DOCTYPE html>
<title>Email Confirmation</title> <html>
<style> <head>
body {{ <meta charset=""UTF-8"">
font-family: Arial, sans-serif; </head>
line-height: 1.6; <body>
margin: 0;
padding: 0; <p>Hej {user.Name},</p>
background-color: #f9f9f9;
}} <div>
.container {{ {viewModel.Body.Replace("\n", "<br><br>")}
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 0.5px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}}
h4, h5, h6 {{
margin: 0;
}}
hr {{
border: none;
border-top: 1px solid #ccc;
margin: 10px 0;
}}
a.button {{
display: inline-block;
padding: 5px 10px;
background-color: #6c757d;
color: #fff;
text-decoration: none;
border-radius: 4px;
}}
a.button:hover {{
background-color: #5a6268;
}}
a {{
color: #007bff;
text-decoration: none;
}}
a:hover {{
text-decoration: underline;
}}
</style>
</head>
<body>
<div class=""container"">
<h4>Hey {user.Name},</h4>
<p>{viewModel.Body}</p><br>
<h5>Søren Eggert Lundsteen Olsen</h5>
<h5><a href=""https://www.seosoft.dk/"" target=""_blank"">SeoSoft ApS</a></h5>
<hr>
<h6>Hovedgaden 3<br>Jordrup<br>Kolding 6064<br>Denmark</h6>
<div style=""text-align: center;"">
<a href=""{confirmationUrl}"" class=""button"">Unsubscribe</a>
</div> </div>
</div>
</body>"; <p>Hvis du har spørgsmål, kan du kontakte os kontakt@nvkn.dk</p>
<p>Med venlig hilsen,<br/>
Nærværskonsulenterne ApS</p>
<hr>
<p><small>
Nærværskonsulenterne ApS<br/>
Brødemosevej 24A, 3300 Frederiksværk<br/>
kontakt@nvkn.dk
</small></p>
<p>
<a href=""{unsubscribeUrl}"">
<button type=""button"">Afmeld nyhedsbrev</button>
</a>
</p>
</body>
</html>";
var email = new EmailToSend(user.Email, viewModel.Subject, emailBody); var email = new EmailToSend(user.Email, viewModel.Subject, emailBody);
var isSent = await _emailServices.SendConfirmationEmailAsync(email); var isSent = await _emailServices.SendConfirmationEmailAsync(email);
@ -190,32 +164,27 @@ namespace Web.Areas.Admin.Controllers
RecipientEmail = user.Email, RecipientEmail = user.Email,
Subject = viewModel.Subject, Subject = viewModel.Subject,
Body = emailBody, Body = emailBody,
SentDate = DateTime.UtcNow,
IsSent = isSent
SentDate = DateTime.UtcNow,
IsSent = isSent // Assuming isSent returns a boolean indicating success
}; };
_context.SentNewsletterEamils.Add(sentEmail); _context.SentNewsletterEamils.Add(sentEmail);
// Add small delay to look more natural
// Handle failure to send email if needed await Task.Delay(2000); // 2 second delay between sends
} }
await _context.SaveChangesAsync(); // Save changes for all sent emails await _context.SaveChangesAsync();
TempData["success"] = "Nyhedsbrev sendt successfully.";
TempData["success"] = "Newsletter sent successfully.";
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
catch (Exception ex) catch (Exception ex)
{ {
// Log or handle the exception as needed TempData["error"] = "Noget gik galt: " + ex.Message;
TempData["error"] = "Something went wrong: " + ex.Message;
return RedirectToAction(nameof(Index)); return RedirectToAction(nameof(Index));
} }
} }
return View(viewModel); return View(viewModel);
} }
[HttpGet] [HttpGet]
public IActionResult UploadSubscribers() public IActionResult UploadSubscribers()
{ {

View file

@ -37,7 +37,7 @@ namespace Web.Controllers
public async Task<IActionResult> Subscribe(Subscription subscription) public async Task<IActionResult> Subscribe(Subscription subscription)
{ {
if(ModelState.IsValid) if (ModelState.IsValid)
{ {
try try
{ {
@ -48,94 +48,55 @@ namespace Web.Controllers
var existingSubscription = await _context.Subscriptions.FirstOrDefaultAsync(s => s.Email == email); var existingSubscription = await _context.Subscriptions.FirstOrDefaultAsync(s => s.Email == email);
if (existingSubscription != null) if (existingSubscription != null)
{ {
TempData["error"] = "Du er allerede abonneret.";
TempData["error"] = "Email already subscribed.";
return RedirectToAction("", "home"); return RedirectToAction("", "home");
} }
string subject = "Subscription Confirmation"; string subject = "Bekræft dit abonnement";
string confirmationPath = _configuration["Email:ConfirmEmailPath"]; // Retrieve the confirmation path from appsettings string confirmationPath = _configuration["Email:ConfirmEmailPath"]; // Retrieve the confirmation path from appsettings
string confirmationUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={email}"; // Construct the confirmation URL string confirmationUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={email}"; // Construct the confirmation URL
string unsubscribeUrl = $"{Request.Scheme}://{Request.Host}/unsubscribe?email={email}"; // Add unsubscribe URL
string body = $@"<head> string body = $@"<!DOCTYPE html>
<html>
<head>
<meta charset=""UTF-8""> <meta charset=""UTF-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
<title>Email Confirmation</title>
<style>
body {{
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}}
.container {{
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 0.5px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}}
h5, h6 {{
margin:0;
}}
hr {{
border: none;
border-top: 1px solid #ccc;
margin: 10px 0;
}}
a.button {{
display: inline-block;
padding: 10px 20px;
background-color: #28a745;
color: #fff;
text-decoration: none;
border-radius: 4px;
}}
a {{
color: #007bff;
text-decoration: none;
}}
a:hover {{
text-decoration: underline;
}}
</style>
</head> </head>
<body> <body style=""font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: white;"">
<div class=""container"">
<p>Dear {senderName},</p> <p>Hej {senderName},</p>
<p>Thank you for subscribing. We're thrilled to have you on board!</p>
<p>To confirm your subscription, please click the following button:</p> <p>Tak for dit abonnement!</p>
<p><a href=""{confirmationUrl}"" class=""button"">Confirm Subscription</a></p>
<p>If you have any questions or need assistance, feel free to contact us at help@seosoft.dk</p> <p>For at bekræfte dit abonnement, skal du klikke knappen herunder:</p>
<h5>Søren Eggert Lundsteen Olsen</h5> <p>
<h5><a href=""https://www.seosoft.dk/"" target=""_blank"">SeoSoft ApS</a></h5> <a href=""{confirmationUrl}"" style=""display: inline-block; padding: 12px 24px; background-color: #28a745; color: white; text-decoration: none; border-radius: 3px; font-weight: bold;"">
<hr> Bekræft abonnement
<h6>Hovedgaden 3 Jordrup<br>Kolding 6064<br>Denmark</h6> </a>
</div> </p>
</body>";
<p>Hvis knappen ikke virker, kan du kopiere dette link ind i din browser:</p>
//string body = $@"Dear {senderName},<br><br> <p>{confirmationUrl}</p>
//Thank you for subscribing. We're thrilled to have you on board!<br><br>
//To confirm your subscription, please click the following button:<br><br>
//<a href=""{confirmationUrl}"" style=""display: inline-block; padding: 10px 20px; background-color: #28a745; color: #fff; text-decoration: none;"">Confirm Subscription</a><br><br> <br>
//If you have any questions or need assistance, feel free to contact us at help@seosoft.dk<br><br>
<p>Med venlig hilsen,<br>
//<h5> Nærværskonsulenterne ApS</p>
// Søren Eggert Lundsteen Olsen<br>
// Seosoft ApS <hr style=""border: none; border-top: 1px solid #cccccc; margin: 20px 0;"">
//</h5>
// <hr> <p style=""font-size: 12px; color: #666666;"">
// <h6> Nærværskonsulenterne ApS<br>
// Hovedgaden 3 Brødemosevej 24A, 3300 Frederiksværk<br>
// Jordrup<br> kontakt@nvkn.dk
// Kolding 6064<br> </p>
// Denmark
//</6>
// ";
</body>
</html>";
var newEmail = new EmailToSend(email, subject, body); var newEmail = new EmailToSend(email, subject, body);
@ -150,27 +111,22 @@ namespace Web.Controllers
_context.Subscriptions.Add(subscriber); _context.Subscriptions.Add(subscriber);
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
TempData["success"] = "Subscription successful. Please confirm your email."; TempData["success"] = "Abonnement oprettet. Bekræft venligst din email.";
return RedirectToAction("", "home"); return RedirectToAction("", "home");
} }
catch (Exception) catch (Exception)
{ {
TempData["error"] = "Failed to subscribe."; TempData["error"] = "Kunne ikke oprette abonnement.";
return RedirectToAction("", "home"); return RedirectToAction("", "home");
} }
} }
return RedirectToAction("", "home"); return RedirectToAction("", "home");
} }
[HttpGet] [HttpGet]
public async Task<IActionResult> Confirmation(string email) public async Task<IActionResult> Confirmation(string email)
{ {
try try
{ {
// Find the subscription with the provided email // Find the subscription with the provided email
@ -181,7 +137,7 @@ namespace Web.Controllers
if (subscription.IsSubscribed) if (subscription.IsSubscribed)
{ {
// If IsSubscribed is already true, inform the user that the email is already confirmed // If IsSubscribed is already true, inform the user that the email is already confirmed
ViewBag.Message = "Your email is already confirmed. Thank you!"; ViewBag.Message = "Din email er allerede bekræftet. Tak!";
} }
else else
{ {
@ -191,7 +147,6 @@ namespace Web.Controllers
var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email); var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email);
// Set IsUnsubscribed flag to true for email events // Set IsUnsubscribed flag to true for email events
foreach (var emailEvent in sentEmails) foreach (var emailEvent in sentEmails)
{ {
@ -202,70 +157,55 @@ namespace Web.Controllers
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
// Send a "thank you" email to the user // Send a "thank you" email to the user
string subject = "Thank You for Confirming Your Subscription"; string subject = "Tak for bekræftelse af dit abonnement";
string body = $@"<head> string unsubscribeUrl = $"{Request.Scheme}://{Request.Host}/unsubscribe?email={email}";
<meta charset=""UTF-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
<title>Email Confirmation</title>
<style>
body {{
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}}
.container {{
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 0.5px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}}
h4, h5, h6 {{
margin: 0;
}}
hr {{
border: none;
border-top: 1px solid #ccc;
margin: 10px 0;
}}
a {{
color: #007bff;
text-decoration: none;
}}
a:hover {{
text-decoration: underline;
}}
</style>
</head>
<body>
<div class=""container"">
<h4>Dear {subscription.Name},</h4>
<p>Thank you for confirming your subscription. You are now subscribed to our newsletter.</p>
<h5>Søren Eggert Lundsteen Olsen</h5>
<h5><a href=""https://www.seosoft.dk/"" target=""_blank"">SeoSoft ApS</a></h5>
<hr>
<h6>Hovedgaden 3 Jordrup<br>Kolding 6064<br>Denmark</h6>
</div>
</body>";
string body = $@"<!DOCTYPE html>
<html>
<head>
<meta charset=""UTF-8"">
</head>
<body style=""font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: white;"">
<p>Hej {subscription.Name},</p>
<p>Tak for at bekræfte dit abonnement. Du er nu tilmeldt vores nyhedsbrev.</p>
<p>Du vil modtage vores seneste nyheder og opdateringer denne email-adresse.</p>
<br>
<p>Med venlig hilsen,<br>
Nærværskonsulenterne ApS</p>
<hr style=""border: none; border-top: 1px solid #cccccc; margin: 20px 0;"">
<p style=""font-size: 12px; color: #666666;"">
Nærværskonsulenterne ApS<br>
Brødemosevej 24A, 3300 Frederiksværk<br>
kontakt@nvkn.dk
</p>
</body>
</html>";
var thankYouEmail = new EmailToSend(subscription.Email, subject, body); var thankYouEmail = new EmailToSend(subscription.Email, subject, body);
await _mailSerivces.SendConfirmationEmailAsync(thankYouEmail); await _mailSerivces.SendConfirmationEmailAsync(thankYouEmail);
// Inform the user that the email has been confirmed // Inform the user that the email has been confirmed
ViewBag.Message = "Thank you for confirming your email. You are now subscribed!"; ViewBag.Message = "Tak for at bekræfte din email. Du er nu tilmeldt!";
} }
return View(subscription); // You can return a view to show a confirmation message return View(subscription); // You can return a view to show a confirmation message
} }
else else
{ {
ViewBag.Message = "You have been unsubscribed from our newsletter. Thank you!"; ViewBag.Message = "Du er blevet afmeldt vores nyhedsbrev. Tak!";
return View(subscription); return View(subscription);
} }
} }
catch (Exception ex) catch (Exception ex)
@ -273,7 +213,6 @@ namespace Web.Controllers
// Log or handle the exception as needed // Log or handle the exception as needed
return View("Error"); // You can return a view to show an error message return View("Error"); // You can return a view to show an error message
} }
} }
[HttpGet] [HttpGet]
@ -296,7 +235,6 @@ namespace Web.Controllers
// Remove the email from SentNewsletterEmail // Remove the email from SentNewsletterEmail
var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email); var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email);
// Set IsUnsubscribed flag to true for email events // Set IsUnsubscribed flag to true for email events
foreach (var emailEvent in sentEmails) foreach (var emailEvent in sentEmails)
{ {
@ -307,83 +245,48 @@ namespace Web.Controllers
await _context.SaveChangesAsync(); await _context.SaveChangesAsync();
// Inform the user that the email has been unsubscribed // Inform the user that the email has been unsubscribed
ViewBag.Message = "You have successfully unsubscribed from our newsletter. We're sorry to see you go"; ViewBag.Message = "Du er nu afmeldt vores nyhedsbrev. Vi er kede af at se dig gå.";
// Optionally, send an email confirmation to the user // Send a simple confirmation email to the user
string subject = "Unsubscription Confirmation"; string subject = "Bekræftelse på afmelding";
string body = $@"<head>
<meta charset=""UTF-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
<title>Unsubscribe Confirmation</title>
<style>
body {{
font-family: Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
background-color: #f9f9f9;
}}
.container {{
max-width: 800px;
margin: 0 auto;
padding: 20px;
border: 0.5px solid #ccc;
border-radius: 5px;
background-color: #f9f9f9;
}}
h5, h6 {{
margin: 0;
}}
hr {{
border: none;
border-top: 1px solid #ccc;
margin: 10px 0;
}}
a {{
color: #007bff;
text-decoration: none;
}}
a:hover {{
text-decoration: underline;
}}
</style>
</head>
<body>
<div class=""container"">
<h3>Unsubscribe Confirmation</h3>
<p>You have successfully unsubscribed from our newsletter. We're sorry to see you go.</p>
<br>
<h5><strong>Søren Eggert Lundsteen Olsen</strong></h5>
<h5><a href=""https://www.seosoft.dk/"" target=""_blank"">SeoSoft ApS</a></h5>
<hr>
<h6>Hovedgaden 3<br>Jordrup<br>Kolding 6064<br>Denmark</h6>
</div>
</body>
</html>";
var thankYouEmail = new EmailToSend(subscription.Email, subject, body); // Simple plain text email body
await _mailSerivces.SendConfirmationEmailAsync(thankYouEmail); string body = $@"Hej,<br/><br/>
return View(subscription); // You can return a view to show a confirmation message Du er nu afmeldt vores nyhedsbrev.<br/><br/>
Med venlig hilsen,<br>
Nærværskonsulenterne ApS
<hr><br/>
<br/>
Nærværskonsulenterne ApS<br>
Brødemosevej 24A, 3300 Frederiksværk<br>
kontakt@nvkn.dk";
var confirmationEmail = new EmailToSend(subscription.Email, subject, body);
await _mailSerivces.SendConfirmationEmailAsync(confirmationEmail);
return View(subscription);
} }
else else
{ {
// If IsSubscribed is already false, inform the user that the email is already unsubscribed // If IsSubscribed is already false, inform the user that the email is already unsubscribed
ViewBag.Message = "Your email is already unsubscribed. Thank you!"; ViewBag.Message = "Din email er allerede afmeldt. Tak!";
return View(subscription); // You can return a view to show a message return View(subscription);
} }
} }
else else
{ {
// Inform the user that the unsubscription process couldn't be completed // Inform the user that the unsubscription process couldn't be completed
ViewBag.Message = "You have been unsubscribed from our newsletter. subscribe first."; ViewBag.Message = "Du er blevet afmeldt vores nyhedsbrev. Tilmeld dig først.";
return View(subscription); // You can return a view to show an error message return View(subscription);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
// Log or handle the exception as needed // Log or handle the exception as needed
return View("Error"); // You can return a view to show an error message return View("Error");
} }
} }