Skip to content

Commit

Permalink
Merge pull request #172 from agorapulse/feature/allow-adding-tags-on-…
Browse files Browse the repository at this point in the history
…emails

Allow adding tags on emails
  • Loading branch information
DKarim authored Aug 17, 2023
2 parents b1778f5 + a87363c commit b21315d
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 32 deletions.
22 changes: 12 additions & 10 deletions docs/guide/src/docs/asciidoc/ses.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ include::{root-dir}/subprojects/micronaut-amazon-awssdk-ses/src/test/groovy/com/
<3> Define the from address
<4> Define one or more recipients
<5> Define HTML body (alternatively you can declare plain text body as well)
<6> Build an attachment
<7> Define the location of the file to be sent
<8> Define the file name (optional - deduced from the file)
<9> Define the mime type (usually optional - deduced from the file)
<10> Define the description of the file (optional)
<6> Define tags for the email, they will be included in SES events
<7> Build an attachment
<8> Define the location of the file to be sent
<9> Define the file name (optional - deduced from the file)
<10> Define the mime type (usually optional - deduced from the file)
<11> Define the description of the file (optional)


[source,java,indent=0,options="nowrap",role="secondary"]
Expand All @@ -72,11 +73,12 @@ include::{root-dir}/subprojects/micronaut-amazon-awssdk-ses/src/test/groovy/com/
<3> Define the from address
<4> Define one or more recipients
<5> Define HTML body (alternatively you can declare plain text body as well)
<6> Build an attachment
<7> Define the location of the file to be sent
<8> Define the file name (optional - deduced from the file)
<9> Define the mime type (usually optional - deduced from the file)
<10> Define the description of the file (optional)
<6> Define tags for the email, they will be included in SES events
<7> Build an attachment
<8> Define the location of the file to be sent
<9> Define the file name (optional - deduced from the file)
<10> Define the mime type (usually optional - deduced from the file)
<11> Define the description of the file (optional)

Please, see
https://agorapulse.github.io/micronaut-aws-sdk/api/com/agorapulse/micronaut/amazon/awsses/SimpleEmailService.html[SimpleEmailService AWS SDK 2.x]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.ses.SesClient;
import software.amazon.awssdk.services.ses.model.MessageTag;
import software.amazon.awssdk.services.ses.model.SendEmailRequest;
import software.amazon.awssdk.services.ses.model.SendRawEmailRequest;

Expand All @@ -41,8 +42,11 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;

import static javax.mail.Message.RecipientType.TO;

Expand Down Expand Up @@ -155,7 +159,9 @@ private EmailDeliveryStatus sendEmailWithAttachment(TransactionalEmail email) th
SendRawEmailRequest rawEmailRequest = SendRawEmailRequest.builder()
.rawMessage(b -> b.data(SdkBytes.fromByteArray(outputStream.toByteArray())))
.destinations(email.getRecipients())
.source(Optional.ofNullable(email.getFrom()).orElseGet(() -> configuration.getSourceEmail().orElse(null))).build();
.source(Optional.ofNullable(email.getFrom()).orElseGet(() -> configuration.getSourceEmail().orElse(null)))
.tags(getCustomTags(email))
.build();

return handleSend(email, () -> client.sendRawEmail(rawEmailRequest));
}
Expand All @@ -178,7 +184,20 @@ private EmailDeliveryStatus sendWithoutAttachments(TransactionalEmail email) {
builder.replyToAddresses(email.getReplyTo());
}

builder.tags(getCustomTags(email));

return handleSend(email, () -> client.sendEmail(builder.build()));
}

