diff --git a/bundles/action/org.openhab.action.pushover/README.md b/bundles/action/org.openhab.action.pushover/README.md index 744ad045203..c31ce83d2e7 100644 --- a/bundles/action/org.openhab.action.pushover/README.md +++ b/bundles/action/org.openhab.action.pushover/README.md @@ -7,19 +7,21 @@ The Pushover action service allows you to notify mobile devices of a message usi You may define default values for parameters to action calls in the file `services/pushover.cfg`. None of the configuration parameters are required as you can specify required configuration items in the action call, but you must at least provide an *API Token*, *User/Group Key* and a *Message* in some manner before a message can be pushed. -| Property | Default | Required | method to set | Description | -|-----------------|---------|:-------------------------------------------------------------:|-------------------------------------|------------------------------------------------------------------------------------------------------------------------| -| defaultTimeout | 10000 | No | - | Timeout in milliseconds for the connection to pushover.net | -| defaultToken | | Yes, if using action call without calling withApiKey() method | withApiKey(String apiKey) | Pushover [API token](https://pushover.net/api) to send to devices | -| defaultUser | | Yes, if using action call without calling withUser() method | withUser(String user) | Pushover User or Group key (not e-mail address) of your user (or you) to send to devices. | -| defaultTitle | openHAB | No | withTitle(String title) | Application title for the message | -| defaultPriority | 0 | No | withPriority(int priority) | Priority of the notification, from -2 (low priority) to 2 (high priority) | -| defaultUrl | | No | withUrl(String url) | URL to attach to the message if not specified in the command. This can be used to trigger actions on the device. | -| defaultUrlTitle | | No | withUrlTitle(String urlTitle) | URL title to attach to the message if not specified in the command. This can be used to trigger actions on the device. | -| attachment | | No | withAttachment(String attachment) | The full path of a JPEG image attachment to be pushed with the message. | -| contentType | | No | withContentType(String contentType) | Content type, ie "image/png" | -| defaultRetry | 300 | No | - | When priority is 2 (high priority), how often (in seconds) should messages be resent | -| defaultExpire | 3600 | No | - | When priority is 2 (high priority), how long (in seconds) to continue resending messages until acknowledged | +| Property | Default | Required | method to set | Description | +|-----------------|---------|:-------------------------------------------------------------:|-----------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| defaultTimeout | 10000 | No | - | Timeout in milliseconds for the connection to pushover.net | +| defaultToken | | Yes, if using action call without calling withApiKey() method | withApiKey(String apiKey) | Pushover [API token](https://pushover.net/api) to send to devices | +| defaultUser | | Yes, if using action call without calling withUser() method | withUser(String user) | Pushover User or Group key (not e-mail address) of your user (or you) to send to devices. | +| defaultTitle | openHAB | No | withTitle(String title) | Application title for the message | +| defaultPriority | 0 | No | withPriority(int priority) | Priority of the notification, from -2 (low priority) to 2 (high priority) | +| defaultUrl | | No | withUrl(String url) | URL to attach to the message if not specified in the command. This can be used to trigger actions on the device. | +| defaultUrlTitle | | No | withUrlTitle(String urlTitle) | URL title to attach to the message if not specified in the command. This can be used to trigger actions on the device. | +| attachment | | No | withAttachment(String attachment) | The full path of a JPEG image attachment to be pushed with the message. | +| contentType | | No | withContentType(String contentType) | Content type, ie "image/png" | +| htmlFormatting | | No | withHtmlFormatting(boolean htmlFormatting) | Enable or disable [HTML/Message Styling](https://pushover.net/api#html). Per default HTML styling is disabled. | +| monospaceFormatting | | No | withMonospaceFormatting(boolean monospaceFormatting) | Enable or disable [Monospace Message Styling](https://pushover.net/api#html). Per default monospace styling is disabled.| +| defaultRetry | 300 | No | - | When priority is 2 (high priority), how often (in seconds) should messages be resent | +| defaultExpire | 3600 | No | - | When priority is 2 (high priority), how long (in seconds) to continue resending messages until acknowledged | ## Actions diff --git a/bundles/action/org.openhab.action.pushover/src/main/java/org/openhab/action/pushover/internal/Pushover.java b/bundles/action/org.openhab.action.pushover/src/main/java/org/openhab/action/pushover/internal/Pushover.java index a92b87e1b28..62cd1894257 100644 --- a/bundles/action/org.openhab.action.pushover/src/main/java/org/openhab/action/pushover/internal/Pushover.java +++ b/bundles/action/org.openhab.action.pushover/src/main/java/org/openhab/action/pushover/internal/Pushover.java @@ -8,6 +8,8 @@ */ package org.openhab.action.pushover.internal; +import static java.nio.charset.StandardCharsets.UTF_8; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -37,6 +39,7 @@ * * @author Chris Graham - Initial contribution * @author Christoph Weitkamp - Added Receipts and Callback API for handling of emergency-priority notifications + * @author Jonas BrĂ¼stel - Added HTML and Monospace formatting option * @since 1.5.0 */ public class Pushover { @@ -45,7 +48,7 @@ public class Pushover { private static final String JSON_API_URL = "https://api.pushover.net/1/messages.json"; private static final String JSON_CANCEL_API_URL = "https://api.pushover.net/1/receipts/{receipt}/cancel.json"; - private static final String UTF_8_ENCODING = "UTF-8"; + private static final String UTF_8_ENCODING = UTF_8.name(); private static final String DEFAULT_CONTENT_TYPE = "image/jpeg"; private static final JsonParser parser = new JsonParser(); @@ -55,7 +58,8 @@ public class Pushover { private static final String API_RETURN_ERRORS_TAG = "errors"; private static final String API_RETURN_RECEIPT_TAG = "receipt"; - private static final int API_MAX_MESSAGE_LENGTH = 512; + private static final int API_MAX_MESSAGE_LENGTH = 1024; + private static final int API_MAX_TITLE_LENGTH = 250; private static final int API_MAX_URL_LENGTH = 512; private static final int API_MAX_URL_TITLE_LENGTH = 100; private static final int[] API_VALID_PRIORITY_LIST = { -2, -1, 0, 1, 2 }; @@ -77,8 +81,11 @@ public class Pushover { public static final String MESSAGE_KEY_RETRY = "retry"; public static final String MESSAGE_KEY_EXPIRE = "expire"; public static final String MESSAGE_KEY_ATTACHMENT = "attachment"; - public static final String MESSAGE_KEY_CONTENT_TYPE = "content-type"; + public static final String MESSAGE_KEY_HTML = "html"; + public static final String MESSAGE_VALUE_HTML = "1"; + public static final String MESSAGE_KEY_MONOSPACE = "monospace"; + public static final String MESSAGE_VALUE_MONOSPACE = "1"; static String defaultApiKey; static String defaultUser; @@ -105,6 +112,8 @@ public class Pushover { private String sound; private String attachment; private String contentType; + private boolean htmlFormatting; + private boolean monospaceFormatting; public Pushover() { apiKey = Pushover.defaultApiKey; @@ -115,6 +124,8 @@ public Pushover() { urlTitle = Pushover.defaultUrlTitle; priority = Pushover.defaultPriority; sound = Pushover.defaultSound; + htmlFormatting = false; + monospaceFormatting = false; } public Pushover withApiKey(String apiKey) { @@ -172,6 +183,16 @@ public Pushover withContentType(String contentType) { return this; } + public Pushover withHtmlFormatting(boolean htmlFormatting) { + this.htmlFormatting = htmlFormatting; + return this; + } + + public Pushover withMonospaceFormatting(boolean monospaceFormatting) { + this.monospaceFormatting = monospaceFormatting; + return this; + } + public static Pushover pushoverBuilder(String message) { Pushover pushover = new Pushover(); pushover.message = message; @@ -323,19 +344,20 @@ public static boolean pushover(@ParamDoc(name = "apiKey", text = "Your applicati @ParamDoc(name = "urlTitle", text = "A title for your supplementary URL, otherwise just the URL is shown.") String urlTitle, @ParamDoc(name = "priority", text = "Send as -1 to always send as a quiet notification, 1 to display as high-priority and bypass the user's quiet hours, or 2 to also require confirmation from the user.") int priority, @ParamDoc(name = "sound", text = "The name of one of the sounds supported by device clients to override the user's default sound choice.") String sound) { - return pushover0(apiKey, user, message, device, title, url, urlTitle, priority, sound, null, null) != null; + return pushover0(apiKey, user, message, device, title, url, urlTitle, priority, sound, null, null, false, false) != null; } @ActionDoc(text = "Send a notification to your device. apiKey, user and message are required. All else can effectively be null.", returns = "a receipt (30 character string containing the character set [A-Za-z0-9]), if emergency, otherwise empty string or null in case of any error.") public static String sendPushoverMessage( @ParamDoc(name = "pushover", text = "The Pushover object containing all required parameters.") Pushover p) { return pushover0(p.apiKey, p.user, p.message, p.device, p.title, p.url, p.urlTitle, p.priority, p.sound, - p.attachment, p.contentType); + p.attachment, p.contentType, p.htmlFormatting, p.monospaceFormatting); } // Primary method for sending a message to the Pushover API private static String pushover0(String apiKey, String user, String message, String device, String title, String url, - String urlTitle, int priority, String sound, String attachment, String contentType) { + String urlTitle, int priority, String sound, String attachment, String contentType, boolean htmlFormatting, + boolean monospaceFormatting) { List parts = new ArrayList<>(); try { @@ -359,11 +381,12 @@ private static String pushover0(String apiKey, String user, String message, Stri } if (!StringUtils.isEmpty(message)) { - if ((message.length() + title.length()) <= API_MAX_MESSAGE_LENGTH) { + if ((message.length() + title.length()) <= API_MAX_MESSAGE_LENGTH && + title.length() <= API_MAX_TITLE_LENGTH) { parts.add(new StringPart(MESSAGE_KEY_MESSAGE, message, UTF_8_ENCODING)); } else { - logger.warn("Together, the event message and title total more than {} characters.", - API_MAX_MESSAGE_LENGTH); + logger.warn("The message character size is greater than {} or the title is greater " + + "than {}.", API_MAX_MESSAGE_LENGTH, API_MAX_TITLE_LENGTH); return null; } } else { @@ -468,6 +491,13 @@ private static String pushover0(String apiKey, String user, String message, Stri attachment, e.getMessage()); } } + + if (htmlFormatting) { + parts.add(new StringPart(MESSAGE_KEY_HTML, MESSAGE_VALUE_HTML, UTF_8_ENCODING)); + } else if (monospaceFormatting) { + parts.add(new StringPart(MESSAGE_KEY_MONOSPACE, MESSAGE_VALUE_MONOSPACE, UTF_8_ENCODING)); + } + PostMethod httpPost = new PostMethod(JSON_API_URL); httpPost.setRequestEntity(