Skip to content

Commit 95d1b6f

Browse files
[openhabcloud] Enhanced Notification Actions (openhab#16938)
* [openhabcloud] Enhanced Notification Actions Co-authored-by: Florian Hotze <[email protected]> Signed-off-by: Dan Cunningham <[email protected]>
1 parent 9744090 commit 95d1b6f

8 files changed

+275
-58
lines changed

bundles/org.openhab.io.openhabcloud/src/main/java/org/openhab/io/openhabcloud/NotificationAction.java

+49-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*
2626
* @author Victor Belov - Initial contribution
2727
* @author Kai Kreuzer - migrated code to ESH APIs
28+
* @author Dan Cunningham - Extended notification enhancements
2829
*/
2930
@NonNullByDefault
3031
public class NotificationAction {
@@ -57,9 +58,32 @@ public static void sendNotification(String userId, String message) {
5758
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
5859
public static void sendNotification(String userId, String message, @Nullable String icon,
5960
@Nullable String severity) {
61+
sendNotification(userId, message, icon, severity, null, null, null, null, null, null);
62+
}
63+
64+
/**
65+
* Sends an advanced push notification to mobile devices of user
66+
*
67+
* @param userId the cloud user id of the recipient
68+
* @param message the body of the notification
69+
* @param icon name for the notification
70+
* @param severity category for the notification
71+
* @param title for the notification
72+
* @param onClickAction the action to perform when clicked
73+
* @param mediaAttachmentUrl the media to attach to a notification
74+
* @param actionButton1 an action button in the format "Title=Action"
75+
* @param actionButton2 an action button in the format "Title=Action"
76+
* @param actionButton3 an action button in the format "Title=Action"
77+
*
78+
*/
79+
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
80+
public static void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity,
81+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
82+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
6083
logger.debug("sending notification '{}' to user {}", message, userId);
6184
if (cloudService != null) {
62-
cloudService.sendNotification(userId, message, icon, severity);
85+
cloudService.sendNotification(userId, message, icon, severity, title, onClickAction, mediaAttachmentUrl,
86+
actionButton1, actionButton2, actionButton3);
6387
}
6488
}
6589

@@ -115,9 +139,32 @@ public static void sendBroadcastNotification(String message) {
115139
*/
116140
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
117141
public static void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
142+
sendBroadcastNotification(message, icon, severity, null, null, null, null, null, null);
143+
}
144+
145+
/**
146+
* Sends an advanced broadcast notification. Broadcast notifications are pushed to all
147+
* mobile devices of all users of the account
148+
*
149+
* @param message the body of the notification
150+
* @param icon name for the notification
151+
* @param severity category for the notification
152+
* @param title for the notification
153+
* @param onClickAction the action to perform when clicked
154+
* @param mediaAttachmentUrl the media to attach to a notification
155+
* @param actionButton1 an action button in the format "Title=Action"
156+
* @param actionButton2 an action button in the format "Title=Action"
157+
* @param actionButton3 an action button in the format "Title=Action"
158+
*
159+
*/
160+
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
161+
public static void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity,
162+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
163+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
118164
logger.debug("sending broadcast notification '{}' to all users", message);
119165
if (cloudService != null) {
120-
cloudService.sendBroadcastNotification(message, icon, severity);
166+
cloudService.sendBroadcastNotification(message, icon, severity, title, onClickAction, mediaAttachmentUrl,
167+
actionButton1, actionButton2, actionButton3);
121168
}
122169
}
123170
}

bundles/org.openhab.io.openhabcloud/src/main/java/org/openhab/io/openhabcloud/internal/CloudClient.java

