5 min read

Sending Emails with Mailgun in Spring Boot

Discover how to integrate Mailgun with Spring Boot to send styled HTML email notifications using Thymeleaf templates.

JavaSpring BootMailgunThymeleaf

Sending email notifications is a common requirement in modern applications. In this post, I’ll show you how to integrate Mailgun with Spring Boot and use Thymeleaf templates to send styled HTML emails, like the error notifications from my previous blog.

Why Mailgun and Thymeleaf?

Mailgun is a reliable email service with a simple API, perfect for transactional emails. Pairing it with Thymeleaf allows us to create dynamic, styled HTML emails instead of plain text, improving readability and professionalism.

Implementation

Here’s how to set up a `MailgunEmailService` in Spring Boot to send HTML emails. I’ll break it into steps for clarity.

Step 1: Service Configuration

We start by configuring the service with Mailgun credentials and the Thymeleaf template engine, injected via Spring.

java
import com.mailgun.api.v3.MailgunMessagesApi;
import com.mailgun.client.MailgunClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;

@Service
public class MailgunEmailService implements EmailService {

    private final MailgunMessagesApi mailgunMessagesApi;
    private final String fromEmail;
    private final String domain;
    private final TemplateEngine templateEngine;

    public MailgunEmailService(
            @Value("${spring.mail.mailgun.api-key}") String apiKey,
            @Value("${spring.mail.mailgun.domain}") String domain,
            @Value("${spring.mail.mailgun.from-email}") String fromEmail,
            @Value("${spring.mail.mailgun.base-url}") String baseUrl,
            TemplateEngine templateEngine) {
        this.mailgunMessagesApi = MailgunClient.config(baseUrl, apiKey)
                .createApi(MailgunMessagesApi.class);
        this.fromEmail = fromEmail;
        this.domain = domain;
        this.templateEngine = templateEngine;
    }
}

Step 2: Rendering the HTML Template

Next, we use Thymeleaf to render an HTML template (`error-template.html`) with dynamic data like the subject and error message.

java
import org.thymeleaf.context.Context;

@Override
public void sendErrorNotification(String to, String subject, String textBody) {
    Context context = new Context();
    context.setVariable("subject", subject);
    context.setVariable("message", textBody);
    context.setVariable("timestamp", java.time.LocalDateTime.now().toString());

    String htmlContent = templateEngine.process("email/error-template", context);
    sendEmail(to, subject, htmlContent);
}

Step 3: Sending the Email with Mailgun

Finally, we build and send the email using Mailgun’s API, wrapping it in error handling.

java
import com.mailgun.model.message.Message;

private void sendEmail(String to, String subject, String htmlContent) {
    Message message = Message.builder()
            .from(fromEmail)
            .to(to)
            .subject(subject)
            .html(htmlContent)
            .build();

    try {
        mailgunMessagesApi.sendMessage(domain, message);
    } catch (Exception e) {
        throw new RuntimeException("Failed to send email: " + e.getMessage(), e);
    }
}

The HTML Template

Here’s a sample `error-template.html` stored in `resources/templates/email/`. It uses basic CSS for styling and Thymeleaf variables for dynamic content.

html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Error Notification</title>
    <style>
        body { font-family: Arial, sans-serif; color: #333; }
        .container { max-width: 600px; margin: 20px auto; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
        h1 { color: #d32f2f; }
        .footer { margin-top: 20px; font-size: 12px; color: #777; }
    </style>
</head>
<body>
    <div class="container">
        <h1 th:text="${subject}">Error Occurred</h1>
        <p><strong>Message:</strong> <span th:text="${message}">[Error Details]</span></p>
        <p><strong>Timestamp:</strong> <span th:text="${timestamp}">[Time]</span></p>
        <div class="footer">
            <p>This is an automated error notification from your cool api muhahahah</p>
        </div>
    </div>
</body>
</html>

Configuration

Add these properties to your `application.properties` or `application.yml` to configure Mailgun:

properties
spring.mail.mailgun.api-key=your-mailgun-api-key
spring.mail.mailgun.domain=your-domain.com
spring.mail.mailgun.from-email=no-reply@your-domain.com
spring.mail.mailgun.base-url=https://api.mailgun.net/v3

Conclusion

With this setup, you can send professional HTML email notifications using Mailgun and Thymeleaf in Spring Boot. It’s reusable for other email types (like password resets) and ties seamlessly into the error logging service from my previous blog.