钉钉-即时通讯-工作通知

news2024/9/27 21:21:49

钉钉-即时通讯-工作通知

  • 钉钉官方文档
  • 创建以及获取应用配置
  • 代码
    • 创建工作通知工具类
    • 创建钉钉消息实体类
    • 好了接下来就可以直接使用了

钉钉官方文档

https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages

创建以及获取应用配置

1.进入企业内部应用页面
在这里插入图片描述
在这里插入图片描述
2.记住下面的框起来的数据配置,后期的许多东西都是需要这些配置才可以正常的使用钉钉的
在这里插入图片描述
3.设置对应的应用支持那些权限可以查询官方文档查看需要开放那些权限
在这里插入图片描述

代码

创建工作通知工具类

发送工作通知 sendMessage
撤回工作通知revocationSendMessage
更新工作通知状态栏updateStatusWorkNotifications
configService 这个不用管主要是用于查询对应的钉钉相关配置数据 可选择删掉
redisCache 这个也是不用管主要是方便后期可能需要查询redis里面的一些缓存数据 可选择删掉


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.docer.common.core.redis.RedisCache;
import com.docer.common.utils.StringUtils;
import com.docer.comp.domain.vo.*;
import com.docer.comp.service.ICompRosterInfoService;
import com.docer.system.service.ISysConfigService;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import io.github.furstenheim.CopyDown;
import io.github.furstenheim.Options;
import io.github.furstenheim.OptionsBuilder;
import org.pegdown.PegDownProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.io.File;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 钉钉消息通知 工具类
 *
 */
@Component
public class DdMessageNotificationUtils {
    protected static final Logger logger = LoggerFactory.getLogger(DdMessageNotificationUtils.class);
    private static ISysConfigService configService;

    public static RedisCache redisCache;
    public static ICompRosterInfoService compRosterInfoService;

    //参数名
    public static final String APP_KEY = "appkey";
    public static final String APP_SECRET = "appsecret";
    public static final String AGENT_ID = "agentId";
    public static final String ACCESS_KEY = "accessKey";
    public static final String ACCESS_SECRET = "accessSecret";

    @Autowired
    public void setConfigService(ISysConfigService configService) {
        DdMessageNotificationUtils.configService = configService;
    }

    @Autowired
    public void setCompRosterInfoService(ICompRosterInfoService compRosterInfoService) {
        DdMessageNotificationUtils.compRosterInfoService = compRosterInfoService;
    }

    @Autowired
    public void setRedisCache(RedisCache redisCache) {
        DdMessageNotificationUtils.redisCache = redisCache;
    }

    /**
     * 获取钉钉AccessToken
     *
     * @return AccessToken
     * @throws Exception
     */
    public static String getAccessToken() throws ApiException {
        String appkey = configService.selectConfigByKey(APP_KEY);
        String appsecret = configService.selectConfigByKey(APP_SECRET);
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(appkey);
        request.setAppsecret(appsecret);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    /**
     * 获取钉钉AccessToken
     *
     * @return AccessToken
     * @throws Exception
     */
    public static String getAccessToken(String appkey, String appsecret) throws ApiException {
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(appkey);
        request.setAppsecret(appsecret);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    //================================================发送工作通知(https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages)=========================================================

    /**
     * 发送工作通知---如果用户人比较多可以增加按照部门进行发送后期添加吧
     * @param DingTalkUseridList接收者的userid列表,最大用户列表长度100。 196431404239053255
     * @param deptIdList 接收者的部门id列表,最大列表长度20。接收者是部门ID时,包括子部门下的所有用户
     * @param ddMessageVo 文本消息/图片消息/语音消息/文件消息/链接消息/OA消息/Markdown消息/卡片消息 { "msgtype": "text", "text": { "content": "请提交日报。" } }
     * @param to_all_user 是否发送给企业全部用户。
     * @return JSONArray.parseObject(oapiMessageCorpconversationAsyncsendV2Response.getBody(), Map.class).get("task_id")获取消息返回的任务id,建议保存到数据库方便以后撤回
     */
    public  OapiMessageCorpconversationAsyncsendV2Response sendMessage(String DingTalkUseridList, String deptIdList, @NotNull DdMessageVo ddMessageVo, Boolean to_all_user) throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(Long.valueOf(configService.selectConfigByKey(AGENT_ID)));
        //request.setAgentId(agentIdNew);
        request.setUseridList(DingTalkUseridList);
        request.setToAllUser(false);

        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();

        String msgType = ddMessageVo.getMsgType();//获取消息类型
        msg.setMsgtype(msgType);
        switch (msgType){
            case "text"://文本消息(text)消息内容,建议500字符以内。
                sendMessageText(ddMessageVo,request,msg);
                break;
            case "image"://图片消息
                sendMessageImage(ddMessageVo,request,msg);
                break;
            case "voice"://语音消息
                sendMessageVoice(ddMessageVo,request,msg);
                break;
            case "file"://文件消息
                sendMessageFile(ddMessageVo,request,msg);
                break;
            case "link"://链接消息
                sendMessageLink(ddMessageVo,request,msg);
                break;
            case "oa":
                sendMessageOa(ddMessageVo,request,msg);
                break;
            case "markdown"://markdown消息
                sendMessageMarkdown(ddMessageVo,request,msg);
                break;
            case "action_card"://ActionCard卡片消息
                sendMessageActionCard(ddMessageVo,request,msg);
                break;
        }
        OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, getAccessToken());
        //OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, getTokenNew());
        System.out.println(rsp.getBody());
        return rsp;
    }

