23 changed files with 631 additions and 126 deletions
@ -0,0 +1,90 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.notification; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.common.util.JacksonUtil; |
|||
import org.thingsboard.rule.engine.api.util.TbNodeUtils; |
|||
import org.thingsboard.server.common.data.AdminSettings; |
|||
import org.thingsboard.server.common.data.id.NotificationTemplateId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
|||
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig; |
|||
import org.thingsboard.server.common.data.notification.settings.NotificationSettings; |
|||
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; |
|||
import org.thingsboard.server.dao.notification.NotificationTemplateService; |
|||
import org.thingsboard.server.dao.settings.AdminSettingsService; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Optional; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class NotificationManagerHelper { |
|||
|
|||
public static final String SETTINGS_KEY = "notifications"; |
|||
private final NotificationTemplateService templateService; |
|||
private final AdminSettingsService adminSettingsService; |
|||
|
|||
public Map<NotificationDeliveryMethod, DeliveryMethodNotificationTemplate> getTemplates(TenantId tenantId, NotificationTemplateId templateId, List<NotificationDeliveryMethod> deliveryMethods) { |
|||
NotificationTemplate notificationTemplate = templateService.findNotificationTemplateById(tenantId, templateId); |
|||
NotificationTemplateConfig config = notificationTemplate.getConfiguration(); |
|||
return deliveryMethods.stream() |
|||
.collect(Collectors.toMap(k -> k, deliveryMethod -> { |
|||
return Optional.ofNullable(config.getTemplates()) |
|||
.map(templates -> templates.get(deliveryMethod)) |
|||
.orElse(config.getDefaultTemplate()); |
|||
})); |
|||
} |
|||
|
|||
public String processTemplate(String template, Map<String, String> templateContext) { |
|||
return TbNodeUtils.processTemplate(template, templateContext); |
|||
} |
|||
|
|||
public NotificationSettings getNotificationSettings(TenantId tenantId) { |
|||
return Optional.ofNullable(adminSettingsService.findAdminSettingsByTenantIdAndKey(tenantId, SETTINGS_KEY)) |
|||
.map(adminSettings -> JacksonUtil.treeToValue(adminSettings.getJsonValue(), NotificationSettings.class)) |
|||
.orElseGet(() -> { |
|||
NotificationSettings settings = new NotificationSettings(); |
|||
NotificationDeliveryMethodConfig defaultConfig = new NotificationDeliveryMethodConfig(); |
|||
defaultConfig.setEnabled(true); |
|||
settings.setDeliveryMethodsConfigs(Map.of( |
|||
NotificationDeliveryMethod.WEBSOCKET, defaultConfig, |
|||
NotificationDeliveryMethod.EMAIL, defaultConfig, |
|||
NotificationDeliveryMethod.SMS, defaultConfig |
|||
)); |
|||
return settings; |
|||
}); |
|||
} |
|||
|
|||
public void saveNotificationSettings(TenantId tenantId, NotificationSettings notificationSettings) { |
|||
AdminSettings adminSettings = Optional.ofNullable(adminSettingsService.findAdminSettingsByTenantIdAndKey(tenantId, SETTINGS_KEY)) |
|||
.orElseGet(() -> { |
|||
AdminSettings newAdminSettings = new AdminSettings(); |
|||
newAdminSettings.setKey(SETTINGS_KEY); |
|||
newAdminSettings.setTenantId(tenantId); |
|||
return newAdminSettings; |
|||
}); |
|||
adminSettings.setJsonValue(JacksonUtil.valueToTree(notificationSettings)); |
|||
adminSettingsService.saveAdminSettings(tenantId, adminSettings); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.notification; |
|||
|
|||
import com.google.common.base.Strings; |
|||
import lombok.Builder; |
|||
import lombok.Getter; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
|||
import org.thingsboard.server.common.data.notification.NotificationRequest; |
|||
import org.thingsboard.server.common.data.notification.NotificationRequestStats; |
|||
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig; |
|||
import org.thingsboard.server.common.data.notification.settings.NotificationSettings; |
|||
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate; |
|||
|
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
@SuppressWarnings("unchecked") |
|||
public class NotificationProcessingContext { |
|||
|
|||
@Getter |
|||
private final TenantId tenantId; |
|||
private final NotificationSettings settings; |
|||
@Getter |
|||
private final NotificationRequest request; |
|||
private final Map<String, String> additionalTemplateContext; |
|||
|
|||
private Map<NotificationDeliveryMethod, DeliveryMethodNotificationTemplate> templates; |
|||
@Getter |
|||
private NotificationRequestStats stats; |
|||
|
|||
@Builder |
|||
public NotificationProcessingContext(TenantId tenantId, NotificationSettings settings, NotificationRequest request, Map<String, String> additionalTemplateContext) { |
|||
this.tenantId = tenantId; |
|||
this.settings = settings; |
|||
this.request = request; |
|||
this.additionalTemplateContext = additionalTemplateContext; |
|||
} |
|||
|
|||
public void init(NotificationManagerHelper notificationManagerHelper) { |
|||
templates = notificationManagerHelper.getTemplates(tenantId, request.getTemplateId(), request.getDeliveryMethods()); |
|||
stats = new NotificationRequestStats(); |
|||
} |
|||
|
|||
public <T extends DeliveryMethodNotificationTemplate> T getTemplate(NotificationDeliveryMethod deliveryMethod) { |
|||
return (T) templates.get(deliveryMethod); |
|||
} |
|||
|
|||
public <C extends NotificationDeliveryMethodConfig> C getDeliveryMethodConfig(NotificationDeliveryMethod deliveryMethod) { |
|||
return (C) settings.getDeliveryMethodsConfigs().get(deliveryMethod); |
|||
} |
|||
|
|||
public Map<String, String> createTemplateContext(User recipient) { |
|||
Map<String, String> templateContext = new HashMap<>(); |
|||
templateContext.put("email", recipient.getEmail()); |
|||
templateContext.put("firstName", Strings.nullToEmpty(recipient.getFirstName())); |
|||
templateContext.put("lastName", Strings.nullToEmpty(recipient.getLastName())); |
|||
if (additionalTemplateContext != null) { |
|||
templateContext.putAll(additionalTemplateContext); |
|||
} |
|||
return templateContext; |
|||
} |
|||
|
|||
} |
|||
@ -1,56 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.notification; |
|||
|
|||
import lombok.RequiredArgsConstructor; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.rule.engine.api.util.TbNodeUtils; |
|||
import org.thingsboard.server.common.data.id.NotificationTemplateId; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationTemplate; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationText; |
|||
import org.thingsboard.server.common.data.notification.template.NotificationTextTemplate; |
|||
import org.thingsboard.server.dao.notification.NotificationTemplateService; |
|||
|
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Optional; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class NotificationTemplateUtil { |
|||
|
|||
private final NotificationTemplateService templateService; |
|||
|
|||
public Map<NotificationDeliveryMethod, NotificationTextTemplate> getTemplates(TenantId tenantId, NotificationTemplateId templateId, List<NotificationDeliveryMethod> deliveryMethods) { |
|||
NotificationTemplate notificationTemplate = templateService.findNotificationTemplateById(tenantId, templateId); |
|||
NotificationTemplateConfig config = notificationTemplate.getConfiguration(); |
|||
return deliveryMethods.stream() |
|||
.collect(Collectors.toMap(k -> k, deliveryMethod -> { |
|||
return Optional.ofNullable(config.getTextTemplates()) |
|||
.map(templates -> templates.get(deliveryMethod)) |
|||
.orElse(config.getDefaultTextTemplate()); |
|||
})); |
|||
} |
|||
|
|||
public NotificationText processTemplate(NotificationTextTemplate template, Map<String, String> templateContext) { |
|||
return new NotificationText(TbNodeUtils.processTemplate(template.getBody(), templateContext), template.getSubject()); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.notification.channels; |
|||
|
|||
import com.google.common.util.concurrent.Futures; |
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import lombok.RequiredArgsConstructor; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.springframework.stereotype.Component; |
|||
import org.thingsboard.server.service.slack.SlackService; |
|||
import org.thingsboard.server.common.data.User; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
|||
import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig; |
|||
import org.thingsboard.server.common.data.notification.template.SlackDeliveryMethodNotificationTemplate; |
|||
import org.thingsboard.server.service.notification.NotificationProcessingContext; |
|||
|
|||
import javax.annotation.PostConstruct; |
|||
import java.util.concurrent.ExecutorService; |
|||
import java.util.concurrent.Executors; |
|||
|
|||
@Component |
|||
@RequiredArgsConstructor |
|||
public class SlackNotificationChannel implements NotificationChannel { |
|||
|
|||
private final SlackService slackService; |
|||
private ExecutorService executor; |
|||
|
|||
@PostConstruct |
|||
private void init() { |
|||
executor = Executors.newSingleThreadExecutor(); |
|||
} |
|||
|
|||
@Override |
|||
public ListenableFuture<Void> sendNotification(User recipient, String text, NotificationProcessingContext ctx) { |
|||
SlackDeliveryMethodNotificationTemplate template = ctx.getTemplate(NotificationDeliveryMethod.SLACK); |
|||
SlackNotificationDeliveryMethodConfig config = ctx.getDeliveryMethodConfig(NotificationDeliveryMethod.SLACK); |
|||
|
|||
String conversationId = template.getConversationId(); |
|||
if (StringUtils.isNotEmpty(conversationId)) { |
|||
if (ctx.getStats().contains(NotificationDeliveryMethod.SLACK)) { |
|||
// FIXME stats.sent will be reported anyway
|
|||
return Futures.immediateFuture(null); // if conversationId is set, we only need to send message once
|
|||
} |
|||
} else { |
|||
String username = StringUtils.join(new String[]{recipient.getFirstName(), recipient.getLastName()}, ' '); |
|||
if (StringUtils.isNotEmpty(username)) { |
|||
conversationId = username; |
|||
} else { |
|||
return Futures.immediateFailedFuture(new IllegalArgumentException("Couldn't determine Slack username for the user")); |
|||
} |
|||
} |
|||
return send(ctx.getTenantId(), config.getBotToken(), conversationId, text); |
|||
} |
|||
|
|||
private ListenableFuture<Void> send(TenantId tenantId, String botToken, String conversationId, String text) { |
|||
return Futures.submit(() -> { |
|||
slackService.sendMessage(tenantId, botToken, conversationId, text); |
|||
return null; |
|||
}, executor); |
|||
} |
|||
|
|||
@Override |
|||
public NotificationDeliveryMethod getDeliveryMethod() { |
|||
return NotificationDeliveryMethod.SLACK; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,101 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.slack; |
|||
|
|||
import com.slack.api.Slack; |
|||
import com.slack.api.methods.MethodsClient; |
|||
import com.slack.api.methods.SlackApiTextResponse; |
|||
import com.slack.api.methods.request.chat.ChatPostMessageRequest; |
|||
import com.slack.api.methods.request.conversations.ConversationsListRequest; |
|||
import com.slack.api.methods.request.users.UsersListRequest; |
|||
import com.slack.api.methods.response.chat.ChatPostMessageResponse; |
|||
import com.slack.api.methods.response.conversations.ConversationsListResponse; |
|||
import com.slack.api.methods.response.users.UsersListResponse; |
|||
import com.slack.api.model.ConversationType; |
|||
import org.springframework.stereotype.Service; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
import java.util.List; |
|||
import java.util.stream.Collectors; |
|||
|
|||
@Service |
|||
public class DefaultSlackService implements SlackService { |
|||
|
|||
private final Slack slack = Slack.getInstance(); |
|||
|
|||
@Override |
|||
public void sendMessage(TenantId tenantId, String token, String conversationId, String message) throws Exception { |
|||
ChatPostMessageRequest request = ChatPostMessageRequest.builder() |
|||
.channel(conversationId) |
|||
.text(message) |
|||
.build(); |
|||
ChatPostMessageResponse response = slack.methods(token).chatPostMessage(request); |
|||
check(response); |
|||
} |
|||
|
|||
@Override |
|||
public List<SlackConversation> listConversations(TenantId tenantId, String token, SlackConversation.Type conversationType) throws Exception { |
|||
MethodsClient methods = slack.methods(token); |
|||
if (conversationType == SlackConversation.Type.USER) { |
|||
UsersListResponse usersListResponse = methods.usersList(UsersListRequest.builder() |
|||
.limit(1000) |
|||
.build()); |
|||
check(usersListResponse); |
|||
return usersListResponse.getMembers().stream() |
|||
.filter(user -> !user.isDeleted() && !user.isStranger() && !user.isBot()) |
|||
.map(user -> { |
|||
SlackConversation conversation = new SlackConversation(); |
|||
conversation.setId(user.getId()); |
|||
conversation.setName(String.format("@%s (%s)", user.getName(), user.getRealName())); |
|||
return conversation; |
|||
}) |
|||
.collect(Collectors.toList()); |
|||
} else { |
|||
ConversationsListResponse conversationsListResponse = methods.conversationsList(ConversationsListRequest.builder() |
|||
.types(List.of(conversationType == SlackConversation.Type.PUBLIC_CHANNEL ? |
|||
ConversationType.PUBLIC_CHANNEL : |
|||
ConversationType.PRIVATE_CHANNEL)) |
|||
.limit(1000) |
|||
.excludeArchived(true) |
|||
.build()); |
|||
check(conversationsListResponse); |
|||
return conversationsListResponse.getChannels().stream() |
|||
.filter(channel -> !channel.isArchived()) |
|||
.map(channel -> { |
|||
SlackConversation conversation = new SlackConversation(); |
|||
conversation.setId(channel.getId()); |
|||
conversation.setName("#" + channel.getName()); |
|||
return conversation; |
|||
}) |
|||
.collect(Collectors.toList()); |
|||
} |
|||
} |
|||
|
|||
private void check(SlackApiTextResponse slackResponse) { |
|||
if (!slackResponse.isOk()) { |
|||
String error = slackResponse.getError(); |
|||
if (error == null) { |
|||
error = "unknown error"; |
|||
} |
|||
if (error.contains("missing_scope")) { |
|||
String neededScope = slackResponse.getNeeded(); |
|||
throw new RuntimeException("Bot token scope '" + neededScope + "' is needed"); |
|||
} |
|||
throw new RuntimeException("Failed to send message via Slack: " + error); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.slack; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class SlackConversation { |
|||
|
|||
private String id; |
|||
private String name; |
|||
|
|||
public enum Type { |
|||
USER, |
|||
PUBLIC_CHANNEL, |
|||
PRIVATE_CHANNEL |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.service.slack; |
|||
|
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
|
|||
import java.util.List; |
|||
|
|||
public interface SlackService { |
|||
|
|||
void sendMessage(TenantId tenantId, String token, String conversationId, String message) throws Exception; |
|||
|
|||
List<SlackConversation> listConversations(TenantId tenantId, String token, SlackConversation.Type conversationType) throws Exception; |
|||
|
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.notification.settings; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class SlackNotificationDeliveryMethodConfig extends NotificationDeliveryMethodConfig { |
|||
|
|||
private String botToken; |
|||
|
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.notification.template; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import com.fasterxml.jackson.annotation.JsonSubTypes; |
|||
import com.fasterxml.jackson.annotation.JsonTypeInfo; |
|||
import lombok.Data; |
|||
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
|||
|
|||
@JsonIgnoreProperties(ignoreUnknown = true) |
|||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "method", visible = true, include = JsonTypeInfo.As.EXISTING_PROPERTY, defaultImpl = DeliveryMethodNotificationTemplate.class) |
|||
@JsonSubTypes({ |
|||
@JsonSubTypes.Type(name = "EMAIL", value = EmailDeliveryMethodNotificationTemplate.class), |
|||
@JsonSubTypes.Type(name = "SLACK", value = SlackDeliveryMethodNotificationTemplate.class) |
|||
}) |
|||
@Data |
|||
public class DeliveryMethodNotificationTemplate { |
|||
|
|||
private String body; |
|||
private NotificationDeliveryMethod method; |
|||
|
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
/** |
|||
* Copyright © 2016-2022 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
package org.thingsboard.server.common.data.notification.template; |
|||
|
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
@Data |
|||
@EqualsAndHashCode(callSuper = true) |
|||
public class SlackDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate { |
|||
|
|||
private String conversationId; // not required, set from user's name if not set
|
|||
|
|||
} |
|||
Loading…
Reference in new issue