可爱静

记录生活、学习和工作

0%

企业微信群机器人发送消息

应用场景

  • 在企业微信群内发送特定消息并@指定的成员

官方文档地址

  1. 发送文字消息
  2. 发送图片消息
  3. 发送图文消息
  4. 发送卡片消息
  5. 发送文件消息

    具体实现

  • 采用模板模式

    封装消息体

  • 将各类消息DTO的公共部分抽取成AbstractMessageDto(第一层)、AbstractWxWorkDto(第二层),AbstractWxWorkDto继承AbstractMessageDto,各类消息DTO继承AbstractWxWorkDto;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // AbstractMessageDto
    private Long sendTime;

    private String messageId;

    private String resultCode;

    private String resultMessage;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // AbstractWxWorkDto
    // 消息类型
    private String msgtype;

    private List<String> mentioned_list = new ArrayList<>();

    private List<String> mentioned_mobile_list = new ArrayList<>();

    // 消息内容
    public abstract void setContent(Object content);

    public abstract void build();

    public abstract void valid();

    定义请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // SendHttpClient
    private static final String DEFAULT_CONTENT_TYPE = "application/json; charset=utf-8";

    public static <K> String doPost(String url, K jsonParam, Map<String, String> headers) {
    if (jsonParam != null) {
    Gson gson = new Gson();
    String jsonStr = gson.toJson(jsonParam);
    HttpResponse response = HttpUtil.createPost(url)
    .header(Header.CONTENT_TYPE, headers.get(Header.CONTENT_TYPE.getValue()))
    .body(jsonStr)
    .timeout(20000)
    .executeAsync();
    return response.body();
    }
    return "";

    }

    public static <T, K> T post(String url, K jsonParam, Class<T> clazz) {
    return post(url, jsonParam, clazz, null);
    }

    public static <T, K> T post(String url, K jsonParam, Class<T> clazz, Map<String, String> header) {
    String json = null;
    header = header == null ? new HashMap<>() : header;
    if (!header.containsKey(Header.CONTENT_TYPE.toString())) {
    header.put(Header.CONTENT_TYPE.toString(), DEFAULT_CONTENT_TYPE);
    }
    json = doPost(url, jsonParam, header);
    Gson gson = new Gson();
    T res = json == null ? null : gson.fromJson(json, clazz);
    return res;
    }

    消息发送模板

  • SendTemplate 泛型
    1
    2
    3
    4
    public abstract class SendTemplate<T extends AbstractMessageDto> {

    public abstract T send(T t);
    }
  • WxWorkSendTemplate extends SendTemplate
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    private static final String WX_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=%s&debug=1";

    @Override
    public AbstractWxWorkDto send(AbstractWxWorkDto abstractWxWorkDto) {
    if (Validator.isNull(abstractWxWorkDto)) {
    throw new IllegalArgumentException("body is null");
    }
    if (Validator.isEmail(abstractWxWorkDto.getMsgtype())) {
    throw new IllegalArgumentException("msgType is null");
    }
    try {
    String url = String.format(WX_URL, "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx");
    WxWorkResultDto result = SendHttpClient.post(url, abstractWxWorkDto,
    WxWorkResultDto.class);
    log.info("result {} ", new Gson().toJson(abstractWxWorkDto));
    log.info("result {} ", result);
    abstractWxWorkDto.setSendTime(System.currentTimeMillis());
    abstractWxWorkDto.setResultCode("0");
    } catch (Exception e) {
    log.info("通知失败 {}", abstractWxWorkDto);
    abstractWxWorkDto.setResultCode("1");
    }
    return abstractWxWorkDto;
    }

    文字消息实例(markdown)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class WxWorkMarkdownDto extends AbstractWxWorkDto {

    private Map<String, String> markdown;

    @Override
    public void setContent(Object content) {
    if (Validator.isNull(content)) {
    throw new IllegalArgumentException("body value is null");
    }
    markdown = new HashMap<>();
    markdown.put("content", content.toString());
    build();
    valid();
    }

    @Override
    public void build() {
    this.setMsgtype("markdown");
    }

    @Override
    public void valid() {
    if (!this.markdown.containsKey("content")) {
    throw new IllegalArgumentException("body key is null");
    }
    if (Validator.isEmail(markdown.get("content"))) {
    throw new IllegalArgumentException("body value is null");
    }
    }
    }
  • 测试:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Test
    @DisplayName("markdown")
    void setMarkdown() {
    WxWorkMarkdownDto wxWorkMarkdownDto = new WxWorkMarkdownDto();
    wxWorkMarkdownDto.setContent("实时新增用户反馈<font color=\"warning\">132例</font>,请相关同事注意。\\n\n" +
    " >类型:<font color=\"comment\">用户反馈</font>\n" +
    " >普通用户反馈:<font color=\"comment\">117例</font>\n" +
    " >VIP用户反馈:<font color=\"comment\">15例</font>\n" +
    " >[嘿凡博客](iiii.host)");
    wxWorkSendTemplate.send(wxWorkMarkdownDto);
    }