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.
- Agentic Reasoning Design Patterns in AI: Examples - October 18, 2024
- LLMs for Adaptive Learning & Personalized Education - October 8, 2024
- Sparse Mixture of Experts (MoE) Models: Examples - October 6, 2024
I found it very helpful. However the differences are not too understandable for me