Reputation: 700
I'm trying to use email templates to personalize the email which I send by passing the data to already created templates through a JSON string. Even though I'm able to send a raw email by attaching the files, I want a way through which I can send email attachments in the email while using email templates in SES.
Upvotes: 8
Views: 7492
Reputation: 882
Solution with SES v2, Java 17 and jakarta.mail:
public class EmailContentDto {
private String templateName;
private String content;
private String subject;
private String[] to;
private String[] cc;
private String[] bcc;
private EmailAttachmentDto[] attachments;
}
private void sendTemplated(EmailContentDto email) throws Exception {
EmailAttachmentDto[] attachments = email.getAttachments();
if (attachments == null || attachments.length < 1) {
Template template = Template.builder()
.templateName(email.getTemplateName())
.templateData(email.getContent())
.build();
EmailContent emailContent = EmailContent.builder()
.template(template)
.build();
SendEmailRequest emailRequest = buildSendEmailRequest(email, emailContent);
awsSesService.send(emailRequest);
} else {
sendRawTemplated(email);
}
}
private void sendRawTemplated(EmailContentDto email) throws Exception {
String mimeContent = awsSesService.getRenderedTemplate(email.getTemplateName(), email.getContent());
String content = parseMimeContent(mimeContent);
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(content, "text/html; charset=" + EmailConstants.DEF_CHARSET);
sendRaw(email, bodyPart);
}
private String parseMimeContent(String mimeContent) throws Exception {
Session session = Session.getDefaultInstance(new Properties());
InputStream inputStream = new ByteArrayInputStream(mimeContent.getBytes());
MimeMessage mimeMessage = new MimeMessage(session, inputStream);
return mimeMessage.getContent().toString();
}
private SendEmailRequest buildSendEmailRequest(EmailContentDto emailDto, EmailContent content) {
return SendEmailRequest.builder()
.destination(Destination.builder()
.toAddresses(emailDto.getTo())
.bccAddresses(emailDto.getBcc() == null ? new String[0] : emailDto.getBcc())
.ccAddresses(emailDto.getCc() == null ? new String[0] : emailDto.getCc())
.build())
.content(content)
.fromEmailAddress(emailFrom)
.build();
}
private void sendRaw(EmailDto email) throws Exception {
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(email.getContent(), "text/plain; charset=" + EmailConstants.DEF_CHARSET);
sendRaw(email, textPart);
}
private void sendRaw(EmailDto email, MimeBodyPart textPart) throws Exception {
Session session = Session.getDefaultInstance(new Properties());
MimeMessage message = new MimeMessage(session);
// basic
message.setSubject(email.getSubject(), EmailConstants.DEF_CHARSET);
message.setFrom(new InternetAddress(emailFrom));
message.setRecipients(jakarta.mail.Message.RecipientType.TO, InternetAddress.parse(email.getToJoining()));
String cc = email.getCcJoining();
if (cc != null) {
message.setRecipients(jakarta.mail.Message.RecipientType.CC, InternetAddress.parse(cc));
}
String bcc = email.getBccJoining();
if (bcc != null) {
message.setRecipients(jakarta.mail.Message.RecipientType.BCC, InternetAddress.parse(bcc));
}
// multipart container.
MimeMultipart msgBody = new MimeMultipart("alternative");
MimeBodyPart wrap = new MimeBodyPart();
msgBody.addBodyPart(textPart);
wrap.setContent(msgBody);
MimeMultipart msg = new MimeMultipart("mixed");
message.setContent(msg);
msg.addBodyPart(wrap);
// attachments
for (EmailAttachmentDto attachment : email.getAttachments()) {
MimeBodyPart att = new MimeBodyPart();
byte[] decoded = Base64.getDecoder().decode(attachment.getContent());
DataSource fds = new ByteArrayDataSource(decoded, attachment.getMimeType());
att.setDataHandler(new DataHandler(fds));
att.setFileName(attachment.getName());
msg.addBodyPart(att);
}
// RawMessage
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
message.writeTo(outputStream);
ByteBuffer buf = ByteBuffer.wrap(outputStream.toByteArray());
byte[] arr = new byte[buf.remaining()];
buf.get(arr);
SdkBytes data = SdkBytes.fromByteArray(arr);
RawMessage rawMessage = RawMessage.builder().data(data).build();
SendEmailRequest emailRequest = SendEmailRequest.builder()
.content(EmailContent.builder().raw(rawMessage).build())
.build();
this.awsSesService.send(emailRequest);
}
class AWSSesService {
public SendEmailResponse send(final SendEmailRequest request) {
SesV2Client client = getClient();
return client.sendEmail(request);
}
// ...
}
Imports jakarta.mail 2.0.1:
import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.mail.Session;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.util.ByteArrayDataSource;
Upvotes: 0
Reputation: 75
As per my RND there is no way to send an email using SES template along with attachment, But yes we can do something like this.
Grab template from SES using the code below then we can replace the token and then we use these in SendRawEmail email along with the attachements.
AmazonSimpleEmailService emailSendClient =
AmazonSimpleEmailServiceClient.builder()
.withRegion(Regions.AP_SOUTH_1).build();
String templateName = "MyTemplate";
GetTemplateRequest getTemplateRequest = new GetTemplateRequest();
getTemplateRequest.setTemplateName(templateName);
GetTemplateResult temp = emailSendClient.getTemplate(getTemplateRequest);
String htmlpart = temp.getTemplate().getHtmlPart();
Upvotes: 8