从头开始,并不意味着失败,相反,正是拥抱成功的第一步,即使还会继续失败

上一章简单介绍了 SpringBoot 发送邮件(四十三), 如果没有看过,请观看上一章

钉钉消息推送, 官方文档: https://open.dingtalk.com/document/group/group-robot

开发钉钉消息推送,我们可以使用 spring-boot-dingtalk-robot-starter 第三方依赖进行快速开发.

对应的官方文档是: https://gitee.com/snowheart/dingtalk-robot

一. 钉钉群安装机器人

点击进入一个群, 选择智能群助手

SpringBoot整合钉钉消息推送(四十四)_钉钉消息推送

选择 添加机器人:

SpringBoot整合钉钉消息推送(四十四)_钉钉消息推送_02

点击 右边的设置

SpringBoot整合钉钉消息推送(四十四)_Apple_03

选择 自定义

SpringBoot整合钉钉消息推送(四十四)_ci_04

点击添加:

SpringBoot整合钉钉消息推送(四十四)_Apple_05

SpringBoot整合钉钉消息推送(四十四)_ci_06

完成之后,会生成一个相应 的 Webhook

https://oapi.dingtalk.com/robot/send?access_token=817edae9c6xxxxxxxxxxxxxxx

SpringBoot整合钉钉消息推送(四十四)_Test_07

二. 钉钉消息推送开发

二.一 pom.xml 添加依赖

<dependency>
    <groupId>cn.snowheart</groupId>
    <artifactId>spring-boot-dingtalk-robot-starter</artifactId>
    <version>1.0.2.RELEASE</version>
</dependency>

二.二 添加配置

application.yml 上添加配置, 只添加一个对应的 webhook 值即可。 webhook 是 群创建机器人的标识

dingtalk:
  robot:
    webhook: https://oapi.dingtalk.com/robot/send?access_token=817edae9c662dc38bb5fcb4231f74b9e1eb9f33d17f1e12b25903980f82b7c9d

二.三 功能测试

先注入客户端

@Autowired
@Qualifier("dingTalkRobotClient")
private DingTalkRobotClient client;

二.三.一 普通文本通知

@Test
 public void testSendTextMessage() throws InterruptedException {
     DingTalkResponse response = null;
 
     response = client.sendTextMessage(new TextMessage("业务报警:构建 TextMessage对象发布!"));
     Assert.assertEquals(response.getErrcode().longValue(), 0L);
     log.info(response.toString());
     Thread.sleep(3000);
 
     response = client.sendTextMessage("业务报警:构建普通字符串发布!");
     Assert.assertEquals(response.getErrcode().longValue(), 0L);
     log.info(response.toString());
     Thread.sleep(3000);
 
     response = client.sendTextMessage("业务报警:通知指定人!", new String[]{"15734078927"});
     Assert.assertEquals(response.getErrcode().longValue(), 0L);
     log.info(response.toString());
     Thread.sleep(3000);
 
     response = client.sendTextMessage("业务报警:通知群内所有人!", true);
     Assert.assertEquals(response.getErrcode().longValue(), 0L);
     log.info(response.toString());
     Thread.sleep(3000);
 }

SpringBoot整合钉钉消息推送(四十四)_Test_08

二.三.二 超链接文本

@Test
public void testSendLinkMessage() throws InterruptedException {
    DingTalkResponse response = null;
 
    //链接,构建 LinkMessage 对象
    response = client.sendLinkMessage(new LinkMessage("业务报警:AAA",
            "BBBBBBB",
            "CCCCC",
            "DDDD"));
    Assert.assertEquals(response.getErrcode().longValue(), 0L);
    log.info(response.toString());
    Thread.sleep(3000);
}

二.三.三 markdown 文本推送

private static final String markDownDemoText = "业务报警:标题" +
           "# 一级标题\n" +
           "## 二级标题\n" +
           "### 三级标题\n" +
           "#### 四级标题\n" +
           "##### 五级标题\n" +
           "###### 六级标题\n" ;  
 
