Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mail] Add support for e-mail headers #11307

Merged
merged 4 commits into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions bundles/org.openhab.binding.mail/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,23 @@ val List<String> attachmentUrlList = newArrayList(
val mailActions = getActions("mail","mail:smtp:sampleserver")
mailActions.sendHtmlMail("mail@example.com", "Test subject", "<h1>Header</h1>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", "<unique-thread-identifier>")
mailActions.sendMail("mail@example.com", "Test subject", "Test message text")
end
```

Note: in the case of the "Reference" header, the `<unique-thread-identifier>` has to be an ASCII string enclosed in angle brackets.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -47,6 +49,7 @@ public class MailBuilder {
private String subject = "(no subject)";
private String text = "";
private String html = "";
private Map<String, String> headers = new HashMap<>();

/**
* Create a new MailBuilder
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -198,6 +206,8 @@ public Email build() throws EmailException {
mail.setFrom(sender);
}

headers.forEach((name, value) -> mail.addHeader(name, value));

return mail;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -44,6 +46,7 @@ public class SendMailActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(SendMailActions.class);

private @Nullable SMTPHandler handler;
private Map<String, String> headers = new HashMap<>();

@RuleAction(label = "@text/sendMessageActionLabel", description = "@text/sendMessageActionDescription")
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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.");
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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"));
Expand Down Expand Up @@ -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<String, String> 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));
}
}