java实现钉钉机器人消息推送

项目开发中需要用到钉钉机器人发送任务状态,本来想单独做一个功能就好,但是想着公司用到钉钉机器人发送项目挺多的。所以把这个钉钉机器人抽离成一个组件发布到企业maven仓库,这样可以给其他同事用提高工作效率。

1.目录结构

java实现钉钉机器人消息推送_第1张图片

2.用抽象类(abstract)规范钉钉发送消息模版

2.1创建一个抽象类
public abstract class BaseMessage {

    public BaseMessage() {
        initMsg();
    }

    protected String msgType;

    public String getMsgType() {
        return msgType;
    }

    protected abstract void initMsg();


    /**
     * 返回Message对象组装出来的Map对象,供后续JSON序列化
     *
     * @return Map
     */
    public abstract JSONObject toMessageMap();
}
2.2钉钉(link,text,markdown)类型创建实体继承BaseMessgae

钉钉api文档 添加链接描述

LinkMessage@Data
public class LinkMessage extends BaseMessage {
    /**
     * 消息简介
     */
    private String text;

    /**
     * 消息标题
     */
    private String title;

    /**
     * 封面图片URL
     */
    private String picUrl;

    /**
     * 消息跳转URL
     */
    private String messageUrl;

    public LinkMessage() {
    }

    public LinkMessage(String title, String text, String messageUrl) {
        this.text = text;
        this.title = title;
        this.messageUrl = messageUrl;
    }

    public LinkMessage(String title, String text, String messageUrl, String picUrl) {
        this.text = text;
        this.title = title;
        this.picUrl = picUrl;
        this.messageUrl = messageUrl;
    }

    @Override
    protected void initMsg() {
        this.msgType = DingTalkMsgEnum.LINK.getType();
    }

    @Override
    public JSONObject toMessageMap() {
        if (StringUtils.isEmpty(this.text) || !DingTalkMsgEnum.LINK.getType().equals(this.msgType)) {
            throw new IllegalArgumentException("please check the necessary parameters!");
        }

        JSONObject resultMap = JSONUtil.createObj();
        resultMap.put("msgtype", this.msgType);
        JSONObject linkItems = JSONUtil.createObj();
        linkItems.put("title", this.title);
        linkItems.put("text", this.text);
        linkItems.put("picUrl", this.picUrl);
        linkItems.put("messageUrl", this.messageUrl);
        resultMap.put("link", linkItems);

        return resultMap;
    }
}

TextMessage@Data
public class TextMessage extends BaseMessage {

    /**
     * 文本消息的具体内容
     */
    private String content;

    /**
     * 可以通过群成员的绑定手机号来艾特具体的群成员
     */
    private String[] atMobiles;

    /**
     * 是否艾特所有人
     * 也可以设置isAtAll=true来艾特所有人
     */
    private boolean isAtAll;

    public TextMessage() {
    }

    public TextMessage(String content) {
        this.content = content;
    }

    public TextMessage(String content, String[] atMobiles) {
        this.content = content;
        this.atMobiles = atMobiles;
    }

    public TextMessage(String content, boolean isAtAll) {
        this.content = content;
        this.isAtAll = isAtAll;
    }


    @Override
    protected void initMsg() {
        this.msgType = DingTalkMsgEnum.TEXT.getType();
    }

    @Override
    public JSONObject toMessageMap() {
        if (StringUtils.isEmpty(this.content) || !DingTalkMsgEnum.TEXT.getType().equals(this.msgType)) {
            throw new IllegalArgumentException("please check the necessary parameters!");
        }

        JSONObject resultMap = JSONUtil.createObj();
        resultMap.put("msgtype", this.msgType);

        JSONObject textItems = JSONUtil.createObj();
        textItems.put("content", this.content);
        resultMap.put("text", textItems);

        JSONObject atItems = JSONUtil.createObj();
        atItems.put("atMobiles", this.atMobiles);
        atItems.put("isAtAll", this.isAtAll);
        resultMap.put("at", atItems);

        return resultMap;
    }
}

MarkdownMessage
@Data
public class MarkdownMessage extends BaseMessage {
    /**
     * 消息简介
     */
    private String text;

    /**
     * 消息标题
     */
    private String title;

    /**
     * 可以通过群成员的绑定手机号来艾特具体的群成员
     */
    private String[] atMobiles;

    /**
     * 是否艾特所有人
     * 也可以设置isAtAll=true来艾特所有人
     */
    private boolean isAtAll;

    public MarkdownMessage() {
    }

    public MarkdownMessage(String title, String text) {
        this.text = text;
        this.title = title;
    }

    public MarkdownMessage(String title, String text, String[] atMobiles) {
        this.text = text;
        this.title = title;
        this.atMobiles = atMobiles;
    }

    public MarkdownMessage(String title, String text, boolean isAtAll) {
        this.text = text;
        this.title = title;
        this.isAtAll = isAtAll;
    }

    @Override
    protected void initMsg() {
        this.msgType = DingTalkMsgEnum.MARKDOWN.getType();
    }

    @Override
    public JSONObject toMessageMap() {
        if (StringUtils.isEmpty(this.text) || !DingTalkMsgEnum.MARKDOWN.getType().equals(this.msgType)) {
            throw new IllegalArgumentException("please check the necessary parameters!");
        }
        JSONObject resultMap = JSONUtil.createObj();
        resultMap.put("msgtype", this.msgType);

        JSONObject markdownItems = JSONUtil.createObj();
        markdownItems.put("title", this.title);
        markdownItems.put("text", this.text);
        resultMap.put("markdown", markdownItems);

        JSONObject atItems = JSONUtil.createObj();
        atItems.put("atMobiles", this.atMobiles);
        atItems.put("isAtAll", this.isAtAll);
        resultMap.put("at", atItems);
        return resultMap;
    }
}

