From bec40ff255c283427d53ef3b4609b7d32c9b0c0c Mon Sep 17 00:00:00 2001 From: Andrew Fiddian-Green Date: Mon, 27 Sep 2021 09:38:13 +0100 Subject: [PATCH] [mail] Add support for e-mail headers (#11307) Signed-off-by: Andrew Fiddian-Green --- bundles/org.openhab.binding.mail/README.md | 20 +++++++++++++++ .../binding/mail/internal/MailBuilder.java | 10 ++++++++ .../mail/internal/action/SendMailActions.java | 25 +++++++++++++++++++ .../resources/OH-INF/i18n/mail.properties | 3 +++ .../openhab/binding/mail/MailBuilderTest.java | 18 +++++++++++++ 5 files changed, 76 insertions(+) diff --git a/bundles/org.openhab.binding.mail/README.md b/bundles/org.openhab.binding.mail/README.md index ad71caf7d854a..0f4940bcd42d9 100644 --- a/bundles/org.openhab.binding.mail/README.md +++ b/bundles/org.openhab.binding.mail/README.md @@ -127,3 +127,23 @@ val List attachmentUrlList = newArrayList( val mailActions = getActions("mail","mail:smtp:sampleserver") mailActions.sendHtmlMail("mail@example.com", "Test subject", "

Header

This is the mail content.", attachmentUrlList) ``` + +## Mail Headers + +The binding allows one to add custom e-mail headers to messages that it sends. +For example if you want e-mails sent by this binding to be grouped into a "threaded view" in your email client, you must provide an e-mail "Reference" header, which acts as the key for grouping messages together. +Headers can be added inside a rule by calling the `mailActions.addHeader()` method before calling the respective `mailActions.sendMail()` method. +See the example below. + +``` +rule "Send Mail with a 'Reference' header; for threaded view in e-mail client" +when + ... +then + val mailActions = getActions("mail","mail:smtp:sampleserver") + mailActions.addHeader("Reference", "") + mailActions.sendMail("mail@example.com", "Test subject", "Test message text") +end +``` + +Note: in the case of the "Reference" header, the `` has to be an ASCII string enclosed in angle brackets. diff --git a/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/MailBuilder.java b/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/MailBuilder.java index 5edf00f0460ac..a2df6082a3587 100644 --- a/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/MailBuilder.java +++ b/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/MailBuilder.java @@ -17,7 +17,9 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.activation.FileDataSource; import javax.mail.internet.AddressException; @@ -47,6 +49,7 @@ public class MailBuilder { private String subject = "(no subject)"; private String text = ""; private String html = ""; + private Map headers = new HashMap<>(); /** * Create a new MailBuilder @@ -137,6 +140,11 @@ public MailBuilder withFileAttachment(String path) { return this; } + public MailBuilder withHeader(String name, String value) { + headers.put(name, value); + return this; + } + /** * Build the Mail * @@ -198,6 +206,8 @@ public Email build() throws EmailException { mail.setFrom(sender); } + headers.forEach((name, value) -> mail.addHeader(name, value)); + return mail; } } diff --git a/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/action/SendMailActions.java b/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/action/SendMailActions.java index 8fa5201649dae..3564e06f898b3 100644 --- a/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/action/SendMailActions.java +++ b/bundles/org.openhab.binding.mail/src/main/java/org/openhab/binding/mail/internal/action/SendMailActions.java @@ -14,7 +14,9 @@ import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.mail.internet.AddressException; @@ -44,6 +46,7 @@ public class SendMailActions implements ThingActions { private final Logger logger = LoggerFactory.getLogger(SendMailActions.class); private @Nullable SMTPHandler handler; + private Map headers = new HashMap<>(); @RuleAction(label = "@text/sendMessageActionLabel", description = "@text/sendMessageActionDescription") public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail( @@ -90,6 +93,8 @@ public class SendMailActions implements ThingActions { } } + headers.forEach((name, value) -> builder.withHeader(name, value)); + final SMTPHandler handler = this.handler; if (handler == null) { logger.info("Handler is null, cannot send mail."); @@ -167,6 +172,8 @@ public static boolean sendMail(ThingActions actions, @Nullable String recipient, } } + headers.forEach((name, value) -> builder.withHeader(name, value)); + final SMTPHandler handler = this.handler; if (handler == null) { logger.warn("Handler is null, cannot send mail."); @@ -210,4 +217,22 @@ public void setThingHandler(@Nullable ThingHandler handler) { public @Nullable ThingHandler getThingHandler() { return handler; } + + @RuleAction(label = "@text/addHeaderActionLabel", description = "@text/addHeaderActionDescription") + public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean addHeader( + @ActionInput(name = "name") @Nullable String name, @ActionInput(name = "value") @Nullable String value) { + if (name != null && !name.isEmpty()) { + if (value != null && !value.isEmpty()) { + headers.put(name, value); + } else { + headers.remove(name); + } + return true; + } + return false; + } + + public static boolean addHeader(ThingActions actions, @Nullable String name, @Nullable String value) { + return ((SendMailActions) actions).addHeader(name, value); + } } diff --git a/bundles/org.openhab.binding.mail/src/main/resources/OH-INF/i18n/mail.properties b/bundles/org.openhab.binding.mail/src/main/resources/OH-INF/i18n/mail.properties index eb66ef566d0d1..c7a481fb2ffae 100644 --- a/bundles/org.openhab.binding.mail/src/main/resources/OH-INF/i18n/mail.properties +++ b/bundles/org.openhab.binding.mail/src/main/resources/OH-INF/i18n/mail.properties @@ -16,3 +16,6 @@ sendHTMLAttachmentMessageActionDescription = Sends a HTML mail with an URL attac sendHTMLAttachmentsMessageActionLabel = send a HTML mail with several attachments sendHTMLAttachmentsMessageActionDescription = Sends a HTML mail with several URL attachments. + +addHeaderActionLabel = add a mail header +addHeaderActionDescription = Adds a mail header to the mail message. diff --git a/bundles/org.openhab.binding.mail/src/test/java/org/openhab/binding/mail/MailBuilderTest.java b/bundles/org.openhab.binding.mail/src/test/java/org/openhab/binding/mail/MailBuilderTest.java index d096d372320be..70d90d6807c97 100644 --- a/bundles/org.openhab.binding.mail/src/test/java/org/openhab/binding/mail/MailBuilderTest.java +++ b/bundles/org.openhab.binding.mail/src/test/java/org/openhab/binding/mail/MailBuilderTest.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.net.MalformedURLException; +import java.util.Map; import javax.mail.MessagingException; import javax.mail.internet.AddressException; @@ -41,6 +42,11 @@ public class MailBuilderTest { private static final String TEST_STRING = "test"; private static final String TEST_EMAIL = "foo@bar.zinga"; + private static final String HEADER_1_KEY = "key_one"; + private static final String HEADER_1_VAL = "value_one"; + private static final String HEADER_2_KEY = "key_two"; + private static final String HEADER_2_VAL = "value_two"; + @Test public void illegalToAddressThrowsException() { assertThrows(AddressException.class, () -> new MailBuilder("foo bar.zinga")); @@ -91,4 +97,16 @@ public void fieldsSetInMail() throws EmailException, MessagingException, IOExcep assertEquals(TEST_EMAIL, builder.build().getToAddresses().get(0).getAddress()); assertEquals(2, builder.withRecipients(TEST_EMAIL).build().getToAddresses().size()); } + + @Test + public void withHeaders() throws EmailException, MessagingException, IOException { + MailBuilder builder = new MailBuilder(TEST_EMAIL); + Email mail = builder.withHeader(HEADER_1_KEY, HEADER_1_VAL).withHeader(HEADER_2_KEY, HEADER_2_VAL).build(); + + Map headers = mail.getHeaders(); + + assertEquals(2, headers.size()); + assertEquals(HEADER_2_VAL, headers.get(HEADER_2_KEY)); + assertEquals(HEADER_1_VAL, headers.get(HEADER_1_KEY)); + } }