    /**
     * 更新工作通知状态 @NotBlank
     * @param taskId 消息id
     * @param statusValue 状态栏值。 已同意
     * @param statusBg 状态栏背景色,推荐0xFF加六位颜色值 0xFF78C06E http://colorchange.wiicha.com/
     */
    public  OapiMessageCorpconversationStatusBarUpdateResponse updateStatusWorkNotifications(Long taskId,String statusValue,String statusBg) throws Exception {
        /**
         * 审批状态颜色参考
         * 已同意 0xFF78C06E
         * 已拒绝 0xFFF65E5E
         * 已撤销 0xFF858E99
         * 待审批 0xFFFF9D46
         */
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/status_bar/update");
        OapiMessageCorpconversationStatusBarUpdateRequest request = new OapiMessageCorpconversationStatusBarUpdateRequest();
        request.setAgentId(agentIdNew);
        request.setStatusValue(statusValue);
        request.setStatusBg(statusBg);
        request.setTaskId(taskId);
        OapiMessageCorpconversationStatusBarUpdateResponse response = client.execute(request,  getTokenNew());
        System.out.println(JSON.toJSONString(response));
        return response;
    }
    public  String toMarkdown(String markdown) {
        OptionsBuilder optionsBuilder = OptionsBuilder.anOptions();
        Options options = optionsBuilder.withBr("-")
                // more options
                .build();
        CopyDown converter = new CopyDown(options);
        return converter.convert(markdown);
    }
    /**
     * 发送ActionCard卡片消息
     * @param ddMessageVo
     * @param request
     * @param msg
     */
    private  void sendMessageActionCard(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setActionCard(new OapiMessageCorpconversationAsyncsendV2Request.ActionCard());
        msg.getActionCard().setTitle(ddMessageVo.getSecondLevel().getTitle());//透出到会话列表和通知的文案。
        String markdown = toMarkdown(ddMessageVo.getSecondLevel().getMarkdown());
        msg.getActionCard().setMarkdown(ddMessageVo.getSecondLevel().getMarkdown());//消息内容,支持markdown,语法参考标准markdown语法。建议1000个字符以内。
        msg.getActionCard().setSingleTitle(ddMessageVo.getSecondLevel().getSingleTitle());//使用整体跳转ActionCard样式时的标题。必须与single_url同时设置,最长20个字符。
        msg.getActionCard().setSingleUrl(ddMessageVo.getSecondLevel().getSingleUrl());//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接,最长500个字符。


        //设置 使用独立跳转ActionCard样式时的按钮列表;必须与btn_orientation同时设置,且长度不超过1000字符。
        msg.getActionCard().setBtnOrientation(ddMessageVo.getSecondLevel().getBtnOrientation());//使用独立跳转ActionCard样式时的按钮排列方式:0:竖直排列1:横向排列必须与btn_json_list同时设置。
        msg.getActionCard().setBtnJsonList(ddMessageVo.getSecondLevel().getBtnJsonList());
        request.setMsg(msg);
    }

    /**
     * 发送markdown消息
     * @param ddMessageVo
     * @param request
     * @param msg
     */
    private  void sendMessageMarkdown(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setMarkdown(new OapiMessageCorpconversationAsyncsendV2Request.Markdown());
        msg.getMarkdown().setTitle(ddMessageVo.getSecondLevel().getTitle());//首屏会话透出的展示内容。
        msg.getMarkdown().setText(ddMessageVo.getSecondLevel().getText());//markdown格式的消息,最大不超过5000字符。
        request.setMsg(msg);
    }

