使用webhook推送消息给群中钉钉机器人或者用户_webhook推送工具-程序员宅基地

技术标签: java  SpringBoot  springboot  

项目中需要给企业微信群使用钉钉机器人定时提醒功能,特此整理设计开发方案demo如下。这里简单介绍发送功能,后期定时调度再陆续更新。

一、创建钉钉群

创建步骤请参考: 自定义机器人接入,创建好机器人后,复制出机器人的Webhook地址。

二、根据Webhook发送至群消息

import com.alibaba.fastjson.JSON;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

public class testSend {
    
    public static void main(String[] args) throws Exception {
    
        File[] disks = File.listRoots();
        long totalSpace = 0;
        long freeSpace = 0;
        for (File file : disks) {
    
            totalSpace += file.getTotalSpace();
            freeSpace += file.getFreeSpace();
        }
        double a = totalSpace / (1024 * 1024) / 1024;
        double b = freeSpace / (1024 * 1024) / 1024;
        double c = (b / a);
        if (c < 1) {
    
            // 钉钉的webhook
            String dingDingToken = "https://*.dingtalk.com/robot/send?access_token=***************";
            Map<String, Object> json = new HashMap();
            Map<String, Object> text = new HashMap();
            json.put("msgtype", "text");
            text.put("content", "磁盘的空间大小为:" + a + "G\n" + "磁盘的剩余空间大小为:" + b + "G\n剩余空间不足" + String.format("%.2f", c * 100) + "%");
            json.put("text", text);
            System.out.println(JSON.toJSONString(json));
            sendJSON(dingDingToken, JSON.toJSONString(json));
        }
    }
    public static String sendJSON(String url, String json) throws Exception {
    
        String res = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        HttpPost request = new HttpPost(url);
        StringEntity params = new StringEntity(json, HTTP.UTF_8);
        request.addHeader("content-type", "application/json");
        request.setEntity(params);
        CloseableHttpResponse response = httpClient.execute(request);
        res = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
        httpClient.close();
        return res;
    }
}

POM文件

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.2</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
    </dependencies>

三、发送给用户,进行钉钉提醒

package com.common.util;

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description: 钉钉工具类
 */
@Slf4j
@Component
public class DingDingUtil {
    
    private static String appKey;

    private static String appSecret;

    private static long agentId;

    private static String getTokenUrl;

    private static String userGetByMobile;

    private static String messageCorpConversationAsyncsend;

    private static String getHcmUserByAdAccountUrl;
    @Value("${dingding.appKey}")
    public void setAppKey(String appKey) {
    
        DingDingUtil.appKey = appKey;
    }
    @Value("${dingding.appSecret}")
    public void setAppSecret(String appSecret) {
    
        DingDingUtil.appSecret = appSecret;
    }
    @Value("${dingding.agentId}")
    public void setAgentId(long agentId) {
    
        DingDingUtil.agentId = agentId;
    }
    @Value("${dingding.getToken}")
    public void setGetTokenUrl(String getTokenUrl) {
    
        DingDingUtil.getTokenUrl = getTokenUrl;
    }
    @Value("${dingding.userGetByMobile}")
    public void setUserGetByMobile(String userGetByMobile) {
    
        DingDingUtil.userGetByMobile = userGetByMobile;
    }
    @Value("${dingding.messageCorpConversationAsyncsend}")
    public void setMessageCorpConversationAsyncsend(String messageCorpConversationAsyncsend) {
    
        DingDingUtil.messageCorpConversationAsyncsend = messageCorpConversationAsyncsend;
    }
    @Value("${bkpaas.getHcmUserByAdAccount}")
    public void setGetHcmUserByAdAccountUrl(String getHcmUserByAdAccountUrl) {
    
        DingDingUtil.getHcmUserByAdAccountUrl = getHcmUserByAdAccountUrl;
    }

    public static String getToken()
    {
    
        String token="";
        String logText="";
        try {
    
            DingTalkClient client = new DefaultDingTalkClient(getTokenUrl);
            OapiGettokenRequest req = new OapiGettokenRequest();
            req.setAppkey(appKey);
            req.setAppsecret(appSecret);
            req.setHttpMethod("GET");
            OapiGettokenResponse rsp = client.execute(req);
            System.out.println(rsp.getBody());
            String bodyStr=rsp.getBody();
            ObjectMapper mapper = new ObjectMapper();
            //Json映射为对象
            Map<String,String> bodyMap = mapper.readValue(bodyStr, Map.class);
            token=bodyMap.get("access_token");
        } catch (ApiException e) {
    
            logText=MessageFormat.format("钉钉获取access token失败,异常:{0}",e.getMessage());
        } catch (JsonParseException e) {
    
            logText=MessageFormat.format("钉钉获取access token失败,异常:{0}",e.getMessage());
        } catch (JsonMappingException e) {
    
            logText=MessageFormat.format("钉钉获取access token失败,异常:{0}",e.getMessage());
        } catch (IOException e) {
    
            logText=MessageFormat.format("钉钉获取access token失败,异常:{0}",e.getMessage());
        }
        if(!logText.equals(""))
            log.error(logText);
        return token;
    }

