钉钉服务端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
转载于:https://www.cnblogs.com/xiaosongJiang/p/9991573.html
钉钉服务端api接口使用的更多相关文章
- 服务端调用接口API利器之HttpClient
前言 之前有介绍过HttpClient作为爬虫的简单使用,那么今天在简单的介绍一下它的另一个用途:在服务端调用接口API进行交互.之所以整理这个呢,是因为前几天在测试云之家待办消息接口的时候,有使用云 ...
- 安卓推送——个推服务端api使用误区
首先你需要在个推开放着平台上注册你的应用,以及获得以下几个必要的值APPID |APPKEY | MASTERSECRET,本文假设你已经完成上述步骤以及完成客户端SDK的集成. 原理 个推服务端ap ...
- C#开发BIMFACE系列4 服务端API之源上传文件
在注册成为BIMFACE的应用开发者后,要能在浏览器里浏览你的模型或者获取你模型内的BIM数据, 首先需要把你的模型文件上传到BIMFACE.根据不同场景,BIMFACE提供了丰富的文件相关的接口. ...
- C#开发BIMFACE系列3 服务端API之获取应用访问凭证AccessToken
系列目录 [已更新最新开发文章,点击查看详细] BIMFACE 平台为开发者提供了大量的服务器端 API 与 JavaScript API,用于二次开发 BIM 的相关应用. BIMFACE ...
- C#开发BIMFACE系列8 服务端API之获取文件上传状态信息
系列目录 [已更新最新开发文章,点击查看详细] 在BIMFACE控制台上传文件,上传过程及结束后它会自动告诉你文件的上传状态,目前有三种状态:uploading,success,failure ...
- C#开发BIMFACE系列10 服务端API之获取文件下载链接
系列目录 [已更新最新开发文章,点击查看详细] 通过BIMFACE控制台或者调用服务接口上传文件成功后,默认场景下需要下载该源文件,下载文件一般需要知道文件的下载链接即可.BIMACE平台提供 ...
- C#开发BIMFACE系列11 服务端API之源文件删除
系列目录 [已更新最新开发文章,点击查看详细] 通过BIMFACE控制台或者调用服务接口上传文件成功后,如果不再需要该文件,则可以通过BIMFACE平台提供的“源文件删除”服务接口删除具体的文 ...
- C#开发BIMFACE系列14 服务端API之批量获取转换状态详情
系列目录 [已更新最新开发文章,点击查看详细] 上一篇<C#开发BIMFACE系列13 服务端API之获取转换状态>中介绍了根据文件ID查询单个文件的转换状态. 本文介绍批量获取转 ...
- C#开发BIMFACE系列13 服务端API之获取转换状态
系列目录 [已更新最新开发文章,点击查看详细] 在<C#开发BIMFACE系列12 服务端API之文件转换>中详细介绍了7种文件转换的方法.发起源文件/模型转换后,转换过程可能成功 ...
随机推荐
- 高精度NTC测温的硬件电路以及软件设计
什么是NTC NTC是热敏电阻,其电阻值对温度变化敏感,在不同的温度下,可以呈现不同的电阻值. 热敏电阻有两类,一类是负温度系数电阻(NTC),温度增加时,电阻值降低,另一类是正温度系数电阻(PTC) ...
- springcloud中微服务的优雅停机(已验证)
大部分项目部署中,为了方便,可能都直接使用kill -9 服务的pid来停掉服务. 但是由于Eureka采用心跳的机制来上下线服务,会导致服务消费者调用此已经kill的服务提供者然后出错. 可以采用以 ...
- 51nod 1115 最大M子段和 V3
环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a[n](a[n-1], a[n], a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和 ...
- class Pagination(object)分页源码
class Pagination(object): def init(self, current_page, all_count, per_page_num=10, pager_count=11): ...
- 服务端高并发分布式架构演进之路 转载,原文地址:https://segmentfault.com/a/1190000018626163
1. 概述 本文以淘宝作为例子,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. 特 ...
- 让更多浏览器支持html5元素的简单方法
当我们试图使用web上的新技术的时候,旧式浏览器总是我们心中不可磨灭的痛!事实上,所有浏览器都有或多或少的问题,现在还没有浏览器能够完整的识别和支持最新的html5结构元素.但是不用担心,你依然可以在 ...
- 趣味编程:FizzBuzz(Haskell版)
g :: Int -> Int -> Int -> String g n 0 0 = "FizzBuzz" g n 0 _ = "Fizz" ...
- WinDbg常用命令系列---||(系统状态)
||(系统状态) 简介 双竖线 ( || ) 命令将打印指定的系统或当前正在调试的所有系统的状态. 使用形式 || System 参数 System 指定要显示的系统. 如果省略此参数,将显示正在调试 ...
- ROM
ROM 是 read only memory的简称,表示只读存储器,是一种半导体存储器.只读存储器(ROM)是一种在正常工作时其存储的数据固定不变,其中的数据只能读出,不能写入,即使断电也能够保留数据 ...
- canvas做动画
一.绘制图片 ①加载图片 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...