Pages

Wednesday, December 20, 2017

SendGrid Email API integration with Spring Boot REST Application

SendGrid is a popular cloud-based email delivery service. A few months ago, I had an opportunity to work with this technology along with Spring Boot application to send email to subscribers. Today I am going to develop a very simple Spring Boot REST application to integrate SendGrid email API to send an email to a valid email address.



High-level architecture of this application:



SendGrid is not free. But you can sign up for one-month free trial without having a credit card. You can send 40000 emails/month by this trial account.

After signing up, you need to create a template. Additionally, you are required to create an API key.

Complete source code is available to download from my GitHub account

Template Creation at SendGrid:

1. From the left panel of your dashboard go to templates->Transactional. Then click "Create Template " button.


2. Give a name of your template and click ‘Save’



3. Template id is visible at this stage. You need this id in our application.



4. Click on ‘Action’ button, then click ‘+ Add Version’



5. Choose ‘Design Editor’ and then click ‘Continue’



6. Give a template name and double click on <%body%> text.



7. Add the following text to the editor and save the template.

Dear <%name%>

<%body%>

Best Regards,
<%from%>



8. Finally, click the right arrow to exit from template editing.




Creating SendGrid API Key:

1.    From the left panel of your dashboard, click ‘API Keys’



2.    Click ‘Create API’ button.



3.    Give a name of your API Key, allow full access and finally click ‘Create and View’ button.



4.    API key is created. Click on API key to copy. Paste it at any safe place to reuse later. Click “Done” button to finish.



Important Note: You can see this API key only once. If you lost your key, you need to recreate again.

Development Environment:

a)    JDK 1.8
b)    Maven
c)    Spring Boot 1.5
d)    SendGrid Mail API – v3
e)    Eclipse
f)    Postman (Google Chrome extension, API client)
g)    Window 10

POM File: We added an additional dependency of SendGrid.


<?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>com.monirthought.sendgrid</groupId>
    <artifactId>SendGrid-With-Spring</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <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.1.2</version>
        </dependency> 
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>


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

</project>

Controller Class:

package com.monirthought.sendgrid.controller;

import org.springframework.web.bind.annotation.RestController;

import com.monirthought.sendgrid.pojo.EmailPojo;
import com.monirthought.sendgrid.service.SendGridService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Simple Controller class to handle HTTP request.
 * 
 * @author Moniruzzaman
 *
 */
@RestController
public class IndexController {

 @Autowired
 SendGridService sendGridService;

 @RequestMapping(value = "/email/", method = RequestMethod.POST)
 public String index(@RequestBody EmailPojo emailPojo) {
  String response = sendGridService.sendMail(emailPojo);
  return response;
 }

}

Pojo Class:

package com.monirthought.sendgrid.pojo;

/**
 * Pojo class to hold user request data.
 * 
 * @author Moniruzzaman Md
 *
 */
public class EmailPojo {

 private String toName;
 private String toEmail;
 private String fromName;
 private String fromEmail;
 private String emailSubject;
 private String message;

 public String getToName() {
  return toName;
 }

 public void setToName(String toName) {
  this.toName = toName;
 }

 public String getToEmail() {
  return toEmail;
 }

 public void setToEmail(String toEmail) {
  this.toEmail = toEmail;
 }

 public String getFromName() {
  return fromName;
 }

 public void setFromName(String fromName) {
  this.fromName = fromName;
 }

 public String getFromEmail() {
  return fromEmail;
 }

 public void setFromEmail(String fromEmail) {
  this.fromEmail = fromEmail;
 }

 public String getEmailSubject() {
  return emailSubject;
 }

 public void setEmailSubject(String emailSubject) {
  this.emailSubject = emailSubject;
 }

 public String getMessage() {
  return message;
 }

 public void setMessage(String message) {
  this.message = message;
 }
}

Service Class:

Most import method is PersonalizeEmail. Here we configure our email settings.

Let’s understand the entire settings with the help of the image below:



1. At very first, we need to create an instance of Mail.

Mail mail = new Mail();
2. Next, it requires creating an instance of Email. With this email instance, we set “from” information of our email.

Email fromEmail = new Email();
fromEmail.setName(emailPojo.getFromName());
fromEmail.setEmail(emailPojo.getFromEmail());
3. We assign this ‘from’ instance to the Mail object we have created in step 1.

mail.setFrom(fromEmail);
4. In this step, we assign subject of this Mail.

mail.setSubject(emailPojo.getEmailSubject());
5. Our next task is to assign recipient to our Mail instance. To accomplish this, SendGrid provides a Class name ‘Personalization’. After instantiating Personalization, we assign recipient name and email id.

Personalization personalization = new Personalization();
Email to = new Email();
to.setName(emailPojo.getToName());
to.setEmail(emailPojo.getToEmail());
personalization.addTo(to);
6. Add Substitution: Please have a look at the mail template at SendGrid -



personalization.addSubstitution("%name%", emailPojo.getToName());
personalization.addSubstitution("%from%", emailPojo.getFromName());

7. Add template id: Assign the SendGrid template id.