    /**
     * 发送oa消息  如果是发送工作通知消息,该参数会被替换为当前应用名称。 head.setText
     * @param ddMessageVo
     * @param request
     * @param msg
     * 已同意 0xFF78C06E
     * 已拒绝 0xFFF65E5E
     * 已撤销 0xFF858E99
     * 待审批 0xFFFF9D46
     */
    private  void sendMessageOa(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setOa(new OapiMessageCorpconversationAsyncsendV2Request.OA());
        OapiMessageCorpconversationAsyncsendV2Request.Head head = new OapiMessageCorpconversationAsyncsendV2Request.Head();
        head.setText(ddMessageVo.getSecondLevel().getHead().getText());//消息的头部标题。
        head.setBgcolor(
                StringUtils.isNotEmpty(ddMessageVo.getSecondLevel().getHead().getBgcolor())?(ddMessageVo.getSecondLevel().getHead().getBgcolor().replaceAll("#","FF")):ddMessageVo.getSecondLevel().getHead().getBgcolor()
        );//消息头部的背景颜色。
        msg.getOa().setHead(head);
        msg.getOa().setStatusBar(new OapiMessageCorpconversationAsyncsendV2Request.StatusBar());//消息状态栏,只支持接收者的userid列表,userid最多不能超过5个人。
        msg.getOa().getStatusBar().setStatusBg(
                StringUtils.isNotEmpty(ddMessageVo.getSecondLevel().getStatusBar().getStatusBg())?(ddMessageVo.getSecondLevel().getStatusBar().getStatusBg().replaceAll("#","0xFF")

                ):ddMessageVo.getSecondLevel().getStatusBar().getStatusBg()
        );//状态栏背景色,默认为黑色,推荐0xFF加六位颜色值。 0xFFE71919
        msg.getOa().getStatusBar().setStatusValue(ddMessageVo.getSecondLevel().getStatusBar().getStatusValue());//状态栏文案。  进行中

        msg.getOa().setBody(new OapiMessageCorpconversationAsyncsendV2Request.Body());
        DdMessageInternalBodyVo body = ddMessageVo.getSecondLevel().getBody();
        msg.getOa().getBody().setTitle(body.getTitle());//消息体的标题,建议50个字符以内。

        //form
        msg.getOa().getBody().setForm(ddMessageVo.getSecondLevel().getBody().getForm());
        msg.getOa().getBody().setRich(ddMessageVo.getSecondLevel().getBody().getRich());
        msg.getOa().getBody().setContent(ddMessageVo.getSecondLevel().getBody().getContent());//消息体的内容,最多显示3行。
        msg.getOa().getBody().setImage(ddMessageVo.getSecondLevel().getBody().getImage());//消息体中的图片,支持图片资源@mediaId。建议宽600像素 x 400像素,宽高比3 : 2。
        msg.getOa().getBody().setFileCount(ddMessageVo.getSecondLevel().getBody().getFileCount());
        msg.getOa().getBody().setAuthor(ddMessageVo.getSecondLevel().getBody().getAuthor());
        //msg.getOa().getBody().getForm()

        msg.getOa().setMessageUrl(ddMessageVo.getSecondLevel().getMessageUrl());
        msg.getOa().setPcMessageUrl(ddMessageVo.getSecondLevel().getPcMessageUrl());
        request.setMsg(msg);
    }

    /**
     * 发送链接消息
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param ddMessageVo 发送消息实体类存储对象
     * @param request
     * @param msg
     */
    private  void sendMessageLink(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
        msg.getLink().setTitle(ddMessageVo.getSecondLevel().getTitle());//消息标题,建议100字符以内。
        msg.getLink().setText(ddMessageVo.getSecondLevel().getText());//消息描述,建议500字符以内。
        msg.getLink().setMessageUrl(ddMessageVo.getSecondLevel().getMessageUrl());//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接。
        msg.getLink().setPicUrl(ddMessageVo.getSecondLevel().getPicUrl());
        request.setMsg(msg);
    }

    /**
     * 发送文本消息
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param ddMessageVo 发送消息实体类存储对象
     * @param request
     * @param msg
     */
    private  void sendMessageText(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
        msg.getText().setContent(ddMessageVo.getSecondLevel().getContent());
        request.setMsg(msg);
    }

    /**
     * 发送图片消息
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param ddMessageVo 发送消息实体类存储对象
     * @param request
     * @param msg
     */
    private  void sendMessageImage(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
        String mediaId = ddMessageVo.getSecondLevel().getMediaId();
        msg.getImage().setMediaId(mediaId);//设置媒体文件mediaid,建议宽600像素 x 400像素,宽高比3 : 2。
        request.setMsg(msg);
    }

    /**
     * 发送语音消息
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param ddMessageVo 发送消息实体类存储对象
     * @param request
     * @param msg
     */
    private  void sendMessageVoice(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setVoice(new OapiMessageCorpconversationAsyncsendV2Request.Voice());
        msg.getVoice().setMediaId(ddMessageVo.getSecondLevel().getMediaId());//媒体文件ID
        //msg.getVoice().setDuration(ddMessageVo.getSecondLevel().getDuration());//正整数,小于60,表示音频时长。
        msg.getVoice().setDuration("90");
        request.setMsg(msg);
    }