@Test
   public void testSendMarkdownMessage() throws InterruptedException {
       DingTalkResponse response = null;
       // 构建 markdown 对象用法
       response = client.sendMarkdownMessage(new MarkdownMessage("业务报警:钉钉markdown消息支持的语法",
               markDownDemoText));
       Assert.assertEquals(response.getErrcode().longValue(), 0L);
       log.info(response.toString());
       Thread.sleep(3000);
 
       // 不构建对象
       response = client.sendMarkdownMessage("业务报警:钉钉markdown消息支持的语法",
               markDownDemoText);
       Assert.assertEquals(response.getErrcode().longValue(), 0L);
       log.info(response.toString());
       Thread.sleep(3000);
 
       // 发送给指定人
       response = client.sendMarkdownMessage("业务报警:钉钉markdown消息支持的语法",
               markDownDemoText, new String[]{"15734078927"});
       Assert.assertEquals(response.getErrcode().longValue(), 0L);
       log.info(response.toString());
       Thread.sleep(3000);
       //发送给全体人
       response = client.sendMarkdownMessage("业务报警:钉钉markdown消息支持的语法",
               markDownDemoText, true);
       Assert.assertEquals(response.getErrcode().longValue(), 0L);
       log.info(response.toString());
       Thread.sleep(3000);
   }

SpringBoot整合钉钉消息推送(四十四)_ci_09

二.三.四 ActionCard 业务推送

@Test
    public void testSendActionCardMessage() throws InterruptedException {
        DingTalkResponse response = null;
 
        response = client.sendActionCardMessage(new ActionCardMessage("业务报警:This is title", "![screenshot](@lADOpwk3K80C0M0FoA)\n" +
                "**Apple Store** 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划"));
        Assert.assertEquals(response.getErrcode().longValue(), 0L);
        log.info(response.toString());
        Thread.sleep(3000);
 
        response = client.sendActionCardMessage("业务报警:This is title", "![screenshot](@lADOpwk3K80C0M0FoA)\n" +
                "**Apple Store** 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划");
        Assert.assertEquals(response.getErrcode().longValue(), 0L);
        log.info(response.toString());
        Thread.sleep(3000);
 
        response = client.sendActionCardMessage("业务报警:This is title", "![screenshot](@lADOpwk3K80C0M0FoA)\n" +
                        "**Apple Store** 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
                HideAvatarType.HIDE);
        Assert.assertEquals(response.getErrcode().longValue(), 0L);
        log.info(response.toString());
        Thread.sleep(3000);
 
        response = client.sendActionCardMessage("业务报警:This is title", "![screenshot](@lADOpwk3K80C0M0FoA)\n" +
                        "**Apple Store** 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
                ActionCardButton.defaultReadButton("https://www.dingtalk.com"));
        Assert.assertEquals(response.getErrcode().longValue(), 0L);
        log.info(response.toString());
        Thread.sleep(3000);
 
        response = client.sendActionCardMessage("业务报警:This is title", "![screenshot](@lADOpwk3K80C0M0FoA)\n" +
                        "**Apple Store** 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",
                HideAvatarType.HIDE,
                ActionCardButton.defaultReadButton("https://www.dingtalk.com"));
        Assert.assertEquals(response.getErrcode().longValue(), 0L);
        log.info(response.toString());
        Thread.sleep(3000);
 
    }

SpringBoot整合钉钉消息推送(四十四)_ci_10

二.三.五 FeedCard 消息推送

@Test
public void testSendFeedCardMessage() throws InterruptedException {
    DingTalkResponse response = null;
 
    ArrayList<FeedCardMessageItem> items = new ArrayList<>();
    items.add(new FeedCardMessageItem("业务报警:成为架构师的路上,看这一篇文章就足够了,因为……",
            "http://mp.weixin.qq.com/s/CPUaB60pue0Zf3fUL9xqvw",
            "https://mmbiz.qpic.cn/mmbiz_jpg/YriaiaJPb26VMtfgPvTsM9amH5hf3pmTbf40ia6OLE845icrDb0vt4AsMnTyva5mMMpwwxnkVR5UjCEI8ADvSic1qWQ/640"));
 
    items.add(new FeedCardMessageItem("业务报警:想成为一名Web开发者?你应该学习Node.js而不是PHP",
            "http://mp.weixin.qq.com/s/x8dm9e7gwLXSEzxE6sQYow",
            "https://mmbiz.qpic.cn/mmbiz_jpg/YriaiaJPb26VND0Q0hSBOoyVkr9cXQrFjWI7hOzax1IxIibqanXYD4W8nyeYX5iaicjgiaqia7ly94iawOsGwehbKGwGsA/640"));
 
    response = client.sendFeedCardMessage(new FeedCardMessage(items));
    Assert.assertEquals(response.getErrcode().longValue(), 0L);
    log.info(response.toString());
    Thread.sleep(3000);
 
    response = client.sendFeedCardMessage(items);
    Assert.assertEquals(response.getErrcode().longValue(), 0L);
    log.info(response.toString());
    Thread.sleep(3000);
}

