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
var subscribedUsers = await _context.Subscriptions.Where(s => s.IsSubscribed).ToListAsync();
string confirmationPath = _configuration["Email:unsubscribePath"];
// Send the newsletter email to each subscribed user
foreach (var user in subscribedUsers)
{
string confirmationUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={user.Email}";
string emailBody = $@"<head>
string unsubscribeUrl = $"{Request.Scheme}://{Request.Host}/{confirmationPath}?email={user.Email}";
// This HTML version with proper line breaks works for primary inbox
string emailBody = $@"<!DOCTYPE html>
<html>
<head>
<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.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>
<p>Hej {user.Name},</p>
<div>
{viewModel.Body.Replace("\n", "<br><br>")}
</div>
<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>
<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>
</body>";
<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 isSent = await _emailServices.SendConfirmationEmailAsync(email);
@ -190,32 +164,27 @@ namespace Web.Areas.Admin.Controllers
RecipientEmail = user.Email,
Subject = viewModel.Subject,
Body = emailBody,
SentDate = DateTime.UtcNow,
IsSent = isSent // Assuming isSent returns a boolean indicating success
IsSent = isSent
};
_context.SentNewsletterEamils.Add(sentEmail);
// Handle failure to send email if needed
// Add small delay to look more natural
await Task.Delay(2000); // 2 second delay between sends
}
await _context.SaveChangesAsync(); // Save changes for all sent emails
TempData["success"] = "Newsletter sent successfully.";
await _context.SaveChangesAsync();
TempData["success"] = "Nyhedsbrev sendt successfully.";
return RedirectToAction(nameof(Index));
}
catch (Exception ex)
{
// Log or handle the exception as needed
TempData["error"] = "Something went wrong: " + ex.Message;
TempData["error"] = "Noget gik galt: " + ex.Message;
return RedirectToAction(nameof(Index));
}
}
return View(viewModel);
}
[HttpGet]
public IActionResult UploadSubscribers()
{

View file

@ -37,7 +37,7 @@ namespace Web.Controllers
public async Task<IActionResult> Subscribe(Subscription subscription)
{
if(ModelState.IsValid)
if (ModelState.IsValid)
{
try
{
@ -48,94 +48,55 @@ namespace Web.Controllers
var existingSubscription = await _context.Subscriptions.FirstOrDefaultAsync(s => s.Email == email);
if (existingSubscription != null)
{
TempData["error"] = "Email already subscribed.";
TempData["error"] = "Du er allerede abonneret.";
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 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 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>
<body>
<div class=""container"">
<p>Dear {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><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>
<body style=""font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: white;"">
<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>";
<p>Hej {senderName},</p>
//string body = $@"Dear {senderName},<br><br>
//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>
//If you have any questions or need assistance, feel free to contact us at help@seosoft.dk<br><br>
<p>Tak for dit abonnement!</p>
//<h5>
// Søren Eggert Lundsteen Olsen<br>
// Seosoft ApS
//</h5>
// <hr>
// <h6>
// Hovedgaden 3
// Jordrup<br>
// Kolding 6064<br>
// Denmark
//</6>
// ";
<p>For at bekræfte dit abonnement, skal du klikke knappen herunder:</p>
<p>
<a href=""{confirmationUrl}"" style=""display: inline-block; padding: 12px 24px; background-color: #28a745; color: white; text-decoration: none; border-radius: 3px; font-weight: bold;"">
Bekræft abonnement
</a>
</p>
<p>Hvis knappen ikke virker, kan du kopiere dette link ind i din browser:</p>
<p>{confirmationUrl}</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 newEmail = new EmailToSend(email, subject, body);
@ -150,27 +111,22 @@ namespace Web.Controllers
_context.Subscriptions.Add(subscriber);
await _context.SaveChangesAsync();
TempData["success"] = "Subscription successful. Please confirm your email.";
TempData["success"] = "Abonnement oprettet. Bekræft venligst din email.";
return RedirectToAction("", "home");
}
catch (Exception)
{
TempData["error"] = "Failed to subscribe.";
TempData["error"] = "Kunne ikke oprette abonnement.";
return RedirectToAction("", "home");
}
}
return RedirectToAction("", "home");
}
[HttpGet]
public async Task<IActionResult> Confirmation(string email)
{
try
{
// Find the subscription with the provided email
@ -181,7 +137,7 @@ namespace Web.Controllers
if (subscription.IsSubscribed)
{
// 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
{
@ -191,7 +147,6 @@ namespace Web.Controllers
var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email);
// Set IsUnsubscribed flag to true for email events
foreach (var emailEvent in sentEmails)
{
@ -202,69 +157,54 @@ namespace Web.Controllers
await _context.SaveChangesAsync();
// Send a "thank you" email to the user
string subject = "Thank You for Confirming Your Subscription";
string body = $@"<head>
string subject = "Tak for bekræftelse af dit abonnement";
string unsubscribeUrl = $"{Request.Scheme}://{Request.Host}/unsubscribe?email={email}";
string body = $@"<!DOCTYPE html>
<html>
<head>
<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>
<body style=""font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: white;"">
<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>";
<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);
await _mailSerivces.SendConfirmationEmailAsync(thankYouEmail);
// 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
}
else
{
ViewBag.Message = "You have been unsubscribed from our newsletter. Thank you!";
ViewBag.Message = "Du er blevet afmeldt vores nyhedsbrev. Tak!";
return View(subscription);
}
}
@ -273,7 +213,6 @@ namespace Web.Controllers
// Log or handle the exception as needed
return View("Error"); // You can return a view to show an error message
}
}
[HttpGet]
@ -296,7 +235,6 @@ namespace Web.Controllers
// Remove the email from SentNewsletterEmail
var sentEmails = _context.SentNewsletterEamils.Where(e => e.RecipientEmail == email);
// Set IsUnsubscribed flag to true for email events
foreach (var emailEvent in sentEmails)
{
@ -307,83 +245,48 @@ namespace Web.Controllers
await _context.SaveChangesAsync();
// 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
string subject = "Unsubscription Confirmation";
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>";
// Send a simple confirmation email to the user
string subject = "Bekræftelse på afmelding";
var thankYouEmail = new EmailToSend(subscription.Email, subject, body);
await _mailSerivces.SendConfirmationEmailAsync(thankYouEmail);
// Simple plain text email body
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
{
// If IsSubscribed is already false, inform the user that the email is already unsubscribed
ViewBag.Message = "Your email is already unsubscribed. Thank you!";
return View(subscription); // You can return a view to show a message
ViewBag.Message = "Din email er allerede afmeldt. Tak!";
return View(subscription);
}
}
else
{
// Inform the user that the unsubscription process couldn't be completed
ViewBag.Message = "You have been unsubscribed from our newsletter. subscribe first.";
return View(subscription); // You can return a view to show an error message
ViewBag.Message = "Du er blevet afmeldt vores nyhedsbrev. Tilmeld dig først.";
return View(subscription);
}
}
catch (Exception ex)
{
// Log or handle the exception as needed
return View("Error"); // You can return a view to show an error message
return View("Error");
}
}