    /**
     * 发送文件消息
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param ddMessageVo 发送消息实体类存储对象
     * @param request
     * @param msg
     */
    private  void sendMessageFile(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setFile(new OapiMessageCorpconversationAsyncsendV2Request.File());
        msg.getFile().setMediaId(ddMessageVo.getSecondLevel().getMediaId());//媒体文件ID,引用的媒体文件最大10MB。
        request.setMsg(msg);
    }

    /**
     * 上传媒体文件
     * https://open.dingtalk.com/document/orgapp/message-types-and-data-format
     * @param type image:图片,图片最大20MB。支持上传jpg、gif、png、bmp格式。
     *             voice:语音,语音文件最大2MB。支持上传amr、mp3、wav格式。
     *             video:视频,视频最大20MB。支持上传mp4格式。
     *             file:普通文件,最大20MB。支持上传doc、docx、xls、xlsx、ppt、pptx、zip、pdf、rar格式。
     * @param filePath 本地文件路径
     * @param file 文件
     */
    public  OapiMediaUploadResponse uploadMediaFiles(String type, String filePath, File file) throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/media/upload");
        OapiMediaUploadRequest req = new OapiMediaUploadRequest();
        req.setType(type);
        // 要上传的媒体文件
        FileItem item = new FileItem(filePath);
        req.setMedia(item);
        OapiMediaUploadResponse rsp = client.execute(req, getAccessToken());
        System.out.println(rsp.getBody());
        return rsp;
    }

    /**
     * 撤回通知 仅支持撤回24小时内的工作消息通知。
     * @param msgTaskId 发送消息时钉钉返回的任务ID。
     */
    public  OapiMessageCorpconversationRecallResponse revocationSendMessage(Long msgTaskId) throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/recall");
        OapiMessageCorpconversationRecallRequest req = new OapiMessageCorpconversationRecallRequest();
        req.setAgentId(Long.valueOf(configService.selectConfigByKey(AGENT_ID)));
        req.setMsgTaskId(msgTaskId);
        OapiMessageCorpconversationRecallResponse rsp = client.execute(req, getAccessToken());
        return rsp;
    }






    //=================================================================================测试================================================================================
    private static Long agentIdNew = **************;
    private static String appkeyNew = "**************";
    private static String appsecretNew = "**************-**************";
    private static String corpIdNew = "**************";

    public static String getTokenNew() throws Exception {
        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest request = new OapiGettokenRequest();
        request.setAppkey(appkeyNew);
        request.setAppsecret(appsecretNew);
        request.setHttpMethod("GET");
        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    public static void main(String[] args) throws Exception {
        //工作通知
        DdMessageVo ddMessageVo = new DdMessageVo();
        assembleAction_cardTest(ddMessageVo);
        OapiMessageCorpconversationAsyncsendV2Response oapiMessageCorpconversationAsyncsendV2Response = sendMessageTest(**************, null, ddMessageVo, false);
        Map map = JSONArray.parseObject(oapiMessageCorpconversationAsyncsendV2Response.getBody(), Map.class);
        Object task_id = map.get("task_id");
        System.out.println("结果 = " + oapiMessageCorpconversationAsyncsendV2Response.getBody());

        //互动卡片


    }

    public static OapiMessageCorpconversationAsyncsendV2Response sendMessageTest(String useridList, String deptIdList, @NotNull DdMessageVo ddMessageVo, Boolean to_all_user) throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setAgentId(agentIdNew);
        request.setUseridList(useridList);
        request.setToAllUser(false);

        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();

        String msgType = ddMessageVo.getMsgType();//获取消息类型
        msg.setMsgtype(msgType);
        switch (msgType){
            case "text"://文本消息(text)消息内容,建议500字符以内。
               // sendMessageText(ddMessageVo,request,msg);
                break;
            case "image"://图片消息
                //sendMessageImage(ddMessageVo,request,msg);
                break;
            case "voice"://语音消息
               // sendMessageVoice(ddMessageVo,request,msg);
                break;
            case "file"://文件消息
                //sendMessageFile(ddMessageVo,request,msg);
                break;
            case "link"://链接消息
               // sendMessageLink(ddMessageVo,request,msg);
                break;
            case "oa":
                //sendMessageOa(ddMessageVo,request,msg);
                break;
            case "markdown"://markdown消息
                //sendMessageMarkdown(ddMessageVo,request,msg);
                break;
            case "action_card"://ActionCard卡片消息
                sendMessageActionCardTest(ddMessageVo,request,msg);
                break;
        }
        OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, getTokenNew());
        System.out.println(rsp.getBody());
        return rsp;
    }
    private static void sendMessageActionCardTest(DdMessageVo ddMessageVo, OapiMessageCorpconversationAsyncsendV2Request request, OapiMessageCorpconversationAsyncsendV2Request.Msg msg) {
        msg.setActionCard(new OapiMessageCorpconversationAsyncsendV2Request.ActionCard());
        msg.getActionCard().setTitle(ddMessageVo.getSecondLevel().getTitle());//透出到会话列表和通知的文案。
        msg.getActionCard().setMarkdown(ddMessageVo.getSecondLevel().getMarkdown());//消息内容,支持markdown,语法参考标准markdown语法。建议1000个字符以内。
        msg.getActionCard().setSingleTitle(ddMessageVo.getSecondLevel().getSingleTitle());//使用整体跳转ActionCard样式时的标题。必须与single_url同时设置,最长20个字符。
        msg.getActionCard().setSingleUrl(ddMessageVo.getSecondLevel().getSingleUrl());//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接,最长500个字符。


        //设置 使用独立跳转ActionCard样式时的按钮列表;必须与btn_orientation同时设置,且长度不超过1000字符。
        msg.getActionCard().setBtnOrientation(ddMessageVo.getSecondLevel().getBtnOrientation());//使用独立跳转ActionCard样式时的按钮排列方式:0:竖直排列1:横向排列必须与btn_json_list同时设置。
        msg.getActionCard().setBtnJsonList(ddMessageVo.getSecondLevel().getBtnJsonList());
        request.setMsg(msg);
    }
    /**
     *
     * @param ddMessageVo
     */
    private static void assembleAction_cardTest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("action_card");
        DdMessageInternalVo ddMessageInternalVo = new DdMessageInternalVo();
        ddMessageInternalVo.setMarkdown("书写Markdown文本");
        ddMessageInternalVo.setTitle("测试标题(透出到会话列表和通知的文案)。");
        //ddMessageInternalVo.setSingleTitle("查看详情");//(使用整体跳转ActionCard样式时的标题。必须与single_url同时设置,最长20个字符。)
        //ddMessageInternalVo.setSingleUrl("https://baijiahao.baidu.com/s?id=1805550025058783239");//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接,最长500个字符。
        ddMessageInternalVo.setBtnOrientation("1");//使用独立跳转ActionCard样式时的按钮排列方式:
        List<OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList> ddMessageInternalBtnJsonListVoArrayList = new ArrayList<>();

        OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList ddMessageInternalBtnJsonListVo = new OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList();
        ddMessageInternalBtnJsonListVo.setActionUrl("https://baike.baidu.com/item/2024%E5%B9%B4%E5%B7%B4%E9%BB%8E%E5%A5%A5%E8%BF%90%E4%BC%9A%E5%BC%80%E5%B9%95%E5%BC%8F/59471777?fr=api_baidu_opex_festival");
        ddMessageInternalBtnJsonListVo.setTitle("1");
        ddMessageInternalBtnJsonListVoArrayList.add(ddMessageInternalBtnJsonListVo);

        OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList ddMessageInternalBtnJsonListVo1 = new OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList();
        ddMessageInternalBtnJsonListVo1.setActionUrl("https://baijiahao.baidu.com/s?id=1805550025058783239");
        ddMessageInternalBtnJsonListVo1.setTitle("2");
        ddMessageInternalBtnJsonListVoArrayList.add(ddMessageInternalBtnJsonListVo1);

        OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList ddMessageInternalBtnJsonListVo2 = new OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList();
        ddMessageInternalBtnJsonListVo2.setActionUrl("https://baijiahao.baidu.com/s?id=1805550025058783239");
        ddMessageInternalBtnJsonListVo2.setTitle("3");
        ddMessageInternalBtnJsonListVoArrayList.add(ddMessageInternalBtnJsonListVo2);

        ddMessageInternalVo.setBtnJsonList(ddMessageInternalBtnJsonListVoArrayList);
        ddMessageVo.setSecondLevel(ddMessageInternalVo);
    }

    /**
     * 只需要MsgType   Title标题   Text内容
     * @param ddMessageVo
     */
    private  void assembleMarkdownTest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("markdown");
        DdMessageInternalVo ddMessageInternalVo = new DdMessageInternalVo();
        ddMessageInternalVo.setTitle("首屏会话透出的展示内容");
        ddMessageInternalVo.setText("# 这是支持markdown的文本   \n   ## 标题2    \n   * 列表1   \n  ![alt 啊](https://img.alicdn.com/tps/TB1XLjqNVXXXXc4XVXXXXXXXXXX-170-64.png)");
        ddMessageVo.setSecondLevel(ddMessageInternalVo);
    }

    /**
     *
     * @param ddMessageVo
     */
    private  void assembleOATest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("oa");
        DdMessageInternalVo secondLevel = new DdMessageInternalVo();
        secondLevel.setMessageUrl("https://open.dingtalk.com/document/orgapp/message-types-and-data-format");//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接。
        secondLevel.setPcMessageUrl("https://oa.dingtalk.com/contacts.htm#/contacts");//PC端点击消息时跳转到的地址。
        secondLevel.setHead(new DdMessageInternalHeadVo("FFBBBBBB","头部标题3333"));
        secondLevel.setStatusBar(new DdMessageInternalStatusBarVo("进行中啦","0xFFF65E5E"));
        DdMessageInternalBodyVo ddMessageInternalBodyVo = new DdMessageInternalBodyVo();
        ddMessageInternalBodyVo.setTitle("正文内容1");//消息体的标题,建议50个字符以内。
        List<OapiMessageCorpconversationAsyncsendV2Request.Form> formList = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            OapiMessageCorpconversationAsyncsendV2Request.Form form = new OapiMessageCorpconversationAsyncsendV2Request.Form();
            form.setKey("姓名1"+i);//消息体的关键字。
            form.setValue("张三1"+i);//消息体的关键字对应的值。
            formList.add(form);
        }
        ddMessageInternalBodyVo.setForm(formList);
        OapiMessageCorpconversationAsyncsendV2Request.Rich rich = new OapiMessageCorpconversationAsyncsendV2Request.Rich();
        rich.setNum("20(单行富文本信息的数目1)");
        rich.setUnit("测试元(单行富文本信息的单位1)");
        ddMessageInternalBodyVo.setRich(rich);
        ddMessageInternalBodyVo.setContent("大段文本(消息体的内容,最多显示3行。1)");
        ddMessageInternalBodyVo.setImage("@lALPDeC3BFrUFVrNAtDNAtA");//消息体中的图片,支持图片资源@mediaId。建议宽600像素 x 400像素,宽高比3 : 2。
        ddMessageInternalBodyVo.setFileCount("10");
        ddMessageInternalBodyVo.setAuthor("作者李四1");
        secondLevel.setBody(ddMessageInternalBodyVo);
        ddMessageVo.setSecondLevel(secondLevel);
    }

    /**
     *
     * @param ddMessageVo
     */
    private  void assembleLinkTest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("link");
        DdMessageInternalVo secondLevel = new DdMessageInternalVo();
        secondLevel.setText("消息描述,建议500字符以内");//消息描述,建议500字符以内
        secondLevel.setTitle("消息标题,建议100字符以内。");
        secondLevel.setPicUrl("@lALPDeC3BFrUFVrNAtDNAtA");//
        secondLevel.setMessageUrl("https://open.dingtalk.com/document/orgapp/message-types-and-data-format");//消息点击链接地址,当发送消息为小程序时支持小程序跳转链接。
        ddMessageVo.setSecondLevel(secondLevel);
    }

    /**
     * 测试组装数据
     * @param ddMessageVo
     */
    private  void assembleTextTest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("text");
        DdMessageInternalVo secondLevel = new DdMessageInternalVo();
        secondLevel.setContent("测试发送消息");
        ddMessageVo.setSecondLevel(secondLevel);
    }

    private  void assembleImageTest(DdMessageVo ddMessageVo) {
        ddMessageVo.setMsgType("image");
        DdMessageInternalVo secondLevel = new DdMessageInternalVo();
        secondLevel.setMediaId("@lALPDeC3BFrUFVrNAtDNAtA");
        ddMessageVo.setSecondLevel(secondLevel);
    }
}