mail.setTemplateId("Your_SendGrid_Template_Id_Here");
8. Add a reply to:
Email replyTo = new Email();
replyTo.setName(emailPojo.getFromName());
replyTo.setEmail(emailPojo.getFromEmail());
mail.setReplyTo(replyTo);
9. Add content to the email.

Content content = new Content();

content.setType("text/plain");
content.setValue(emailPojo.getMessage());
mail.addContent(content);

Complete Code: Please don't forget to replace "Your_SendGripd_API_Key" with your real SendGrid API Key before run.

/**
 * Service class is to configure and send email using SendGrid API
 * 
 * @author Moniruzzaman Md
 *
 */
@Service
public class SendGridServiceImpl implements SendGridService {

 final private String sendGridApi = "Your_SendGripd_API_Key";

 /**
  * PersonalizeEmail - details setting for each email. For the complete example:
  * https://github.com/sendgrid/sendgrid-java/blob/master/examples/helpers/mail/Example.java
  * 
  * @param emailPojo
  * @return Mail
  */
 private Mail PersonalizeEmail(EmailPojo emailPojo) {

  Mail mail = new Mail();

  /* From information setting */
  Email fromEmail = new Email();
  fromEmail.setName(emailPojo.getFromName());
  fromEmail.setEmail(emailPojo.getFromEmail());
  
  mail.setFrom(fromEmail);
  mail.setSubject(emailPojo.getEmailSubject());

  /*
   * Personalization setting, we only add recipient info for this particular
   * example
   */
  Personalization personalization = new Personalization();
  Email to = new Email();
  to.setName(emailPojo.getToName());
  to.setEmail(emailPojo.getToEmail());
  personalization.addTo(to);

  personalization.addHeader("X-Test", "test");
  personalization.addHeader("X-Mock", "true");

  /* Substitution value settings */
  personalization.addSubstitution("%name%", emailPojo.getToName());
  personalization.addSubstitution("%from%", emailPojo.getFromName());

  mail.addPersonalization(personalization);

  /* Set template id */
  mail.setTemplateId("Your_SendGrid_Template_Id");

  /* Reply to setting */
  Email replyTo = new Email();
  replyTo.setName(emailPojo.getFromName());
  replyTo.setEmail(emailPojo.getFromEmail());
  mail.setReplyTo(replyTo);

  /* Adding Content of the email */
  Content content = new Content();

  /* Adding email message/body */
  content.setType("text/plain");
  content.setValue(emailPojo.getMessage());
  mail.addContent(content);

  return mail;
 }

 /*
  * (non-Javadoc)
  * 
  * @see
  * com.monirthougth.sendgrid.service.SendGridService#sendMail(com.monirthought.
  * sendgrid.pojo.EmailPojo)
  */
 @Override
 public String sendMail(EmailPojo emailPojo) {

  SendGrid sg = new SendGrid(sendGridApi);
  sg.addRequestHeader("X-Mock", "true");

  Request request = new Request();
  Mail mail = PersonalizeEmail(emailPojo);
  try {
   request.setMethod(Method.POST);
   request.setEndpoint("mail/send");
   request.setBody(mail.build());
   Response response = sg.api(request);
   System.out.println(response.getStatusCode());
   System.out.println(response.getBody());
   System.out.println(response.getHeaders());
  } catch (IOException ex) {
   ex.printStackTrace();
   return "Failed to send mail! " + ex.getMessage();
  }
  return "Email is sent Successfully!!";
 }

}

Sending Email: Please have a look at the sendMail method above.

1. Need to create an instance of SendGrid.
2. Set Header.
3. Create a Request object.
4. Get Mail instance calling method PersonalizeEmail
5. Set method = POST of the Request instance.
6. Set endpoint = "mail/send" to send email. This endpoint allows us to delivery email over SendGrid’s v3 Web API.
7. Set body of the Request instance with the help of build method of the Mail.
8. Send email calling API method, which returns Response type instance.

Testing:

1. Download the full source code from my GitHub repository.
2. Assign template id and SendGrid API key.
3. Build the project with Maven [ mvn clean package]
4. Start Spring Boot Application [mvn spring-boot:run]
5. Open Postman and configure as like image below -

* Set URL = http://localhost:8080/email
* Select method = POST

* In Body section, request JASON data format is-

{
    "toName": "Recipient Name",
    "toEmail":" Recipient Email Id",
    "fromName": "Your Name",
    "fromEmail": "Your email Id",
    "emailSubject": "Subject of your email",
    "message": "Body of this email."
}

Finally click ‘Send’.

5. If everything goes right, the recipient should receive this email very shortly. In my case, I had this email.



6. In Postman, you will get response data “Email is sent Successfully!!”

7. In the console, you can see these messages -




8. Go to the SendGrid dashboard, then click Activity from the left panel. Delivery reports are available there.



If you want to send email to a Gmail account, you need to consider few issues. Please read this discussion at Stackoverflow

1 comment:

  1. Monir thank you very much for this post it was amazing. Real good step by step guide.

    ReplyDelete