    public static String getUserId(String accessToken,String mobile)
    {
    
        String userId="";
        String logText="";
        try {
    
            DingTalkClient client = new DefaultDingTalkClient(userGetByMobile);
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(mobile);
            OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
            String bodyStr=rsp.getBody();
            ObjectMapper mapper = new ObjectMapper();
            //Json映射为对象
            Map<String,Object> bodyMap = mapper.readValue(bodyStr, Map.class);
            Map<String,Object> resultMap=(Map) bodyMap.get("result");
            userId=resultMap.get("userid").toString();
        } catch (ApiException e) {
    
            logText=MessageFormat.format("钉钉获取手机号{0}的user id失败,异常:{1}",mobile,e.getMessage());
        } catch (JsonParseException e) {
    
            logText=MessageFormat.format("钉钉获取手机号{0}的user id失败,异常:{1}",mobile,e.getMessage());
        } catch (JsonMappingException e) {
    
            logText=MessageFormat.format("钉钉获取手机号{0}的user id失败,异常:{1}",mobile,e.getMessage());
        } catch (IOException e) {
    
            logText=MessageFormat.format("钉钉获取手机号{0}的user id失败,异常:{1}",mobile,e.getMessage());
        }
        if(!logText.equals(""))
            log.error(logText);
        return userId;
    }

    public static String getMobileByUserAccount(String account)
    {
    
        String mobile="";
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        Request request = new Request.Builder()
                .url(getHcmUserByAdAccountUrl+"/"+account)
                .method("GET", null)
                .addHeader("Cookie", "szcrowd.token_key=\"yKKce-oz7AzCaiAAAAAAF4AGcy1zZmM=\"")
                .build();
        try {
    
            Response response = client.newCall(request).execute();
            String bodyStr= response.body().string();
            ObjectMapper mapper = new ObjectMapper();
            //Json映射为对象
            Map<String,Object> bodyMap = mapper.readValue(bodyStr, Map.class);
            Boolean result=(Boolean) bodyMap.get("result");
            if(result)
            {
    
                Map<String,Object> dataMap= (Map)bodyMap.get("data");
                mobile=dataMap.get("ding_mobile").toString();
                String logText= MessageFormat.format("获取域账号{0}的手机号{1}成功",account,mobile);
                log.info(logText);
            }
        } catch (IOException e) {
    
            String logText=MessageFormat.format("获取域账号{0}的手机号失败,异常:{1}",account,e.getMessage());
            log.error(logText);
        }
        return mobile;
    }

    /*
    * @Description: 通过手机号发送钉钉消息,目前支持文本(text)和Markdown消息(markdown,需提供标题)类型
    * @Param: [mobileList, msgType, msg, title]
    * @return: java.lang.Boolean
    **/
    public static Boolean sendMsgByMobileList(List<String> mobileList,String msgType,String msg,String title)
    {
    
        Boolean sendResult=false;
        try {
    
            String accessToken=getToken();
            //获取user id
            List<String> userIdList=new ArrayList<>();
            for (String mobile:mobileList) {
    
                String userId=getUserId(accessToken,mobile);
                userIdList.add(userId);
            }
            String userIdStr=String.join(",",userIdList);
            DingTalkClient client = new DefaultDingTalkClient(messageCorpConversationAsyncsend);
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(agentId);
            req.setToAllUser(false);
            req.setUseridList(userIdStr);
            OapiMessageCorpconversationAsyncsendV2Request.Msg obj1 = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            obj1.setMsgtype(msgType);
            OapiMessageCorpconversationAsyncsendV2Request.Text obj2 = new OapiMessageCorpconversationAsyncsendV2Request.Text();
            obj2.setContent(msg);
            obj1.setText(obj2);
            OapiMessageCorpconversationAsyncsendV2Request.Markdown obj3 = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
            obj3.setText(msg);
            obj3.setTitle(title);
            obj1.setMarkdown(obj3);
            req.setMsg(obj1);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, accessToken);
            System.out.println(rsp.getBody());
            sendResult=true;
        } catch (ApiException e) {
    
            String logText=MessageFormat.format("通过手机号发送钉钉消息失败,异常:{0}",e.getMessage());
            log.error(logText);
        }
        return sendResult;
    }

    /*
    * @Description: 通过员工域账号发送钉钉消息,目前支持文本(text)和Markdown消息(markdown,需提供标题)类型
    * @Param: [accountList, msgType, msg, title]
    **/
    public static Boolean sendMsgByDomainAccountList(List<String> accountList,String msgType,String msg,String title)
    {
    
        List<String> mobileList=new ArrayList<>();
        for (String account:accountList) {
    
            String mobile=getMobileByUserAccount(account);
            mobileList.add(mobile);
        }
        Boolean sendResult=sendMsgByMobileList(mobileList,msgType,msg,title);
        return sendResult;
    }
}