private List<MessageTag> getCustomTags(TransactionalEmail email) {
if (email.getTags() == null || email.getTags().isEmpty()) {
return Collections.emptyList();
}
return email.getTags().entrySet().stream()
.map(entry -> MessageTag.builder()
.name(entry.getKey())
.value(entry.getValue()).build())
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
Expand All @@ -32,6 +34,7 @@ public class TransactionalEmail {
private String subject = "";
private String htmlBody = "<html><body></body></html>";
private String replyTo = "";
private Map<String, String> tags = new HashMap<>();

private final List<String> recipients = new ArrayList<>();
private final List<TransactionalEmailAttachment> attachments = new ArrayList<>();
Expand Down Expand Up @@ -76,6 +79,11 @@ public TransactionalEmail replyTo(String str) {
return this;
}

public TransactionalEmail tags(Map<String, String> customTags) {
this.tags = customTags;
return this;
}

public String getFrom() {
return from;
}
Expand All @@ -100,6 +108,10 @@ public List<TransactionalEmailAttachment> getAttachments() {
return Collections.unmodifiableList(attachments);
}

public Map<String, String> getTags() {
return tags;
}

// CHECKSTYLE:OFF
@Override
public String toString() {
Expand All @@ -110,6 +122,7 @@ public String toString() {
", replyTo='" + replyTo + '\'' +
", recipients=" + recipients +
", attachments=" + attachments +
", tags=" + tags +
'}';
}
// CHECKSTYLE:ON
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,20 @@ class SendEmailSpec extends Specification {
file.createNewFile()
file.text = 'not a real PDF'
String thePath = file.canonicalPath
Map<String, String> mapOfTags = [myTagKey: 'myTagValue']
when:
// tag::builder[]
EmailDeliveryStatus status = service.send { // <1>
subject 'Hi Paul' // <2>
from '[email protected]' // <3>
to '[email protected]' // <4>
htmlBody '<p>This is an example body</p>' // <5>
attachment { // <6>
filepath thePath // <7>
filename 'test.pdf' // <8>
mimeType 'application/pdf' // <9>
description 'An example pdf' // <10>
tags mapOfTags // <6>
attachment { // <7>
filepath thePath // <8>
filename 'test.pdf' // <9>
mimeType 'application/pdf' // <10>
description 'An example pdf' // <11>
}
}
// end::builder[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand All @@ -54,18 +56,21 @@ public void testSendEmail() throws IOException {

Files.write(file.toPath(), Collections.singletonList("not a real PDF"));
String filepath = file.getCanonicalPath();
Map<String, String> mapOfTags = new HashMap<>();
mapOfTags.put("myTagKey", "myTagValue");

// tag::builder[]
EmailDeliveryStatus status = service.send(e -> // <1>
e.subject("Hi Paul") // <2>
.from("[email protected]") // <3>
.to("[email protected]") // <4>
.htmlBody("<p>This is an example body</p>") // <5>
.attachment(a -> // <6>
a.filepath(filepath) // <7>
.filename("test.pdf") // <8>
.mimeType("application/pdf") // <9>
.description("An example pdf") // <10>
.tags(mapOfTags) // <6>
.attachment(a -> // <7>
a.filepath(filepath) // <8>
.filename("test.pdf") // <9>
.mimeType("application/pdf") // <10>
.description("An example pdf") // <11>
)
);
// end::builder[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,15 @@ class SimpleEmailServiceSpec extends Specification {
)

void "test transactionalEmailWithClosure"() {
given:
Map<String, String> customTags = [key1: 'value1', key2: 'value2']
when:
TransactionalEmail transactionalEmail = SimpleEmailService.email {
subject 'Hi Paul'
from '[email protected]'
to '[email protected]'
htmlBody '<p>This is an example body</p>'
tags customTags
attachment {
filename 'test.pdf'
filepath '/tmp/test.pdf'
Expand All @@ -64,6 +67,7 @@ class SimpleEmailServiceSpec extends Specification {
transactionalEmail.htmlBody == '<p>This is an example body</p>'
transactionalEmail.from == '[email protected]'
transactionalEmail.recipients == ['[email protected]']
transactionalEmail.tags == [key1: 'value1', key2: 'value2']
transactionalEmail.attachments.size() == 1
transactionalEmail.attachments.first().filename == 'test.pdf'
transactionalEmail.attachments.first().filepath == '/tmp/test.pdf'
Expand All @@ -82,6 +86,7 @@ class SimpleEmailServiceSpec extends Specification {
htmlBody '<p>This is an example body</p>'
to '[email protected]'
from '[email protected]'
tags customTags
attachment {
filepath f.absolutePath
}
Expand All @@ -93,6 +98,7 @@ class SimpleEmailServiceSpec extends Specification {
transactionalEmail.htmlBody == '<p>This is an example body</p>'
transactionalEmail.from == '[email protected]'
transactionalEmail.recipients == ['[email protected]']
transactionalEmail.tags == [key1: 'value1', key2: 'value2']
transactionalEmail.attachments.size() == 1
transactionalEmail.attachments.first().filename == 'groovylogo.png'
transactionalEmail.attachments.first().filepath == f.absolutePath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import spock.lang.Specification
*/
@Ignore
@Remember(
value = '2023-06-01',
value = '2024-06-01',
description = 'Try to fix this test or remove this feature completely'
)
class LambdaEchoFunctionSpec extends Specification {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class DefaultSimpleEmailService implements SimpleEmailService {

rawEmailRequest.destinations = email.recipients
rawEmailRequest.source = email.from ?: configuration.sourceEmail.orElse(null)
rawEmailRequest.tags = getTags(email)

return handleSend(email) {
client.sendRawEmail(rawEmailRequest)
Expand Down Expand Up @@ -184,8 +185,20 @@ class DefaultSimpleEmailService implements SimpleEmailService {
if (email.replyTo) {
sendEmailRequest.replyToAddresses = singletonList(email.replyTo)
}
sendEmailRequest.tags = getTags(email)
client.sendEmail(sendEmailRequest)
}
}

private List<MessageTag> getTags(TransactionalEmail email) {
if (!email.tags) {
return []
}
return email.tags.collect { entry ->
new MessageTag()
.withName(entry.key)
.withValue(entry.value)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
Expand All @@ -35,6 +37,7 @@ public class TransactionalEmail {
private String subject = "";
private String htmlBody = "<html><body></body></html>";
private String replyTo = "";
private Map<String, String> tags = new HashMap<>();

private final List<String> recipients = new ArrayList<>();
private final List<TransactionalEmailAttachment> attachments = new ArrayList<>();
Expand Down Expand Up @@ -83,6 +86,11 @@ public TransactionalEmail replyTo(String str) {
return this;
}

public TransactionalEmail tags(Map<String, String> customTags) {
this.tags = customTags;
return this;
}

public String getFrom() {
return from;
}
Expand All @@ -107,6 +115,10 @@ public List<TransactionalEmailAttachment> getAttachments() {
return attachments;
}

public Map<String, String> getTags() {
return tags;
}

// CHECKSTYLE:OFF
@Override
public String toString() {
Expand All @@ -117,6 +129,7 @@ public String toString() {
", replyTo='" + replyTo + '\'' +
", recipients=" + recipients +
", attachments=" + attachments +
", tags=" + tags +
'}';
}
// CHECKSTYLE:ON
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,20 @@ class SendEmailSpec extends Specification {
file.createNewFile()
file.text = 'not a real PDF'
String thePath = file.canonicalPath
Map<String, String> mapOfTags = [myTagKey: 'myTagValue']
when:
// tag::builder[]
EmailDeliveryStatus status = service.send { // <1>
subject 'Hi Paul' // <2>
from '[email protected]' // <3>
to '[email protected]' // <4>
htmlBody '<p>This is an example body</p>' // <5>
attachment { // <6>
filepath thePath // <7>
filename 'test.pdf' // <8>
mimeType 'application/pdf' // <9>
description 'An example pdf' // <10>
tags mapOfTags // <6>
attachment { // <7>
filepath thePath // <8>
filename 'test.pdf' // <9>
mimeType 'application/pdf' // <10>
description 'An example pdf' // <11>
}
}
// end::builder[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import java.io.IOException;
import java.nio.file.Files;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -55,18 +57,21 @@ public void testSendEmail() throws IOException {
file.createNewFile();
Files.write(file.toPath(), Collections.singletonList("not a real PDF"));
String filepath = file.getCanonicalPath();
Map<String, String> mapOfTags = new HashMap<>();
mapOfTags.put("myTagKey", "myTagValue");

// tag::builder[]
EmailDeliveryStatus status = service.send(e -> // <1>
e.subject("Hi Paul") // <2>
.from("[email protected]") // <3>
.to("[email protected]") // <4>
.htmlBody("<p>This is an example body</p>") // <5>
.attachment(a -> // <6>
a.filepath(filepath) // <7>
.filename("test.pdf") // <8>
.mimeType("application/pdf") // <9>
.description("An example pdf") // <10>
.tags(mapOfTags) // <6>
.attachment(a -> // <7>
a.filepath(filepath) // <8>
.filename("test.pdf") // <9>
.mimeType("application/pdf") // <10>
.description("An example pdf") // <11>
)
);
// end::builder[]
Expand Down
Loading

0 comments on commit b21315d

Please sign in to comment.