钉钉发送消息(非群机器人)

钉钉发送消息(非群机器人)

保姆式记录,亲测

一、钉钉的准备工作

首先进入钉钉的开发者后台 https://open.dingtalk.com/

应用开发—> 企业应用开发

进入之后选择创建应用

小程序和h5微应用都可以。这里只是把他们作为一个载体,只需要他们的一些对应信息就可以了,不需要前端进行开发对应的应用,如果前端想开发那也可以。

接下来就是点击自己创建的应用

最重要的就是下面的三个参数

AgentId

AppKey

AppSecret
在这里插入图片描述

这里的服务器出口ip地址,就是你本地服务器的公网地址,如果是本地测试不知道的话,后面调用钉钉接口,获得access_token 时候,会报错(某某地址不是白名单ip,这是你把他提示的地址放在下面就好了)

在这里插入图片描述

然后就是下面的权限管理

在这里插入图片描述

一般是全部员工,然后,你想调用那个接口就申请那个权限。如果你不知道申请那个权限可以再他的官方文档里找,那里有提示。

在这里插入图片描述

(建议不管是新旧API,找到符合你需求的即可)

因为这里是做的发送消息通知,那么就需要通讯录的权限,找到通讯录,把需要的都选了。

二、开发的准备工作

  1. pom的导入

            <!-- 钉钉 -->
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>dingtalk</artifactId>
                <version>1.2.15</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>alibaba-dingtalk-service-sdk</artifactId>
                <version>2.0.0</version>
            </dependency>
                
    
  2. 配置文件(yml配置文件)

    dingtalk:    #钉钉--消息通知 
        agentId: 146xxxcs
        appKey: dingwxsssdcs
        appSecret: jHsdsBvsdsdsdccccsss
       
    
    

    这里需要的参数,在前面已经说了再那里找

  3. 配置类

    
    @Data
    @Configuration
    @ConfigurationProperties(prefix="dingtalk")
    public class DingTalkProperties {
    	/**
    	 * AgentId
    	 */
    	private String agentId;
    	/**
    	 * AppKey
    	 */
    	private String appKey;
    	/**
    	 * AppSecret
    	 */
    	private String appSecret;
    
    }
    
    
  4. 工具类

    1. 首先获得对应的access_token

      /**
       * @date 2022/2/15 10:31
       * 钉钉发送消息工具类
       */
      @Slf4j
      @Component
      @AllArgsConstructor
      public class DingTalkUtil {
      
          private final DingTalkProperties dingTalkProperties;
        
      
      
          /**
           * 使用钉钉自带的方法去获取通行证
           * 获取钉钉的token
           *
           * @return access_token
           */
          public String getAccessToken() {
              try {
                  DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
                  OapiGettokenRequest request = new OapiGettokenRequest();
                  request.setAppkey(dingTalkProperties.getAppKey());
                  request.setAppsecret(dingTalkProperties.getAppSecret());
                  request.setHttpMethod("GET");
                  OapiGettokenResponse response = client.execute(request);
                  return response.getAccessToken();
              } catch (ApiException e) {
                  log.error("请求获取钉钉的access_token失败:{}", e.getErrMsg());
              }
              return null;
      
          }
      
      
    2. 根据这个access_token就是获得了对应的接口凭证,现在根据api

      根据用户电话获得钉钉的userId

      
      /**
           * 使用钉钉自带的方法,获取钉钉的用户的userid
           *
           * @param phone 用户电话
           * @return 钉钉用户内部userId
           */
          public String getDingTalkUserId(String phone) {
      
              String accessToken = this.getAccessToken();
              if (accessToken == null) {
                  throw new CiErrorException(63001, "钉钉出现异常,没有获取到对应的access_token,请联系管理员进行检查!");
              }
              try {
                  DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
                  OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
                  req.setMobile(phone);
                  OapiV2UserGetbymobileResponse rsp = client.execute(req, accessToken);
                  //把userId存入数据库,这里的userId是不变的,可以存入数据库
                  String userId = rsp.getResult().getUserid();
                  return userId;
              } catch (ApiException e) {
                  log.error("请求获取钉钉用户的userid失败:{}", e.getErrMsg());
              }
              return null;
          }
      
      
    3. 根据userId可以发送消息

      这里采用的是工作消息(消息类型是oa)

       /**
           * 多条发送消息
           * 钉钉发送工作通知(oa)
           * 注意请求接口的时候的参数配置,这里采用的是发送oa消息
           * 钉钉接口文档地址:https://open.dingtalk.com/document/orgapp-server/asynchronous-sending-of-enterprise-session-messages
           *
           * @param userIdList 钉钉内部用户id列表,多个用户id用 ' ,' 分割
           * @param msgVO      内容(类型不同内容不同)
           */
          public void sendDingTalkMsg(String userIdList, MsgVO msgVO) {
      
              String accessToken = this.getAccessToken();
              if (accessToken == null) {
                  throw new CiErrorException(63001, "钉钉出现异常,没有获取到对应的access_token,请联系管理员进行检查!");
              }
              try {
                  DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
                  OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
      
                  req.setAgentId(Long.parseLong(dingTalkProperties.getAgentId()));
                  req.setUseridList(userIdList);
      
                  //设置消息发送类型
                  OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
                  msg.setMsgtype("oa");
      
                  //设置跳转链接
                  OapiMessageCorpconversationAsyncsendV2Request.OA oa = new OapiMessageCorpconversationAsyncsendV2Request.OA();
                  oa.setPcMessageUrl(msgVO.getPcMessageUrl());
                  oa.setMessageUrl(msgVO.getMessageUrl());
      
                  //设置消息主题
                  OapiMessageCorpconversationAsyncsendV2Request.Body body = new OapiMessageCorpconversationAsyncsendV2Request.Body();
                  //设置作者
                  body.setAuthor("xxxx");
                  //设置通知消息标题
                  body.setTitle(msgVO.getTitle());
                  //设置表单内容
                  body.setForm(this.setMsgForm(msgVO.getFormVOList()));
                  oa.setBody(body);
      
                  //设置状态提示栏
                  OapiMessageCorpconversationAsyncsendV2Request.StatusBar statusBar = new OapiMessageCorpconversationAsyncsendV2Request.StatusBar();
                  //设置状态提示颜色
                  statusBar.setStatusBg("0xFFF65E5E");
                  //设置状态提示内容
                  statusBar.setStatusValue(msgVO.getStatusContent());
                  oa.setStatusBar(statusBar);
      
                  //设置头部内容
                  OapiMessageCorpconversationAsyncsendV2Request.Head head = new OapiMessageCorpconversationAsyncsendV2Request.Head();
                  head.setBgcolor("0xFFF65E5E");
                  oa.setHead(head);
      
                  msg.setOa(oa);
                  req.setMsg(msg);
                  OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, accessToken);
              } catch (ApiException e) {
                  log.error("发送钉钉消息失败:{}", e.getErrMsg());
              }
          }
      
          /**
           * 设置发送消息的表单
           *
           * @param list 消息表单
           * @return 处理表单
           */
          private List<OapiMessageCorpconversationAsyncsendV2Request.Form> setMsgForm(List<FormVO> list) {
              List<OapiMessageCorpconversationAsyncsendV2Request.Form> formList = new ArrayList<>(7);
              for (FormVO formVO : list) {
                  OapiMessageCorpconversationAsyncsendV2Request.Form form = new OapiMessageCorpconversationAsyncsendV2Request.Form();
                  form.setKey(formVO.getKey());
                  form.setValue(formVO.getValue());
                  formList.add(form);
              }
              return formList;
          }
      

      这里对应的vo

      
      import lombok.Data;
      
      /**
       * @author zwh
       * @date 2022/2/15 20:21
       * 钉钉发送消息表单实体类
       *
       * 钉钉最多展示是6个,多的就会折叠不显示
       */
      @Data
      public class FormVO {
      
          /**
           * 键
           */
          private String key;
      
          /**
           * 值
           */
          private String value;
      }
      
      
      import lombok.Data;
      
      import java.util.List;
      
      /**
       * @date 2022/2/15 20:35
       * 钉钉发送消息实体类
       */
      @Data
      public class MsgVO {
      
          /**
           * 移动端跳转url
           */
          private String messageUrl;
      
          /**
           * PC端跳转url
           */
          private String pcMessageUrl;
      
          /**
           * body参数中的正文标题
           */
          private String title;
      
          /**
           * body参数中的表单数据
           */
          private List<FormVO> formVOList;
      
          /**
           * 状态提示消息
           */
          private String statusContent;
      
      
      }
      
      
  5. 然后只要调用这里面的发送消息的方法就可以了,但是必须满足对应的参数。

    当前也可以使用其他方式的消息类型,我这边使用了最复杂的一个,因为业务需要。

