diff --git a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java index d97ab6ff6d..50a7d49f66 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/notification/DefaultNotificationSettingsService.java @@ -148,21 +148,33 @@ public class DefaultNotificationSettingsService implements NotificationSettingsS } NotificationTarget originatorEntityOwnerUsers = createTarget(tenantId, "Users of the entity owner", new OriginatorEntityOwnerUsersFilter(), - "Customer users in case trigger entity (e.g. alarm) has customer, tenant admins otherwise"); + "In case trigger entity (e.g. created device or alarm) is owned by customer, then recipients are this customer's users, otherwise tenant admins"); NotificationTarget affectedUser = createTarget(tenantId, "Affected user", new AffectedUserFilter(), "If rule trigger is an action that affects some user (e.g. alarm assigned to user) - this user"); - NotificationTemplate alarmNotificationTemplate = createTemplate(tenantId, "Alarm notification", NotificationType.ALARM, + NotificationTemplate newAlarmNotificationTemplate = createTemplate(tenantId, "New alarm notification", NotificationType.ALARM, + "New alarm '${alarmType}'", + "Severity: ${alarmSeverity}, originator: ${alarmOriginatorEntityType} '${alarmOriginatorName}'", + "notifications", null, null); + AlarmNotificationRuleTriggerConfig newAlarmRuleTriggerConfig = new AlarmNotificationRuleTriggerConfig(); + newAlarmRuleTriggerConfig.setAlarmTypes(null); + newAlarmRuleTriggerConfig.setAlarmSeverities(null); + newAlarmRuleTriggerConfig.setNotifyOn(Set.of(AlarmAction.CREATED)); + createRule(tenantId, "New alarm", newAlarmNotificationTemplate.getId(), newAlarmRuleTriggerConfig, + List.of(tenantAdmins.getId(), originatorEntityOwnerUsers.getId()), "Send notification to tenant admins and alarm's customer users " + + "when an alarm is created"); + + NotificationTemplate alarmUpdateNotificationTemplate = createTemplate(tenantId, "Alarm update notification", NotificationType.ALARM, "Alarm '${alarmType}' - ${action}", "Severity: ${alarmSeverity}, originator: ${alarmOriginatorEntityType} '${alarmOriginatorName}'", "notifications", null, null); AlarmNotificationRuleTriggerConfig alarmRuleTriggerConfig = new AlarmNotificationRuleTriggerConfig(); alarmRuleTriggerConfig.setAlarmTypes(null); alarmRuleTriggerConfig.setAlarmSeverities(null); - alarmRuleTriggerConfig.setNotifyOn(Set.of(AlarmAction.CREATED, AlarmAction.SEVERITY_CHANGED, AlarmAction.ACKNOWLEDGED, AlarmAction.CLEARED)); - createRule(tenantId, "Alarm", alarmNotificationTemplate.getId(), alarmRuleTriggerConfig, - List.of(originatorEntityOwnerUsers.getId()), "Send notification to tenant admins or customer users " + - "when any alarm is created, updated or cleared"); + alarmRuleTriggerConfig.setNotifyOn(Set.of(AlarmAction.SEVERITY_CHANGED, AlarmAction.ACKNOWLEDGED, AlarmAction.CLEARED)); + createRule(tenantId, "Alarm update", alarmUpdateNotificationTemplate.getId(), alarmRuleTriggerConfig, + List.of(tenantAdmins.getId(), originatorEntityOwnerUsers.getId()), "Send notification to tenant admins and alarm's customer users " + + "when any alarm is updated or cleared"); NotificationTemplate deviceActionNotificationTemplate = createTemplate(tenantId, "Device action notification", NotificationType.ENTITY_ACTION, "${entityType} was ${actionType}", diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNode.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNode.java index 0d402b7c42..c87b68517f 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNode.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNode.java @@ -15,15 +15,12 @@ */ package org.thingsboard.rule.engine.notification; -import com.google.common.util.concurrent.ListenableFuture; -import org.apache.commons.lang3.StringUtils; import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.rule.engine.api.RuleNode; import org.thingsboard.rule.engine.api.TbContext; import org.thingsboard.rule.engine.api.TbNode; import org.thingsboard.rule.engine.api.TbNodeConfiguration; import org.thingsboard.rule.engine.api.TbNodeException; -import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.msg.TbMsg; @@ -34,8 +31,8 @@ import java.util.concurrent.ExecutionException; type = ComponentType.EXTERNAL, name = "send to Slack", configClazz = TbSlackNodeConfiguration.class, - nodeDescription = "Send message to a Slack channel or user", - nodeDetails = "", + nodeDescription = "Send message via Slack", + nodeDetails = "Sends message to a Slack channel or user", uiResources = {"static/rulenode/rulenode-core-config.js"} ) public class TbSlackNode implements TbNode { @@ -50,7 +47,7 @@ public class TbSlackNode implements TbNode { @Override public void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException { String token; - if (config.isUseDefaultNotificationSettings()) { + if (config.isUseSystemSettings()) { token = ctx.getSlackService().getToken(ctx.getTenantId()); } else { token = config.getBotToken(); @@ -60,28 +57,11 @@ public class TbSlackNode implements TbNode { } String message = TbNodeUtils.processPattern(config.getMessageTemplate(), msg); - - ListenableFuture result; - if (StringUtils.isNotEmpty(config.getConversationId())) { - result = ctx.getExternalCallExecutor().executeAsync(() -> { - ctx.getSlackService().sendMessage(ctx.getTenantId(), token, config.getConversationId(), message); - }); - } else { - result = ctx.getExternalCallExecutor().executeAsync(() -> { - SlackConversation conversation = ctx.getSlackService().findConversation(ctx.getTenantId(), token, config.getConversationType(), config.getConversationNamePattern()); - if (conversation == null) { - throw new IllegalArgumentException("Couldn't find conversation by name pattern"); - } - ctx.getSlackService().sendMessage(ctx.getTenantId(), token, conversation.getId(), message); - }); - } - - DonAsynchron.withCallback(result, r -> { - ctx.tellSuccess(msg); - }, - e -> { - ctx.tellFailure(msg, e); - }); + DonAsynchron.withCallback(ctx.getExternalCallExecutor().executeAsync(() -> { + ctx.getSlackService().sendMessage(ctx.getTenantId(), token, config.getConversation().getId(), message); + }), + r -> ctx.tellSuccess(msg), + e -> ctx.tellFailure(msg, e)); } } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java index 035e899ec2..55fdf198f2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/notification/TbSlackNodeConfiguration.java @@ -17,8 +17,10 @@ package org.thingsboard.rule.engine.notification; import lombok.Data; import org.thingsboard.rule.engine.api.NodeConfiguration; +import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation; import org.thingsboard.server.common.data.notification.targets.slack.SlackConversationType; +import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -26,14 +28,14 @@ import javax.validation.constraints.NotNull; public class TbSlackNodeConfiguration implements NodeConfiguration { private String botToken; - private boolean useDefaultNotificationSettings; + private boolean useSystemSettings; @NotEmpty private String messageTemplate; - @NotNull private SlackConversationType conversationType; - private String conversationId; // if not set, need to specify conversationNamePattern - private String conversationNamePattern; + @NotNull + @Valid + private SlackConversation conversation; @Override public TbSlackNodeConfiguration defaultConfiguration() {