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

项目开发中需要用到钉钉机器人发送任务状态,本来想单独做一个功能就好,但是想着公司用到钉钉机器人发送项目挺多的。所以把这个钉钉机器人抽离成一个组件发布到企业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" +
                "> ![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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/154717.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言加密字符(ZZULIOJ1064:加密字符)

题目描述 从键盘输入一批字符,以结束,按要求加密并输出。 输入:从键盘输入一批字符,占一行,以结束。 输出:输出占一行 加密规则: 1)所有字母均转换为小写。 2)若是字母a到y&#xff…

系列七、JVM的内存结构【堆(Heap)】

一、概述 一个JVM实例只存在一个堆内存,堆内存的大小是可以手动调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,保存所有引用类型的真实信息,以方便执行器执行,堆内存分为三个部分,即…

EtherCAT从站EEPROM组成信息详解(3):字16-63邮箱、EEPROM信息

0 工具准备 1.EtherCAT从站EEPROM数据(本文使用DE3E-556步进电机驱动器)1 字10-63邮箱、EEPROM信息 1.1 字10-63组成规范 字10-63虽然包含的空间区域很大,但实际上仅包含引导状态下邮箱配置、标准邮箱配置、EEPROM大小、执行的SII标准版本…

相机突然断电,保存的DAT视频文件如何修复

3-7 本文主要解决因相机突然断电导致拍摄的视频文件损坏的问题。 在平常使用相机拍摄视频,比如用单反相机、无人机拍摄视频的时候,如果电池突然断电,或者突然炸机了,就非常有可能会得到一个损坏的视频文件,比如会产生…

网络安全(黑客技术)—高效自学

前言 前几天发布了一篇 网络安全(黑客)自学 没想到收到了许多人的私信想要学习网安黑客技术!却不知道从哪里开始学起!怎么学 今天给大家分享一下,很多人上来就说想学习黑客,但是连方向都没搞清楚就开始学习…

udp多点通信-广播-组播

单播 每次只有两个实体相互通信,发送端和接收端都是唯一确定的。 广播 主机之间的一对多的通信所有的主机都可以接收到广播消息(不管你是否需要)广播禁止穿过路由器(只能做局域网通信)只有UDP可以广播广播地址 有效网络号全是1的主机号 192.1…

卷积神经网络(CNN)多种图片分类的实现

文章目录 前期工作1. 设置GPU(如果使用的是CPU可以忽略这步)我的环境: 2. 导入数据3.归一化4.可视化 二、构建CNN网络模型三、编译模型四、训练模型五、预测六、模型评估 前期工作 1. 设置GPU(如果使用的是CPU可以忽略这步&#…

ElasticStack日志分析平台-ES 集群、Kibana与Kafka

一、Elasticsearch 1、介绍: Elasticsearch 是一个开源的分布式搜索和分析引擎,Logstash 和 Beats 收集的数据可以存储在 Elasticsearch 中进行搜索和分析。 Elasticsearch为所有类型的数据提供近乎实时的搜索和分析:一旦数据被索引&#…

Python Numpy.einsum

、 见 https://zhuanlan.zhihu.com/p/27739282

Resolume Arena 7.15.0(VJ音视频软件)

Resolume Arena 7是一款专业的实时视觉效果软件,用于创造引人入胜的视频演出和灯光秀。它提供了丰富多样的功能和工具,可以将音频、视频和图像合成在一起,创造出令人惊叹的视觉效果。 Resolume Arena 7支持多种媒体格式,包括视频文…

微信@all bug复现及原理分析

1、复现 条件: 1、Windows PC 端微信 2、自建一个群聊拥有群管权限可以所有人 废话不多说,直接上图 所有人 剪切后,到另一个群中,引用任意一个群里成员的消息,并将刚才剪切的粘贴至此,发送 便可完成非群…

LeetCode之二叉树

发现更多计算机知识,欢迎访问Cr不是铬的个人网站 最近数据结构学到二叉树,就刷了刷力扣,写这篇文章也是辅助记忆。 103二叉树锯齿形遍历 要解出本道题,首先要会层次遍历。层次遍历我们都知道用一个队列去实现就行。但是力扣这里…

重磅 | 进一步夯实生态建设,朗思科技与阿里龙蜥完成兼容性认证

近日,北京朗思智能科技有限公司(以下简称“朗思科技”)自主研发的数字员工产品与OpenAnolis龙蜥社区龙蜥操作系统(Anolis OS)8完成兼容性认证。测试结果显示,双方产品相互兼容,功能正常&#xf…

【window 10】开启加速器,连接外网 打开外网链接

打开网页 链接 https://steampp.net/,点击下载 下载 我选的是 微软商店 安装 打开后界面是这样,先注册个用户登录 选择 需要加速的内容 先选中下面的复选框 再点击 ‘一键加速’ 按钮,出现下面的界面 打开外网的链接 直接访问 就好了&#xf…

【算法每日一练]-图论(保姆级教程 篇3(遍历))#图的遍历 #奶牛牧场 #杂务

今天讲图的遍历 目录 题目:图的遍历 思路: 题目:奶牛牧场 思路: 题目:杂务 思路: 题目:图的遍历 思路: 正向建边需要跑O(N^2)会超时,所以反向建边,先从最大的点出发&#x…

解锁编程潜能:探索亚马逊CodeWhisperer,打造编程世界的声音引导者

文章目录 前言一、什么是 Amazon CodeWhisperer?二、如何使用CodeWhisperer?安装CodeWhisperer插件配置CodeWhisperer生成注释和文档 总结 前言 随着CHATGPT的一声巨响,大语言模型已经成为了一个备受瞩目的创新应用。亚马逊云科技作为全球领…

Java常用命令行指令有哪些?Java指令分享!

在Java开发中,命令行工具是非常重要的,它们允许开发人员执行各种任务,从编译和运行Java程序到管理Java虚拟机。本文将介绍一些常用的Java命令行指令,并通过具体实例演示它们的用法。 1. 编译Java源代码 使用javac命令可以将Java源…

贪吃蛇基础知识铺垫2(c语言)

宽字符的打印 那如果想在屏幕上打印宽字符,怎么打印呢? 宽字符的字⾯量必须加上前缀“L”,否则 C 语⾔会把字⾯量当作窄字符类型处理。前缀“L”在单引 号前⾯,表⽰宽字符,对应 wprintf() 的占位符为 %lc &#xff1b…

[Linux]NFS文件共享服务

一、NFS 1.1 NFS的简介 NFS(Network File System 网络文件服务),是一种基于 TCP/IP 传输的网络文件系统协议,最初由 Sun 公司开发。 NFS 服务的实现依赖于 RPC(Remote Process Call,远端过程调用&#x…
最新文章