1. 程式人生 > >釘釘服務端api介面使用

釘釘服務端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 + "\n" + 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 + "\n" + 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