Java开发企业微信群机器人发送markdown消息
企业微信群机器人配置使用Java发送markdown消息消息应答结果实体核心代码完整Java工具类完整Java工具类Demo01Demo02sendMarkdown 简化企业微信群机器人配置
群机器人配置说明发送应用消息参考网址
使用Java发送markdown消息
注意: 本代码仅依赖 com.google.gson.Gson , 其他均JDK1.8原生类.
消息应答结果实体
/*** 企业微信群机器人发送消息应答结果.<br>*/public final class WeComRobotResponse {private int errcode;private String errmsg;public int getErrcode() {return errcode;}public void setErrcode(int errcode) {this.errcode = errcode;}public String getErrmsg() {return errmsg;}public void setErrmsg(String errmsg) {this.errmsg = errmsg;}}
核心代码
/*** 发送相应的Markdown内容到对应key的机器人.* * @param key机器人key* @param markdown Markdown内容* @return*/public final WeComRobotResponse sendMarkdown(@Nullable final String key, @Nonnull final String markdown) {if (markdown.isEmpty()) {return null;}/** 拼接数据, 格式: {'msgtype': 'markdown', 'markdown': {'content': 'Markdown实际内容.'}} */Map<String, String> data = new HashMap<>();data.put("content", markdown);Map<String, Object> json = new HashMap<>();json.put("msgtype", "markdown");json.put("markdown", data);byte[] bytes = new Gson().toJson(json).getBytes(StandardCharsets.UTF_8);// 创建链接HttpURLConnection httpConnection = null;try {URL url = new URL(String.format(TARGET_URL, Optional.ofNullable(key).orElseGet(() -> defaultKey)));httpConnection = HttpURLConnection.class.cast(url.openConnection());httpConnection.setRequestMethod("POST");httpConnection.addRequestProperty("Content-Type", "application/json;charset=UTF-8");httpConnection.setRequestProperty("Accept", "application/json");httpConnection.setRequestProperty("Content-Length", String.valueOf(bytes.length));httpConnection.setDoInput(true);httpConnection.setDoOutput(true);httpConnection.setUseCaches(false);httpConnection.connect();} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 推送数据try (OutputStream out = httpConnection.getOutputStream();) {out.write(bytes);out.flush();} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 请求失败try {if (200 != httpConnection.getResponseCode()) {return null;}} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 接收数据String response = null;try (ByteArrayOutputStream baos = new ByteArrayOutputStream(1 << 5); InputStream isr = httpConnection.getInputStream();) {byte[] buffer = new byte[512];int n = 0;while ((n = isr.read(buffer)) >= 0) {baos.write(buffer, 0, n);}response = new String(baos.toByteArray(), StandardCharsets.UTF_8);} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 断开连接httpConnection.disconnect();LOGGER.info("We Com Send Message State :: {}", response);return new Gson().fromJson(response, WeComRobotResponse.class);}
完整Java工具类
完整Java工具类
import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .HttpURLConnection;import .URL;import java.nio.charset.StandardCharsets;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Objects;import java.util.Optional;import javax.annotation.Nonnull;import javax.annotation.Nullable;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.annotation.Order;import org.ponent;import com.google.gson.Gson;/*** 企业微信群机器人发送消息.<br>* * demo01:<br>* <blockquote>* * <pre>* @org.springframework.beans.factory.annotation.Autowired* private WeComRobotUtils wecomRobot;* ......* String markdown = WeComRobotUtils.Markdown.of("运维中心告警预告")*.addProp("名称", "主机阈值越界", "red")*.addProp("主机", "localhost-01.local")*.addProp("时间", LocalDateTime.now().toString(), "#027e7e")*.setFooter("请尽快处理.")*.toString();* wecomRobot.sendMarkdown(markdown); 或 wecomRobot.sendMarkdownAndCheck(markdown);* 或者* String key = "......";* wecomRobot.sendMarkdown(key, markdown); 或 wecomRobot.sendMarkdownAndCheck(key, markdown);* ......* </pre>* * </blockquote>* <p>* demo02:<br>* <blockquote>* * <pre>* @org.springframework.beans.factory.annotation.Autowired* private WeComRobotUtils wecomRobot;* ......* String markdown = "运维中心告警预告:\n\n>名称: 主机阈值越界\n主机: <font color='red'>localhost-01.local</font>\n\n请尽快处理.";* wecomRobot.sendMarkdown(markdown); 或 wecomRobot.sendMarkdownAndCheck(markdown);* 或者* String key = "......";* wecomRobot.sendMarkdown(key, markdown); 或 wecomRobot.sendMarkdownAndCheck(key, markdown);* ......* </pre>* * </blockquote>*/@Order(value = Integer.MIN_VALUE)@Componentpublic class WeComRobotUtils {private static final Logger LOGGER = LoggerFactory.getLogger(WeComRobotUtils.class);private static final String TARGET_URL = "https://qyapi./cgi-bin/webhook/send?key=%s";@Value(value = "${wecom.robot.key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}")private String defaultKey;/*** 企业微信群机器人发送消息构造工具.<br>* 格式如下:<br>* <code>* ${title}:<br>* > props[0].label: <font color='props[0].color'>props[0].value</font><br>* > props[1].label: <font color='props[1].color'>props[1].value</font><br>* > props[2].label: <font color='props[2].color'>props[2].value</font><br>* > ......<br>* ${footer}:<br>* </code>*/public static final class Markdown {private static final String PROPS_FORMAT = "> %s: <font color='%s'>%s</font>\n";private String title;private List<ColorValue> props = new ArrayList<>(1 << 5);private String footer;private static final class ColorValue {private String label;private String value;private String color;public static final ColorValue of(final String label, final String value) {return new ColorValue(label, value, "#747474");}public static final ColorValue of(final String label, final String value, final String color) {return new ColorValue(label, value, color);}private ColorValue(String label, String value, String color) {this.label = label;this.value = value;this.color = color;}public String getLabel() {return label;}public String getValue() {return value;}public String getColor() {return color;}}public static final Markdown of(final String title) {return new Markdown(title);}public Markdown(String title) {this.title = title;}public String getTitle() {return title;}public List<ColorValue> getProps() {return props;}public String getFooter() {return footer;}public Markdown setFooter(final String footer) {this.footer = footer;return this;}public Markdown addProp(final String label, final String value) {this.getProps().add(ColorValue.of(label, value));return this;}public Markdown addProp(final String label, final String value, final String color) {this.getProps().add(ColorValue.of(label, value, color));return this;}@Overridepublic String toString() {StringBuilder out = new StringBuilder(1 << 8);out.append(this.getTitle()).append(":").append("\n\n"); // 标题this.getProps().forEach(item -> out.append(String.format(PROPS_FORMAT, item.getLabel(), item.getColor(), item.getValue())));out.append("\n").append(Optional.ofNullable(this.getFooter()).orElseGet(() -> "")); // 结尾return out.toString();}}/*** 企业微信群机器人发送消息应答结果.<br>*/public final class WeComRobotResponse {private int errcode;private String errmsg;public int getErrcode() {return errcode;}public void setErrcode(int errcode) {this.errcode = errcode;}public String getErrmsg() {return errmsg;}public void setErrmsg(String errmsg) {this.errmsg = errmsg;}}/*** 发送相应的Markdown内容到默认key的机器人, 并做校验.* * @param markdown Markdown内容* @return*/public final boolean sendMarkdownAndCheck(@Nonnull final String markdown) {return WeComRobotUtils.isOk(this.sendMarkdown(defaultKey, markdown));}/*** 发送相应的Markdown内容到对应key的机器人, 并做校验.* * @param key机器人key* @param markdown Markdown内容* @return*/public final boolean sendMarkdownAndCheck(@Nullable final String key, @Nonnull final String markdown) {return WeComRobotUtils.isOk(this.sendMarkdown(key, markdown));}/*** 发送相应的Markdown内容到默认key的机器人.* * @param markdown Markdown内容* @return*/public final WeComRobotResponse sendMarkdown(@Nonnull final String markdown) {return this.sendMarkdown(defaultKey, markdown);}/*** 发送相应的Markdown内容到对应key的机器人.* * @param key机器人key* @param markdown Markdown内容* @return*/public final WeComRobotResponse sendMarkdown(@Nullable final String key, @Nonnull final String markdown) {if (markdown.isEmpty()) {return null;}/** 拼接数据, 格式: {'msgtype': 'markdown', 'markdown': {'content': 'Markdown实际内容.'}} */Map<String, String> data = new HashMap<>();data.put("content", markdown);Map<String, Object> json = new HashMap<>();json.put("msgtype", "markdown");json.put("markdown", data);byte[] bytes = new Gson().toJson(json).getBytes(StandardCharsets.UTF_8);// 创建链接HttpURLConnection httpConnection = null;try {URL url = new URL(String.format(TARGET_URL, Optional.ofNullable(key).orElseGet(() -> defaultKey)));httpConnection = HttpURLConnection.class.cast(url.openConnection());httpConnection.setRequestMethod("POST");httpConnection.addRequestProperty("Content-Type", "application/json;charset=UTF-8");httpConnection.setRequestProperty("Accept", "application/json");httpConnection.setRequestProperty("Content-Length", String.valueOf(bytes.length));httpConnection.setDoInput(true);httpConnection.setDoOutput(true);httpConnection.setUseCaches(false);httpConnection.connect();} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 推送数据try (OutputStream out = httpConnection.getOutputStream();) {out.write(bytes);out.flush();} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 请求失败try {if (200 != httpConnection.getResponseCode()) {return null;}} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 接收数据String response = null;try (ByteArrayOutputStream baos = new ByteArrayOutputStream(1 << 5); InputStream isr = httpConnection.getInputStream();) {byte[] buffer = new byte[512];int n = 0;while ((n = isr.read(buffer)) >= 0) {baos.write(buffer, 0, n);}response = new String(baos.toByteArray(), StandardCharsets.UTF_8);} catch (IOException e) {LOGGER.error(e.getClass().getName(), e);return null;}// 断开连接httpConnection.disconnect();LOGGER.info("We Com Send Message State :: {}", response);return new Gson().fromJson(response, WeComRobotResponse.class);}/*** 判断发送是否成功.<br>* 成功 :: true<br>* 失败 :: false<br>* * @param res 发送结果* @return*/public static final boolean isOk(WeComRobotResponse res) {return Objects.nonNull(res) && 0 == res.getErrcode();}}
Demo01
@org.springframework.beans.factory.annotation.Autowiredprivate WeComRobotUtils wecomRobot;......String markdown = WeComRobotUtils.Markdown.of("Markdown标题").addProp("Label01", "Label01-Value", "red").addProp("Label02", "Label02-Value").addProp("时间", LocalDateTime.now().toString(), "#027e7e").setFooter("请尽快处理.").toString();wecomRobot.sendMarkdown(markdown); 或 wecomRobot.sendMarkdownAndCheck(markdown);或者String key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";wecomRobot.sendMarkdown(key, markdown); 或 wecomRobot.sendMarkdownAndCheck(key, markdown);
Demo02
@org.springframework.beans.factory.annotation.Autowiredprivate WeComRobotUtils wecomRobot;......String markdown = "Markdown标题:\n\n>Label01: Label01-Value\nLabel02: <font color='red'>Label02-Value</font>\n\n请尽快处理.";wecomRobot.sendMarkdown(markdown); 或 wecomRobot.sendMarkdownAndCheck(markdown);或者String key = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";wecomRobot.sendMarkdown(key, markdown); 或 wecomRobot.sendMarkdownAndCheck(key, markdown);......
sendMarkdown 简化
import org.springframework.web.client.RestTemplate;public final WeComRobotResponse sendMarkdown(@Nullable final String key, @Nonnull final String markdown) {/** 拼接数据, 格式: {'msgtype': 'markdown', 'markdown': {'content': 'Markdown实际内容.'}} */Map<String, String> data = new HashMap<>();data.put("content", markdown);Map<String, Object> json = new HashMap<>();json.put("msgtype", "markdown");json.put("markdown", data);String url = String.format(TARGET_URL, Optional.ofNullable(key).orElseGet(() -> defaultKey));return new RestTemplate().postForEntity(url, json, WeComRobotResponse.class).getBody();}