@@ -62,7 +62,7 @@ public class MicrosoftTeamsNotifier extends AbstractStatusChangeNotifier {
6262
6363 private static final String SOURCE_KEY = "Source" ;
6464
65- private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? '6db33f ' : 'b32d36 ') : '439fe0 '}" ;
65+ private static final String DEFAULT_THEME_COLOR_EXPRESSION = "#{event.type == 'STATUS_CHANGED' ? (event.statusInfo.status=='UP' ? 'Good ' : 'Attention ') : 'Accent '}" ;
6666
6767 private static final String DEFAULT_DEREGISTER_ACTIVITY_SUBTITLE_EXPRESSION = "#{instance.registration.name} with id #{instance.id} has de-registered from Spring Boot Admin" ;
6868
@@ -197,24 +197,44 @@ protected Message getStatusChangedMessage(Instance instance, EvaluationContext c
197197 protected Message createMessage (Instance instance , String registeredTitle , String activitySubtitle ,
198198 EvaluationContext context ) {
199199 List <Fact > facts = new ArrayList <>();
200- facts .add (new Fact (STATUS_KEY , instance .getStatusInfo ().getStatus ()));
201- facts .add (new Fact (SERVICE_URL_KEY , instance .getRegistration ().getServiceUrl ()));
202- facts .add (new Fact (HEALTH_URL_KEY , instance .getRegistration ().getHealthUrl ()));
203- facts .add (new Fact (MANAGEMENT_URL_KEY , instance .getRegistration ().getManagementUrl ()));
204- facts .add (new Fact (SOURCE_KEY , instance .getRegistration ().getSource ()));
205-
206- Section section = Section .builder ()
207- .activityTitle (instance .getRegistration ().getName ())
208- .activitySubtitle (activitySubtitle )
209- .facts (facts )
210- .build ();
200+ addFactIfNotNull (facts , STATUS_KEY , instance .getStatusInfo ().getStatus ());
201+ addFactIfNotNull (facts , SERVICE_URL_KEY , instance .getRegistration ().getServiceUrl ());
202+ addFactIfNotNull (facts , HEALTH_URL_KEY , instance .getRegistration ().getHealthUrl ());
203+ addFactIfNotNull (facts , MANAGEMENT_URL_KEY , instance .getRegistration ().getManagementUrl ());
204+ addFactIfNotNull (facts , SOURCE_KEY , instance .getRegistration ().getSource ());
211205
212- return Message .builder ()
213- .title (registeredTitle )
214- .summary (messageSummary )
215- .themeColor (evaluateExpression (context , themeColor ))
216- .sections (singletonList (section ))
217- .build ();
206+ String themeColorValue = evaluateExpression (context , themeColor );
207+
208+ List <CardElement > cardBody = new ArrayList <>();
209+
210+ // Title
211+ cardBody .add (CardElement .builder ()
212+ .type ("TextBlock" )
213+ .text (registeredTitle )
214+ .size ("Large" )
215+ .weight ("Bolder" )
216+ .color (themeColorValue )
217+ .build ());
218+
219+ // Service Name
220+ cardBody .add (CardElement .builder ()
221+ .type ("TextBlock" )
222+ .text (instance .getRegistration ().getName ())
223+ .size ("Medium" )
224+ .weight ("Bolder" )
225+ .build ());
226+
227+ // Activity Subtitle
228+ cardBody .add (CardElement .builder ().type ("TextBlock" ).text (activitySubtitle ).wrap (true ).build ());
229+
230+ // Facts
231+ cardBody .add (CardElement .builder ().type ("FactSet" ).facts (facts ).build ());
232+
233+ AdaptiveCard adaptiveCard = AdaptiveCard .builder ().body (cardBody ).build ();
234+
235+ Attachment attachment = Attachment .builder ().content (adaptiveCard ).build ();
236+
237+ return Message .builder ().attachments (singletonList (attachment )).build ();
218238 }
219239
220240 protected String evaluateExpression (EvaluationContext context , Expression expression ) {
@@ -232,6 +252,12 @@ protected EvaluationContext createEvaluationContext(InstanceEvent event, Instanc
232252 .build ();
233253 }
234254
255+ private void addFactIfNotNull (List <Fact > facts , String title , @ Nullable String value ) {
256+ if (value != null && !value .isBlank ()) {
257+ facts .add (new Fact (title , value ));
258+ }
259+ }
260+
235261 @ Nullable public URI getWebhookUrl () {
236262 return webhookUrl ;
237263 }
@@ -278,31 +304,62 @@ public void setStatusActivitySubtitle(String statusActivitySubtitle) {
278304 @ Builder
279305 public static class Message {
280306
281- private final String summary ;
307+ private final String type = "message" ;
282308
283- private final String themeColor ;
309+ @ Builder .Default
310+ private final List <Attachment > attachments = new ArrayList <>();
284311
285- private final String title ;
312+ }
286313
287- @ Builder .Default
288- private final List <Section > sections = new ArrayList <>();
314+ @ Data
315+ @ Builder
316+ public static class Attachment {
317+
318+ private final String contentType = "application/vnd.microsoft.card.adaptive" ;
319+
320+ @ Nullable private final String contentUrl = null ;
321+
322+ private final AdaptiveCard content ;
289323
290324 }
291325
292326 @ Data
293327 @ Builder
294- public static class Section {
328+ public static class AdaptiveCard {
329+
330+ @ Builder .Default
331+ private final String schema = "http://adaptivecards.io/schemas/adaptive-card.json" ;
295332
296- private final String activityTitle ;
333+ private final String type = "AdaptiveCard" ;
297334
298- private final String activitySubtitle ;
335+ private final String version = "1.2" ;
299336
300337 @ Builder .Default
301- private final List <Fact > facts = new ArrayList <>();
338+ private final List <CardElement > body = new ArrayList <>();
339+
340+ }
341+
342+ @ Data
343+ @ Builder
344+ public static class CardElement {
345+
346+ private final String type ;
347+
348+ @ Nullable private final String text ;
349+
350+ @ Nullable private final String size ;
351+
352+ @ Nullable private final String weight ;
353+
354+ @ Nullable private final String color ;
355+
356+ @ Nullable private final Boolean wrap ;
357+
358+ @ Nullable private final List <Fact > facts ;
302359
303360 }
304361
305- public record Fact (String name , @ Nullable String value ) {
362+ public record Fact (String title , @ Nullable String value ) {
306363 }
307364
308365}
0 commit comments