3. 钉钉异常错误类

public class DingTalkResponse {
    /**
     * 错误码
     */
    private Integer errcode;

    /**
     * 错误信息
     */
    private String errmsg;

    public Integer getErrcode() {
        return errcode;
    }

    public void setErrcode(Integer errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    @Override
    public String toString() {
        return "DingTalkResponse{" +
                "errcode=" + errcode +
                ", errmsg='" + errmsg + '\'' +
                '}';
    }
}

4.钉钉类型枚举

@Getter
public enum DingTalkMsgEnum {
    LINK("link"),
    TEXT("text"),
    MARKDOWN("markdown");

    private final String type;

    DingTalkMsgEnum(String type) {
        this.type = type;
    }

}

5.实现类方法

public class DingTalkRobotClient {

    /**
     * 钉钉机器人WebHook地址的access_token
     */
    private String accessToken;

    private static String DING_TALK_PATH = "https://oapi.dingtalk.com/robot/send?access_token=ACCESS_TOKEN";

    public DingTalkRobotClient(String token) {
        if(StringUtils.isEmpty(token)){
            throw new ServiceException("accessToken获取失败!");
        }
        this.accessToken = token;
    }

    private DingTalkResponse sendMessage(BaseMessage message) {
        String result = HttpUtil.post(DING_TALK_PATH.replace("ACCESS_TOKEN", this.accessToken), message.toMessageMap().toString());
        DingTalkResponse dingTalkResponse = JSON.parseObject(result, DingTalkResponse.class);
        // 对DingTalkResponse为空情况做异常封装
        if (dingTalkResponse == null) {
            throw new ServiceException("请求钉钉报错!");
        }
        if (dingTalkResponse.getErrcode() != 0) {
            throw new ServiceException(String.format("错误码:%s;%s", dingTalkResponse.getErrcode(), dingTalkResponse.getErrmsg()));
        }
        return dingTalkResponse;
    }

    /**
     * 发送文本消息到钉钉
     *
     * @param message
     * @return
     */
    public DingTalkResponse sendTextMessage(TextMessage message) {
        return this.sendMessage(message);
    }

    /**
     * 发送文本消息到钉钉
     *
     * @param content
     * @return
     */
    public DingTalkResponse sendTextMessage(String content) {
        return this.sendMessage(new TextMessage(content));
    }

    /**
     * 发送文本消息到钉钉
     *
     * @param content
     * @param atMobiles
     * @return
     */
    public DingTalkResponse sendTextMessage(String content, String[] atMobiles) {
        return this.sendMessage(new TextMessage(content, atMobiles));
    }

    /**
     * 发送文本消息到钉钉
     *
     * @param content
     * @param isAtAll
     * @return
     */
    public DingTalkResponse sendTextMessage(String content, boolean isAtAll) {
        return this.sendMessage(new TextMessage(content, isAtAll));
    }

    /**
     * 发送Link消息到钉钉
     *
     * @param message
     * @return
     */
    public DingTalkResponse sendLinkMessage(LinkMessage message) {
        return this.sendMessage(message);
    }

    /**
     * 发送Link消息到钉钉
     *
     * @param title
     * @param text
     * @param messageUrl
     * @return
     */
    public DingTalkResponse sendLinkMessage(String title, String text, String messageUrl) {
        return this.sendMessage(new LinkMessage(title, text, messageUrl));
    }

    /**
     * 发送Link消息到钉钉
     *
     * @param title
     * @param text
     * @param messageUrl
     * @param picUrl
     * @return
     */
    public DingTalkResponse sendLinkMessage(String title, String text, String messageUrl, String picUrl) {
        return this.sendMessage(new LinkMessage(title, text, messageUrl, picUrl));
    }

    /**
     * 发送MarkDown消息到钉钉
     *
     * @param message
     * @return
     */
    public DingTalkResponse sendMarkdownMessage(MarkdownMessage message) {
        return this.sendMessage(message);
    }

    /**
     * 发送MarkDown消息到钉钉
     *
     * @param title
     * @param text
     * @return
     */
    public DingTalkResponse sendMarkdownMessage(String title, String text) {
        return this.sendMessage(new MarkdownMessage(title, text));
    }

    /**
     * 发送MarkDown消息到钉钉
     *
     * @param title
     * @param text
     * @param atMobiles
     * @return
     */
    public DingTalkResponse sendMarkdownMessage(String title, String text, String[] atMobiles) {
        return this.sendMessage(new MarkdownMessage(title, text, atMobiles));
    }

    /**
     * 发送MarkDown消息到钉钉
     *
     * @param title
     * @param text
     * @param isAtAll
     * @return
     */
    public DingTalkResponse sendMarkdownMessage(String title, String text, boolean isAtAll) {
        return this.sendMessage(new MarkdownMessage(title, text, isAtAll));
    }


    public static void main(String[] args) {
        new DingTalkRobotClient("accessToken").sendMarkdownMessage("构建任务","#### 杭州天气 @156xxxx8827\n" +
                "> 9度,西北风1级,空气良89,相对温度73%\n\n" +
                "> ![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png)\n"  +
                "> ###### 10点20分发布 [天气](http://www.thinkpage.cn/) \n");
    }

6. DingTalkConfig配置

@ConfigurationProperties(prefix = "dingtalk")
@Configuration
@Data
public class DingTalkConfig {

    private String accessToken;

    @Bean
    public DingTalkRobotClient dingTalkRobotClient(){
        return new DingTalkRobotClient(accessToken);
    }
}

你可能感兴趣的:(java,钉钉,机器人)