Integrate MailGun with Spring Boot and Java App

0

In this post, you will learn about integrating your Spring Boot & Java app with MailGun REST API. The following are some of the points covered:

  • Create & Configure/Load MailGun API details
  • MailGun EmailService custom implementation
  • Spring RestTemplate implementation
  • Invoke/Test Email Service

Create & Configure/Load MailGun API Details

The following represents the Config class used to load the configuration beans by loading the properties from application.properties file.

@Configuration
@PropertySource("classpath:application.properties")
public class MailGunConfig {

    @Value("${mailgun.api.username}") String mailGunAPIUsername;
    @Value("${mailgun.api.password}") String mailGunAPIPassword;
    @Value("${mailgun.api.base.url}") String mailGunAPIBaseUrl;
    @Value("${mailgun.api.messages.url}") String mailGunAPIMessagesUrl;

    @Bean
    public String mailGunAPIUsername() {
        return this.mailGunAPIUsername;
    }

    @Bean
    public String mailGunAPIPassword() {
        return this.mailGunAPIPassword;
    }

    @Bean
    public String mailGunAPIBaseUrl() {
        return this.mailGunAPIBaseUrl;
    }

    @Bean
    public String mailGunAPIMessagesUrl() {
        return this.mailGunAPIMessagesUrl;
    }
}

The following represents the code in application.properties file:

#
# MailGun API key
#
mailgun.api.base.url = https://api.mailgun.net/v3/sandbox328746234ashdsad3287ajahdgsj234234.mailgun.org
mailgun.api.messages.url = https://api.mailgun.net/v3/sandbox328746234ashdsad3287ajahdgsj234234.mailgun.org/messages
mailgun.api.username = api
mailgun.api.password = key-gfd234be65dasd1e46b57sd25bd9a122

You could get the above details from MailGun Dashboard.

MailGun EmailService Custom Implementation

Pay attention to some of the following in the code sample given below:

  • Custom RestClient (Spring RestTemplate) is used for making calls to MailGun Web APIs
  • MailGun details such as username, password and URL is passed to RestClient.
  • An object of type MultiValueMap is used for populating the input parameters.
  • Separate APIs for sending text and HTML email
  • Note the @Service annotation used to annotate the class as service.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import com.vflux.rbot.rest.RESTClient;

@Service
public class MailGunEmailService implements EmailService {

    private RESTClient springRestClient;
    private String password;
    private String messagesUrl;
    private String username;

    @Autowired
    public MailGunEmailService(RESTClient springRestClient, String mailGunAPIMessagesUrl, String mailGunAPIUsername,
            String mailGunAPIPassword) {
        this.springRestClient = springRestClient;
        this.username = mailGunAPIUsername;
        this.password = mailGunAPIPassword;
        this.messagesUrl = mailGunAPIMessagesUrl;
    }

    @Override
    public void sendText(String from, String to, String subject, String body) {
        MultiValueMap<String, String> map = getPostRequestObject(from, to, subject);
        map.add("text", body);
        sendEmail(map);

    }

    @Override
    public void sendHTML(String from, String to, String subject, String body) {
        MultiValueMap<String, String> map = getPostRequestObject(from, to, subject);
        map.add("html", body);
        sendEmail(map);
    }

    private void sendEmail(MultiValueMap<String, String> map) {
        this.springRestClient.post(this.messagesUrl, map, this.username, this.password);
    }

    private MultiValueMap<String, String> getPostRequestObject(String from, String to, String subject) {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("from", from);
        map.add("to", to);
        map.add("subject", subject);
        return map;
    }

}

The above class implements the following interface which was also used to create SendGrid Email implementation.

public interface EmailService {
    void sendText(String from, String to, String subject, String body);   
    void sendHTML(String from, String to, String subject, String body);
}

Spring RestTemplate Implementation

Pay attention to some of the following in the custom code given below:

  • Header information populated with the following information:
    • Accept
    • Content-type: Note the type as MediaType.APPLICATION_FORM_URLENCODED. MailGun supports media type as form_urlencoded.
    • Authorization: Basic + Base64 encoded value of username:password
      See the code given below:

      private HttpHeaders createHeadersWithUsernamePassword(String username, String password) {
        return new HttpHeaders() {
            {
                String auth = username + ":" + password;
                byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
                String authHeader = "Basic " + new String(encodedAuth);
                set("Accept", MediaType.APPLICATION_JSON.toString());
                set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
                set("Authorization", authHeader);
            }
        };
      }
      
  • MultiValueMap is the type of input object used with HttpEntity object. See the following code:
    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(request, createHeadersWithUsernamePassword(username, password));
    
  • Response type is set as String. See the following code:
    ResponseEntity<String> response = this.restTemplate.exchange(resourceUrl, HttpMethod.POST, requestEntity, String.class);
    
  • RestTemplateBuilder is used to build an instance of RestTemplate
import java.nio.charset.Charset;
import java.util.Base64;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service("springRestClient")
public class SpringRestClient implements RESTClient {

    private RestTemplate restTemplate;

    @Autowired
    public SpringRestClient(RestTemplateBuilder builder) {
        this.restTemplate =  builder.build();
    }

    @Override
    public Object post(String resourceUrl, MultiValueMap<String, String> request, String username, String password) {
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(request,
                createHeadersWithUsernamePassword(username, password));
        ResponseEntity<String> response = this.restTemplate.exchange(resourceUrl, HttpMethod.POST, requestEntity, String.class);
        Object postObject = response.getBody();
        return postObject;
    }

    private HttpHeaders createHeadersWithUsernamePassword(String username, String password) {
        return new HttpHeaders() {
            {
                String auth = username + ":" + password;
                byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
                String authHeader = "Basic " + new String(encodedAuth);
                set("Accept", MediaType.APPLICATION_JSON.toString());
                set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString());
                set("Authorization", authHeader);
            }
        };
    }
}

The above class implements the following interface:

public interface RESTClient {
    Object post(String resourceUrl, MultiValueMap<String, String> request, String username, String password);
}

Invoke/Test MailGun Email Service

The following is the sample Spring Boot code which can be used to invoke the custom MailGun email implementation created in above example. Make sure your MmailGun account is activated before you try this code sample. You could check the logs of your mails in MailGun Logs Page.

@SpringBootApplication
public class RecruiterbotApplication implements CommandLineRunner {

    @Autowired EmailService mailGunEmailService;

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(RecruiterbotApplication.class);
        app.run(args);
    }

    @Override
    public void run(String... arg0) throws IOException, URISyntaxException {

        this.mailGunEmailService.sendHTML("abc@gmail.com", "efg@gmail.com", "Hello World", "Hello, <strong>how are you doing?</strong>");
    }
}

Further Reading / References

Summary

In this post, you learned about how to integrate your Spring Boot application using MailGun RESTful Web APIs.

Did you find this article useful? Do you have any questions or suggestions about this article? Leave a comment and ask your questions and I shall do my best to address your queries.

Ajitesh Kumar

Ajitesh Kumar

Ajitesh is passionate about various different technologies including programming languages such as Java/JEE, Javascript, PHP, C/C++, mobile programming languages etc, and, computing fundamentals related with cloud-native technologies, application security, cloud computing platforms, mobile apps, big data etc.

He has also authored the book, Building Web Apps with Spring 5 and Angular.
Ajitesh Kumar

Leave A Reply

Time limit is exhausted. Please reload the CAPTCHA.