Skip to content
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

[improve] beautify lark notification #2683

Merged
merged 5 commits into from
Sep 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,15 @@

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

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.Data;
import java.util.Arrays;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.hertzbeat.common.entity.alerter.Alert;
import org.apache.hertzbeat.common.entity.manager.NoticeReceiver;
import org.apache.hertzbeat.common.entity.manager.NoticeTemplate;
import org.apache.hertzbeat.common.util.StrUtil;
import org.apache.hertzbeat.common.util.JsonUtil;
import org.apache.hertzbeat.manager.support.exception.AlertNoticeException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
Expand All @@ -44,59 +42,23 @@
@Slf4j
final class FlyBookAlertNotifyHandlerImpl extends AbstractAlertNotifyHandlerImpl {

/**
* Title color corresponding to the alarm priority
*/
private static final String[] TITLE_COLOR = {"red", "yellow", "orange"};


@Override
public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert alert) {
try {
FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto();
flyBookWebHookDto.setMsgType("post");

Content content = new Content();
flyBookWebHookDto.setContent(content);

Post post = new Post();
content.setPost(post);

ZhCn zhCn = new ZhCn();
post.setZhCn(zhCn);

zhCn.setTitle("[" + bundle.getString("alerter.notify.title") + "]");

List<FlyBookContent> contentList = new ArrayList<>();

FlyBookContent textContent = new FlyBookContent();
textContent.setTag("text");
textContent.setText(renderContent(noticeTemplate, alert));
contentList.add(textContent);

FlyBookContent linkContent = new FlyBookContent();
linkContent.setTag("a");
linkContent.setText(bundle.getString("alerter.notify.console"));
linkContent.setHref(alerterProperties.getConsoleUrl());
contentList.add(linkContent);

String userId = receiver.getUserId();
List<String> userIdList = StrUtil.analysisArgToList(userId);
if (userIdList != null && !userIdList.isEmpty()) {
List<FlyBookContent> atContents = userIdList.stream()
.map(userID -> {
FlyBookContent atContent = new FlyBookContent();
atContent.setTag("at");
atContent.setUserId(userID);
return atContent;
})
.toList();
contentList.addAll(atContents);
}

List<List<FlyBookContent>> contents = Collections.singletonList(contentList);
zhCn.setContent(contents);

String notificationContent = JsonUtil.toJson(renderContent(noticeTemplate, alert));
String cardMessage = createLarkMessage(receiver.getUserId(), notificationContent, alert.getPriority());
String webHookUrl = alerterProperties.getFlyBookWebhookUrl() + receiver.getAccessToken();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<FlyBookWebHookDto> flyEntity = new HttpEntity<>(flyBookWebHookDto, headers);
HttpEntity<String> flyEntity = new HttpEntity<>(cardMessage, headers);
ResponseEntity<CommonRobotNotifyResp> entity = restTemplate.postForEntity(webHookUrl,
flyEntity, CommonRobotNotifyResp.class);
flyEntity, CommonRobotNotifyResp.class);
if (entity.getStatusCode() == HttpStatus.OK) {
assert entity.getBody() != null;
if (entity.getBody().getCode() == null || entity.getBody().getCode() == 0) {
Expand All @@ -114,77 +76,129 @@ public void send(NoticeReceiver receiver, NoticeTemplate noticeTemplate, Alert a
}
}


@Override
public byte type() {
return 6;
}

@Data
private static class FlyBookWebHookDto {

private static final String DEFAULT_MSG_TYPE = "post";

/**
* Message type
*/
@JsonProperty("msg_type")
private String msgType = DEFAULT_MSG_TYPE;


private Content content;

}

/**
* Message content
* create a lark notification card message
*
* @param userId at user id
* @param notificationContent notification content
* @param priority priority for alert
* @return message
*/
@Data
private static class Content {
public Post post;
}

@Data
private static class FlyBookContent {
/**
* format currently supports text、hyperlink、@people function
*/
public String tag;

/**
* text
*/
public String text;

/**
* hyperlink address
*/
public String href;

@JsonProperty("user_id")
public String userId;

@JsonProperty("user_name")
public String userName;
}

@Data
private static class Post {
@JsonProperty("zh_cn")
public ZhCn zhCn;
private String createLarkMessage(String userId, String notificationContent, byte priority) {
String larkCardMessage = """
{
"msg_type": "interactive",
"card": {
"config": {
"update_multi": true
},
"i18n_elements": {
"zh_cn": [
{
"tag": "column_set",
"flex_mode": "none",
"horizontal_spacing": "default",
"background_style": "default",
"columns": [
{
"tag": "column",
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": "",
"text_size": "normal",
"text_align": "left",
"text_color": "default"
}
}
],
"width": "weighted",
"weight": 1
}
]
},
{
"tag": "column_set",
"flex_mode": "none",
"horizontal_spacing": "default",
"background_style": "default",
"columns": [
{
"tag": "column",
"elements": [
{
"tag": "div",
"text": {
"tag": "plain_text",
"content": %s,
"text_size": "normal",
"text_align": "left",
"text_color": "default"
}
}
],
"width": "weighted",
"weight": 1
}
]
},
%s
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {
"tag": "plain_text",
"content": "登入控制台"
},
"type": "default",
"complex_interaction": true,
"width": "default",
"size": "medium",
"multi_url": {
"url": "%s"
}
}
]
}
]
},
"i18n_header": {
"zh_cn": {
"title": {
"tag": "plain_text",
"content": "HertzBeat 告警"
},
"template": "%s"
}
}
}
}
""";

String atUserElement = "";
if (StringUtils.isNotBlank(userId)) {
String atUserId = Arrays.stream(userId.split(","))
.map(id -> "<at id=" + id + "></at>")
.collect(Collectors.joining(" "));
atUserElement = String.format("""
{
"tag": "div",
"text": {
"content": "%s",
"tag": "lark_md"
}
},
""", atUserId);
}
return String.format(larkCardMessage, notificationContent, atUserElement, alerterProperties.getConsoleUrl(), TITLE_COLOR[priority]);
}

@Data
private static class ZhCn {
/**
* Title
*/
public String title;

/**
* Content
*/
public List<List<FlyBookContent>> content;
@Override
public byte type() {
return 6;
}

}
Loading