钉钉服务端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种文件转换的方法.发起源文件/模型转换后,转换过程可能成功 ...
随机推荐
- Linux-网络RAID技术DRBD
DRBD简介 官方文档 DRBD的全称为:Distributed Replicated Block Device(DRBD)分布式块设备复制,DRBD是由内核模块和相关脚本构成,用以构建高可用的集群. ...
- Alpha2的项目互评互测
目录 @(Alpha2项目测试) 这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求的链接 团队名称 你的代码我的发 这个作业的目标 其他参考文献 软件测试用例 姓名 学号 团队名称 李涵 ...
- C# 保存文件到数据库
html <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FileUploa ...
- 使用CefSharp在C#访问网站,支持x86和x64
早已久仰CefSharp大名,今日才得以实践,我其实想用CefSharp来访问网站页面,然后抓取html源代码进行分析,如果使用自带的WebBrowser控件,可能会出现一些不兼容js的错误. Cef ...
- MyBatis框架之注解开发
MyBatis注解开发 @Insert注解注解属性value:写入SQL语句 @Options注解实现添加新数据的主键封装注解属性useGeneratedKeys:使用生成的主键,配置为truekey ...
- “Another git process seems to be running in this repository...”Git此问题解决
Git中显示:Another git process seems to be running in this repository, e.g.an editor opened by 'git comm ...
- 闷声发大财,中国 App 出海编年史及方法论
https://zhuanlan.zhihu.com/p/26700406 第一代 iPhone 发布于 2007 年初,至今已有十年有余.中国互联网公司出海的新篇章,也正始于这 iPhone / A ...
- Django 中使用redis
Django使用redis 方式一,使用Django-redis模块 #安装: pip3 install django-redis CACHES = { "default": ...
- Bootstrap Method
bootstrap方法是一种重采样技术,用于通过抽样数据集来估计总体统计数据.是一种面向应用的.基于大量计算的统计思维——模拟抽样统计推断. 它可以用来估计统计数据,例如平均值或标准差.在应用机器学习 ...
- zzulioj - 2628: 小新的字母广场
题目链接:http://acm.zzuli.edu.cn/problem.php?id=2628 题目描述 放假了,小新决定出去散散心,于是他来到了著名的字母广场.这个广场是由n*m块砖 ...