10 changed files with 347 additions and 15 deletions
@ -0,0 +1,143 @@ |
|||||
|
package org.thingsboard.server.service.notification.channels; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import com.google.common.base.Strings; |
||||
|
import lombok.Data; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.Setter; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.springframework.boot.web.client.RestTemplateBuilder; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.client.RestTemplate; |
||||
|
import org.thingsboard.server.common.data.id.TenantId; |
||||
|
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
||||
|
import org.thingsboard.server.common.data.notification.targets.MicrosoftTeamsNotificationTargetConfig; |
||||
|
import org.thingsboard.server.common.data.notification.template.MicrosoftTeamsDeliveryMethodNotificationTemplate; |
||||
|
import org.thingsboard.server.service.notification.NotificationProcessingContext; |
||||
|
|
||||
|
import java.time.Duration; |
||||
|
import java.time.temporal.ChronoUnit; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
public class MicrosoftTeamsNotificationChannel implements NotificationChannel<MicrosoftTeamsNotificationTargetConfig, MicrosoftTeamsDeliveryMethodNotificationTemplate> { |
||||
|
|
||||
|
@Setter |
||||
|
private RestTemplate restTemplate = new RestTemplateBuilder() |
||||
|
.setConnectTimeout(Duration.of(15, ChronoUnit.SECONDS)) |
||||
|
.setReadTimeout(Duration.of(15, ChronoUnit.SECONDS)) |
||||
|
.build(); |
||||
|
|
||||
|
@Override |
||||
|
public void sendNotification(MicrosoftTeamsNotificationTargetConfig targetConfig, MicrosoftTeamsDeliveryMethodNotificationTemplate processedTemplate, NotificationProcessingContext ctx) throws Exception { |
||||
|
if (StringUtils.isNotEmpty(processedTemplate.getCustomMessageCardJson())) { |
||||
|
restTemplate.postForEntity(targetConfig.getWebhookUrl(), processedTemplate.getCustomMessageCardJson(), String.class); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
Message message = new Message(); |
||||
|
message.setThemeColor(Strings.emptyToNull(processedTemplate.getThemeColor())); |
||||
|
if (StringUtils.isEmpty(processedTemplate.getSubject())) { |
||||
|
message.setText(processedTemplate.getBody()); |
||||
|
} else { |
||||
|
message.setSummary(processedTemplate.getSubject()); |
||||
|
Message.Section section = new Message.Section(); |
||||
|
section.setActivityTitle(processedTemplate.getSubject()); |
||||
|
section.setActivitySubtitle(processedTemplate.getBody()); |
||||
|
message.setSections(List.of(section)); |
||||
|
} |
||||
|
if (processedTemplate.getButton() != null) { |
||||
|
var button = processedTemplate.getButton(); |
||||
|
Message.ActionCard actionCard = new Message.ActionCard(); |
||||
|
actionCard.setType("OpenUri"); |
||||
|
actionCard.setName(button.getName()); |
||||
|
var target = new Message.ActionCard.Target("default", button.getUri()); |
||||
|
actionCard.setTargets(List.of(target)); |
||||
|
message.setPotentialAction(List.of(actionCard)); |
||||
|
} |
||||
|
|
||||
|
restTemplate.postForEntity(targetConfig.getWebhookUrl(), message, String.class); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void check(TenantId tenantId) throws Exception { |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public NotificationDeliveryMethod getDeliveryMethod() { |
||||
|
return NotificationDeliveryMethod.MICROSOFT_TEAMS; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class Message { |
||||
|
@JsonProperty("@type") |
||||
|
private final String type = "MessageCard"; |
||||
|
@JsonProperty("@context") |
||||
|
private final String context = "http://schema.org/extensions"; |
||||
|
private String themeColor; |
||||
|
private String summary; |
||||
|
private String text; |
||||
|
private List<Section> sections; |
||||
|
private List<ActionCard> potentialAction; |
||||
|
|
||||
|
@Data |
||||
|
public static class Section { |
||||
|
private String activityTitle; |
||||
|
private String activitySubtitle; |
||||
|
private String activityImage; |
||||
|
private List<Fact> facts; |
||||
|
private boolean markdown; |
||||
|
|
||||
|
@Data |
||||
|
public static class Fact { |
||||
|
private final String name; |
||||
|
private final String value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||
|
public static class ActionCard { |
||||
|
@JsonProperty("@type") |
||||
|
private String type; // ActionCard, OpenUri
|
||||
|
private String name; |
||||
|
private List<Input> inputs; // for ActionCard
|
||||
|
private List<Action> actions; // for ActionCard
|
||||
|
private List<Target> targets; |
||||
|
|
||||
|
@Data |
||||
|
public static class Input { |
||||
|
@JsonProperty("@type") |
||||
|
private String type; // TextInput, DateInput, MultichoiceInput
|
||||
|
private String id; |
||||
|
private boolean isMultiple; |
||||
|
private String title; |
||||
|
private boolean isMultiSelect; |
||||
|
|
||||
|
@Data |
||||
|
public static class Choice { |
||||
|
private final String display; |
||||
|
private final String value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class Action { |
||||
|
@JsonProperty("@type") |
||||
|
private final String type; // HttpPOST
|
||||
|
private final String name; |
||||
|
private final String target; // url
|
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class Target { |
||||
|
private final String os; |
||||
|
private final String uri; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
package org.thingsboard.server.common.data.notification.targets; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
|
||||
|
import javax.validation.constraints.NotBlank; |
||||
|
import javax.validation.constraints.NotEmpty; |
||||
|
|
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
public class MicrosoftTeamsNotificationTargetConfig extends NotificationTargetConfig implements NotificationRecipient { |
||||
|
|
||||
|
@NotBlank |
||||
|
private String webhookUrl; |
||||
|
@NotEmpty |
||||
|
private String channelName; |
||||
|
|
||||
|
@Override |
||||
|
public NotificationTargetType getType() { |
||||
|
return NotificationTargetType.MICROSOFT_TEAMS; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Object getId() { |
||||
|
return webhookUrl; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getTitle() { |
||||
|
return channelName; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
package org.thingsboard.server.common.data.notification.template; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import lombok.EqualsAndHashCode; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import lombok.ToString; |
||||
|
import org.apache.commons.lang3.StringUtils; |
||||
|
import org.apache.commons.lang3.tuple.Pair; |
||||
|
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.function.Consumer; |
||||
|
|
||||
|
@Data |
||||
|
@EqualsAndHashCode(callSuper = true) |
||||
|
@NoArgsConstructor |
||||
|
@ToString(callSuper = true) |
||||
|
public class MicrosoftTeamsDeliveryMethodNotificationTemplate extends DeliveryMethodNotificationTemplate implements HasSubject { |
||||
|
|
||||
|
private String subject; |
||||
|
private String themeColor; |
||||
|
private Button button; |
||||
|
|
||||
|
private String customMessageCardJson; |
||||
|
|
||||
|
public MicrosoftTeamsDeliveryMethodNotificationTemplate(DeliveryMethodNotificationTemplate other) { |
||||
|
super(other); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public NotificationDeliveryMethod getMethod() { |
||||
|
return NotificationDeliveryMethod.MICROSOFT_TEAMS; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public MicrosoftTeamsDeliveryMethodNotificationTemplate copy() { |
||||
|
return new MicrosoftTeamsDeliveryMethodNotificationTemplate(this); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public List<TemplatableValue> getTemplatableValues() { |
||||
|
return List.of( |
||||
|
TemplatableValue.of(body, this::setBody), |
||||
|
TemplatableValue.of(subject, this::setSubject), |
||||
|
TemplatableValue.of(button, Button::getName, Button::setName), |
||||
|
TemplatableValue.of(button, Button::getUri, Button::setUri), |
||||
|
TemplatableValue.of(customMessageCardJson, this::setCustomMessageCardJson) |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
public static class Button { |
||||
|
private String name; |
||||
|
private String uri; |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue