Skip to content

Commit

Permalink
- Modified existing codes for newsletter subscription and unsubscript…
Browse files Browse the repository at this point in the history
…ion:

  - Enhanced the subscription logic to check for existing subscribers and manage reactivation.
  - Implemented the unsubscription logic to handle user requests using a unique token.
- Integrated JavaMailSender for sending subscription confirmation emails:
  - Set up email configuration to enable sending emails via Gmail.
  - Added functionality to send an email notification to users upon successful subscription.
  • Loading branch information
shreya5653 committed Oct 27, 2024
1 parent d7e708a commit 0e978fc
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 111 deletions.
32 changes: 32 additions & 0 deletions src/main/java/com/libraryman_api/newsletter/EmailService1.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.libraryman_api.newsletter;


import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

@Service
public class EmailService1 {

private final JavaMailSender mailSender;

public EmailService1(JavaMailSender mailSender) {
this.mailSender = mailSender;
}

public void send(String to, String body, String subject, Object notification) {
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, "utf-8");
helper.setText(body, true);
helper.setTo(to);
helper.setSubject(subject);
helper.setFrom("[email protected]");
mailSender.send(mimeMessage);
} catch (MessagingException e) {
throw new IllegalStateException("Failed to send email", e);
}
}
}
27 changes: 27 additions & 0 deletions src/main/java/com/libraryman_api/newsletter/MailConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.libraryman_api.newsletter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
public class MailConfig {

@Bean
public JavaMailSender javaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("[email protected]");
mailSender.setPassword("your-password");

Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
return mailSender;
}
}
Original file line number Diff line number Diff line change
@@ -1,44 +1,26 @@
package com.libraryman_api.newsletter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/newsletter")
@RequestMapping("/newsletter")
public class NewsletterController {

private final NewsletterService newsletterService;

@Autowired
private NewsletterService newsletterService;
public NewsletterController(NewsletterService newsletterService) {
this.newsletterService = newsletterService;
}

// Subscribe endpoint
@PostMapping("/subscribe")
public ResponseEntity<String> subscribe(@RequestBody Map<String, String> requestBody) {
String email = requestBody.get("email");

// Call the service to handle subscription
String response = newsletterService.subscribe(email);

// Return response from the service
if (response.equals("Invalid email format.") || response.equals("Email is already subscribed.")) {
return ResponseEntity.badRequest().body(response);
}

return ResponseEntity.ok(response);
public String subscribe(@RequestParam String email) {
return newsletterService.subscribe(email);
}

// Unsubscribe endpoint using token
@GetMapping("/unsubscribe/{token}")
public ResponseEntity<String> unsubscribe(@PathVariable String token) {
String response = newsletterService.unsubscribe(token);

// Check if the response indicates an error
if (response.equals("Invalid or expired token.") || response.equals("You are already unsubscribed.")) {
return ResponseEntity.badRequest().body(response);
}

return ResponseEntity.ok(response);
@GetMapping("/unsubscribe")
public String unsubscribe(@RequestParam String token) {
return newsletterService.unsubscribe(token);
}
}
73 changes: 36 additions & 37 deletions src/main/java/com/libraryman_api/newsletter/NewsletterService.java
Original file line number Diff line number Diff line change
@@ -1,74 +1,73 @@
package com.libraryman_api.newsletter;

import com.libraryman_api.email.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class NewsletterService {

private final NewsletterSubscriberRepository subscriberRepository;
private final EmailService emailService;

@Autowired
private NewsletterSubscriberRepository subscriberRepository;
public NewsletterService(NewsletterSubscriberRepository subscriberRepository, EmailService emailService) {
this.subscriberRepository = subscriberRepository;
this.emailService = emailService;
}

// Subscribe user after validating email
public String subscribe(String email) {
if (!isValidEmail(email)) {
return "Invalid email format.";
}
if (!isValidEmail(email)) return "Invalid email format.";

// Check if the email already exists
Optional<NewsletterSubscriber> optionalSubscriber = subscriberRepository.findByEmail(email);

if (optionalSubscriber.isPresent()) {
NewsletterSubscriber subscriber = optionalSubscriber.get();

// If the subscriber is inactive, reactivate them
if (!subscriber.isActive()) {
subscriber.setActive(true); // Reactivate the subscriber
subscriber.regenerateToken(); // Generate a new token
subscriberRepository.save(subscriber); // Save the updated subscriber
subscriber.setActive(true);
subscriber.regenerateToken();
subscriberRepository.save(subscriber);
sendSubscriptionEmail(email, subscriber.getUnsubscribeToken());
return "You have successfully re-subscribed!";
} else {
return "Email is already subscribed.";
}
return "Email is already subscribed.";
}

// Save new subscriber if not present
NewsletterSubscriber subscriber = new NewsletterSubscriber(email);
subscriberRepository.save(subscriber);
NewsletterSubscriber newSubscriber = new NewsletterSubscriber(email);
subscriberRepository.save(newSubscriber);
sendSubscriptionEmail(email, newSubscriber.getUnsubscribeToken());
return "You have successfully subscribed!";
}

// Unsubscribe user using the token
public String unsubscribe(String token) {
Optional<NewsletterSubscriber> optionalSubscriber = subscriberRepository.findByUnsubscribeToken(token);

if (optionalSubscriber.isEmpty()) {
return "Invalid or expired token.";
}
if (optionalSubscriber.isEmpty()) return "Invalid or expired token.";

NewsletterSubscriber subscriber = optionalSubscriber.get();
if (!subscriber.isActive()) return "You are already unsubscribed.";

if (!subscriber.isActive()) {
return "You are already unsubscribed.";
}

subscriber.setActive(false); // Set active to false
subscriberRepository.save(subscriber); // Save the updated subscriber
subscriber.setActive(false);
subscriberRepository.save(subscriber);
sendUnsubscribeEmail(subscriber.getEmail());
return "You have successfully unsubscribed!";
}

// Email validation logic
private boolean isValidEmail(String email) {
if (email == null || email.trim().isEmpty()) {
return false;
}
String emailRegex = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
Pattern pattern = Pattern.compile(emailRegex);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
return Pattern.compile(emailRegex).matcher(email).matches();
}

private void sendSubscriptionEmail(String email, String token) {
String subject = "Welcome to Our Newsletter!";
String body = "Thank you for subscribing! To unsubscribe, click the link:\n" +
"http://localhost:8080/newsletter/unsubscribe?token=" + token;
emailService.send(email, body, subject, null);
}

private void sendUnsubscribeEmail(String email) {
String subject = "You have been unsubscribed";
String body = "You have successfully unsubscribed. If this was a mistake, you can re-subscribe.";
emailService.send(email, body, subject, null);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.libraryman_api.newsletter;

import jakarta.persistence.*;

import java.util.UUID;

@Entity
Expand All @@ -16,53 +15,28 @@ public class NewsletterSubscriber {
private String email;

@Column(nullable = false)
private boolean active = true; // Manage subscription status
private boolean active = true;

@Column(name = "unsubscribe_token", nullable = false, unique = true)
private String unsubscribeToken; // Token for unsubscribing
private String unsubscribeToken;

// Default constructor that initializes the token
// Default constructor initializing unsubscribe token
public NewsletterSubscriber() {
this.unsubscribeToken = UUID.randomUUID().toString(); // Generate token by default
this.unsubscribeToken = UUID.randomUUID().toString();
}

// Constructor to initialize with email
// Constructor initializing with email
public NewsletterSubscriber(String email) {
this();
this.email = email;
}

// Getters and setters
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public boolean isActive() {
return active;
}

public void setActive(boolean active) {
this.active = active;
}

public String getUnsubscribeToken() {
return unsubscribeToken;
}

// Method to regenerate a new token
public void regenerateToken() {
this.unsubscribeToken = UUID.randomUUID().toString();
}
// Getters and Setters
public Long getId() { return id; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public boolean isActive() { return active; }
public void setActive(boolean active) { this.active = active; }
public String getUnsubscribeToken() { return unsubscribeToken; }
public void regenerateToken() { this.unsubscribeToken = UUID.randomUUID().toString(); }
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
package com.libraryman_api.newsletter;

import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface NewsletterSubscriberRepository extends JpaRepository<NewsletterSubscriber, Long> {

// Find a subscriber by email
Optional<NewsletterSubscriber> findByEmail(String email);

// Find a subscriber by unsubscribe token
Optional<NewsletterSubscriber> findByUnsubscribeToken(String unsubscribeToken);
}
2 changes: 1 addition & 1 deletion src/main/resources/application-development.properties
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ spring.mail.username=Add_Your_Mail_Service_Username
spring.mail.password=Add_Your_Mail_Service_Password
spring.mail.properties.mail.smtp.auth=Add_Your_Mail_Service_SMTP
spring.mail.properties.mail.starttls.enable=Add_Your_Mail_Service_Start_TLS
spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name
spring.mail.properties.domain_name=Add_Your_Mail_Service_Domain_Name

0 comments on commit 0e978fc

Please sign in to comment.