釘釘機器人SDK 封裝預警消息發送工具


1 群機器人

    (1) 引言
    釘釘聊天群內支持的群機器人, 類似QQ 群機器人, 可以發天氣, 講笑話那樣;
    釘釘群機器人支持自定義機器人, 允許開發者管理機器人做預警消息通知;
    注意: 我沒重置access_token, demo支持消息發送, 但會發送到我這個群, 建議你們使用自己的webhook
    (2) 限制

  • 6 個機器人/每群, 20條消息/每分鍾
  • 不支持應答模式, 僅做群消息通知

    (3) 消息格式
    支持普通文本消息, 鏈接消息, markdown 格式(注意僅部分語法支持)文本, 圖片及鏈接, 支持FeedCard, ActionCard 等消息
    (4) 官方開發文檔
    https://open-doc.dingtalk.com/microapp/serverapi3/iydd5h

2 自定義機器人

2.1 創建機器人

    自定義機器人依賴於釘釘群, 首先創建釘釘群(群主有權限查看access_token), 拿到webhook 信息, 通過網絡發送請求, 釘釘開放平台響應請求發送預警消息到指定access_token 的釘釘群
    釘釘群創建方式是在聊天頁面, 點擊"+"添加其他人來創建一個釘釘群.
在這里插入圖片描述

圖2-1. 釘釘群創建圖

    進入群, 打開設置, 選中群機器人, 創建自定義機器人, 完善機器人基本信息后創建完成, 機器人自動推送一條歡迎語到釘釘群.
在這里插入圖片描述

圖2-2. 添加自定義機器人圖

在這里插入圖片描述

圖2-3. 創建自定義機器人圖

在這里插入圖片描述

圖2-4. 群機器人歡迎語圖
    查看群機器人, 可以看到當前釘釘群已有的機器人列表, 可以管理添加機器人, 移除機器人, 編輯已有機器人名稱,頭像; 其中群機器人支持關閉開啟消息推送和指定webhook 重置功能. webhook 可以理解為access_token 是身份標識, 此身份標識了指定群, 也標識了擁有群機器人消息推送的權限.

在這里插入圖片描述

圖2-5. 群機器人管理頁面圖
2.2 Postman 通過webhook 發送消息演示

    此處使用Postman 模擬請求, 如下所示, 發送普通文本消息后, 釘釘群會收到機器人的預警消息.
在這里插入圖片描述

圖2-6. Postman 通過webhook 發送普通文本消息圖

圖2-7. 群機器人發送消息成功圖

3 創建項目引入釘釘機器人SDK

    本機開發環境win10, 已創建釘釘群, 並獲取到webhook, 本機使用的IDEA, 下載的Java SDK

3.1 創建Maven 項目引入SDK

    (1)Java SDK 下載
    下載SDK: https://open-doc.dingtalk.com/microapp/faquestions/vzbp02, 官方支持以下版本, 此處使用Java SDK;

  • JAVA版本
  • PHP版本
  • .NET版
  • Python版
        解壓后是官方直接打好的jar 包, 也包括源碼包

    (2)創建Maven 項目引入Jar
    創建Maven 項目引入打好的jar 包: 本機jar 包地址: D:\download\dingtalk-sdk-java\taobao-sdk-java-auto_1479188381469-20190704.jar

  • mvn 命令

mvn install:install-file
-Dfile=D:\download\dingtalk-sdk-java\taobao-sdk-java-auto_1479188381469-20190704.jar -DgroupId=com.dingtalk -DartifactId=com-dingtalk-api
-Dversion=1.0.0 -Dpackaging=jar

  • 參數說明

-Dfile jar包所在路徑,需要包含jar包名.此處D:\download\dingtalk-sdk-java\taobao-sdk-java-auto_1479188381469-20190704.jar
-DgroupId 指定導入jar時的groupid,可以自定義,此處com.dingtalk
-DartifactId指定導入jar時的artifactId,可以自定義,此處com-dingtalk-api
-Dversion 指定導入jar時的版本號,可以自定義,此處1.0.0
-Dpackaging 指定文件類型 ,由於這里是jar包的形式,所以這里得是jar

