第一步:注冊釘釘企業賬號
打開鏈接: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
轉載於:https://www.cnblogs.com/xiaosongJiang/p/9991573.html