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


















