DEV Community

DevCorner
DevCorner

Posted on

1

How to Build a Newsletter Website with Daily Email Updates (Step-by-Step)

A newsletter website allows users to subscribe and receive daily emails with useful content. In this tutorial, we will build a Spring Boot newsletter website that sends a random LeetCode question to users every day at 7:30 PM.


1. Project Setup

Step 1: Create a Spring Boot Project

Use Spring Initializr to create a Spring Boot project with the following dependencies:

  • Spring Web (for REST API)
  • Spring Boot Mail (for email service)
  • Spring Data JPA (for database operations)
  • Spring Scheduler (for scheduling jobs)
  • H2 Database (or MySQL for persistence)

Download the generated project and extract it.


2. Configure Dependencies

Step 2: Add Dependencies in pom.xml

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

3. Configure Database and Email

Step 3: Update application.properties

# H2 Database Configuration (for development)
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

# Email Configuration
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=your-email@gmail.com
spring.mail.password=your-email-password
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
Enter fullscreen mode Exit fullscreen mode

Note: Use environment variables or a secrets manager for email credentials in production.


4. Create Entity Model

Step 4: Create User Entity

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String email;
    private boolean subscribed;

    // Constructors, Getters, and Setters
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Create Question Entity

@Entity
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private String url;
    private String difficulty;
}
Enter fullscreen mode Exit fullscreen mode

5. Create Services

Step 6: Implement Email Service

@Service
public class EmailService {
    @Autowired
    private JavaMailSender mailSender;

    public void sendEmail(String to, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(to);
        message.setSubject(subject);
        message.setText(text);
        mailSender.send(message);
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 7: Implement Question Service

@Service
public class QuestionService {
    @Autowired
    private QuestionRepository questionRepository;

    public Question getRandomQuestion() {
        List<Question> questions = questionRepository.findAll();
        return questions.isEmpty() ? null : questions.get(new Random().nextInt(questions.size()));
    }
}
Enter fullscreen mode Exit fullscreen mode

6. Implement Subscription System

Step 8: Create User Repository

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}
Enter fullscreen mode Exit fullscreen mode

Step 9: Create Subscription Controller

@RestController
@RequestMapping("/api/subscription")
public class SubscriptionController {
    @Autowired
    private UserRepository userRepository;

    @PostMapping("/subscribe")
    public String subscribe(@RequestParam String email) {
        if (userRepository.findByEmail(email).isPresent()) {
            return "You are already subscribed!";
        }
        userRepository.save(new User(email, true));
        return "Subscription successful!";
    }

    @PostMapping("/unsubscribe")
    public String unsubscribe(@RequestParam String email) {
        userRepository.findByEmail(email).ifPresent(user -> {
            user.setSubscribed(false);
            userRepository.save(user);
        });
        return "Unsubscribed successfully!";
    }
}
Enter fullscreen mode Exit fullscreen mode

7. Implement Email Scheduler

Step 10: Schedule Daily Emails

@Component
public class EmailScheduler {
    @Autowired
    private QuestionService questionService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private UserRepository userRepository;

    @Scheduled(cron = "0 30 19 * * ?") // Runs daily at 7:30 PM
    public void sendDailyQuestion() {
        Question question = questionService.getRandomQuestion();
        if (question != null) {
            String subject = "Daily LeetCode Question - " + question.getDifficulty();
            String body = "Today's question: " + question.getTitle() + "\n"
                        + "Solve it here: " + question.getUrl();

            List<User> subscribers = userRepository.findAll();
            for (User user : subscribers) {
                if (user.isSubscribed()) {
                    emailService.sendEmail(user.getEmail(), subject, body);
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

8. Test and Run the Application

  1. Run Spring Boot Application
mvn spring-boot:run
Enter fullscreen mode Exit fullscreen mode
  1. Subscribe to the newsletter
curl -X POST "http://localhost:8080/api/subscription/subscribe?email=user@example.com"
Enter fullscreen mode Exit fullscreen mode
  1. Unsubscribe from the newsletter
curl -X POST "http://localhost:8080/api/subscription/unsubscribe?email=user@example.com"
Enter fullscreen mode Exit fullscreen mode
  1. Check email inbox at 7:30 PM 🚀

🎯 Congratulations! You have successfully built a newsletter website that sends daily LeetCode questions via email.

Let me know if you have any questions! 🚀

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

DEV is better (more customized, reading settings like dark mode etc) when you're signed in!

Okay