[外鏈圖片轉存失敗(img-GQS8mBgB-1562409744840)(https://raw.githubusercontent.com/niaonao/ImageIcon/master/IDEAProject/DingTalk/dingding008.png)]

圖3-1. 項目引入SDK 圖
    (3)配置依賴, 如果項目沒有自動引入依賴,可以點擊reimport 重新加載依賴

在這里插入圖片描述

圖3-2. 重新加載依賴圖
3.2 預警消息發送工具類封裝
3.2.1 工具類說明

    項目成功引入SDK, 支持通過SDK 指定自定義機器人去發送群消息, 前面有說明群機器人支持發送多種類型的消息, 也支持消息帶跳轉鏈接, 或者圖片帶跳轉鏈接等;
    工具類創建客戶端client 實例需要擁有正確的webhook, 就是圖2-5. 群機器人管理頁面圖中群設置中可以查看或者重置的hook 標識.

    /**
     * 釘釘群設置 webhook, 支持重置
     */
    private static final String ACCESS_TOKEN = "https://oapi.dingtalk.com/robot/send?access_token=36ba0cc82d41d3c6aaef7d2c09c9f14de0727069edbc498b5c9d88edb72db227";
    /**
     * 消息類型
     */
    private static final String MSG_TYPE_TEXT = "text";
    private static final String MSG_TYPE_LINK = "link";
    private static final String MSG_TYPE_MARKDOWN = "markdown";
    private static final String MSG_TYPE_ACTION_CARD = "actionCard";
    private static final String MSG_TYPE_FEED_CARD = "feedCard";
    /**
     * 客戶端實例
     */
    public static DingTalkClient client = new DefaultDingTalkClient(ACCESS_TOKEN);

    util 下即封裝的工具類RobotHelperUtil.java, 其中test 包下有做單元測試

在這里插入圖片描述

圖3-3. 項目結構圖
3.3.2 測試發送消息

    此處單元測試測試方法sendMessageByMarkdown(), sendMessageByActionCardMulti(), sendMessageByFeedCard() 等方法, 群機器人會發送群消息, 其中方法參數title 效果如圖中左側(聯系人列表頁面)透出的消息內容, text 是進入群后的真正的消息.;

在這里插入圖片描述

圖3-4. 單元測試消息發送方法圖

在這里插入圖片描述

圖3-5. sendMessageByMarkdown 消息發送成功圖

    此處發送的支持單獨跳轉的消息, 初始化了三個按鈕附帶跳轉鏈接, 按鈕默認縱向排列. 點擊按鈕即可跳轉指定鏈接查看詳細內容.
在這里插入圖片描述

圖3-6. sendMessageByActionCardMulti 消息發送成功圖

    此處發送的支持多個Link 的消息, 初始化了三個link , 指定標題導圖及跳轉鏈接; 首個link 效果更突出, 這個還挺好玩的.
在這里插入圖片描述

圖3-7. sendMessageByFeedCard 消息發送成功圖
3.3 項目源碼
  • 工具類代碼:
package pers.niaonao.dingtalkrobot.util;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest ;
import com.dingtalk.api.response.OapiRobotSendResponse;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;

/**
 * @className: RobotHelperUtil
 * @description: 機器人工具類
 *      每個機器人每分鍾最多發送20條
 *      限制6 個機器人/群
 * @author: niaonao
 * @date: 2019/7/6
 **/
@Slf4j
public class RobotHelperUtil {

    /**
     * 釘釘群設置 webhook, 支持重置
     */
    private static final String ACCESS_TOKEN = "https://oapi.dingtalk.com/robot/send?access_token=36ba0cc82d41d3c6aaef7d2c09c9f14de0727069edbc498b5c9d88edb72db227";
    /**
     * 消息類型
     */
    private static final String MSG_TYPE_TEXT = "text";
    private static final String MSG_TYPE_LINK = "link";
    private static final String MSG_TYPE_MARKDOWN = "markdown";
    private static final String MSG_TYPE_ACTION_CARD = "actionCard";
    private static final String MSG_TYPE_FEED_CARD = "feedCard";

    /**
     * 客戶端實例
     */
    public static DingTalkClient client = new DefaultDingTalkClient(ACCESS_TOKEN);

    /**
     * @description: 官方演示示例
     *      title 是消息列表下透出的標題
     *      text 是進入群后看到的消息內容
     *
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static void sdkDemoJava() {
        DingTalkClient client = RobotHelperUtil.client;
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("text");
        OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
        text.setContent("測試文本消息");
        request.setText(text);
        OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
        at.setAtMobiles(Arrays.asList("13261303345"));
        request.setAt(at);

        request.setMsgtype("link");
        OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
        link.setMessageUrl("https://www.dingtalk.com/");
        link.setPicUrl("");
        link.setTitle("時代的火車向前開");
        link.setText("這個即將發布的新版本,創始人陳航(花名“無招”)稱它為“紅樹林”。\n" +
                "而在此之前,每當面臨重大升級,產品經理們都會取一個應景的代號,這一次,為什么是“紅樹林");
        request.setLink(link);

        request.setMsgtype("markdown");
        OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
        markdown.setTitle("杭州天氣");
        markdown.setText("#### 杭州天氣 @156xxxx8827\n" +
                "> 9度,西北風1級,空氣良89,相對溫度73%\n\n" +
                "> ![screenshot](https://gw.alipayobjects.com/zos/skylark-tools/public/files/84111bbeba74743d2771ed4f062d1f25.png)\n"  +
                "> ###### 10點20分發布 [天氣](http://www.thinkpage.cn/) \n");
        request.setMarkdown(markdown);
        try {
            client.execute(request);
        } catch (ApiException e) {
            log.error("[ApiException]: 消息發送演示示例, 異常捕獲{}", e.getMessage());
        }
    }

    /**
     * @description: 發送普通文本消息
     * @param content   文本消息
     * @param mobileList    指定@ 聯系人
     * @param isAtAll       是否@ 全部聯系人
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByText(String content, List<String> mobileList, boolean isAtAll) {
        if (StringUtils.isEmpty(content)) {
            return null;
        }

        //參數	參數類型	必須	說明
        //msgtype	String	是	消息類型,此時固定為:text
        //content	String	是	消息內容
        //atMobiles	Array	否	被@人的手機號(在content里添加@人的手機號)
        //isAtAll	bool	否	@所有人時:true,否則為:false
        OapiRobotSendRequest.Text text = new OapiRobotSendRequest.Text();
        text.setContent(content);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        if (!CollectionUtils.isEmpty(mobileList)) {
            // 發送消息並@ 以下手機號聯系人
            OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
            at.setAtMobiles(mobileList);
            at.setIsAtAll(isAtAll ? "true" : "false");
            request.setAt(at);
        }
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_TEXT);
        request.setText(text);

        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送普通文本消息]: 發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }

    /**
     * @description: 發送link 類型消息
     * @param title 消息標題
     * @param text  消息內容
     * @param messageUrl     點擊消息后跳轉的url
     * @param picUrl    插入圖片的url
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByLink(String title, String text, String messageUrl, String picUrl) {
        if (!DataValidUtil.checkNotEmpty(title, text, messageUrl)) {
            return null;
        }
        //參數	參數類型	必須	說明
        //msgtype	String	是	消息類型,此時固定為:link
        //title	String	是	消息標題
        //text	String	是	消息內容。如果太長只會部分展示
        //messageUrl	String	是	點擊消息跳轉的URL
        //picUrl	String	否	圖片URL
        OapiRobotSendRequest.Link link = new OapiRobotSendRequest.Link();
        link.setTitle(title);
        link.setText(text);
        link.setMessageUrl(messageUrl);
        link.setPicUrl(picUrl);

        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_LINK);
        request.setLink(link);

        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送link 類型消息]: 發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }


    /**
     * @description: 發送Markdown 編輯格式的消息
     * @param title 標題
     * @param markdownText  支持markdown 編輯格式的文本信息
     * @param mobileList    消息@ 聯系人
     * @param isAtAll   是否@ 全部
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByMarkdown(String title, String markdownText, List<String> mobileList, boolean isAtAll) {
        if (!DataValidUtil.checkNotEmpty(title, markdownText)) {
            return null;
        }
        //參數	類型	必選	說明
        //msgtype	String	是	此消息類型為固定markdown
        //title	String	是	首屏會話透出的展示內容
        //text	String	是	markdown格式的消息
        //atMobiles	Array	否	被@人的手機號(在text內容里要有@手機號)
        //isAtAll	bool	否	@所有人時:true,否則為:false
        OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
        markdown.setTitle(title);
        markdown.setText(markdownText);

        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_MARKDOWN);
        request.setMarkdown(markdown);
        if (!CollectionUtils.isEmpty(mobileList)) {
            OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
            at.setIsAtAll(isAtAll ? "true" : "false");
            at.setAtMobiles(mobileList);
            request.setAt(at);
        }

        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送link 類型消息]: 發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }

    /**
     * @description: 整體跳轉ActionCard類型的消息發送
     * @param title 消息標題, 會話消息會展示標題
     * @param markdownText  markdown格式的消息
     * @param singleTitle   單個按鈕的標題
     * @param singleURL 單個按鈕的跳轉鏈接
     * @param btnOrientation    是否橫向排列(true 橫向排列, false 縱向排列)
     * @param hideAvatar    是否隱藏發消息者頭像(true 隱藏頭像, false 不隱藏)
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByActionCardSingle(String title, String markdownText, String singleTitle, String singleURL, boolean btnOrientation, boolean hideAvatar) {
        if (!DataValidUtil.checkNotEmpty(title, markdownText)) {
            return null;
        }
        //參數	類型	必選	說明
        //    msgtype	string	true	此消息類型為固定actionCard
        //    title	string	true	首屏會話透出的展示內容
        //    text	string	true	markdown格式的消息
        //    singleTitle	string	true	單個按鈕的方案。(設置此項和singleURL后btns無效)
        //    singleURL	string	true	點擊singleTitle按鈕觸發的URL
        //    btnOrientation	string	false	0-按鈕豎直排列,1-按鈕橫向排列
        //    hideAvatar	string	false	0-正常發消息者頭像,1-隱藏發消息者頭像
        OapiRobotSendRequest.Actioncard actionCard = new OapiRobotSendRequest.Actioncard();
        actionCard.setTitle(title);
        actionCard.setText(markdownText);
        actionCard.setSingleTitle(singleTitle);
        actionCard.setSingleURL(singleURL);
        // 此處默認為0
        actionCard.setBtnOrientation(btnOrientation ? "1" : "0");
        // 此處默認為0
        actionCard.setHideAvatar(hideAvatar ? "1" : "0");

        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_ACTION_CARD);
        request.setActionCard(actionCard);
        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送ActionCard 類型消息]: 整體跳轉ActionCard類型的發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }

    /**
     * @description: 獨立跳轉ActionCard類型 消息發送
     * @param title 標題
     * @param markdownText  文本
     * @param btns  按鈕列表
     * @param btnOrientation    是否橫向排列(true 橫向排列, false 縱向排列)
     * @param hideAvatar    是否隱藏發消息者頭像(true 隱藏頭像, false 不隱藏)
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByActionCardMulti(String title, String markdownText, List<OapiRobotSendRequest.Btns> btns, boolean btnOrientation, boolean hideAvatar) {
        if (!DataValidUtil.checkNotEmpty(title, markdownText) || CollectionUtils.isEmpty(btns)) {
            return null;
        }
        //參數	類型	必選	說明
        //msgtype	string	true	此消息類型為固定actionCard
        //title	string	true	首屏會話透出的展示內容
        //text	string	true	markdown格式的消息
        //btns	array	true	按鈕的信息:title-按鈕方案,actionURL-點擊按鈕觸發的URL
        //btnOrientation	string	false	0-按鈕豎直排列,1-按鈕橫向排列
        //hideAvatar	string	false	0-正常發消息者頭像,1-隱藏發消息者頭像
        OapiRobotSendRequest.Actioncard actionCard = new OapiRobotSendRequest.Actioncard();
        actionCard.setTitle(title);
        actionCard.setText(markdownText);
        // 此處默認為0
        actionCard.setBtnOrientation(btnOrientation ? "1" : "0");
        // 此處默認為0
        actionCard.setHideAvatar(hideAvatar ? "1" : "0");

        actionCard.setBtns(btns);

        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_ACTION_CARD);
        request.setActionCard(actionCard);
        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送ActionCard 類型消息]: 獨立跳轉ActionCard類型發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }

    /** 
     * @description: 發送FeedCard類型消息
     * @param links
     * @return: com.dingtalk.api.response.OapiRobotSendResponse
     * @author: niaonao
     * @date: 2019/7/6
     */
    public static OapiRobotSendResponse sendMessageByFeedCard(List<OapiRobotSendRequest.Links> links) {
        if (CollectionUtils.isEmpty(links)) {
            return null;
        }

        //msgtype	string	true	此消息類型為固定feedCard
        //title	string	true	單條信息文本
        //messageURL	string	true	點擊單條信息到跳轉鏈接
        //picURL	string	true	單條信息后面圖片的URL
        OapiRobotSendRequest.Feedcard feedcard = new  OapiRobotSendRequest.Feedcard();
        feedcard.setLinks(links);
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype(RobotHelperUtil.MSG_TYPE_FEED_CARD);
        request.setFeedCard(feedcard);
        OapiRobotSendResponse response = new OapiRobotSendResponse();
        try {
            response = RobotHelperUtil.client.execute(request);
        } catch (ApiException e) {
            log.error("[發送ActionCard 類型消息]: 獨立跳轉ActionCard類型發送消息失敗, 異常捕獲{}", e.getMessage());
        }
        return response;
    }

    /*public static void main(String args[]) {
        sdkDemoJava();
    }*/
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM