diff --git a/collector/pom.xml b/collector/pom.xml index 5b1eacb..63b99cc 100644 --- a/collector/pom.xml +++ b/collector/pom.xml @@ -51,6 +51,11 @@ httpclient 4.5.13 + + commons-io + commons-io + 2.0.1 + commons-net diff --git a/collector/src/main/java/com/usthe/collector/collect/common/http/HttpUtils.java b/collector/src/main/java/com/usthe/collector/collect/common/http/HttpUtils.java new file mode 100644 index 0000000..d552847 --- /dev/null +++ b/collector/src/main/java/com/usthe/collector/collect/common/http/HttpUtils.java @@ -0,0 +1,473 @@ +package com.usthe.collector.collect.common.http; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.google.common.base.Charsets; +import com.google.common.base.Strings; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.apache.http.*; +import org.apache.http.client.HttpClient; +import org.apache.http.client.ResponseHandler; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.*; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.HTTP; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Http各种请求方法的实现 + * + * @author 花城 + * @version 1.0 + * @date 2022/2/21 7:16 下午 + * @Description + */ +@Slf4j +public class HttpUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class); + + private CloseableHttpClient httpClient; + //连接超时时间为30s + private int connectionTimeout = 30000; + //读取超时时间为300s + private int socketTimeout = 300000; + private int MAX_TOTAL = 3000; + //单路由的最大并发连接数 + private int MAX_PER_ROUTE = 1000; + //设置从链接池中获取连接时间为无限大 + private int CONNECTION_REQUEST_TIMEOUT = 0; + + private static ObjectMapper objectMapper; + + static { + objectMapper = new ObjectMapper(); + // asr返回格式为命名用下划线格式,java为驼峰式,json需要转换 +// objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); + objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); + + objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false); + objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); + objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true); + + } + + public void init() { + RequestConfig config = RequestConfig.custom().setConnectTimeout(connectionTimeout). + setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT).setSocketTimeout(socketTimeout).build(); + PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager(); + pccm.setMaxTotal(MAX_TOTAL); + pccm.setDefaultMaxPerRoute(MAX_PER_ROUTE); + httpClient = HttpClients.custom().setConnectionManager(pccm).setDefaultRequestConfig(config).build(); + } + + public HttpResult doGet(String url, Map params) { + try { + URIBuilder uriBuilder = new URIBuilder(url); + for (Map.Entry entry : params.entrySet()) { + uriBuilder.addParameter(entry.getKey(), entry.getValue()); + } + HttpGet httpget = new HttpGet(uriBuilder.build()); + httpget.addHeader("contentEncoding", "UTF-8"); + return doExecuteHttpRqeuestBase(httpget); + } catch (Exception e) { + LOGGER.error("Error when doGet : " + url, e); + return failHttp(e.getMessage()); + } + } + + public HttpResult doGetWithHeaders(String url, Map params, Map headers) { + try { + URIBuilder uriBuilder = new URIBuilder(url); + params.forEach(uriBuilder::addParameter); + HttpGet httpget = new HttpGet(uriBuilder.build()); + httpget.addHeader("contentEncoding", "UTF-8"); + headers.forEach(httpget::addHeader); + return doExecuteHttpRqeuestBase(httpget); + } catch (Exception e) { + LOGGER.error("Error when doGet : " + url, e); + return failHttp(e.getMessage()); + } + } + + public HttpResult doPutWithHeaders(String url, Map params, Map headers) { + try { + URIBuilder uriBuilder = new URIBuilder(url); + params.forEach(uriBuilder::addParameter); + HttpPut httpget = new HttpPut(uriBuilder.build()); + httpget.addHeader("contentEncoding", "UTF-8"); + headers.forEach(httpget::addHeader); + return doExecuteHttpRqeuestBase(httpget); + } catch (Exception e) { + LOGGER.error("Error when doPut : " + url, e); + return failHttp(e.getMessage()); + } + } + + public HttpResult doPost(String url, Map formParams) { + // 创建httppost + HttpPost httpPost = new HttpPost(url); + // 设置参数 + RequestConfig.Builder customReqConf = RequestConfig.custom(); + customReqConf.setConnectTimeout(connectionTimeout); + customReqConf.setSocketTimeout(socketTimeout); + httpPost.setConfig(customReqConf.build()); + + List formparams = new ArrayList(); + for (Map.Entry entry : formParams.entrySet()) { + formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + UrlEncodedFormEntity entity = null; + try { + entity = new UrlEncodedFormEntity(formparams, "UTF-8"); + entity.setChunked(true); + } catch (UnsupportedEncodingException e) { + LOGGER.error("UrlEncode error : " + url, e); + } + httpPost.setEntity(entity); + return doExecuteHttpRqeuestBase(httpPost); + } + + public HttpResult doPostWithHeader(String url, String bodyJsonString, Map headers) { + // 创建httppost + HttpPost httpPost = new HttpPost(url); + + // 设置参数 + RequestConfig.Builder customReqConf = RequestConfig.custom(); + customReqConf.setConnectTimeout(connectionTimeout); + customReqConf.setSocketTimeout(socketTimeout); + httpPost.setConfig(customReqConf.build()); + headers.forEach(httpPost::addHeader); + StringEntity entity = new StringEntity(bodyJsonString, "UTF-8");//解决中文乱码问题 + entity.setContentEncoding("UTF-8"); + entity.setContentType(ContentType.APPLICATION_JSON.toString()); + httpPost.setEntity(entity); + return doExecuteHttpRqeuestBase(httpPost); + } + + public HttpResponse doPostWithOriginalResponse(String url, List nvpList, String charset) { + HttpResponse response = null; + try{ + HttpPost httpPost = new HttpPost(url); + httpPost.setHeader(HttpHeaders.CONNECTION, "close"); + httpPost.setEntity(new UrlEncodedFormEntity(nvpList,charset)); + response = httpClient.execute(httpPost); + }catch (Exception e){ + LOGGER.error("doPostWithOriginalResponse error : ", e); + } + return response; + } + + public HttpResult doPost(String url, String bodyJsonString) { + // 创建httppost + HttpPost httpPost = new HttpPost(url); + + // 设置参数 + RequestConfig.Builder customReqConf = RequestConfig.custom(); + customReqConf.setConnectTimeout(connectionTimeout); + customReqConf.setSocketTimeout(socketTimeout); + httpPost.setConfig(customReqConf.build()); + + StringEntity entity = new StringEntity(bodyJsonString, "UTF-8");//解决中文乱码问题 + entity.setContentEncoding("UTF-8"); + entity.setContentType(ContentType.APPLICATION_JSON.toString()); + httpPost.setEntity(entity); + return doExecuteHttpRqeuestBase(httpPost); + } + + public HttpResult doPostWithEntity(String url, HttpEntity entity) { + // 创建httppost + HttpPost httpPost = new HttpPost(url); + + // 设置参数 + RequestConfig.Builder customReqConf = RequestConfig.custom(); + customReqConf.setConnectTimeout(connectionTimeout); + customReqConf.setSocketTimeout(socketTimeout); + httpPost.setConfig(customReqConf.build()); + + httpPost.setEntity(entity); + return doExecuteHttpRqeuestBase(httpPost); + } + + public HttpResult doDeleteWithHeaders(String url, Map params, Map headers) { + try { + URIBuilder uriBuilder = new URIBuilder(url); + params.forEach(uriBuilder::addParameter); + HttpDelete httpDelete = new HttpDelete(uriBuilder.build()); + httpDelete.addHeader("contentEncoding", "UTF-8"); + headers.forEach(httpDelete::addHeader); + return doExecuteHttpRqeuestBase(httpDelete); + + } catch (Exception e) { + LOGGER.error("Error when doDelete : " + url, e); + return failHttp(e.getMessage()); + } + } + + private HttpResult doExecuteHttpRqeuestBase(HttpRequestBase httpRequestBase) { + try { + HttpResultResponseHandler sph = new HttpResultResponseHandler(); + return httpClient.execute(httpRequestBase, sph); + } catch (Exception e) { + LOGGER.error("Error when " + httpRequestBase.getMethod() + " : " + httpRequestBase.getURI(), e); + return failHttp(e.getMessage()); + } finally { + if (httpRequestBase != null) { + httpRequestBase.abort(); + } + } + } + + /** + * 请求体为json格式对象 + * + * @param path + * @param form + * @return + */ + public static HttpPost newJsonBodyPostRequest(String path, Map form) { + HttpPost post = new HttpPost(path); + String json = toJsonString(form); + HttpEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON); + post.setEntity(entity); + post.addHeader(HttpHeaders.ACCEPT, CONTENT_TYPE); + post.addHeader(HttpHeaders.CONTENT_TYPE, CONTENT_TYPE); + return post; + } + static final String CONTENT_TYPE = "application/json"; + + + public static String toJsonString(Object val) { + try { + byte[] bytes = objectMapper.writeValueAsBytes(val); + return new String(bytes, Charsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("toJsonString error", e); + } + } + + public static T parseHttpResponseObject(String json, TypeReference type) throws IOException { + if (Strings.isNullOrEmpty(json)) { + return null; + } + return objectMapper.readValue(json, type); + } + + public static String toRequestString(HttpRequestBase r) { + if (r == null) { + return "null"; + } + return r.getMethod() + " " + r.getURI(); + } + + private class HttpResultResponseHandler implements ResponseHandler { + @Override + public HttpResult handleResponse(HttpResponse response) throws IOException { + HttpResult result = new HttpResult(); + HttpEntity entity = response.getEntity(); + Header[] headers = response.getAllHeaders(); + if (isNotEmpty(headers)) { + HashMap headerMap = new HashMap(); + for (Header h : headers) { + headerMap.put(h.getName(), h.getValue()); + } + result.setHeader(headerMap); + } + + InputStream i = entity.getContent(); + String res = IOUtils.toString(new InputStreamReader(i, "UTF-8")); + result.setCode(response.getStatusLine().getStatusCode()); + result.setBody(res); + + i.close(); + + return result; + } + } + + private boolean isNotEmpty(Object[] array) { + return array != null && array.length > 0; + } + + private HttpResult failHttp(String message) { + HttpResult result = new HttpResult(); + result.setCode(500); + result.setBody(message); + return result; + } + + public static class HttpResult { + private String body; + private Map header; + private int code; + + public String getBody() { + return body; + } + + void setBody(String body) { + this.body = body; + } + + public Map getHeader() { + return header; + } + + void setHeader(Map header) { + this.header = header; + } + + public int getCode() { + return code; + } + + void setCode(int code) { + this.code = code; + } + + public boolean is200() { + return this.code == 200; + } + + public boolean isNot200() { + return !this.is200(); + } + + public HttpResult checkHttpCode() { + if (isNot200()) { + throw new RuntimeException("执行http方法出错,返回值非200,body=" + body); + } + return this; + } + + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public void setSocketTimeout(int socketTimeout) { + this.socketTimeout = socketTimeout; + } + + public void setMAX_PER_ROUTE(int MAX_PER_ROUTE) { + this.MAX_PER_ROUTE = MAX_PER_ROUTE; + } + + public void setMAX_TOTAL(int MAX_TOTAL) { + this.MAX_TOTAL = MAX_TOTAL; + } + + public void setCONNECTION_REQUEST_TIMEOUT(int CONNECTION_REQUEST_TIMEOUT) { + this.CONNECTION_REQUEST_TIMEOUT = CONNECTION_REQUEST_TIMEOUT; + } + /** + * 发送post请求 + * + * @param url 请求的url + * @param body json串 + * @return + */ + public static String sendPostJsonBody(String url, String body) { + log.debug("[HttpClientUtil][sendPostJsonBody] 入参 url={} body={}", url, body); + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8"); + StringEntity entity = new StringEntity(body, "utf-8"); + entity.setContentEncoding("UTF-8"); + entity.setContentType("application/json"); + httpPost.setEntity(entity); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + try { + HttpClient client = httpClientBuilder.build(); + HttpResponse response = client.execute(httpPost); + if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + String result = EntityUtils.toString(response.getEntity(), "utf-8"); + log.debug("[HttpClientUtil][sendPostJsonBody] 结果 url={} result={}", url, result); + return result; + } + log.warn("[HttpClientUtil][sendPostJsonBody] 请求失败 response={}", url, response.toString()); + return ""; + } catch (IOException ex) { + log.error("[HttpClientUtil][sendPostJsonBody] 请求异常 ex={}", url, ex); + return ""; + } + } + + /** + * 发送post请求 + * + * @param url 请求的url + * @param body json串 + * @return + */ + public static String sendPostJsonBodyNoEncoding(String url, String body) { + log.debug("[HttpClientUtil][sendPostJsonBody] 入参 url={} body={}", url, body); + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json;charset=utf-8"); + StringEntity entity = new StringEntity(body, "utf-8"); + entity.setContentType("application/json"); + httpPost.setEntity(entity); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + try { + HttpClient client = httpClientBuilder.build(); + HttpResponse response = client.execute(httpPost); + if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + String result = EntityUtils.toString(response.getEntity(), "utf-8"); + log.debug("[HttpClientUtil][sendPostJsonBody] 结果 url={} result={}", url, result); + return result; + } + log.warn("[HttpClientUtil][sendPostJsonBody] 请求失败 response={}", url, response.toString()); + return ""; + } catch (IOException ex) { + log.error("[HttpClientUtil][sendPostJsonBody] 请求异常 ex={}", url, ex); + return ""; + } + } + + public static String sendGet(String url) { + log.debug("[HttpClientUtil][sendPostJsonBody] 入参 url={} ", url); + HttpGet httpPost = new HttpGet(url); + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + try { + HttpClient client = httpClientBuilder.build(); + HttpResponse response = client.execute(httpPost); + if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + String result = EntityUtils.toString(response.getEntity(), "utf-8"); + log.debug("[HttpClientUtil][sendPostJsonBody] 结果 url={} result={}", url, result); + return result; + } + log.warn("[HttpClientUtil][sendPostJsonBody] 请求失败 response={}", url, response.toString()); + return ""; + } catch (IOException ex) { + log.error("[HttpClientUtil][sendPostJsonBody] 请求异常 ex={}", url, ex); + return ""; + } + } + +} diff --git a/common/src/main/java/com/usthe/common/entity/dto/WeChatWebHookDTO.java b/common/src/main/java/com/usthe/common/entity/dto/WeChatWebHookDTO.java new file mode 100644 index 0000000..edfbd95 --- /dev/null +++ b/common/src/main/java/com/usthe/common/entity/dto/WeChatWebHookDTO.java @@ -0,0 +1,54 @@ +package com.usthe.common.entity.dto; + +import io.swagger.annotations.ApiModel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author 花城 + * @version 1.0 + * @date 2022/2/21 6:55 下午 + * @Description + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ApiModel(description = "企业微信WebHook模版") +public class WeChatWebHookDTO { + /** + * 消息类型 + */ + private String msgtype; + + private TextDTO text; + + private MarkdownDTO markdown; + + @Data + public static class TextDTO{ + /** + * 消息内容 + */ + private String content; + + /** + * @人的名称英文拼写列表 + */ + private List mentioned_list; + + } + + @Data + public static class MarkdownDTO{ + /** + * 消息内容 + */ + private String content; + } + +} diff --git a/common/src/main/java/com/usthe/common/util/PriorityLevelEnum.java b/common/src/main/java/com/usthe/common/util/PriorityLevelEnum.java new file mode 100644 index 0000000..cbc2b8c --- /dev/null +++ b/common/src/main/java/com/usthe/common/util/PriorityLevelEnum.java @@ -0,0 +1,24 @@ +package com.usthe.common.util; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * @author 花城 + * @version 1.0 + * @date 2022/2/21 7:07 下午 + * @Description + */ +@AllArgsConstructor +@Getter +public enum PriorityLevelEnum { + + EMERGENCY(0,"紧急告警"), + CRITICAL(1,"严重告警"), + WARNING(2,"警告告警"), + ; + private Integer level; + private String message; +} diff --git a/manager/src/main/java/com/usthe/manager/component/alerter/DispatchAlarm.java b/manager/src/main/java/com/usthe/manager/component/alerter/DispatchAlarm.java index e0713be..af689f7 100644 --- a/manager/src/main/java/com/usthe/manager/component/alerter/DispatchAlarm.java +++ b/manager/src/main/java/com/usthe/manager/component/alerter/DispatchAlarm.java @@ -1,10 +1,13 @@ package com.usthe.manager.component.alerter; +import com.alibaba.fastjson.JSON; import com.usthe.alert.AlerterDataQueue; import com.usthe.alert.AlerterWorkerPool; +import com.usthe.collector.collect.common.http.HttpUtils; import com.usthe.common.util.CommonUtil; import com.usthe.common.entity.alerter.Alert; import com.usthe.alert.service.AlertService; +import com.usthe.manager.pojo.dto.FlyBookWebHookDto; import com.usthe.manager.pojo.dto.WeWorkWebHookDTO; import com.usthe.common.util.CommonConstants; import com.usthe.common.entity.manager.Monitor; @@ -23,6 +26,7 @@ import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.RestTemplate; import javax.mail.internet.MimeMessage; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -120,15 +124,69 @@ public class DispatchAlarm { switch (receiver.getType()) { // todo 短信通知 case 0: break; - case 1: sendEmailAlert(receiver, alert); break; +// case 1: sendEmailAlert(receiver, alert); break; case 2: sendWebHookAlert(receiver, alert); break; case 3: sendWeChatAlert(receiver, alert); break; case 4: sendWeWorkRobotAlert(receiver, alert);break; + case 1: sendFlyBookAlert(receiver,alert); break; default: break; } } } + /** + * 通过飞书发送告警信息 + * @param receiver + * @param alert + */ + private void sendFlyBookAlert(NoticeReceiver receiver, Alert alert) { + FlyBookWebHookDto flyBookWebHookDto = new FlyBookWebHookDto(); + FlyBookWebHookDto.Content content = new FlyBookWebHookDto.Content(); + FlyBookWebHookDto.Post post = new FlyBookWebHookDto.Post(); + FlyBookWebHookDto.zh_cn zh_cn = new FlyBookWebHookDto.zh_cn(); + content.setPost(post); + post.setZh_cn(zh_cn); + flyBookWebHookDto.setMsg_type("post"); + List> contents = new ArrayList<>(); + List contents1 = new ArrayList<>(); + FlyBookWebHookDto.FlyBookContent flyBookContent = new FlyBookWebHookDto.FlyBookContent(); + flyBookContent.setTag("text"); + StringBuilder text = new StringBuilder(); + text.append("告警目标对象 :" + alert.getTarget()) + .append("\n所属监控ID :" + alert.getMonitorId()) + .append("\n所属监控名称 :" + alert.getMonitorName()) + .append("\n告警级别 :" + CommonUtil.transferAlertPriority(alert.getPriority())) + .append("\n内容详情 : " + alert.getContent()); + flyBookContent.setText(text.toString()); + contents1.add(flyBookContent); + FlyBookWebHookDto.FlyBookContent bookContent = new FlyBookWebHookDto.FlyBookContent(); + bookContent.setTag("a"); + bookContent.setText("点击查看"); + bookContent.setHref("https://www.baidu.com"); + contents1.add(bookContent); + contents.add(contents1); + zh_cn.setTitle("[TanCloud探云告警]"); + zh_cn.setContent(contents); + flyBookWebHookDto.setContent(content); + //TODO 这个地方要加新的字段 + String webHookUrl = FlyBookWebHookDto.WEBHOOK_URL + receiver.getWechatId(); + try { + ResponseEntity entity = restTemplate.postForEntity(webHookUrl, flyBookWebHookDto, String.class); + if (entity.getStatusCode() == HttpStatus.OK) { + log.debug("Send weWork webHook: {} Success", webHookUrl); + } else { + log.warn("Send weWork webHook: {} Failed: {}", webHookUrl, entity.getBody()); + } + } catch (ResourceAccessException e) { + log.warn("Send WebHook: {} Failed: {}.", webHookUrl, e.getMessage()); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + + + } + /** * 通过企业微信发送告警信息 * @param receiver 通知配置信息 diff --git a/manager/src/main/java/com/usthe/manager/pojo/dto/FlyBookWebHookDto.java b/manager/src/main/java/com/usthe/manager/pojo/dto/FlyBookWebHookDto.java new file mode 100644 index 0000000..a86b2ab --- /dev/null +++ b/manager/src/main/java/com/usthe/manager/pojo/dto/FlyBookWebHookDto.java @@ -0,0 +1,67 @@ +package com.usthe.manager.pojo.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 飞书机器人消息实体 + * + * @author 花城 + * @version 1.0 + * @date 2022/2/22 6:41 下午 + * @Description + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FlyBookWebHookDto { + //TODO hook后面是特有的地址 + public static final String WEBHOOK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/"; + + private static final String MARKDOWN = "post"; + + /** + * 消息类型 + */ + private String msg_type = MARKDOWN; + + private Content content; + + /** + * 消息内容 + */ + @Data + public static class Content { + public Post post; + } + + @Data + public static class FlyBookContent{ + //格式 目前支持文本、超链接、@人的功能 text a at + public String tag; + //文本 + public String text; + //超链接地址 + public String href; + + public String user_id; + public String user_name; + } + @Data + public static class Post { + public zh_cn zh_cn; + } + @Data + public static class zh_cn{ + //标题 + public String title; + //内容 + public List> content; + } + +}