added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.binding.mail/.classpath
Normal file
32
bundles/org.openhab.binding.mail/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.binding.mail/.project
Normal file
23
bundles/org.openhab.binding.mail/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.binding.mail</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
25
bundles/org.openhab.binding.mail/NOTICE
Normal file
25
bundles/org.openhab.binding.mail/NOTICE
Normal file
@@ -0,0 +1,25 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
|
||||
== Third-party Content
|
||||
|
||||
commons-email:
|
||||
* License: Apache 2.0 License
|
||||
* Project: https://commons.apache.org/proper/commons-email
|
||||
* Source: https://commons.apache.org/proper/commons-email
|
||||
|
||||
javax.mail:
|
||||
* License: Common Development and Distribution License (CDDL) v1.1 and GNU General Public License (GPL) v2 with Classpath Exception
|
||||
* Project: https://javaee.github.io/javamail/
|
||||
* Source: https://github.com/javaee/javamail
|
||||
129
bundles/org.openhab.binding.mail/README.md
Normal file
129
bundles/org.openhab.binding.mail/README.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# Mail Binding
|
||||
|
||||
The Mail binding provides support for sending mails from rules.
|
||||
|
||||
## Supported Things
|
||||
|
||||
There are three things: `smtp`, `imap` and `pop3` which represents respective servers.
|
||||
|
||||
## Thing Configuration
|
||||
|
||||
### SMTP Server (`smtp`)
|
||||
|
||||
There are two mandatory parameters `hostname` and `sender`.
|
||||
|
||||
The `hostname` may contain an IP address or a FQDN like `smtp.gmail.com`.
|
||||
The `sender` must be a valid mail address used as sender address for mails.
|
||||
|
||||
The `security`, `port`, `username` and `password` parameters are optional.
|
||||
|
||||
The `security` parameter defines the transport security and can be set to `PLAIN` (default), `STARTTLS` or `SSL` (for implicit SSL/TLS).
|
||||
The `port` parameter is used to change the default ports for the SMTP server.
|
||||
Default ports are `25` (for `PLAIN` and `STARTTLS`) and `465` (for `SSL`).
|
||||
For authentication, `username` and `password` can be supplied.
|
||||
If one or both are empty, no authentication data is provided to the SMTP server during connect.
|
||||
|
||||
### IMAP Server (`imap`) / POP3 Server (`pop3`)
|
||||
|
||||
There is one mandatory parameter: `hostname`, `username`, `password`.
|
||||
The `hostname` may contain an IP address or a FQDN like `mail.gmail.com`.
|
||||
For authentication `username` and `password` need to be supplied.
|
||||
|
||||
The `refresh`, `security`, `port`, `username` and `password` parameters are optional.
|
||||
|
||||
The `refresh` parameter is the time in seconds between two refreshes of the thing's channels.
|
||||
If omitted, the default of 60s is used.
|
||||
The `security` parameter defines the transport security and can be set to `PLAIN` (default), `STARTTLS` or `SSL` (for implicit SSL/TLS).
|
||||
The `port` parameter is used to change the default ports for the SMTP server.
|
||||
Default ports are `143` (for `PLAIN` and `STARTTLS`) and `993` (for `SSL`) in the case of `imap` or `110` (for `PLAIN` and `STARTTLS`) and `995` (for `SSL`) in the case of `pop3`.
|
||||
|
||||
## Channels
|
||||
|
||||
There are no channels for the `smtp` thing.
|
||||
The `imap` and `pop3` things can be extended with `mailcount`-type channels.
|
||||
|
||||
### Type `mailcount`
|
||||
|
||||
Each channel has two parameters: `folder` and `type`.
|
||||
The `folder` is mandatory and denotes the folder name on the given account.
|
||||
You can either use the root folder like (e.g. "INBOX") or a sub directory of your structure (e.g. "INBOX.Sent" or "INBOX.Junk").
|
||||
The `type` parameter can be `UNREAD` or `TOTAL` (default).
|
||||
Channels with type `UNREAD` give the number on unread mails in that folder.
|
||||
|
||||
## Full Example
|
||||
|
||||
mail.things:
|
||||
|
||||
```
|
||||
Thing mail:smtp:samplesmtp [ hostname="smtp.example.com", sender="mail@example.com", security="SSL", username="user", password="pass" ]
|
||||
|
||||
Thing mail:imap:sampleimap [ hostname="imap.example.com", security="SSL", username="user", password="pass" ] {
|
||||
Channels:
|
||||
Type mailcount : inbox_total [ folder="INBOX", type="TOTAL" ]
|
||||
Type mailcount : inbox_unread [ folder="INBOX", type="UNREAD" ]
|
||||
}
|
||||
```
|
||||
|
||||
mail.items:
|
||||
|
||||
```
|
||||
Number InboxTotal "INBOX [%d]" { channel="mail:imap:sampleimap:inbox_total" }
|
||||
Number InboxUnread "INBOX Unread [%d]" { channel="mail:imap:sampleimap:inbox_unread" }
|
||||
```
|
||||
|
||||
mail.sitemap:
|
||||
|
||||
```
|
||||
sitemap demo label="Main Menu"
|
||||
{
|
||||
Frame {
|
||||
Text item=InboxTotal
|
||||
Text item=InboxUnread
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Rule Action
|
||||
|
||||
This binding includes rule actions for sending email.
|
||||
Six different actions available:
|
||||
|
||||
* `boolean success = sendMail(String recipient, String subject, String text)`
|
||||
* `boolean success = sendMail(String recipient, String subject, String text, String URL)`
|
||||
* `boolean success = sendMail(String recipient, String subject, String text, List<String> URL)`
|
||||
* `boolean success = sendHtmlMail(String recipient, String subject, String htmlContent)`
|
||||
* `boolean success = sendHtmlMail(String recipient, String subject, String htmlContent, String URL)`
|
||||
* `boolean success = sendHtmlMail(String recipient, String subject, String htmlContent, List<String> URL)`
|
||||
|
||||
The `sendMail(...)` send a plain text mail (with attachments if supplied).
|
||||
The `sendHtmlMail(...)` send a HTML mail (with attachments if supplied).
|
||||
|
||||
Both functions return a boolean as the result of the operation.
|
||||
|
||||
`recipient` can be a single address (`mail@example.com`) or a list of addresses, concatenated by a comma (`mail@example.com, mail2@example.com`).
|
||||
|
||||
Since there is a separate rule action instance for each `smtp` thing, this needs to be retrieved through `getActions(scope, thingUID)`.
|
||||
The first parameter always has to be `mail` and the second is the full Thing UID of the SMTP server that should be used.
|
||||
Once this action instance is retrieved, you can invoke the action method on it.
|
||||
|
||||
Please note: All strings are expected to be UTF-8 encoded.
|
||||
Using different character sets may produce unwanted results.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
val mailActions = getActions("mail","mail:smtp:samplesmtp")
|
||||
val success = mailActions.sendMail("mail@example.com", "Test subject", "This is the mail content.")
|
||||
success = mailActions.sendMail("mail1@example.com, mail2@example.com", "Test subject", "This is the mail content sent to multiple recipients.")
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
import java.util.List
|
||||
|
||||
val List<String> attachmentUrlList = newArrayList(
|
||||
"http://some.web/site/snap.jpg¶m=value",
|
||||
"file:///tmp/201601011031.jpg")
|
||||
val mailActions = getActions("mail","mail:smtp:sampleserver")
|
||||
mailActions.sendHtmlMail("mail@example.com", "Test subject", "<h1>Header</h1>This is the mail content.", attachmentUrlList)
|
||||
```
|
||||
36
bundles/org.openhab.binding.mail/pom.xml
Normal file
36
bundles/org.openhab.binding.mail/pom.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.mail</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Mail Binding</name>
|
||||
|
||||
<properties>
|
||||
<dep.noembedding>javax.mail</dep.noembedding>
|
||||
<bnd.importpackage>sun.security.util;resolution:=optional</bnd.importpackage>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-email</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.mail</groupId>
|
||||
<artifactId>javax.mail</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.binding.mail-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-binding-mail" description="Mail Binding" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle dependency="true">mvn:com.sun.mail/javax.mail/1.6.2</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.mail/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.action;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link ISendMailActions} interface defines rule actions for sending mail
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface ISendMailActions {
|
||||
Boolean sendMail(@Nullable String recipient, @Nullable String subject, @Nullable String text,
|
||||
@Nullable List<String> urlStringList);
|
||||
|
||||
Boolean sendHtmlMail(@Nullable String recipient, @Nullable String subject, @Nullable String html,
|
||||
@Nullable List<String> urlStringList);
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.action;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.mail.internet.AddressException;
|
||||
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.mail.internal.MailBuilder;
|
||||
import org.openhab.binding.mail.internal.SMTPHandler;
|
||||
import org.openhab.core.automation.annotation.ActionInput;
|
||||
import org.openhab.core.automation.annotation.ActionOutput;
|
||||
import org.openhab.core.automation.annotation.RuleAction;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SendMailActions} class defines rule actions for sending mail
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@ThingActionsScope(name = "mail")
|
||||
@NonNullByDefault
|
||||
public class SendMailActions implements ThingActions, ISendMailActions {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(SendMailActions.class);
|
||||
|
||||
private @Nullable SMTPHandler handler;
|
||||
|
||||
@RuleAction(label = "Send Text Mail", description = "sends a text mail")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject,
|
||||
@ActionInput(name = "text") @Nullable String text) {
|
||||
return sendMail(recipient, subject, text, new ArrayList<>());
|
||||
}
|
||||
|
||||
@RuleAction(label = "Send Text Mail", description = "sends a text mail with URL attachment")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
|
||||
@ActionInput(name = "url") @Nullable String urlString) {
|
||||
List<String> urlList = new ArrayList<>();
|
||||
if (urlString != null) {
|
||||
urlList.add(urlString);
|
||||
}
|
||||
return sendMail(recipient, subject, text, urlList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@RuleAction(label = "Send Text Mail", description = "sends a text mail with several URL attachments")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "text") @Nullable String text,
|
||||
@ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
|
||||
if (recipient == null) {
|
||||
logger.warn("Cannot send mail as recipient is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
MailBuilder builder = new MailBuilder(recipient);
|
||||
|
||||
if (subject != null && !subject.isEmpty()) {
|
||||
builder.withSubject(subject);
|
||||
}
|
||||
if (text != null && !text.isEmpty()) {
|
||||
builder.withText(text);
|
||||
}
|
||||
if (urlStringList != null) {
|
||||
for (String urlString : urlStringList) {
|
||||
builder.withURLAttachment(urlString);
|
||||
}
|
||||
}
|
||||
|
||||
final SMTPHandler handler = this.handler;
|
||||
if (handler == null) {
|
||||
logger.info("Handler is null, cannot send mail.");
|
||||
return false;
|
||||
} else {
|
||||
return handler.sendMail(builder.build());
|
||||
}
|
||||
} catch (AddressException | MalformedURLException | EmailException e) {
|
||||
logger.warn("Could not send mail: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
|
||||
@Nullable String text) {
|
||||
return SendMailActions.sendMail(actions, recipient, subject, text, new ArrayList<>());
|
||||
}
|
||||
|
||||
public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
|
||||
@Nullable String text, @Nullable String urlString) {
|
||||
List<String> urlList = new ArrayList<>();
|
||||
if (urlString != null) {
|
||||
urlList.add(urlString);
|
||||
}
|
||||
return SendMailActions.sendMail(actions, recipient, subject, text, urlList);
|
||||
}
|
||||
|
||||
public static boolean sendMail(@Nullable ThingActions actions, @Nullable String recipient, @Nullable String subject,
|
||||
@Nullable String text, @Nullable List<String> urlStringList) {
|
||||
return invokeMethodOf(actions).sendMail(recipient, subject, text, urlStringList);
|
||||
}
|
||||
|
||||
@RuleAction(label = "Send HTML Mail", description = "sends a HTML mail")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject,
|
||||
@ActionInput(name = "html") @Nullable String html) {
|
||||
return sendHtmlMail(recipient, subject, html, new ArrayList<>());
|
||||
}
|
||||
|
||||
@RuleAction(label = "Send HTML Mail", description = "sends a HTML mail with URL attachment")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
|
||||
@ActionInput(name = "url") @Nullable String urlString) {
|
||||
List<String> urlList = new ArrayList<>();
|
||||
if (urlString != null) {
|
||||
urlList.add(urlString);
|
||||
}
|
||||
return sendHtmlMail(recipient, subject, html, urlList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@RuleAction(label = "Send HTML Mail", description = "sends a HTML mail with several URL attachments")
|
||||
public @ActionOutput(name = "success", type = "java.lang.Boolean") Boolean sendHtmlMail(
|
||||
@ActionInput(name = "recipient") @Nullable String recipient,
|
||||
@ActionInput(name = "subject") @Nullable String subject, @ActionInput(name = "html") @Nullable String html,
|
||||
@ActionInput(name = "urlList") @Nullable List<String> urlStringList) {
|
||||
if (recipient == null) {
|
||||
logger.warn("Cannot send mail as recipient is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
MailBuilder builder = new MailBuilder(recipient);
|
||||
|
||||
if (subject != null && !subject.isEmpty()) {
|
||||
builder.withSubject(subject);
|
||||
}
|
||||
if (html != null && !html.isEmpty()) {
|
||||
builder.withHtml(html);
|
||||
}
|
||||
if (urlStringList != null) {
|
||||
for (String urlString : urlStringList) {
|
||||
builder.withURLAttachment(urlString);
|
||||
}
|
||||
}
|
||||
|
||||
final SMTPHandler handler = this.handler;
|
||||
if (handler == null) {
|
||||
logger.warn("Handler is null, cannot send mail.");
|
||||
return false;
|
||||
} else {
|
||||
return handler.sendMail(builder.build());
|
||||
}
|
||||
} catch (AddressException | MalformedURLException | EmailException e) {
|
||||
logger.warn("Could not send mail: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
|
||||
@Nullable String subject, @Nullable String html) {
|
||||
return SendMailActions.sendHtmlMail(actions, recipient, subject, html, new ArrayList<>());
|
||||
}
|
||||
|
||||
public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
|
||||
@Nullable String subject, @Nullable String html, @Nullable String urlString) {
|
||||
List<String> urlList = new ArrayList<>();
|
||||
if (urlString != null) {
|
||||
urlList.add(urlString);
|
||||
}
|
||||
return SendMailActions.sendHtmlMail(actions, recipient, subject, html, urlList);
|
||||
}
|
||||
|
||||
public static boolean sendHtmlMail(@Nullable ThingActions actions, @Nullable String recipient,
|
||||
@Nullable String subject, @Nullable String html, @Nullable List<String> urlStringList) {
|
||||
return invokeMethodOf(actions).sendHtmlMail(recipient, subject, html, urlStringList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThingHandler(@Nullable ThingHandler handler) {
|
||||
if (handler instanceof SMTPHandler) {
|
||||
this.handler = (SMTPHandler) handler;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ThingHandler getThingHandler() {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
private static ISendMailActions invokeMethodOf(@Nullable ThingActions actions) {
|
||||
if (actions == null) {
|
||||
throw new IllegalArgumentException("actions cannot be null");
|
||||
}
|
||||
if (actions.getClass().getName().equals(SendMailActions.class.getName())) {
|
||||
if (actions instanceof ISendMailActions) {
|
||||
return (ISendMailActions) actions;
|
||||
} else {
|
||||
return (ISendMailActions) Proxy.newProxyInstance(ISendMailActions.class.getClassLoader(),
|
||||
new Class[] { ISendMailActions.class }, (Object proxy, Method method, Object[] args) -> {
|
||||
Method m = actions.getClass().getDeclaredMethod(method.getName(),
|
||||
method.getParameterTypes());
|
||||
return m.invoke(actions, args);
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Actions is not an instance of SendMailActions");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.type.ChannelTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link MailBindingConstants} class defines common constants, which are
|
||||
* used across the whole binding.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MailBindingConstants {
|
||||
private static final String BINDING_ID = "mail";
|
||||
|
||||
public static final ThingTypeUID THING_TYPE_SMTPSERVER = new ThingTypeUID(BINDING_ID, "smtp");
|
||||
public static final ThingTypeUID THING_TYPE_IMAPSERVER = new ThingTypeUID(BINDING_ID, "imap");
|
||||
public static final ThingTypeUID THING_TYPE_POP3SERVER = new ThingTypeUID(BINDING_ID, "pop3");
|
||||
|
||||
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(
|
||||
Arrays.asList(THING_TYPE_SMTPSERVER, THING_TYPE_IMAPSERVER, THING_TYPE_POP3SERVER));
|
||||
|
||||
public static final ChannelTypeUID CHANNEL_TYPE_UID_FOLDER_MAILCOUNT = new ChannelTypeUID(BINDING_ID, "mailcount");
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.activation.FileDataSource;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
||||
import org.apache.commons.mail.Email;
|
||||
import org.apache.commons.mail.EmailAttachment;
|
||||
import org.apache.commons.mail.EmailConstants;
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.apache.commons.mail.HtmlEmail;
|
||||
import org.apache.commons.mail.MultiPartEmail;
|
||||
import org.apache.commons.mail.SimpleEmail;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link MailBuilder} class provides a builder for an mail.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class MailBuilder {
|
||||
private String sender = "";
|
||||
private List<InternetAddress> recipients = new ArrayList<>();
|
||||
private List<URL> attachmentURLs = new ArrayList<>();
|
||||
private List<File> attachmentFiles = new ArrayList<>();
|
||||
private String subject = "(no subject)";
|
||||
private String text = "";
|
||||
private String html = "";
|
||||
|
||||
/**
|
||||
* Create a new MailBuilder
|
||||
*
|
||||
* @param recipients comma separated sequence of addresses (must follow RFC822 syntax)
|
||||
* @throws AddressException on invalid recipient address
|
||||
*/
|
||||
public MailBuilder(String recipients) throws AddressException {
|
||||
this.recipients.addAll(Arrays.asList(InternetAddress.parse(recipients)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add one or more recipients
|
||||
*
|
||||
* @param recipients comma separated sequence of addresses (must follow RFC822 syntax)
|
||||
* @return a MailBuilder
|
||||
* @throws AddressException on invalid recipient address
|
||||
*/
|
||||
public MailBuilder withRecipients(String recipients) throws AddressException {
|
||||
this.recipients.addAll(Arrays.asList(InternetAddress.parse(recipients)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the sender address
|
||||
*
|
||||
* @param sender address (must follow RFC822 syntax)
|
||||
* @return a MailBuilder
|
||||
*/
|
||||
public MailBuilder withSender(String sender) {
|
||||
this.sender = sender;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mail subject
|
||||
*
|
||||
* @param subject String containing the subject
|
||||
* @return a MailBuilder
|
||||
*/
|
||||
public MailBuilder withSubject(String subject) {
|
||||
this.subject = subject;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the plain text content
|
||||
*
|
||||
* @param text String containing the text
|
||||
* @return a MailBuilder
|
||||
*/
|
||||
public MailBuilder withText(String text) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTML content
|
||||
*
|
||||
* @param html a String containing HTML (syntax not checked)
|
||||
* @return a MailBuilder
|
||||
*/
|
||||
public MailBuilder withHtml(String html) {
|
||||
this.html = html;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach an URL
|
||||
*
|
||||
* @param urlString the URL as String
|
||||
* @return a MailBuilder
|
||||
* @throws MalformedURLException if url has invalid format
|
||||
*/
|
||||
public MailBuilder withURLAttachment(String urlString) throws MalformedURLException {
|
||||
attachmentURLs.add(new URL(urlString));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a file
|
||||
*
|
||||
* @param path String with path to local file
|
||||
* @return a MailBuilder
|
||||
*/
|
||||
public MailBuilder withFileAttachment(String path) {
|
||||
attachmentFiles.add(new File(path));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the Mail
|
||||
*
|
||||
* @return instance of Email
|
||||
* @throws EmailException if something goes wrong
|
||||
*/
|
||||
public Email build() throws EmailException {
|
||||
Email mail;
|
||||
|
||||
if (attachmentURLs.isEmpty() && attachmentFiles.isEmpty() && html.isEmpty()) {
|
||||
// text mail without attachments
|
||||
mail = new SimpleEmail();
|
||||
mail.setCharset(EmailConstants.UTF_8);
|
||||
if (!text.isEmpty()) {
|
||||
mail.setMsg(text);
|
||||
}
|
||||
} else if (html.isEmpty()) {
|
||||
// text mail with attachments
|
||||
MultiPartEmail multipartMail = new MultiPartEmail();
|
||||
multipartMail.setCharset(EmailConstants.UTF_8);
|
||||
if (!text.isEmpty()) {
|
||||
multipartMail.setMsg(text);
|
||||
}
|
||||
for (File file : attachmentFiles) {
|
||||
multipartMail.attach(file);
|
||||
}
|
||||
for (URL url : attachmentURLs) {
|
||||
String fileName = url.toString().replaceFirst(".*/([^/?]+).*", "$1");
|
||||
multipartMail.attach(url, fileName, fileName, EmailAttachment.ATTACHMENT);
|
||||
}
|
||||
mail = multipartMail;
|
||||
} else {
|
||||
// html email
|
||||
HtmlEmail htmlMail = new HtmlEmail();
|
||||
htmlMail.setCharset(EmailConstants.UTF_8);
|
||||
if (!text.isEmpty()) {
|
||||
// alternate text supplied
|
||||
htmlMail.setTextMsg(text);
|
||||
htmlMail.setHtmlMsg(html);
|
||||
} else {
|
||||
htmlMail.setMsg(html);
|
||||
}
|
||||
for (File file : attachmentFiles) {
|
||||
htmlMail.attach(new FileDataSource(file), "", "");
|
||||
}
|
||||
for (URL url : attachmentURLs) {
|
||||
EmailAttachment attachment = new EmailAttachment();
|
||||
attachment.setURL(url);
|
||||
attachment.setDisposition(EmailAttachment.ATTACHMENT);
|
||||
htmlMail.attach(attachment);
|
||||
}
|
||||
mail = htmlMail;
|
||||
}
|
||||
|
||||
mail.setTo(recipients);
|
||||
mail.setSubject(subject);
|
||||
|
||||
if (!sender.isEmpty()) {
|
||||
mail.setFrom(sender);
|
||||
}
|
||||
|
||||
return mail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
/**
|
||||
* The {@link MailCountChannelType} enum for folder mail count type
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
public enum MailCountChannelType {
|
||||
UNREAD,
|
||||
TOTAL
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
import static org.openhab.binding.mail.internal.MailBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingTypeUID;
|
||||
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
|
||||
/**
|
||||
* The {@link MailHandlerFactory} is responsible for creating things and thing
|
||||
* handlers.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(configurationPid = "binding.mail", service = ThingHandlerFactory.class)
|
||||
public class MailHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
@Override
|
||||
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
|
||||
return SUPPORTED_THING_TYPES.contains(thingTypeUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable ThingHandler createHandler(Thing thing) {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
|
||||
if (THING_TYPE_SMTPSERVER.equals(thingTypeUID)) {
|
||||
return new SMTPHandler(thing);
|
||||
} else if (THING_TYPE_IMAPSERVER.equals(thingTypeUID) || THING_TYPE_POP3SERVER.equals(thingTypeUID)) {
|
||||
return new POP3IMAPHandler(thing);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
import static org.openhab.binding.mail.internal.MailBindingConstants.CHANNEL_TYPE_UID_FOLDER_MAILCOUNT;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.mail.Flags;
|
||||
import javax.mail.Folder;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Store;
|
||||
import javax.mail.search.FlagTerm;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.mail.internal.config.POP3IMAPChannelConfig;
|
||||
import org.openhab.binding.mail.internal.config.POP3IMAPConfig;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link POP3IMAPHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class POP3IMAPHandler extends BaseThingHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(POP3IMAPHandler.class);
|
||||
|
||||
private @NonNullByDefault({}) POP3IMAPConfig config;
|
||||
private @Nullable ScheduledFuture<?> refreshTask;
|
||||
private final String baseProtocol;
|
||||
private String protocol = "imap";
|
||||
|
||||
public POP3IMAPHandler(Thing thing) {
|
||||
super(thing);
|
||||
baseProtocol = thing.getThingTypeUID().getId(); // pop3 or imap
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(POP3IMAPConfig.class);
|
||||
|
||||
protocol = baseProtocol;
|
||||
|
||||
if (config.security == ServerSecurity.SSL) {
|
||||
protocol = protocol.concat("s");
|
||||
}
|
||||
|
||||
if (config.port == 0) {
|
||||
switch (protocol) {
|
||||
case "imap":
|
||||
config.port = 143;
|
||||
break;
|
||||
case "imaps":
|
||||
config.port = 993;
|
||||
break;
|
||||
case "pop3":
|
||||
config.port = 110;
|
||||
break;
|
||||
case "pop3s":
|
||||
config.port = 995;
|
||||
break;
|
||||
default:
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
refreshTask = scheduler.scheduleWithFixedDelay(this::refresh, 0, config.refresh, TimeUnit.SECONDS);
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
@SuppressWarnings("null")
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (refreshTask != null) {
|
||||
if (!refreshTask.isCancelled()) {
|
||||
refreshTask.cancel(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mail." + baseProtocol + ".starttls.enable", "true");
|
||||
props.setProperty("mail.store.protocol", protocol);
|
||||
Session session = Session.getInstance(props);
|
||||
|
||||
try (Store store = session.getStore()) {
|
||||
store.connect(config.hostname, config.port, config.username, config.password);
|
||||
|
||||
for (Channel channel : thing.getChannels()) {
|
||||
if (CHANNEL_TYPE_UID_FOLDER_MAILCOUNT.equals(channel.getChannelTypeUID())) {
|
||||
final POP3IMAPChannelConfig channelConfig = channel.getConfiguration()
|
||||
.as(POP3IMAPChannelConfig.class);
|
||||
final String folderName = channelConfig.folder;
|
||||
if (folderName == null || folderName.isEmpty()) {
|
||||
logger.info("missing or empty folder name in channel {}", channel.getUID());
|
||||
} else {
|
||||
try (Folder mailbox = store.getFolder(folderName)) {
|
||||
mailbox.open(Folder.READ_ONLY);
|
||||
if (channelConfig.type == MailCountChannelType.TOTAL) {
|
||||
updateState(channel.getUID(), new DecimalType(mailbox.getMessageCount()));
|
||||
} else {
|
||||
updateState(channel.getUID(), new DecimalType(
|
||||
mailbox.search(new FlagTerm(new Flags(Flags.Flag.SEEN), false)).length));
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (MessagingException e) {
|
||||
logger.info("error when trying to refresh IMAP: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.mail.DefaultAuthenticator;
|
||||
import org.apache.commons.mail.Email;
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.mail.action.SendMailActions;
|
||||
import org.openhab.binding.mail.internal.config.SMTPConfig;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingStatus;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link SMTPHandler} is responsible for handling commands, which are
|
||||
* sent to one of the channels.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SMTPHandler extends BaseThingHandler {
|
||||
private final Logger logger = LoggerFactory.getLogger(SMTPHandler.class);
|
||||
|
||||
private @NonNullByDefault({}) SMTPConfig config;
|
||||
|
||||
public SMTPHandler(Thing thing) {
|
||||
super(thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(ChannelUID channelUID, Command command) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
config = getConfigAs(SMTPConfig.class);
|
||||
|
||||
if (config.port == 0) {
|
||||
if (config.security == ServerSecurity.SSL) {
|
||||
config.port = 465;
|
||||
} else {
|
||||
config.port = 25;
|
||||
}
|
||||
}
|
||||
|
||||
updateStatus(ThingStatus.ONLINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* use this server to send a mail
|
||||
*
|
||||
* @param mail the Email that needs to be sent
|
||||
* @return true if successful, false if failed
|
||||
*/
|
||||
public boolean sendMail(Email mail) {
|
||||
try {
|
||||
if (mail.getFromAddress() == null) {
|
||||
mail.setFrom(config.sender);
|
||||
}
|
||||
mail.setHostName(config.hostname);
|
||||
switch (config.security) {
|
||||
case SSL:
|
||||
mail.setSSLOnConnect(true);
|
||||
mail.setSslSmtpPort(config.port.toString());
|
||||
break;
|
||||
case STARTTLS:
|
||||
mail.setStartTLSEnabled(true);
|
||||
mail.setStartTLSRequired(true);
|
||||
mail.setSmtpPort(config.port);
|
||||
break;
|
||||
case PLAIN:
|
||||
mail.setSmtpPort(config.port);
|
||||
}
|
||||
if (!config.username.isEmpty() && !config.password.isEmpty()) {
|
||||
mail.setAuthenticator(new DefaultAuthenticator(config.username, config.password));
|
||||
}
|
||||
mail.send();
|
||||
} catch (EmailException e) {
|
||||
logger.warn("{}", e.getMessage());
|
||||
if (e.getCause() != null) {
|
||||
logger.warn("{}", e.getCause().toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return Collections.singletonList(SendMailActions.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal;
|
||||
|
||||
/**
|
||||
* The {@link ServerSecurity} enum contains security configuration options
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
public enum ServerSecurity {
|
||||
PLAIN,
|
||||
SSL,
|
||||
STARTTLS
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.mail.internal.ServerSecurity;
|
||||
|
||||
/**
|
||||
* The {@link BaseConfig} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class BaseConfig {
|
||||
public @Nullable String hostname;
|
||||
public Integer port = 0;
|
||||
public String username = "";
|
||||
public String password = "";
|
||||
public ServerSecurity security = ServerSecurity.PLAIN;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.mail.internal.MailCountChannelType;
|
||||
|
||||
/**
|
||||
* The {@link POP3IMAPChannelConfig} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class POP3IMAPChannelConfig {
|
||||
public @Nullable String folder;
|
||||
public MailCountChannelType type = MailCountChannelType.TOTAL;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* The {@link POP3IMAPConfig} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class POP3IMAPConfig extends BaseConfig {
|
||||
public int refresh = 60;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail.internal.config;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The {@link SMTPConfig} class contains fields mapping thing configuration parameters.
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
@NonNullByDefault
|
||||
public class SMTPConfig extends BaseConfig {
|
||||
public @Nullable String sender;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<binding:binding id="mail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
|
||||
|
||||
<name>Mail Binding</name>
|
||||
<description>This binding is used to access POP3, IMAP and SMTP servers.</description>
|
||||
<author>Jan N. Klug</author>
|
||||
|
||||
</binding:binding>
|
||||
@@ -0,0 +1,57 @@
|
||||
# binding
|
||||
binding.mail.name = Mail Binding
|
||||
binding.mail.description = Unterstützung von POP3, IMAP und SMTP Servern
|
||||
|
||||
# thing types
|
||||
thing-type.mail.smtp.label = SMTP Server
|
||||
thing-type.mail.smtp.description = Wird zum Versenden von E-Mails verwendet
|
||||
thing-type.config.mail.smtp.sender.label = Absender
|
||||
thing-type.config.mail.smtp.sender.description = Standard-Absender für E-Mails
|
||||
thing-type.config.mail.smtp.hostname.label = IP-Adresse
|
||||
thing-type.config.mail.smtp.hostname.description = IP-Adresse oder Hostname des SMTP Servers
|
||||
thing-type.config.mail.smtp.port.label = Port
|
||||
thing-type.config.mail.smtp.port.description = Standard Ports sind 25 für PLAIN/STARTTLS und 465 für SSL/TLS
|
||||
thing-type.config.mail.smtp.security.label = Sicherheitsprotokoll
|
||||
thing-type.config.mail.smtp.security.description = Server Sicherheitsprotokoll zur Kommunikation mit dem SMTP Server
|
||||
thing-type.config.mail.smtp.username.label = Benutzer
|
||||
thing-type.config.mail.smtp.username.description = Benutzer zur Authentifizierung am SMTP Server
|
||||
thing-type.config.mail.smtp.password.label = Passwort
|
||||
thing-type.config.mail.smtp.password.description = Passwort zur Authentifizierung am SMTP Server
|
||||
|
||||
thing-type.mail.imap.label = IMAP Server
|
||||
thing-type.mail.imap.description = IMAP Postfach Überwachung
|
||||
thing-type.config.mail.imap.hostname.label = IP-Adresse
|
||||
thing-type.config.mail.imap.hostname.description = IP-Adresse oder Hostname des IMAP Servers
|
||||
thing-type.config.mail.imap.port.label = Port
|
||||
thing-type.config.mail.imap.port.description = Standard Ports sind 143 für PLAIN/STARTTLS und 993 für SSL/TLS
|
||||
thing-type.config.mail.imap.security.label = Sicherheitsprotokoll
|
||||
thing-type.config.mail.imap.security.description = Server Sicherheitsprotokoll zur Kommunikation mit dem IMAP Server
|
||||
thing-type.config.mail.imap.username.label = Benutzer
|
||||
thing-type.config.mail.imap.username.description = Benutzer zur Authentifizierung am IMAP Server
|
||||
thing-type.config.mail.imap.password.label = Passwort
|
||||
thing-type.config.mail.imap.password.description = Passwort zur Authentifizierung am IMAP Server
|
||||
thing-type.config.mail.imap.refresh.label = Abfrageintervall
|
||||
thing-type.config.mail.imap.refresh.description = Zeit zwischen zwei Abfragen (in s, Standard ist 60s)
|
||||
|
||||
thing-type.mail.pop3.label = POP3 Server
|
||||
thing-type.mail.pop3.description = POP3 Postfach Überwachung
|
||||
thing-type.config.mail.pop3.hostname.label = IP-Adresse
|
||||
thing-type.config.mail.pop3.hostname.description = IP-Adresse oder Hostname des POP3 Servers
|
||||
thing-type.config.mail.pop3.port.label = Port
|
||||
thing-type.config.mail.pop3.port.description = Standard Ports sind 110 für PLAIN/STARTTLS und 995 für SSL/TLS
|
||||
thing-type.config.mail.pop3.security.label = Sicherheitsprotokoll
|
||||
thing-type.config.mail.pop3.security.description = Server Sicherheitsprotokoll zur Kommunikation mit dem POP3 Server
|
||||
thing-type.config.mail.pop3.username.label = Benutzer
|
||||
thing-type.config.mail.pop3.username.description = Benutzer zur Authentifizierung am POP3 Server
|
||||
thing-type.config.mail.pop3.password.label = Passwort
|
||||
thing-type.config.mail.pop3.password.description = Passwort zur Authentifizierung am POP3 Server
|
||||
thing-type.config.mail.pop3.refresh.label = Abfrageintervall
|
||||
thing-type.config.mail.pop3.refresh.description = Zeit zwischen zwei Abfragen (in s, Standard ist 60s)
|
||||
|
||||
channel-type.mail.mailcount.label = Anzahl
|
||||
channel-type.mail.mailcount.description = Anzahl der E-Mails im Postfach
|
||||
channel-type.config.mail.mailcount.folder.label = Postfach
|
||||
channel-type.config.mail.mailcount.folder.description = Name des Postfachs auf dem Server
|
||||
channel-type.config.mail.mailcount.type.label = Typ
|
||||
channel-type.config.mail.mailcount.type.option.TOTAL = Gesamt
|
||||
channel-type.config.mail.mailcount.type.option.UNREAD = Ungelesen
|
||||
@@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<thing:thing-descriptions bindingId="mail"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||
|
||||
<thing-type id="smtp">
|
||||
<label>SMTP Server</label>
|
||||
<description>Used for sending emails via rule actions</description>
|
||||
<config-description>
|
||||
<parameter name="sender" type="text" required="true">
|
||||
<label>Sender</label>
|
||||
<description>Default sender address for mail</description>
|
||||
</parameter>
|
||||
<parameter name="hostname" type="text" required="true">
|
||||
<label>Server Hostname</label>
|
||||
</parameter>
|
||||
<parameter name="port" type="text" required="false">
|
||||
<label>Server Port</label>
|
||||
<description>Default values are 25 for plain/STARTTLS and 465 for SSL/TLS</description>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="security" type="text" required="false">
|
||||
<label>SMTP Server Security Protocol</label>
|
||||
<options>
|
||||
<option value="PLAIN">plain</option>
|
||||
<option value="STARTTLS">STARTTLS</option>
|
||||
<option value="SSL">SSL/TLS</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
<default>PLAIN</default>
|
||||
</parameter>
|
||||
<parameter name="username" type="text" required="false">
|
||||
<label>SMTP Server Username</label>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="false">
|
||||
<label>SMTP Server Password</label>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
<thing-type id="imap" extensible="mailcount">
|
||||
<label>IMAP Server</label>
|
||||
<description>Used for receiving emails</description>
|
||||
<config-description>
|
||||
<parameter name="hostname" type="text" required="true">
|
||||
<label>Server Hostname</label>
|
||||
</parameter>
|
||||
<parameter name="port" type="text" required="false">
|
||||
<label>Server Port</label>
|
||||
<description>Default values are 143 for plain/STARTTLS and 993 for SSL/TLS</description>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="security" type="text" required="false">
|
||||
<label>SMTP Server Security Protocol</label>
|
||||
<options>
|
||||
<option value="PLAIN">plain</option>
|
||||
<option value="STARTTLS">STARTTLS</option>
|
||||
<option value="SSL">SSL/TLS</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
<default>PLAIN</default>
|
||||
</parameter>
|
||||
<parameter name="username" type="text" required="true">
|
||||
<label>SMTP Server Username</label>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true">
|
||||
<label>SMTP Server Password</label>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" required="false">
|
||||
<label>Refresh Time for This Account in S</label>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
<thing-type id="pop3" extensible="mailcount">
|
||||
<label>POP3 Server</label>
|
||||
<description>Used for receiving emails</description>
|
||||
<config-description>
|
||||
<parameter name="hostname" type="text" required="true">
|
||||
<label>Server Hostname</label>
|
||||
</parameter>
|
||||
<parameter name="port" type="text" required="false">
|
||||
<label>Server Port</label>
|
||||
<description>Default values are 110 for plain/STARTTLS and 995 for SSL/TLS</description>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
<parameter name="security" type="text" required="false">
|
||||
<label>SMTP Server Security Protocol</label>
|
||||
<options>
|
||||
<option value="PLAIN">plain</option>
|
||||
<option value="STARTTLS">STARTTLS</option>
|
||||
<option value="SSL">SSL/TLS</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
<default>PLAIN</default>
|
||||
</parameter>
|
||||
<parameter name="username" type="text" required="true">
|
||||
<label>SMTP Server Username</label>
|
||||
</parameter>
|
||||
<parameter name="password" type="text" required="true">
|
||||
<label>SMTP Server Password</label>
|
||||
<context>password</context>
|
||||
</parameter>
|
||||
<parameter name="refresh" type="integer" required="false">
|
||||
<label>Refresh Time for This Account in S</label>
|
||||
<default>60</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</thing-type>
|
||||
|
||||
<channel-type id="mailcount">
|
||||
<item-type>Number</item-type>
|
||||
<label>Mail Count</label>
|
||||
<description>Number of emails in folder</description>
|
||||
<state readOnly="true"/>
|
||||
<config-description>
|
||||
<parameter name="folder" type="text" required="true">
|
||||
<label>Folder Name</label>
|
||||
<required>true</required>
|
||||
</parameter>
|
||||
<parameter name="type" type="text" required="false">
|
||||
<options>
|
||||
<option value="UNREAD">Unread</option>
|
||||
<option value="TOTAL">Total</option>
|
||||
</options>
|
||||
<limitToOptions>true</limitToOptions>
|
||||
<default>TOTAL</default>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</channel-type>
|
||||
</thing:thing-descriptions>
|
||||
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.mail;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.AddressException;
|
||||
|
||||
import org.apache.commons.mail.Email;
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.apache.commons.mail.HtmlEmail;
|
||||
import org.apache.commons.mail.MultiPartEmail;
|
||||
import org.apache.commons.mail.SimpleEmail;
|
||||
import org.junit.Test;
|
||||
import org.openhab.binding.mail.internal.MailBuilder;
|
||||
|
||||
/**
|
||||
* The {@link MailBuilderTest} class defines tests for the {@link MailBuilder} class
|
||||
*
|
||||
* @author Jan N. Klug - Initial contribution
|
||||
*/
|
||||
|
||||
public class MailBuilderTest {
|
||||
|
||||
private static final String TEST_STRING = "test";
|
||||
private static final String TEST_EMAIL = "foo@bar.zinga";
|
||||
|
||||
@Test(expected = AddressException.class)
|
||||
public void illegalToAddressThrowsException() throws AddressException {
|
||||
MailBuilder builder = new MailBuilder("foo bar.zinga");
|
||||
}
|
||||
|
||||
@Test(expected = EmailException.class)
|
||||
public void illegalFromAddressThrowsException() throws AddressException, EmailException {
|
||||
Email mail = new MailBuilder("TEST_EMAIL").withSender("foo bar.zinga").build();
|
||||
}
|
||||
|
||||
@Test(expected = MalformedURLException.class)
|
||||
public void illegalURLThrowsException() throws AddressException, MalformedURLException {
|
||||
MailBuilder builder = new MailBuilder("TEST_EMAIL").withURLAttachment("foo bar.zinga");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withTextOnlyReturnsSimpleEmail() throws AddressException, EmailException {
|
||||
MailBuilder builder = new MailBuilder(TEST_EMAIL);
|
||||
Email mail = builder.withText("boo").build();
|
||||
assertThat(mail, instanceOf(SimpleEmail.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withURLAttachmentReturnsMultiPartEmail()
|
||||
throws AddressException, EmailException, MalformedURLException {
|
||||
MailBuilder builder = new MailBuilder(TEST_EMAIL);
|
||||
Email mail = builder.withText("boo").withURLAttachment("http://www.openhab.org").build();
|
||||
assertThat(mail, instanceOf(MultiPartEmail.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withHtmlReturnsHtmlEmail() throws AddressException, EmailException {
|
||||
MailBuilder builder = new MailBuilder(TEST_EMAIL);
|
||||
Email mail = builder.withHtml("<html>test</html>").build();
|
||||
assertThat(mail, instanceOf(HtmlEmail.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldsSetInMail() throws EmailException, MessagingException, IOException {
|
||||
MailBuilder builder = new MailBuilder(TEST_EMAIL);
|
||||
|
||||
assertEquals("(no subject)", builder.build().getSubject());
|
||||
assertEquals(TEST_STRING, builder.withSubject(TEST_STRING).build().getSubject());
|
||||
|
||||
assertEquals(TEST_EMAIL, builder.withSender(TEST_EMAIL).build().getFromAddress().getAddress());
|
||||
|
||||
assertEquals(TEST_EMAIL, builder.build().getToAddresses().get(0).getAddress());
|
||||
assertEquals(2, builder.withRecipients(TEST_EMAIL).build().getToAddresses().size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user