17
17
18
18
package org .apache .hertzbeat .manager .component .alerter .impl ;
19
19
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 ;
25
22
import lombok .RequiredArgsConstructor ;
26
23
import lombok .extern .slf4j .Slf4j ;
24
+ import org .apache .commons .lang3 .StringUtils ;
27
25
import org .apache .hertzbeat .common .entity .alerter .Alert ;
28
26
import org .apache .hertzbeat .common .entity .manager .NoticeReceiver ;
29
27
import org .apache .hertzbeat .common .entity .manager .NoticeTemplate ;
30
- import org .apache .hertzbeat .common .util .StrUtil ;
28
+ import org .apache .hertzbeat .common .util .JsonUtil ;
31
29
import org .apache .hertzbeat .manager .support .exception .AlertNoticeException ;
32
30
import org .springframework .http .HttpEntity ;
33
31
import org .springframework .http .HttpHeaders ;
44
42
@ Slf4j
45
43
final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {
46
44
45
+ /**
46
+ * Title color corresponding to the alarm priority
47
+ */
48
+ private static final String [] TITLE_COLOR = {"red" , "yellow" , "orange" };
49
+
50
+
47
51
@ Override
48
52
public void send (NoticeReceiver receiver , NoticeTemplate noticeTemplate , Alert alert ) {
49
53
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 ());
94
56
String webHookUrl = alerterProperties .getFlyBookWebhookUrl () + receiver .getAccessToken ();
95
57
HttpHeaders headers = new HttpHeaders ();
96
58
headers .setContentType (MediaType .APPLICATION_JSON );
97
- HttpEntity <FlyBookWebHookDto > flyEntity = new HttpEntity <>(flyBookWebHookDto , headers );
59
+ HttpEntity <String > flyEntity = new HttpEntity <>(cardMessage , headers );
98
60
ResponseEntity <CommonRobotNotifyResp > entity = restTemplate .postForEntity (webHookUrl ,
99
- flyEntity , CommonRobotNotifyResp .class );
61
+ flyEntity , CommonRobotNotifyResp .class );
100
62
if (entity .getStatusCode () == HttpStatus .OK ) {
101
63
assert entity .getBody () != null ;
102
64
if (entity .getBody ().getCode () == null || entity .getBody ().getCode () == 0 ) {
@@ -114,77 +76,129 @@ public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert a
114
76
}
115
77
}
116
78
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
-
139
79
/**
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
141
86
*/
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 ]);
175
198
}
176
199
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 ;
188
203
}
189
-
190
204
}
0 commit comments