-
Notifications
You must be signed in to change notification settings - Fork 3.1k
fix: update Microsoft Teams message structure and theme color handling #5363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
SteKoe
wants to merge
1
commit into
master
Choose a base branch
from
fix/5321-ms-teams-webhooks
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+271
−79
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,7 +62,7 @@ public class MicrosoftTeamsNotifier extends AbstractStatusChangeNotifier { | |
|
|
||
| private static final String SOURCE_KEY = "Source"; | ||
|
|
||
| private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? '6db33f' : 'b32d36') : '439fe0'}"; | ||
| private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? 'Good' : 'Attention') : 'Accent'}"; | ||
|
|
||
| private static final String DEFAULT_DEREGISTER_ACTIVITY_SUBTITLE_EXPRESSION = "#{instance.registration.name} with id #{instance.id} has de-registered from Spring Boot Admin"; | ||
|
|
||
|
|
@@ -197,24 +197,44 @@ protected Message getStatusChangedMessage(Instance instance, EvaluationContext c | |
| protected Message createMessage(Instance instance, String registeredTitle, String activitySubtitle, | ||
| EvaluationContext context) { | ||
| List<Fact> facts = new ArrayList<>(); | ||
| facts.add(new Fact(STATUS_KEY, instance.getStatusInfo().getStatus())); | ||
| facts.add(new Fact(SERVICE_URL_KEY, instance.getRegistration().getServiceUrl())); | ||
| facts.add(new Fact(HEALTH_URL_KEY, instance.getRegistration().getHealthUrl())); | ||
| facts.add(new Fact(MANAGEMENT_URL_KEY, instance.getRegistration().getManagementUrl())); | ||
| facts.add(new Fact(SOURCE_KEY, instance.getRegistration().getSource())); | ||
|
|
||
| Section section = Section.builder() | ||
| .activityTitle(instance.getRegistration().getName()) | ||
| .activitySubtitle(activitySubtitle) | ||
| .facts(facts) | ||
| .build(); | ||
| addFactIfNotNull(facts, STATUS_KEY, instance.getStatusInfo().getStatus()); | ||
| addFactIfNotNull(facts, SERVICE_URL_KEY, instance.getRegistration().getServiceUrl()); | ||
| addFactIfNotNull(facts, HEALTH_URL_KEY, instance.getRegistration().getHealthUrl()); | ||
| addFactIfNotNull(facts, MANAGEMENT_URL_KEY, instance.getRegistration().getManagementUrl()); | ||
| addFactIfNotNull(facts, SOURCE_KEY, instance.getRegistration().getSource()); | ||
|
|
||
| return Message.builder() | ||
| .title(registeredTitle) | ||
| .summary(messageSummary) | ||
| .themeColor(evaluateExpression(context, themeColor)) | ||
| .sections(singletonList(section)) | ||
| .build(); | ||
| String themeColorValue = evaluateExpression(context, themeColor); | ||
|
|
||
| List<CardElement> cardBody = new ArrayList<>(); | ||
|
|
||
| // Title | ||
| cardBody.add(CardElement.builder() | ||
| .type("TextBlock") | ||
| .text(registeredTitle) | ||
| .size("Large") | ||
| .weight("Bolder") | ||
| .color(themeColorValue) | ||
| .build()); | ||
|
|
||
| // Service Name | ||
| cardBody.add(CardElement.builder() | ||
| .type("TextBlock") | ||
| .text(instance.getRegistration().getName()) | ||
| .size("Medium") | ||
| .weight("Bolder") | ||
| .build()); | ||
|
|
||
| // Activity Subtitle | ||
| cardBody.add(CardElement.builder().type("TextBlock").text(activitySubtitle).wrap(true).build()); | ||
|
|
||
| // Facts | ||
| cardBody.add(CardElement.builder().type("FactSet").facts(facts).build()); | ||
|
|
||
| AdaptiveCard adaptiveCard = AdaptiveCard.builder().body(cardBody).build(); | ||
|
|
||
| Attachment attachment = Attachment.builder().content(adaptiveCard).build(); | ||
|
|
||
| return Message.builder().attachments(singletonList(attachment)).build(); | ||
| } | ||
|
|
||
| protected String evaluateExpression(EvaluationContext context, Expression expression) { | ||
|
|
@@ -232,6 +252,12 @@ protected EvaluationContext createEvaluationContext(InstanceEvent event, Instanc | |
| .build(); | ||
| } | ||
|
|
||
| private void addFactIfNotNull(List<Fact> facts, String title, @Nullable String value) { | ||
| if (value != null && !value.isBlank()) { | ||
| facts.add(new Fact(title, value)); | ||
| } | ||
| } | ||
|
|
||
| @Nullable public URI getWebhookUrl() { | ||
| return webhookUrl; | ||
| } | ||
|
|
@@ -278,31 +304,62 @@ public void setStatusActivitySubtitle(String statusActivitySubtitle) { | |
| @Builder | ||
| public static class Message { | ||
|
|
||
| private final String summary; | ||
| private final String type = "message"; | ||
|
|
||
| private final String themeColor; | ||
| @Builder.Default | ||
| private final List<Attachment> attachments = new ArrayList<>(); | ||
|
|
||
| private final String title; | ||
| } | ||
|
|
||
| @Builder.Default | ||
| private final List<Section> sections = new ArrayList<>(); | ||
| @Data | ||
| @Builder | ||
| public static class Attachment { | ||
|
|
||
| private final String contentType = "application/vnd.microsoft.card.adaptive"; | ||
|
|
||
| @Nullable private final String contentUrl = null; | ||
|
|
||
| private final AdaptiveCard content; | ||
|
|
||
| } | ||
|
|
||
| @Data | ||
| @Builder | ||
| public static class Section { | ||
| public static class AdaptiveCard { | ||
|
|
||
| @Builder.Default | ||
| private final String schema = "http://adaptivecards.io/schemas/adaptive-card.json"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The JSON key for this entry should be renamed to |
||
|
|
||
| private final String activityTitle; | ||
| private final String type = "AdaptiveCard"; | ||
|
|
||
| private final String activitySubtitle; | ||
| private final String version = "1.2"; | ||
|
|
||
| @Builder.Default | ||
| private final List<Fact> facts = new ArrayList<>(); | ||
| private final List<CardElement> body = new ArrayList<>(); | ||
|
|
||
| } | ||
|
|
||
| @Data | ||
| @Builder | ||
| public static class CardElement { | ||
|
|
||
| private final String type; | ||
|
|
||
| @Nullable private final String text; | ||
|
|
||
| @Nullable private final String size; | ||
|
|
||
| @Nullable private final String weight; | ||
|
|
||
| @Nullable private final String color; | ||
|
|
||
| @Nullable private final Boolean wrap; | ||
|
|
||
| @Nullable private final List<Fact> facts; | ||
|
|
||
| } | ||
|
|
||
| public record Fact(String name, @Nullable String value) { | ||
| public record Fact(String title, @Nullable String value) { | ||
| } | ||
|
|
||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any docs reference about these new color constants?
Before it was kind of clear since the precise hex value was passed, but now there is no clue what those really stand for.
Maybe you can attach such reference as Javadoc/comment.