application.yml

server:
  port: 9002
  servlet:
    context-path: /testProject
dingding:
  appKey: dingxbgxp**********
  appSecret: NBpYiuPU3MNxK2fdo9VNshTURKYI2SjZVHzxbx**********
  agentId: 1211016099
  getToken: http://oapi.dingtalk.com.internal/gettoken
  userGetByMobile: http://oapi.dingtalk.com.internal/topapi/v2/*** 
  messageCorpConversationAsyncsend: http://oapi.dingtalk.com.internal/topapi/message/***    

BzAbnormalMsgPushController.java触发方法

package com.modules.bz.controller;

import com.common.api.vo.Result;
import com.common.aspect.annotation.AutoLog;
import com.common.util.DingDingUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 异常情况钉钉推送消息
 * @author: He JianPing
 */
@Slf4j
@RestController
@RequestMapping("/api/dingding")
@Api(value = "钉钉推送消息", tags = {
    "钉钉推送消息"})
public class BzAbnormalMsgPushController {
    

    @ApiOperation("推送数据校验异常消息")
    @AutoLog(value = "推送数据校验异常消息")
    @RequestMapping(value = "/push/verify", method = RequestMethod.POST)
    public Result getBgPanelIndex(String users,String msg)
    {
    
        Result<String> result=new Result<>();
        String [] usersArray=users.split(",");
        List<String> usersList= Arrays.asList(usersArray);
        DingDingUtil.sendMsgByDomainAccountList(usersList,"text",msg,"");
        result.setResult("OK");
        result.success("OK");
        return result;
    }
}

参考文章
https://blog.csdn.net/lonewolves/article/details/118598517
https://blog.csdn.net/weixin_37650458/article/details/105280528
https://blog.csdn.net/lonewolves/article/details/118598517

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jike11231/article/details/118795334

智能推荐

python命令行补全功能实现_python自动补全设置-程序员宅基地

文章浏览阅读678次。访问官网下载python源码3.6.7版本https://www.python.org/downloads/release/python-367/_python自动补全设置

FDQuery多表更新生成sql语句的问题-程序员宅基地

文章浏览阅读396次。query.sql='select a,b,c,d,e from a,b,c where ....';来源3个表,设计时添加字段列表,每个字段有Origin属性分别是a.a,b.b,c.c格式,表示该字段是那个表。 然后query.edit,query.post方法调用后,生成update或insert语句的时候,UPDATE ttdb.dbo.aSET [a.a] ..._fdquery.updateoptions

python做什么生意好找_Python 的练手项目有哪些值得推荐?-程序员宅基地

文章浏览阅读113次。一、不同的阶段,不同的练习我把IT编程类的学习,一般分为以下几个阶段:(以下为递进关系)程序逻辑阶段练习基本都是解答数学题,如万年历,斐波那契数列,完全数,鸡兔同笼问题。要求掌握循环、嵌套循环,二维数组熟练应用。面向对象阶段思维要从面向过程向面向对象,面向接口转变。没有一定代码量的基础,转不过,把面向过程的方法调用,参数传递,方法如何定义设计弄清楚,再转到类的设计,消息传递上。这个时候的练习走向综..._这是因为python的主要工作仍然是在较为深入的系统和框架层做设计和开发

【youcans 的 OpenCV 例程200篇】147. 图像分割之孤立点检测_opencv 孤立点-程序员宅基地