+68-21
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.eclipse.jetty.http.HttpStatus;
4141
import org.eclipse.jetty.util.BufferUtil;
4242
import org.eclipse.jetty.util.URIUtil;
43+
import org.json.JSONArray;
4344
import org.json.JSONException;
4445
import org.json.JSONObject;
4546
import org.openhab.core.OpenHAB;
@@ -70,6 +71,7 @@
7071
*
7172
* @author Victor Belov - Initial contribution
7273
* @author Kai Kreuzer - migrated code to new Jetty client and ESH APIs
74+
* @author Dan Cunningham - Extended notification enhancements
7375
*/
7476
public class CloudClient {
7577

@@ -587,39 +589,67 @@ private void handleCommandEvent(JSONObject data) {
587589
* @param message notification message text
588590
* @param icon name of the icon for this notification
589591
* @param severity severity name for this notification
592+
* @param title for the notification
593+
* @param onClickAction the action to perform when clicked
594+
* @param mediaAttachmentUrl the media to attach to a notification
595+
* @param actionButton1 an action button in the format "Title=Action"
596+
* @param actionButton2 an action button in the format "Title=Action"
597+
* @param actionButton3 an action button in the format "Title=Action"
590598
*/
591-
public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity) {
592-
if (isConnected()) {
593-
JSONObject notificationMessage = new JSONObject();
594-
try {
595-
notificationMessage.put("userId", userId);
596-
notificationMessage.put("message", message);
597-
notificationMessage.put("icon", icon);
598-
notificationMessage.put("severity", severity);
599-
socket.emit("notification", notificationMessage);
600-
} catch (JSONException e) {
601-
logger.debug("{}", e.getMessage());
602-
}
603-
} else {
604-
logger.debug("No connection, notification is not sent");
605-
}
599+
public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity,
600+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
601+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
602+
sendNotificationInternal(userId, message, icon, severity, title, onClickAction, mediaAttachmentUrl,
603+
actionButton1, actionButton2, actionButton3);
606604
}
607605

608606
/**
609-
* This method sends log notification to the openHAB Cloud
607+
* This method sends broadcast notification to the openHAB Cloud
610608
*
611609
* @param message notification message text
612610
* @param icon name of the icon for this notification
613611
* @param severity severity name for this notification
612+
* @param title for this notification
613+
* @param onClickAction the action to perform when clicked
614+
* @param mediaAttachmentUrl the media to attach to a notification
615+
* @param actionButton1 an action button in the format "Title=Action"
616+
* @param actionButton2 an action button in the format "Title=Action"
617+
* @param actionButton3 an action button in the format "Title=Action"
614618
*/
615-
public void sendLogNotification(String message, @Nullable String icon, @Nullable String severity) {
619+
public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity,
620+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
621+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
622+
sendNotificationInternal(null, message, icon, severity, title, onClickAction, mediaAttachmentUrl, actionButton1,
623+
actionButton2, actionButton3);
624+
}
625+
626+
private void sendNotificationInternal(@Nullable String userId, String message, @Nullable String icon,
627+
@Nullable String severity, @Nullable String title, @Nullable String onClickAction,
628+
@Nullable String mediaAttachmentUrl, @Nullable String actionButton1, @Nullable String actionButton2,
629+
@Nullable String actionButton3) {
616630
if (isConnected()) {
617631
JSONObject notificationMessage = new JSONObject();
618632
try {
633+
if (userId != null) {
634+
notificationMessage.put("userId", userId);
635+
}
619636
notificationMessage.put("message", message);
620637
notificationMessage.put("icon", icon);
621638
notificationMessage.put("severity", severity);
622-
socket.emit("lognotification", notificationMessage);
639+
if (title != null) {
640+
notificationMessage.put("title", title);
641+
}
642+
if (onClickAction != null) {
643+
notificationMessage.put("on-click", onClickAction);
644+
}
645+
if (mediaAttachmentUrl != null) {
646+
notificationMessage.put("media-attachment-url", mediaAttachmentUrl);
647+
}
648+
JSONArray actionArray = createActionArray(actionButton1, actionButton2, actionButton3);
649+
if (!actionArray.isEmpty()) {
650+
notificationMessage.put("actions", actionArray);
651+
}
652+
socket.emit(userId == null ? "broadcastnotification" : "notification", notificationMessage);
623653
} catch (JSONException e) {
624654
logger.debug("{}", e.getMessage());
625655
}
@@ -629,20 +659,20 @@ public void sendLogNotification(String message, @Nullable String icon, @Nullable
629659
}
630660

631661
/**
632-
* This method sends broadcast notification to the openHAB Cloud
662+
* This method sends log notification to the openHAB Cloud
633663
*
634664
* @param message notification message text
635665
* @param icon name of the icon for this notification
636666
* @param severity severity name for this notification
637667
*/
638-
public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
668+
public void sendLogNotification(String message, @Nullable String icon, @Nullable String severity) {
639669
if (isConnected()) {
640670
JSONObject notificationMessage = new JSONObject();
641671
try {
642672
notificationMessage.put("message", message);
643673
notificationMessage.put("icon", icon);
644674
notificationMessage.put("severity", severity);
645-
socket.emit("broadcastnotification", notificationMessage);
675+
socket.emit("lognotification", notificationMessage);
646676
} catch (JSONException e) {
647677
logger.debug("{}", e.getMessage());
648678
}
@@ -715,6 +745,23 @@ private JSONObject getJSONHeaders(HttpFields httpFields) {
715745
return headersJSON;
716746
}
717747

748+
private JSONArray createActionArray(@Nullable String... actionStrings) {
749+
JSONArray actionArray = new JSONArray();
750+
for (String actionString : actionStrings) {
751+
if (actionString == null) {
752+
continue;
753+
}
754+
String[] parts = actionString.split("=", 2);
755+
if (parts.length == 2) {
756+
JSONObject action = new JSONObject();
757+
action.put("title", parts[0]);
758+
action.put("action", parts[1]);
759+
actionArray.put(action);
760+
}
761+
}
762+
return actionArray;
763+
}
764+
718765
private static String censored(String secret) {
719766
if (secret.length() < 4) {
720767
return "*******";

bundles/org.openhab.io.openhabcloud/src/main/java/org/openhab/io/openhabcloud/internal/CloudService.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
*
6464
* @author Victor Belov - Initial contribution
6565
* @author Kai Kreuzer - migrated code to new Jetty client and ESH APIs
66+
* @author Dan Cunningham - Extended notification enhancements
6667
*/
6768
@Component(service = { CloudService.class, EventSubscriber.class,
6869
ActionService.class }, configurationPid = "org.openhab.openhabcloud", property = Constants.SERVICE_PID
@@ -114,10 +115,19 @@ public CloudService(final @Reference HttpClientFactory httpClientFactory,
114115
* @param message the {@link String} containing a message to send to specified user id
115116
* @param icon the {@link String} containing a name of the icon to be used with this notification
116117
* @param severity the {@link String} containing severity (good, info, warning, error) of notification
118+
* @param title the {@link String} containing the title to be used with this notification
119+
* @param onClickAction the {@link String} containing the action to perform when clicked
120+
* @param mediaAttachmentUrl the {@link String} containing the media to attach to a notification
121+
* @param actionButton1 the {@link String} containing the action button in the format "Title=Action"
122+
* @param actionButton2 the {@link String} containing the action button in the format "Title=Action"
123+
* @param actionButton3 the {@link String} containing the action button in the format "Title=Action"
117124
*/
118-
public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity) {
125+
public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity,
126+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
127+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
119128
logger.debug("Sending message '{}' to user id {}", message, userId);
120-
cloudClient.sendNotification(userId, message, icon, severity);
129+
cloudClient.sendNotification(userId, message, icon, severity, title, onClickAction, mediaAttachmentUrl,
130+
actionButton1, actionButton2, actionButton3);
121131
}
122132

123133
/**
@@ -140,10 +150,19 @@ public void sendLogNotification(String message, @Nullable String icon, @Nullable
140150
* @param message the {@link String} containing a message to send to specified user id
141151
* @param icon the {@link String} containing a name of the icon to be used with this notification
142152
* @param severity the {@link String} containing severity (good, info, warning, error) of notification
153+
* @param title the {@link String} containing the title to be used with this notification
154+
* @param onClickAction the {@link String} containing the action to perform when clicked
155+
* @param mediaAttachmentUrl the {@link String} containing the media to attach to a notification
156+
* @param actionButton1 the {@link String} containing the action button in the format "Title=Action"
157+
* @param actionButton2 the {@link String} containing the action button in the format "Title=Action"
158+
* @param actionButton3 the {@link String} containing the action button in the format "Title=Action"
143159
*/
144-
public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
160+
public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity,
161+
@Nullable String title, @Nullable String onClickAction, @Nullable String mediaAttachmentUrl,
162+
@Nullable String actionButton1, @Nullable String actionButton2, @Nullable String actionButton3) {
145163
logger.debug("Sending broadcast message '{}' to all users", message);
146-
cloudClient.sendBroadcastNotification(message, icon, severity);
164+
cloudClient.sendBroadcastNotification(message, icon, severity, title, onClickAction, mediaAttachmentUrl,
165+
actionButton1, actionButton2, actionButton3);
147166
}
148167

149168
private String substringBefore(String str, String separator) {

bundles/org.openhab.io.openhabcloud/src/main/java/org/openhab/io/openhabcloud/internal/actions/BaseNotificationActionHandler.java

+25-4
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,39 @@
1717
import org.openhab.core.automation.Action;
1818
import org.openhab.core.automation.handler.BaseActionModuleHandler;
1919
import org.openhab.core.automation.handler.ModuleHandler;
20+
import org.openhab.core.config.core.ConfigParser;
2021
import org.openhab.io.openhabcloud.internal.CloudService;
2122

2223
/**
2324
* This is a base {@link ModuleHandler} implementation for {@link Action}s to send a notifications via openHAB Cloud.
2425
*
2526
* @author Christoph Weitkamp - Initial contribution
27+
* @author Dan Cunningham - Extended notification enhancements
2628
*/
2729
@NonNullByDefault
2830
public abstract class BaseNotificationActionHandler extends BaseActionModuleHandler {
2931

3032
public static final String PARAM_MESSAGE = "message";
3133
public static final String PARAM_ICON = "icon";
3234
public static final String PARAM_SEVERITY = "severity";
35+
public static final String PARAM_TITLE = "title";
36+
public static final String PARAM_ON_CLICK_ACTION = "onClickAction";
37+
public static final String PARAM_MEDIA_ATTACHMENT_URL = "mediaAttachmentUrl";
38+
public static final String PARAM_ACTION_BUTTON_1 = "actionButton1";
39+
public static final String PARAM_ACTION_BUTTON_2 = "actionButton2";
40+
public static final String PARAM_ACTION_BUTTON_3 = "actionButton3";
3341

3442
protected final CloudService cloudService;
3543

3644
protected final String message;
3745
protected final @Nullable String icon;
3846
protected final @Nullable String severity;
47+
protected final @Nullable String title;
48+
protected final @Nullable String onClickAction;
49+
protected final @Nullable String mediaAttachmentUrl;
50+
protected final @Nullable String actionButton1;
51+
protected final @Nullable String actionButton2;
52+
protected final @Nullable String actionButton3;
3953

4054
public BaseNotificationActionHandler(Action module, CloudService cloudService) {
4155
super(module);
@@ -48,10 +62,17 @@ public BaseNotificationActionHandler(Action module, CloudService cloudService) {
4862
throw new IllegalArgumentException(String.format("Param '%s' should be of type String.", PARAM_MESSAGE));
4963
}
5064

51-
Object iconParam = module.getConfiguration().get(PARAM_ICON);
52-
this.icon = iconParam instanceof String ? iconParam.toString() : null;
65+
this.icon = stringConfig(PARAM_ICON);
66+
this.severity = stringConfig(PARAM_SEVERITY);
67+
this.title = stringConfig(PARAM_TITLE);
68+
this.onClickAction = stringConfig(PARAM_ON_CLICK_ACTION);
69+
this.mediaAttachmentUrl = stringConfig(PARAM_MEDIA_ATTACHMENT_URL);
70+
this.actionButton1 = stringConfig(PARAM_ACTION_BUTTON_1);
71+
this.actionButton2 = stringConfig(PARAM_ACTION_BUTTON_2);
72+
this.actionButton3 = stringConfig(PARAM_ACTION_BUTTON_3);
73+
}
5374

54-
Object severityParam = module.getConfiguration().get(PARAM_SEVERITY);
55-
this.severity = severityParam instanceof String ? severityParam.toString() : null;
75+
private @Nullable String stringConfig(String key) {
76+
return ConfigParser.valueAs(module.getConfiguration().get(key), String.class);
5677
}
5778
}

0 commit comments

Comments
 (0)