之前一篇博文中,讲解了如何推送钉钉群消息,感兴趣的可以点击查看。

钉钉开发(一)——Java给钉钉群推送消息

在钉钉群内推送的消息是公共的,即使是@了某个人,群内每个人也还是都能看到。有时候我们并不希望以这种方式进行工作通知,而是希望以更加隐秘的方式,也就是工作通知的形式,推送给某个人。本篇博文,将讲解如何在Java后台中,推送钉钉工作通知。

1、打开钉钉开放平台,登录开发者后台,以管理员的方式登录。

2、登录后,创建企业内部应用,相关设置如下。需要注意的是,应用名称和应用图标,决定了日后推送的工作通知形式。

java 动态消息模板 java消息通知怎么做_推送

java 动态消息模板 java消息通知怎么做_java_02

3、创建应用之后,点击查看应用基本信息,保存应用凭证。

java 动态消息模板 java消息通知怎么做_java 动态消息模板_03

4、点击权限管理,配置该应用的权限。

java 动态消息模板 java消息通知怎么做_Java_04

权限默认为全部员工。如果选择部分员工的话,选择的部门中应该包括所有需要推送通知的人员。

此外,还需要开通的接口访问权限如下,均为【通讯录权限】

java 动态消息模板 java消息通知怎么做_java 动态消息模板_05

5、下载sdk,导入项目中

java 动态消息模板 java消息通知怎么做_java_06

6、至此,所有开发需要的准备工作已经妥当,下面可以着手进行后台的代码工作了。

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *@author: Chris.Mont
 *@date: 2021-06-07 10:53
 *@desc: 钉钉发送工作通知
 */
@Slf4j
@Service
public class DingWorkBiz {

    private String APP_KEY = "dingecf5x7vxxxxxxxxxx";
    private String APP_SECRET = "04EaZggxxxxxx0-T3E66Y27b9FRxxxxxxxxxxxxx6kydsDw";
    private Long AGENT_ID = 1210000099997L;

    private String MESSAGE_URL = "https://www.baidu.com";
    private String PC_MESSAGE_URL = "https://www.baidu.com";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:dd");

    /**
     * 获取AccessToken
     * @return  AccessToken
     * @throws ApiException
     */
    private String getAccessToken() throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        //Appkey
        request.setAppkey(APP_KEY);
        //Appsecret
        request.setAppsecret(APP_SECRET);
        /*请求方式*/
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    /**
     * 发送OA消息
     * @param mobile 发送消息人的电话,多个英文逗号拼接
     * @throws ApiException
     */
    public void sendOA(String mobile) throws ApiException {
        log.info("发送钉钉通知");
        String accessToken = getAccessToken();
        if(StringUtils.isBlank(mobile)){
            return;
        }
        //电话号码数组
        String[] split = mobile.split(",");
        for (String s : split) {
            DingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get_by_mobile");
            OapiUserGetByMobileRequest req = new OapiUserGetByMobileRequest();
            req.setMobile(s);
            req.setHttpMethod("GET");
            OapiUserGetByMobileResponse rsp = client2.execute(req, accessToken);
            //获取到Urid就是在公司里要发送到那个人的id
            String urid = rsp.getUserid();
            //根据用户id获取用户详情
            DingTalkClient userDetail = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
            OapiUserGetRequest userReq = new OapiUserGetRequest();
            userReq.setUserid(urid);
            userReq.setHttpMethod("GET");
            OapiUserGetResponse userRsp = userDetail.execute(userReq, accessToken);
            String userName = userRsp.getName();

            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
            request.setUseridList(urid);
            request.setAgentId(AGENT_ID);
            request.setToAllUser(false);

            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
            //跳转链接
            msg.getOa().setMessageUrl(MESSAGE_URL);
            msg.getOa().setPcMessageUrl(PC_MESSAGE_URL);
            //设置head
            msg.getOa().setHead(new OapiMessageCorpconversationAsyncsendV2Request.Head());
            msg.getOa().getHead().setText("待办事宜");
            msg.getOa().getHead().setBgcolor("00409eff");
            //设置body
            msg.getOa().setBody(new OapiMessageCorpconversationAsyncsendV2Request.Body());
            msg.getOa().getBody().setTitle("邮件现有功能已完成开发,抄送、密送以及发送异常处理暂未开始~!");
            msg.getOa().getBody().setContent("创建人:" + userName + "\n创建时间:" + sdf.format(new Date()));
            //消息类型
            msg.setMsgtype("oa");
            request.setMsg(msg);
            log.info("获取发送通知消息体和获取发送通知人完成");
            OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request,accessToken);
            log.info("发送消息是否成功"+response.isSuccess());
            System.out.println(response.isSuccess());
            log.info("消息任务ID"+response.getTaskId());
            System.out.println(response.getTaskId());
        }
    }


}

7、将项目密钥分别替换成真实的,最后发送效果如下

java 动态消息模板 java消息通知怎么做_java 动态消息模板_07

点击详情,弹出设置的超链接页面

java 动态消息模板 java消息通知怎么做_推送_08

这个详情,可以替换成其他链接,比如公司内部的OA链接,配合前端H5页面,就可以实现公司内部办公系统与钉钉的对接了。有些功能,比如公司审批流、工资条的推送等,都可以以这种方式推送消息,并直接进行处理。

需要注意的是,获取access_token的方法,钉钉返回的token有效时间为7200秒,且短时间内不支持重复调用。所以在实际应用中,最好是获取到token后,放入缓存中,比如Redis,设置失效时间。对于根据手机号获取用户钉钉id等方法也是同理。