文章浏览阅读2.7k次,点赞2次,收藏16次。所谓图像分割是指根据灰度、彩色、空间纹理、几何形状等特征把图像划分成若干个互不相交的区域,使得这些特征在同一区域内表现出一致性或相似性,而在不同区域间表现出明显的不同。简单的说就是在一副图像中,把目标从背景中分离出来。从数学角度来看,图像分割是将数字图像划分成互不相交的区域的过程。图像分割的过程也是一个标记过程,即把属于同一区域的像索赋予相同的编号。_opencv 孤立点

NCL windows系统安装-程序员宅基地

文章浏览阅读1.5k次,点赞2次,收藏5次。http://www.doc88.com/p-192266283281.htmlNCL在Linux下的安装非常容易,只需下载适当版本的文件,设置好环境变量即可使用。NCL在Windows下的安装则要麻烦一些,需要先安装一个虚拟Linux环境(Cygwin/X)。本帖将按以下内容详细介绍NCL在Windows平台上的安装过程,希望仅具备Windows基本操作技能的用户也能轻松安装NCL。一..._nclwiq

【Android】 context.getSystemService()浅析-程序员宅基地

文章浏览阅读219次。同事在进行code review的时候问到我context中的getSystemService方法在哪实现的,他看到了一个ClipBoardManager来进行剪切板存储数据的工具方法中用到了context.getSystemService(),而此处我使用的是Application级别的Context进行调用的,可IDE跳转时发现当前类中的getSystemService()方法居然是抽象的,C..._商米 mcontext.getsystemservice(context.usb_service) getdevicelist

随便推点

ChatGPT和生成式AI的11大安全趋势-程序员宅基地

文章浏览阅读244次。来源:新智元近期爆火的 AI 聊天机器人 ChatGPT,以及文生图模型 Dall·E 2、Stable Diffusion 等,让生成式人工智能(generative AI)成功出圈。然而,技术的背后,也暗藏了一些不容忽视的风险。对安全团队而言,ChatGPT 和生成式人工智能究竟是福还是祸?最近,普华永道的分析师们对国外科技媒体 VentureBeat 分享了关于生成式人工智能和 ChatGP..._生成式ai安全评测

前端学习6:HTML链接_html超链接代码-程序员宅基地

文章浏览阅读6.4k次,点赞2次,收藏11次。在 HTML 中,我们使用来表示超链接。. 超链接(Hyperlink)是网页中最常见的元素之一,整个互联网都是基于超链接而构建的。超链接可以是一个字,一个词、或者一组词,也可以是一幅图画,您可以点击这些内容来跳转到新的文档或者当前文档中的某个部分。我们通过使用标签在HTML中创建链接。有两种使用标签的方式:1.通过使用href属性 - 创建指向另一个文档的链接2.通过使用name属性 - 创建文档的书签。_html超链接代码

mysql查4个表_mysql – 在SQL查询中加入4个表-程序员宅基地

文章浏览阅读380次。在我的数据库中有4个关系表,并希望加入它们以获得总价值…例如,我有朋友,家人,跟随和熟人,并希望加入这些以获得“全部”值.表格格式如下:友id follower following---------------------1 2 32 4 5家庭id follower following---------------------1 5 62 ..._mysql根据id查询4个一样的表

linux中操作mysql,linux系统中mysql的安装与基本操作(终端操作)-程序员宅基地

文章浏览阅读154次。本机系统为ubuntu系统1、安装安装命令:sudo apt-get install mysql-server在执行以上命令后,系统会提示输入mysql密码,输入两遍。这是最省事的办法,另外还有deb安装和rpm安装的方法,过程都比较复杂。2、验证是否安装成功登录mysqlmysql -u root -pcloud注意其中 ‘-u’后面的‘root’,为mysql的用户名;‘-p’后面的是安装过程..._linux下安装好mysql,使用mysql -uroot -p报错mysql: [error] unknown option '--

df的索引_df索引-程序员宅基地

文章浏览阅读4.6k次,点赞2次,收藏9次。df 的索引df = pd.DataFrame([[0, 2, 3], [0, 4, 1], [10, 20, 30]], index=[4, 5, 6], columns=['A', 'B', 'C']) A B C4 0 2 35 0 4 16 10 20 30# 获取某些列——用列名 得到的还是dfdf['A']4 05 06 10print(type(df['A']))<_df索引

qt pro工程转换成sln工程_qt zhuan sln-程序员宅基地

文章浏览阅读2.4k次。1.打开vs2017,点击qt vs tool,打开pro文件,如下图所示2.接着就可以看到输出的vc工程文件。问题:1.找不到mingw解决方案:下载mingw并且配置path。mingw的下载配置见https://blog.csdn.net/QIUCHUNHUIGE/article/details/89177834..._qt zhuan sln