Skip to content

Commit b00a50a

Browse files
authored
[improve] beautify lark notification (apache#2683)
1 parent 98354f2 commit b00a50a

File tree

1 file changed

+134
-120
lines changed

1 file changed

+134
-120
lines changed

manager/src/main/java/org/apache/hertzbeat/manager/component/alerter/impl/FlyBookAlertNotifyHandlerImpl.java

Lines changed: 134 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,15 @@
1717

1818
package org.apache.hertzbeat.manager.component.alerter.impl;
1919

20-
import com.fasterxml.jackson.annotation.JsonProperty;
21-
import java.util.ArrayList;
22-
import java.util.Collections;
23-
import java.util.List;
24-
import lombok.Data;
20+
import java.util.Arrays;
21+
import java.util.stream.Collectors;
2522
import lombok.RequiredArgsConstructor;
2623
import lombok.extern.slf4j.Slf4j;
24+
import org.apache.commons.lang3.StringUtils;
2725
import org.apache.hertzbeat.common.entity.alerter.Alert;
2826
import org.apache.hertzbeat.common.entity.manager.NoticeReceiver;
2927
import org.apache.hertzbeat.common.entity.manager.NoticeTemplate;
30-
import org.apache.hertzbeat.common.util.StrUtil;
28+
import org.apache.hertzbeat.common.util.JsonUtil;
3129
import org.apache.hertzbeat.manager.support.exception.AlertNoticeException;
3230
import org.springframework.http.HttpEntity;
3331
import org.springframework.http.HttpHeaders;
@@ -44,59 +42,23 @@
4442
@Slf4j
4543
final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
4644

45+
/**
46+
* Title color corresponding to the alarm priority
47+
*/
48+
private static final String[] TITLE_COLOR = {"red", "yellow", "orange"};
49+
50+
4751
@Override
4852
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) {
4953
try {
50-
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
51-
flyBookWebHookDto.setMsgType("post");
52-
53-
Content content = new Content();
54-
flyBookWebHookDto.setContent(content);
55-
56-
Post post = new Post();
57-
content.setPost(post);
58-
59-
ZhCn zhCn = new ZhCn();
60-
post.setZhCn(zhCn);
61-
62-
zhCn.setTitle("[" + bundle.getString("alerter.notify.title") + "]");
63-
64-
List<FlyBookContent> contentList = new ArrayList<>();
65-
66-
FlyBookContent textContent = new FlyBookContent();
67-
textContent.setTag("text");
68-
textContent.setText(renderContent(noticeTemplate, alert));
69-
contentList.add(textContent);
70-
71-
FlyBookContent linkContent = new FlyBookContent();
72-
linkContent.setTag("a");
73-
linkContent.setText(bundle.getString("alerter.notify.console"));
74-
linkContent.setHref(alerterProperties.getConsoleUrl());
75-
contentList.add(linkContent);
76-
77-
String userId = receiver.getUserId();
78-
List<String> userIdList = StrUtil.analysisArgToList(userId);
79-
if (userIdList != null && !userIdList.isEmpty()) {
80-
List<FlyBookContent> atContents = userIdList.stream()
81-
.map(userID -> {
82-
FlyBookContent atContent = new FlyBookContent();
83-
atContent.setTag("at");
84-
atContent.setUserId(userID);
85-
return atContent;
86-
})
87-
.toList();
88-
contentList.addAll(atContents);
89-
}
90-
91-
List<List<FlyBookContent>> contents = Collections.singletonList(contentList);
92-
zhCn.setContent(contents);
93-
54+
String notificationContent = JsonUtil.toJson(renderContent(noticeTemplate, alert));
55+
String cardMessage = createLarkMessage(receiver.getUserId(), notificationContent, alert.getPriority());
9456
String webHookUrl = alerterProperties.getFlyBookWebhookUrl() + receiver.getAccessToken();
9557
HttpHeaders headers = new HttpHeaders();
9658
headers.setContentType(MediaType.APPLICATION_JSON);
97-
HttpEntity<FlyBookWebHookDto> flyEntity = new HttpEntity<>(flyBookWebHookDto, headers);
59+
HttpEntity<String> flyEntity = new HttpEntity<>(cardMessage, headers);
9860
ResponseEntity<CommonRobotNotifyResp> entity = restTemplate.postForEntity(webHookUrl,
99-
flyEntity, CommonRobotNotifyResp.class);
61+
flyEntity, CommonRobotNotifyResp.class);
10062
if (entity.getStatusCode() == HttpStatus.OK) {
10163
assert entity.getBody() != null;
10264
if (entity.getBody().getCode() == null || entity.getBody().getCode() == 0) {
@@ -114,77 +76,129 @@ public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert a
11476
}
11577
}
11678

117-
118-
@Override
119-
public byte type() {
120-
return 6;
121-
}
122-
123-
@Data
124-
private static class FlyBookWebHookDto {
125-
126-
private static final String DEFAULT_MSG_TYPE = "post";
127-
128-
/**
129-
* Message type
130-
*/
131-
@JsonProperty("msg_type")
132-
private String msgType = DEFAULT_MSG_TYPE;
133-
134-
135-
private Content content;
136-
137-
}
138-
13979
/**
140-
* Message content
80+
* create a lark notification card message
81+
*
82+
* @param userId at user id
83+
* @param notificationContent notification content
84+
* @param priority priority for alert
85+
* @return message
14186
*/
142-
@Data
143-
private static class Content {
144-
public Post post;
145-
}
146-
147-
@Data
148-
private static class FlyBookContent {
149-
/**
150-
* format currently supports text、hyperlink、@people function
151-
*/
152-
public String tag;
153-
154-
/**
155-
* text
156-
*/
157-
public String text;
158-
159-
/**
160-
* hyperlink address
161-
*/
162-
public String href;
163-
164-
@JsonProperty("user_id")
165-
public String userId;
166-
167-
@JsonProperty("user_name")
168-
public String userName;
169-
}
170-
171-
@Data
172-
private static class Post {
173-
@JsonProperty("zh_cn")
174-
public ZhCn zhCn;
87+
private String createLarkMessage(String userId, String notificationContent, byte priority) {
88+
String larkCardMessage = """
89+
{
90+
"msg_type": "interactive",
91+
"card": {
92+
"config": {
93+
"update_multi": true
94+
},
95+
"i18n_elements": {
96+
"zh_cn": [
97+
{
98+
"tag": "column_set",
99+
"flex_mode": "none",
100+
"horizontal_spacing": "default",
101+
"background_style": "default",
102+
"columns": [
103+
{
104+
"tag": "column",
105+
"elements": [
106+
{
107+
"tag": "div",
108+
"text": {
109+
"tag": "plain_text",
110+
"content": "",
111+
"text_size": "normal",
112+
"text_align": "left",
113+
"text_color": "default"
114+
}
115+
}
116+
],
117+
"width": "weighted",
118+
"weight": 1
119+
}
120+
]
121+
},
122+
{
123+
"tag": "column_set",
124+
"flex_mode": "none",
125+
"horizontal_spacing": "default",
126+
"background_style": "default",
127+
"columns": [
128+
{
129+
"tag": "column",
130+
"elements": [
131+
{
132+
"tag": "div",
133+
"text": {
134+
"tag": "plain_text",
135+
"content": %s,
136+
"text_size": "normal",
137+
"text_align": "left",
138+
"text_color": "default"
139+
}
140+
}
141+
],
142+
"width": "weighted",
143+
"weight": 1
144+
}
145+
]
146+
},
147+
%s
148+
{
149+
"tag": "action",
150+
"actions": [
151+
{
152+
"tag": "button",
153+
"text": {
154+
"tag": "plain_text",
155+
"content": "登入控制台"
156+
},
157+
"type": "default",
158+
"complex_interaction": true,
159+
"width": "default",
160+
"size": "medium",
161+
"multi_url": {
162+
"url": "%s"
163+
}
164+
}
165+
]
166+
}
167+
]
168+
},
169+
"i18n_header": {
170+
"zh_cn": {
171+
"title": {
172+
"tag": "plain_text",
173+
"content": "HertzBeat 告警"
174+
},
175+
"template": "%s"
176+
}
177+
}
178+
}
179+
}
180+
""";
181+
182+
String atUserElement = "";
183+
if (StringUtils.isNotBlank(userId)) {
184+
String atUserId = Arrays.stream(userId.split(","))
185+
.map(id -> "<at id=" + id + "></at>")
186+
.collect(Collectors.joining(" "));
187+
atUserElement = String.format("""
188+
{
189+
"tag": "div",
190+
"text": {
191+
"content": "%s",
192+
"tag": "lark_md"
193+
}
194+
},
195+
""", atUserId);
196+
}
197+
return String.format(larkCardMessage, notificationContent, atUserElement, alerterProperties.getConsoleUrl(), TITLE_COLOR[priority]);
175198
}
176199

177-
@Data
178-
private static class ZhCn {
179-
/**
180-
* Title
181-
*/
182-
public String title;
183-
184-
/**
185-
* Content
186-
*/
187-
public List<List<FlyBookContent>> content;
200+
@Override
201+
public byte type() {
202+
return 6;
188203
}
189-
190204
}

0 commit comments

Comments
 (0)