创建钉钉消息实体类

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 钉钉消息实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DdMessageVo {

    /**
     * 钉钉的userId,发送给谁 todo
     * 这个字段占时没有用到后期可以将 sendMessage方法里面的String DingTalkUseridList替换掉
     * 并且可以考虑后期添加部门的字段来替换sendMessage方法里面的String deptIdList
     */
    private String dingDingUserID;
    private String msgType;
    private DdMessageInternalVo secondLevel;
}


import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DdMessageInternalVo {
    /**
     *
     */
    private String content;

    /**
     * 媒体文件mediaid
     */
    private String mediaId;

    /**
     * 正整数,小于60,表示音频时长。
     */
    private String duration;

    /**
     * 消息点击链接地址,当发送消息为小程序时支持小程序跳转链接。
     */
    private String messageUrl;

    /**
     * 媒体文件 图片
     */
    private String picUrl;

    /**
     *
     */
    private String title;

    private String text;

    private String pcMessageUrl;
    private String image;


    /**
     * OA 消息头部内容。
     */
    private DdMessageInternalHeadVo head;

    /**
     * OA 消息体。
     */
    private DdMessageInternalBodyVo body;

    /**
     * 消息内容,支持markdown,语法参考标准markdown语法。建议1000个字符以内。
     */
    private String markdown;
    /**
     * 使用整体跳转ActionCard样式时的标题。必须与single_url同时设置,最长20个字符。
     */
    private String singleTitle;
    /**
     * 消息点击链接地址,当发送消息为小程序时支持小程序跳转链接,最长500个字符。
     */
    private String singleUrl;

    /**
     * 使用独立跳转ActionCard样式时的按钮排列方式:必须与btn_json_list同时设置。0:竖直排列1:横向排列
     */
    private String btnOrientation;
    /**
     * 使用独立跳转ActionCard样式时的按钮列表;必须与btn_orientation同时设置,且长度不超过1000字符。
     */
    private List<OapiMessageCorpconversationAsyncsendV2Request.BtnJsonList> btnJsonList;

    /**
     * 消息状态栏,只支持接收者的userid列表,userid最多不能超过5个人。
     */
    private DdMessageInternalStatusBarVo statusBar;

}

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DdMessageInternalHeadVo {
    /**
     * 头部标题颜色 消息头部的背景颜色。长度限制为8个英文字符,其中前2为表示透明度,后6位表示颜色值。不要添加0x。
     */
    private String bgcolor;
    /**
     * 头部标题
     */
    private String text;
}