SpringBoot整合钉钉消息推送(四十四)_ci_11

三. 钉钉业务消息Service 封装

也采用模板的方式进行处理

三.一 接口

public interface DingService {
	/**
	 * 发送普通的文本消息
	 *  @param toArr   发送人, 之间用 ,号分隔
	 * @param content 发送的内容, 普通文本内容
	 */
	boolean sendSimpleText(String[] toArr, String content);

	/**
	 * 发送邮件 velocity 模板邮件
	 * @param title   主题
	 * @param toArr                发送人
	 * @param dataMap              发送模板邮件填充数据
	 * @param templateName 模板名称
	 */
	boolean sendVelocityText(String title, String[] toArr, Map<String, Object> dataMap, String templateName);
}

三.二 接口实现

@Service
@Slf4j
public class DingServiceImpl implements DingService {
	@Autowired
	@Qualifier("dingTalkRobotClient")
	private DingTalkRobotClient client;

	@Value("${dingtalk.robot.webhook}")
	private String webhook;

	private VelocityEngine velocityEngine;
	

	
	@PostConstruct
	public void initVelocityEngine() {
		velocityEngine = new VelocityEngine();
		Properties p = new Properties();
		velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
		velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
		// 配置资源
		// velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "/usr/local/templates/");
		velocityEngine.init(p);
	}
	
	@Override
	public boolean sendSimpleText(String[] toArr, String content) {
		//发送信息
		try {
			TextMessage textMessage = new TextMessage(content,toArr);
			DingTalkResponse response = client.sendMessageByURL(webhook, textMessage);
			return response.getErrcode() == 0? true :false;
		} catch (Exception e) {
			log.error("componentAndSendReqeust simple mail error", e);
			return false;
		}
	}

	@Override
    public boolean sendVelocityText(String title, String[] toArr, Map<String, Object> dataMap, String templateName) {
		//发送信息
		try {
			String velocityMailText = getVelocityMailText(dataMap,templateName);
			MarkdownMessage markdownMessage = new MarkdownMessage(title,velocityMailText,toArr);
			DingTalkResponse response = client.sendMessageByURL(webhook, markdownMessage);
			return response.getErrcode() == 0? true :false;
		} catch (Exception e) {
			log.error("componentAndSendReqeust simple mail error", e);
			return false;
		}
    }

    private String getVelocityMailText(Map<String, Object> dataMap, String templateName) {
        VelocityContext velocityContext = new VelocityContext(dataMap);
        StringWriter writer = new StringWriter();
        velocityEngine.mergeTemplate(templateName, "UTF-8", velocityContext, writer);
        return writer.toString();
    }
}

三.三 服务测试

@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class ServiceTest {

    @Resource
    private DingService dingService;

    @Test
    public void simpleEmailTest() {
        String[] toArr = new String[]{"15734078927"};
        dingService.sendSimpleText(toArr, "钉钉发送消息");
        log.info(">>>钉钉发送消息成功");
    }

    @Test
    public void velocityTest() {
        String[] toArr = new String[]{"15734078927"};
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("line",System.lineSeparator());
        dataMap.put("title","你叫什么名称");
        dataMap.put("content","我叫岳泽霖,是一个快乐的程序员");
        dingService.sendVelocityText("md消息",toArr, dataMap,"interface_tenwhy.vm");
        log.info(">>>发送测试钉钉成功");
    }
}

本章节的代码放置在 github 上:



https://github.com/yuejianli/springboot/tree/develop/SpringBoot_Dingding



谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!