Skip to content

Commit 6ef1c07

Browse files
authored
Merge pull request #17 from hmislk/main
Add Email Capabilities
2 parents e000ed9 + 00c1754 commit 6ef1c07

File tree

8 files changed

+191
-1
lines changed

8 files changed

+191
-1
lines changed

.github/workflows/rh_prod_actions.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ jobs:
2121

2222
- name: Build with Java Compiler
2323
run: |
24-
javac -cp "lib/ESMSlibV4.0.jar:lib/jakarta.ws.rs-api-3.1.0.jar:lib/jakarta.enterprise.cdi-api-4.1.0.jar:lib/jakarta.inject-api-2.0.1.jar" -d target/WEB-INF/classes src/java/org/carecode/sms/mobitel/controllers/*
24+
javac -cp "lib/ESMSlibV4.0.jar:lib/jakarta.ws.rs-api-3.1.0.jar:lib/jakarta.enterprise.cdi-api-4.1.0.jar:lib/jakarta.inject-api-2.0.1.jar:lib/jakarta.mail-api-2.1.3.jar" -d target/WEB-INF/classes src/java/org/carecode/sms/mobitel/controllers/*
2525
mkdir target/WEB-INF/lib
2626
cp lib/ESMSlibV4.0.jar target/WEB-INF/lib/
27+
echo ${{ secrets.CONFIG }} > target/WEB-INF/classes/config.properties
2728
jar -cvf target/ccmm.war -C target/ .
2829
jar tf target/ccmm.war
2930

config.properties

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Email configuration properties
2+
mail.username=[email protected]
3+
mail.password=password
4+
mail.smtp.host=smtp.gmail.com
5+
mail.smtp.port=587
6+
mail.smtp.auth=true
7+
mail.smtp.starttls.enable=true

lib/jakarta.mail-api-2.1.3.jar

231 KB
Binary file not shown.

src/java/org/carecode/sms/mobitel/controllers/ApplicationConfig.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22

33
import jakarta.ws.rs.core.Application;
44

5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.util.Map;
8+
import java.util.Properties;
59
import java.util.Set;
10+
import java.util.logging.Logger;
611

712
/**
813
* @author Dr M H B Ariyaratne <[email protected]>
914
*/
1015
@jakarta.ws.rs.ApplicationPath("ws")
1116
public class ApplicationConfig extends Application {
17+
private static final Logger logger = Logger.getLogger(ApplicationConfig.class.getName());
18+
1219
@Override
1320
public Set<Class<?>> getClasses() {
1421
Set<Class<?>> resources = new java.util.HashSet<>();
@@ -24,4 +31,24 @@ public Set<Class<?>> getClasses() {
2431
*/
2532
private void addRestResourceClasses(Set<Class<?>> resources) {
2633
}
34+
35+
@Override
36+
public Map<String, Object> getProperties() {
37+
Map<String, Object> props = super.getProperties();
38+
loadPropertiesFromFile();
39+
40+
return props;
41+
}
42+
43+
private void loadPropertiesFromFile() {
44+
Properties props = System.getProperties();
45+
46+
final String configFilePath = "config.properties";
47+
48+
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(configFilePath)) {
49+
props.load(inputStream);
50+
} catch (IOException e) {
51+
logger.severe("Error loading config.properties: " + e.getMessage());
52+
}
53+
}
2754
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.carecode.sms.mobitel.controllers;
2+
3+
import java.util.List;
4+
5+
public final class EmailRequest {
6+
public String subject;
7+
public String body;
8+
public List<String> recipients;
9+
public String replyTo;
10+
public Boolean isHtml;
11+
12+
@Override
13+
public String toString() {
14+
return "EmailRequest{" +
15+
"subject='" + subject + '\'' +
16+
", body='" + body + '\'' +
17+
", recipients=" + recipients +
18+
", replyTo='" + replyTo + '\'' +
19+
", isHtml=" + isHtml +
20+
'}';
21+
}
22+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package org.carecode.sms.mobitel.controllers;
2+
3+
import jakarta.mail.*;
4+
import jakarta.mail.internet.AddressException;
5+
import jakarta.mail.internet.InternetAddress;
6+
import jakarta.mail.internet.MimeMessage;
7+
import jakarta.ws.rs.Consumes;
8+
import jakarta.ws.rs.POST;
9+
import jakarta.ws.rs.Path;
10+
import jakarta.ws.rs.Produces;
11+
import jakarta.ws.rs.core.MediaType;
12+
import jakarta.ws.rs.core.Response;
13+
14+
import java.util.List;
15+
import java.util.Properties;
16+
import java.util.logging.Logger;
17+
18+
@Path("email")
19+
public class EmailResource {
20+
private static final Logger logger = Logger.getLogger(EmailResource.class.getName());
21+
22+
private static Session session;
23+
24+
@POST
25+
@Path("send")
26+
@Consumes(MediaType.APPLICATION_JSON)
27+
@Produces(MediaType.APPLICATION_JSON)
28+
public Response sendEmail(final EmailRequest emailRequest) {
29+
try {
30+
updateSession();
31+
32+
MimeMessage message = new MimeMessage(session);
33+
message.setHeader("format", "flowed");
34+
message.setHeader("Content-Transfer-Encoding", "quoted-printable");
35+
36+
if (emailRequest.subject != null) {
37+
message.setSubject(emailRequest.subject);
38+
} else {
39+
throw new RuntimeException("Subject is required.");
40+
}
41+
42+
if (emailRequest.isHtml != null && emailRequest.isHtml) {
43+
message.setContent(emailRequest.body, "text/html");
44+
message.setHeader("Content-Type", "text/html; charset=utf-8");
45+
} else {
46+
message.setText(emailRequest.body);
47+
message.setHeader("Content-Type", "text/plain; charset=utf-8");
48+
}
49+
50+
if (emailRequest.replyTo != null) {
51+
message.setReplyTo(new InternetAddress[]{new InternetAddress(emailRequest.replyTo)});
52+
} else {
53+
message.setReplyTo(InternetAddress.parse("[email protected]", false));
54+
}
55+
56+
if (emailRequest.recipients != null && !emailRequest.recipients.isEmpty()) {
57+
message.addRecipients(Message.RecipientType.TO, getInternetAddresses(emailRequest.recipients));
58+
} else {
59+
throw new RuntimeException("At least one recipient email address is required.");
60+
}
61+
62+
Transport.send(message);
63+
logger.info("Email sent successfully to recipients.");
64+
65+
return Response.ok(new EmailResponse(
66+
SentStatus.SENT, "Email sent successfully to recipients.")).build();
67+
} catch (Exception e) {
68+
final String message = "Failed to send email: " + e.getMessage();
69+
70+
logger.severe(message);
71+
return Response.ok(new EmailResponse(SentStatus.FAILED, message)).build();
72+
}
73+
}
74+
75+
private static void updateSession() {
76+
if (session == null) {
77+
Properties properties = new Properties();
78+
79+
System.getProperties().forEach((key, value) -> {
80+
if (key.toString().startsWith("mail.")) {
81+
properties.put(key, value);
82+
}
83+
});
84+
85+
Authenticator auth = new Authenticator() {
86+
protected PasswordAuthentication getPasswordAuthentication() {
87+
return new PasswordAuthentication(
88+
properties.getProperty("mail.username"), properties.getProperty("mail.password"));
89+
}
90+
};
91+
92+
session = Session.getInstance(properties, auth);
93+
}
94+
}
95+
96+
private static InternetAddress[] getInternetAddresses(final List<String> recipients) {
97+
return recipients.stream()
98+
.map(recipientAddress -> {
99+
try {
100+
return new InternetAddress(recipientAddress);
101+
} catch (AddressException e) {
102+
logger.severe(
103+
"Invalid recipient email address: " + recipientAddress + " : " + e.getMessage());
104+
throw new RuntimeException(e);
105+
}
106+
})
107+
.toArray(InternetAddress[]::new);
108+
}
109+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.carecode.sms.mobitel.controllers;
2+
3+
public final class EmailResponse {
4+
public SentStatus status;
5+
public String message;
6+
7+
public EmailResponse(SentStatus status, String message) {
8+
this.status = status;
9+
this.message = message;
10+
}
11+
12+
@Override
13+
public String toString() {
14+
return "EmailResponse{" +
15+
"status=" + status +
16+
", message='" + message + '\'' +
17+
'}';
18+
}
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.carecode.sms.mobitel.controllers;
2+
3+
public enum SentStatus {
4+
SENT, FAILED
5+
}

0 commit comments

Comments
 (0)