import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DdMessageInternalBodyVo {
    /**
     * 正文标题 消息体的标题,建议50个字符以内。
     */
    private String title;
    /**
     * 消息体的表单,最多显示6个,超过会被隐藏。 key消息体的关键字。 value消息体的关键字对应的值。
     */
    private List<OapiMessageCorpconversationAsyncsendV2Request.Form> form;

    /**
     * 单行富文本信息
     */
    private OapiMessageCorpconversationAsyncsendV2Request.Rich rich;

    /**
     * 消息体的内容,最多显示3行。
     */
    private String content;
    /**
     * 消息体中的图片,支持图片资源@mediaId。建议宽600像素 x 400像素,宽高比3 : 2。
     */
    private String image;
    /**
     * 自定义的附件数目。此数字仅供显示,钉钉不作验证。
     */
    private String fileCount;
    /**
     * 自定义的作者名字。
     */
    private String author;

}


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 消息状态栏,只支持接收者的userid列表,userid最多不能超过5个人。
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DdMessageInternalStatusBarVo {
    /**
     * 状态栏文案。  进行中
     */
    private String statusValue;
    /**
     * 状态栏背景色,默认为黑色,推荐0xFF加六位颜色值。 0xFFF65E5E
     */
    private String statusBg;
}

好了接下来就可以直接使用了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最大池化、非线性激活、线性层

