diff --git a/build.gradle b/build.gradle index cd34738d..c4f4cdff 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,9 @@ ext { dependencies { implementation("org.springframework.boot:spring-boot-starter-web:2.5.5") implementation("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion") + implementation ("org.springframework.boot:spring-boot-starter-validation:$springBootVersion") + implementation 'org.springframework.boot:spring-boot-starter-mail' + testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation("org.springframework.boot:spring-boot-starter-data-jpa:2.5.2") implementation("org.flywaydb:flyway-core:6.4.0") implementation('org.apache.velocity:velocity:1.7') diff --git a/src/main/java/org/fineract/messagegateway/sms/api/EmailApiResource.java b/src/main/java/org/fineract/messagegateway/sms/api/EmailApiResource.java new file mode 100644 index 00000000..a77aa687 --- /dev/null +++ b/src/main/java/org/fineract/messagegateway/sms/api/EmailApiResource.java @@ -0,0 +1,35 @@ +package org.fineract.messagegateway.sms.api; + +import org.fineract.messagegateway.sms.data.EmailRequestDTO; +import org.fineract.messagegateway.sms.service.EmailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; + +@RestController +@RequestMapping("/emails") +public class EmailApiResource { + + @Autowired + EmailService emailService; + + @PostMapping + public ResponseEntity sendEmail( + @RequestHeader("Platform-Tenant-Id") String platformTenantId, + @RequestHeader(value = "X-CallbackUrl", required = false) String callbackUrl, + @RequestHeader(value = "X-Correlation-Id", required = false) String correlationId, + @Valid @RequestBody EmailRequestDTO emailRequest + ) { + if (platformTenantId == null || platformTenantId.isEmpty()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Platform-Tenant-Id header is missing"); + } + + emailService.sendEmail(emailRequest,callbackUrl); + + return ResponseEntity.status(HttpStatus.ACCEPTED).body("Email accepted to be sent"); + } +} + diff --git a/src/main/java/org/fineract/messagegateway/sms/data/EmailRequestDTO.java b/src/main/java/org/fineract/messagegateway/sms/data/EmailRequestDTO.java new file mode 100644 index 00000000..b28ad6ef --- /dev/null +++ b/src/main/java/org/fineract/messagegateway/sms/data/EmailRequestDTO.java @@ -0,0 +1,42 @@ +package org.fineract.messagegateway.sms.data; + +import java.util.List; +import javax.validation.Valid; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotEmpty; +public class EmailRequestDTO { + @NotEmpty + private List< String> to; + + @NotEmpty + private String subject; + + @NotEmpty + private String body; + + // Getters and setters + + public List getTo() { + return to; + } + + public void setTo(List to) { + this.to = to; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } +} diff --git a/src/main/java/org/fineract/messagegateway/sms/service/EmailService.java b/src/main/java/org/fineract/messagegateway/sms/service/EmailService.java new file mode 100644 index 00000000..c1ee7c2b --- /dev/null +++ b/src/main/java/org/fineract/messagegateway/sms/service/EmailService.java @@ -0,0 +1,95 @@ +package org.fineract.messagegateway.sms.service; + +import org.fineract.messagegateway.MessageGateway; +import org.fineract.messagegateway.sms.data.EmailRequestDTO; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; +import org.springframework.stereotype.Service; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.client.RestTemplate; + +import java.util.Properties; + + +@Service +public class EmailService { + + private static final Logger logger = LoggerFactory.getLogger(EmailService.class); + @Autowired + private JavaMailSender mailSender; + + @Value("${spring.mail.host}") + private String smtpHost; + + @Value("${spring.mail.port}") + private int smtpPort; + + @Value("${spring.mail.username}") + private String smtpUsername; + + @Value("${spring.mail.password}") + private String smtpPassword; + + + + + public void sendEmail(EmailRequestDTO emailRequest, String callbackUrl) { + boolean flag = false; + String error = null; + try{ + ((JavaMailSenderImpl) mailSender).setHost(smtpHost); + ((JavaMailSenderImpl) mailSender).setPort(smtpPort); + ((JavaMailSenderImpl) mailSender).setUsername(smtpUsername); + ((JavaMailSenderImpl) mailSender).setPassword(smtpPassword); + Properties mailProperties = ((JavaMailSenderImpl) mailSender).getJavaMailProperties(); + mailProperties.put("mail.smtp.connectiontimeout", 5000); + mailProperties.put("mail.smtp.timeout", 5000); + mailProperties.put("mail.smtp.writetimeout", 5000); + ((JavaMailSenderImpl) mailSender).setJavaMailProperties(mailProperties); + + SimpleMailMessage message = new SimpleMailMessage(); + message.setTo(emailRequest.getTo().toArray(new String[0])); + message.setSubject(emailRequest.getSubject()); + message.setText(emailRequest.getBody()); + mailSender.send(message); + flag = true; + + } catch (Exception e) { + error = e.getMessage(); + } + RestTemplate restTemplate = new RestTemplate(); + + if(flag) + { + String requestBody = "Email sent successfully to {to}"; + restTemplate.postForObject(callbackUrl, requestBody.replace("{to}", + emailRequest.getTo().toString()), String.class); + logger.info("Email sent to: " + emailRequest.getTo()); + } + else { + String requestBody = "Email could not be sent to {to} because of {error} "; + requestBody = requestBody.replace("{error}",error); + restTemplate.postForObject(callbackUrl, requestBody.replace("{to}", + emailRequest.getTo().toString()), String.class); + logger.info("Email failed to be sent because {}", error); + + } + + + + } + private ClientHttpRequestFactory createTimeoutRequestFactory() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + factory.setConnectTimeout(5000); + factory.setReadTimeout(5000); + return factory; + } + + + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index d88f1798..29bfbf6a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,6 +22,18 @@ spring: password: ${MYSQL_PASSWORD:password} driver-class-name: org.drizzle.jdbc.DrizzleDriver + mail: + host: ${EMAIL_URL:localhost} + port: 3025 + username: greenmail + password: greenmail + properties: + mail: + smtp: + auth: false + starttls: + enable: false + # Status Callback configuration for Twilio. Port will be taken from server configuration hostconfig: host: localhost @@ -91,4 +103,5 @@ zeebe: contactpoint: "zeebe-zeebe-gateway:26500" worker: timer: "PT15S" - retries: 3 \ No newline at end of file + retries: 3 +