三、总结

这里的所有方法都是从钉钉的调试里面进行修改的,可以直接现在钉钉的调试中进行调试,然后再把代码借鉴过来,然后进行修改,符合自己的需求就可以了。

(1)、获取企业内部的access_token https://open.dingtalk.com/document/orgapp-server/obtain-orgapp-token

(2)、根据用户phone获得userId https://open.dingtalk.com/document/orgapp-server/query-users-by-phone-number

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

消息类型 https://open.dingtalk.com/document/orgapp-server/message-types-and-data-format

一定要好好的阅读钉钉的接口文档,并且使用他们的原生方法,节省时间(自己能力不足,所以直接那人家的方法用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItIm7NeO-1645434398518)(C:\Users\Yuki\AppData\Roaming\Typora\typora-user-images\image-20220221170307997.png)]

ment/orgapp-server/query-users-by-phone-number>

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

消息类型 https://open.dingtalk.com/document/orgapp-server/message-types-and-data-format

一定要好好的阅读钉钉的接口文档,并且使用他们的原生方法,节省时间(自己能力不足,所以直接那人家的方法用)

在这里插入图片描述

注意: 这里的消息不会发送重复消息,比如你把一条消息发给三个人,但是你在把这样的消息发给其他的四个人,那么这后面的四个人是收不到消息的,因为钉钉任务你在发送重复消息。

资源连接 https://download.csdn.net/download/zhuwenaptx/81739940

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值