#HOWTO: Send E-Mails with SendGrid and Spring Boot

In the last weeks, I was searching for a nice solution to send emails to users for one of my side projects. Sending plain text formatted emails with the Spring Boot Mail Starter is quite easy as it is an abstraction using the JavaMailSender interface and auto-configured. It’s also possible to send HTML formatted emails or use a template engine like Thymeleaf to generate the content. With this setup, I had to generate the different email templates by myself using my editor. As email design and HTML is not one of my main strengths I took a lot of time and I started searching for a solution where the “business” could template the emails by themselves with a WYSIWYG as they have no deeper HTML knowledge.

For this task, I found a service called SendGrid. With SendGrid you can create nice looking email templates using a web editor with drag-and-drop functionality. You can also define variables within your email templates to e.g. add the username or a link to the body. Another nice benefit of SendGrid is that it is integrated into the most Cloud Providers (e.g. Azure, Heroku, Pivotal Web Services …) and with the free version of SendGrid you can cover most of the use cases of a small to a mid-sized project.

The built-in email editor gives you the opportunity to add own HTML code or to use some prebuild modules for your email e.g. a button, social media icons and a unsubscribe link. Variables for your email are surrounded with –VARIABLE_NAME- :

 

To reproduce the following code example you need an own SendGrid account and you have to create an API key to communicate with the internal SendGrid API.

For a quick example, I’ll create a Spring Boot web project with one REST controller which will trigger sending an email. The pom.xml for this project looks like the following:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>de.rieckpil.blog</groupId>
    <artifactId>send-emails-with-sendgrid-and-spring-boot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>send-emails-with-sendgrid-and-spring-boot</name>
    <description>Demo project for Spring Boot with SendGrid</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.sendgrid</groupId>
            <artifactId>sendgrid-java</artifactId>
            <version>4.2.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

If you have spring-boot-autoconfigure on your classpath which is a transitive dependency of e.g. spring-boot-starter-web you just have to add your API key to your application.properties file and Spring Boot will take care of creating the central bean for the communication with the SendGrid API:

spring.sendgrid.api-key=YOUR_API_KEY_HERE

The REST endpoint looks like the following:

package de.rieckpil.blog.sendemailswithsendgridandspringboot;

import com.sendgrid.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
public class MailController {

    @Autowired
    private SendGrid sendGrid;

    @Value("${templateId}")
    private String EMAIL_TEMPLATE_ID;

    @GetMapping("/sendgrid")
    public String sendEmailWithSendGrid(@RequestParam("msg") String message) {

        Email from = new Email("yourname@yourhostname.de");
        String subject = "Hello World!";
        Email to = new Email("yourname@yourhostname.de");
        Content content = new Content("text/html", "I'm replacing the <strong>body tag</strong>" + message);

        Mail mail = new Mail(from, subject, to, content);

        mail.setReplyTo(new Email("yourname@yourhostname.de"));
        mail.personalization.get(0).addSubstitution("-username-", "Some blog user");
        mail.setTemplateId(EMAIL_TEMPLATE_ID);

        Request request = new Request();
        Response response = null;


        try {
            request.setMethod(Method.POST);
            request.setEndpoint("mail/send");
            request.setBody(mail.build());

            response = sendGrid.api(request);

            System.out.println(response.getStatusCode());
            System.out.println(response.getBody());
            System.out.println(response.getHeaders());
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }

        return "email was successfully send";
    }
}

The central communication interface is the SendGrid bean which offers a nice programming API for sending emails. The substitution of variables is achieved with the following line of code:

mail.personalization.get(0).addSubstitution("-username-", "Some blog user");

To address the right email template you have to set the template ID correctly. A simple HTTP GET call in the browser like http://localhost:8080/sendgrid?msg=Hello%20World will send the following email:

You can find the full code example on GitHub. To use it locally you have to replace the SendGrid API key and the template id in the application.properties file.

Happy email sending!

Phil

Leave a comment

Your email address will not be published. Required fields are marked *