一、最大池化原理 二、最大池化实例 import torch import torchvision from torch import nn from torch.nn import MaxPool2d from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterdataset torchvision.datasets.CIFAR10("../c…

springboot+vue+mybatis计算机房屋服务平台+PPT+论文+讲解+售后

近些年来&#xff0c;随着科技的飞速发展&#xff0c;互联网的普及逐渐延伸到各行各业中&#xff0c;给人们生活带来了十分的便利&#xff0c;房屋中介服务平台利用计算机网络实现信息化管理&#xff0c;使整个房屋中介服务的发展和服务水平有显著提升。 本文拟采用Eclipse开发…

Datawhale X 李宏毅苹果书 AI夏令营第五期 DL进阶方向 Task2笔记

Datawhale X 李宏毅苹果书 向李宏毅学深度学习&#xff08;进阶&#xff09; 是 Datawhale 2024 年 AI 夏令营第五期的学习活动&#xff08;“深度学习 进阶”方向&#xff09; 往期task1链接&#xff1a;深度学习进阶-Task1 我做的task1的笔记博客&#xff1a;传送门 Datawhal…

Tensorflow实现深度学习8:猫狗识别

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 导入数据 import matplotlib.pyplot as plt import tensorflow as tf # 支持中文 plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] Fals…

开放式耳机会漏音吗?开放式耳机测评

开放式耳机由于其独特的设计&#xff0c;允许声音在一定程度上自然地与外界环境融合。这种设计带来的一个常见误解是&#xff0c;人们可能会认为开放式耳机会有较大的声音泄露。然而&#xff0c;实际上&#xff0c;高质量的开放式耳机通过精心的声学设计&#xff0c;可以有效地…

Video Recording,视频录制

一.录屏软件 1.1 Xbox Game Bar 对于 win 来说&#xff0c;快捷键是 Win G&#xff0c;即可以启动 Xbot Game Bar 来进行录制。但是有一个比较致命的缺点就是&#xff0c;当我们切换页面的时候&#xff0c;录制就会失败&#xff0c;这款还是很适合于单页面的视频录制。 1.2 …

Python以及Python历史版本的安装的安装

文章目录 前言Python的安装Python历史版本下载总结 前言 Python 是一种广泛使用的高级编程语言&#xff0c;以其简洁易读的语法和强大的功能而受到开发者的青睐。从数据分析到网页开发&#xff0c;从自动化脚本到人工智能&#xff0c;Python 的应用领域几乎无处不在。然而&…

深度学习论文被评“创新性不足、工作量不够”怎么办?

投稿时遇到审稿人提出文章创新性不足、工作量不够&#xff0c;该怎么办&#xff1f; 今天我就来分享三种应对方法&#xff1a;下采样策略、归一化策略、改进网络模型。 改进网络模型 增加创新性&#xff1a; 从模型架构和训练策略这两方面入手&#xff1a; 模型架构创新&a…

c++ 135 错误: 成员函数的作用 内存四区

1。 类中不写成员函数 现在要求c1 的属性 原来怎么求的&#xff1a; 虽然把r改成10 但是没有执行area的那句话 area还是一个未知变量 当执行c1.area时 只是内存变量标示的内存空间拿值 跟r10 没有半毛钱关系 面向过程转换成面向对象

代码随想录 | 贪心算法总结

贪心理论基础 在贪心系列开篇词贪心算法理论基础中&#xff0c;我们就讲解了大家对贪心的普遍疑惑。 贪心很简单&#xff0c;就是常识&#xff1f; 贪心思路往往很巧妙&#xff0c;并不简单。 贪心有没有固定的套路&#xff1f; 贪心无套路&#xff0c;也没有框架之类的&a…

MarsCode代码练习能力初体验

MarsCode代码练习能力初体验 地址&#xff1a;https://sourl.cn/JJeBEF 最近MarsCode上线了代码练习能力&#xff0c;对准备算法题的同学来说是一个福音。下面是编程主界面。 除了左边内置的算法外&#xff0c;还可以手动添加题目自己练习&#xff0c;AI会去理解题目&#xf…

Java整体基础知识体系图

一 java 介绍 ‌Java是一种高级编程语言&#xff0c;由Sun Microsystems公司于1995年推出。‌ Java具有跨平台性、面向对象、健壮性、安全性、可移植性等特点&#xff0c;被广泛应用于企业级应用开发、移动应用开发、大数据处理、云计算等领域。Java程序可以在不同的操作系统上…

鸿蒙开发—黑马云音乐之music页面播放音乐(上)

目录 1.封装播放对象管理类 2.musicPage中调用AvPlayerManager完成播放歌曲 3.index.ets的播放信息样式 4.musicPage向index传数据 1.封装播放对象管理类 封装一个播放对象&#xff0c;之后播放音乐直接调用该对象。 src/main/ets/services/AvPlayerManager.ets&#xff…

本地Linux系统搭建Plik临时文件上传站点并实现远程访问共享文件

文章目录 前言1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 前言 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设…

虚幻地形高度图生成及测试

虚幻地形高度图生成及测试 虚幻引擎地形系统将高度数据存储在高度图中&#xff0c;这是一个灰阶图像&#xff0c;使用黑白色值来存储地貌高程。在高度图中&#xff0c;纯黑色值表示最低点&#xff0c;纯白色值表示最高点。支持16位灰阶PNG、8位灰阶r8及16位灰阶r16格式。 本文…

纯vue实现笔记系统

前言 最近研究了一个笔记记录系统&#xff0c;然后突然想到一个问题&#xff0c;我该如何才能只用前端就实现笔记的记录系统&#xff1f;经过这两天的研究将其做出来了&#xff0c;接下来将分享实现的过程 ✨✨✨✨✨✨✨✨✨✨ 项目演示 在我的项目中&#xff0c;是可以适…

PCIe prefix总结

这周研究了一下spec中关于prefix的部分&#xff0c;在此做一个总结&#xff0c;欢迎大家指正补充。 TLP Prefix基本介绍 • TLP 第 0 字节的 Fmt [2:0] 字段值为 100b 表示当前 DW 为 TLP Prefix 。 • TLP Prefix 分为两大类&#xff1a; Local 和 End-End &#xff0c;其中…

深入理解归并排序

目录 一、概念 二、递归版实现 三、非递归实现 三、文件归并排序 小结 一、概念 归并排序&#xff08;Merge sort&#xff09;是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法&#xff08;Divide and Conquer&#xff09;的一个非常典型的应用。将…

海外新闻稿发布:企业如何充分利用数字化媒体进行

在全球数字化进程加速的时代&#xff0c;企业要在激烈的国际市场中脱颖而出&#xff0c;利用数字化媒体进行海外新闻稿发布是一个不可或缺的战略。精确的策略和有效的执行能够帮助企业获得更高的曝光度和市场份额。以下将从多个角度探讨如何充分利用数字化媒体进行海外新闻稿发…

万亿生成式AI市场,商汤迎来“长坡厚雪”

AI掀起了全球科技玩家的军备竞赛&#xff0c;然而声浪越强噪音越多&#xff0c;这个领域的混乱程度也变得远超以往。就连刚刚公布财报的英伟达&#xff0c;市场也没有买账&#xff0c;因为担心AI驱动的增长高峰已过&#xff0c;接下来&#xff0c;下游会更看重实际成果。 “囤…