zoukankan      html  css  js  c++  java
  • 钉钉服务端api接口使用

    第一步:注册钉钉企业账号

    打开链接:https://oa.dingtalk.com/#/login,注册账号即可

    第二步:创建应用

    以创建e应用为例:

     

    还需要授权一个开发人员,并获取CorpSecret,需要把corpId和CorpSecret作为参数请求api接口获取AccessToken,后面的所有接口都需要AccessToken

    第三步:接入接口

    一、获取token

     1 const corpid = 'dingd***587da6ee21d35c2f4657eb63***';
     2 const corpsecret = '*********';
     3 const requestPromise = require("request-promise");
     4 
     5 const getAccessToken = async (corpid, corpsecret) => {
     6   // https://oapi.dingtalk.com/gettoken?corpid={corpid}&corpsecret={corpSecret或开发授权码}
     7   const result = await requestPromise({ uri: 'https://oapi.dingtalk.com/gettoken', qs: { corpid, corpsecret } });
     8   console.log(result);
     9 };
    10 getAccessToken(corpid, corpsecret);

    二、promise请求接口封装

    function request(url, method, params, headers = {}) {
      const options = {
        url,
        method,
        // timeout: 3000,
        headers: Object.assign(headers, {
          'content-type': 'application/json',
        }),
        rejectUnauthorized: false, // https
        json: true,
      };
      switch (method) {
        case 'POST':
        case 'PUT':
          options.body = params;
          break;
        case 'GET':
        case 'DELETE':
          options.qs = params;
          break;
        default:
          break;
      }
      return new Promise((resolve, reject) => {
        request(options, (error, response, body) => {
          if (!error) {
            resolve(body);
          } else {
            reject(error);
          }
        });
      });
       .catch (error => ({
    
         msg: error.message,
       }));
    }
    

      

    三、接口见代码(后端使用koa.js)

    const host = 'https://oapi.dingtalk.com/';
    /*
     *发送工作通知消息
     */
    router.post('/api/dingtalkserve/asyncsend_v2', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['userid_list'] && !body['dept_id_list'] && !body['to_all_user']) {
          return response.fail({
            'msg': "userid_list,dept_id_list, to_all_user必须有一个不能为空"
          });
        }
        if (!body['msg']) {
          return response.fail({
            'msg': "msg不能为空"
          });
        }
    
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          agent_id: parseInt(agentId4EP),
          msg: {
            "msgtype": "text",
            "text": {
              "content": body['msg']
            }
          }
        };
        body['to_all_user'] ? params['to_all_user'] = true : false;
        body['dept_id_list'] ? params['dept_id_list'] = body['dept_id_list'] : "";
        body['userid_list'] ? params['userid_list'] = body['userid_list'] : "";
        let messageRes = await request(`${host}topapi/message/corpconversation/asyncsend_v2?access_token=${accessToken}`, 'POST', params);
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取工作通知消息的发送进度
     */
    router.post('/api/dingtalkserve/getsendprogress', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['task_id']) {
          return response.fail({
            'msg': "task_id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          agent_id: parseInt(agentId4EP),
          task_id: body['task_id']
        };
        let messageRes = await request(`${host}topapi/message/corpconversation/getsendprogress?access_token=${accessToken}`, 'POST', params);
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取工作通知消息的发送结果
     */
    router.post('/api/dingtalkserve/getsendresult', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['task_id']) {
          return response.fail({
            'msg': "task_id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          agent_id: parseInt(agentId4EP),
          task_id: body['task_id']
        };
        let messageRes = await request(`${host}topapi/message/corpconversation/getsendresult?access_token=${accessToken}`, 'POST', params);
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取子部门ID列表
     */
    router.post('/api/dingtalkserve/list_ids', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['id']) {
          return response.fail({
            'msg': "父部门id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          id: body['id']
        };
        let messageRes = await request(`${host}department/list_ids`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取部门列表
     */
    router.post('/api/dingtalkserve/list', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['id']) {
          return response.fail({
            'msg': "父部门id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          id: body['id']
        };
        body['lang'] ? params['lang'] = body['lang'] : "";
        body['fetch_child'] ? params['fetch_child'] = true : false;
        let messageRes = await request(`${host}department/list`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取部门详情
     */
    router.post('/api/dingtalkserve/departmentget', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['id']) {
          return response.fail({
            'msg': "部门id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          id: body['id']
        };
        body['lang'] ? params['lang'] = body['lang'] : "";
        let messageRes = await request(`${host}department/get`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 查询部门的所有上级父部门路径
     */
    router.post('/api/dingtalkserve/list_parent_depts_by_dept', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['id']) {
          return response.fail({
            'msg': "部门id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          id: body['id']
        };
        let messageRes = await request(`${host}department/list_parent_depts_by_dept`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    /*
     * 查询指定用户的所有上级父部门路径
     */
    router.post('/api/dingtalkserve/list_parent_depts', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['userId']) {
          return response.fail({
            'msg': "用户id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          userId: body['userId']
        };
        let messageRes = await request(`${host}department/list_parent_depts`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取企业员工人数
     */
    router.post('/api/dingtalkserve/get_org_user_count', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['onlyActive']) {
          return response.fail({
            'msg': "激活钉钉状态不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          onlyActive: body['onlyActive']
        };
        let messageRes = await request(`${host}user/get_org_user_count`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取用户详情
     */
    router.post('/api/dingtalkserve/userinfo', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['userid']) {
          return response.fail({
            'msg': "userid不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          userid: body['userid']
        };
        body['lang'] ? params['lang'] = body['lang'] : "";
        let messageRes = await request(`${host}user/get`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取部门用户userid列表
     */
    router.post('/api/dingtalkserve/getDeptMember', async ({ request, response, session }) => {
      try {
        let body = request.fields;
        if (!body['deptId']) {
          return response.fail({
            'msg': "部门id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          deptId: body['deptId']
        };
        let messageRes = await request(`${host}user/getDeptMember`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取部门用户(详情)
     */
    router.post('/api/dingtalkserve/listbypage', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['department_id']) {
          return response.fail({
            'msg': "部门id不能为空"
          });
        }
        if (!body['offset']) {
          return response.fail({
            'msg': "偏移量不能为空"
          });
        }
        if (!body['size']) {
          return response.fail({
            'msg': "每页数量不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          department_id: body['department_id'],
          offset: parseInt(body['offset']),
          size: parseInt(body['size'])
        };
        let messageRes = await request(`${host}user/listbypage`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 根据unionid获取userid
     */
    router.post('/api/dingtalkserve/getUseridByUnionid', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['unionid']) {
          return response.fail({
            'msg': "unionid不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          unionid: body['unionid']
        };
        let messageRes = await request(`${host}user/getUseridByUnionid`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取通讯录权限范围
     */
    router.post('/api/dingtalkserve/authScopes', async ({ request, response, session }) => {
      try {
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken
        };
        let messageRes = await request(`${host}/auth/scopes`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 创建群
     */
    router.post('/api/dingtalkserve/createChat', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['name']) {
          return response.fail({
            'msg': "群名称不能为空"
          });
        }
        if (!body['owner']) {
          return response.fail({
            'msg': "群主userid不能为空"
          });
        }
        if (!body['useridlist']) {
          return response.fail({
            'msg': "群成员不能为空"
          });
        }
        if (body['useridlist'].indexOf(body['owner']) < 0) {
          return response.fail({
            'msg': "群主必须为群成员"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          name: body['name'],
          owner: body['owner'],
          useridlist: body['useridlist'].split(",")
        };
        let messageRes = await request(`${host}chat/create?access_token=${accessToken}`, 'POST', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 获取群聊会话信息
     */
    router.post('/api/dingtalkserve/chatInfo', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['chatid']) {
          return response.fail({
            'msg': "群id不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          chatid: body['chatid']
        };
        let messageRes = await request(`${host}chat/get`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 发送群消息
     */
    router.post('/api/dingtalkserve/chatSend', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['chatid']) {
          return response.fail({
            'msg': "群id不能为空"
          });
        }
        if (!body['msg']) {
          return response.fail({
            'msg': "群消息不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          chatid: body['chatid'],
          msg: {
            "msgtype": "text",
            "text": {
              "content": body['msg']
            }
          }
        };
        let messageRes = await request(`${host}chat/send?access_token=${accessToken}`, 'POST', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });
    
    /*
     * 查询群消息已读人员列表
     */
    router.post('/api/dingtalkserve/getReadList', async ({ request, response, session }) => {
      try {
    
        let body = request.fields;
        if (!body['messageId']) {
          return response.fail({
            'msg': "messageId不能为空"
          });
        }
        if (!body['cursor']) {
          return response.fail({
            'msg': "cursor不能为空"
          });
        }
        if (!body['size']) {
          return response.fail({
            'msg': "每页数量不能为空"
          });
        }
        // 获取TOKEN
        let accessToken = await getAccessToken();
        let params = {
          access_token: accessToken,
          messageId: body['messageId'],
          cursor: body['cursor'],
          size: parseInt(body['size']),
        };
        let messageRes = await request(`${host}chat/getReadList`, 'GET', params);
        console.log("messageRes", messageRes)
        return response.success({ 'data': messageRes });
      } catch (e) {
        console.log(e);
        return response.fail({
          'msg': e
        });
      }
    });

    以上针对的是钉钉企业内部应用

    如果是ISV开发者应用,则需要通过接口获取企业的基本信息

    nodejs签名实现

    /*
     * 把timestamp + "
    " + suiteTicket当做签名字符串, suiteSecret做为签名秘钥,
     *  使用HmacSHA256算法计算签名, 然后进行Base64 encode获取最后结果。
     *  然后把签名参数再进行urlconde, 加到请求url后面。
     */
    const crypto = require('crypto');
    const accessKey = 'suiteqh0ljtdheuee****'; // suiteKey
    const suiteSecret = '******';
    const suiteTicket = 'TestSuiteTicket';
    const timestamp = Date.now();
    const stringToSign = timestamp + "
    " + suiteTicket;
    
    const hash = crypto.createHmac('sha256', suiteSecret)
      .update(stringToSign, 'utf8')
      .digest().toString('base64');
    console.log(hash);
    var request = require("request");
    var urlencode = require('urlencode');
    
    var options = {
      method: 'POST',
      url: 'https://oapi.dingtalk.com/service/get_auth_info',
      qs: {
        signature: hash,
        timestamp: timestamp,
        suiteTicket: suiteTicket,
        accessKey: accessKey
      },
      headers: {
        'Cache-Control': 'no-cache',
        'Content-Type': 'application/json'
      },
      body: { auth_corpid: 'dingd142a587da6ee21d35c2f4657eb6378f' },
      json: true
    };
    
    request(options, function (error, response, body) {
      if (error) throw new Error(error);
    
      console.log(body);
    });
    

      

    钉钉文档开发者链接 :https://open-doc.dingtalk.com/microapp/serverapi2/isu6nk

     

  • 相关阅读:
    mysql启动错误
    maven环境变量配置
    记一次服务器Tomcat优化经历
    自动定时备份删除脚本
    Tomcat网页加载速度过慢的解决方法
    tomcat运行war包报错,找不到context-root文件
    maven下配置pom.xml
    [LeetCode]题解(python):116-Populating Next Right Pointers in Each Node
    [LeetCode]题解(python):115-Distinct Subsequences
    [LeetCode]题解(python):114-Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/xiaosongJiang/p/9991573.html
Copyright © 2011-2022 走看看