钉钉服务端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种文件转换的方法.发起源文件/模型转换后,转换过程可能成功 ...
随机推荐
- 面试中的nginx高可用高并发!
本文转自:91博客:原文地址:http://www.9191boke.com/439923471.html 面试题: nginx高可用?nginx 是如何实现并发的?为什么nginx不使用多线程?ng ...
- Zabbix 完整的监控流程
目录 1.Zabbix的监控历程概念 1.1 基本概念 1.2 流程图 2.创建主机并加入主机组 3.添加新加主机的应用集(aplication) 4.添加监控项(item) 5.告警触发器配置(Tr ...
- 安装JDK(Windows)
安装JDK java 安装JDK 下载JDK并安装 配置环境变量 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.8.0_144 (jdk安装路径) 变量名: ...
- The Sum of the k-th Powers(Educational Codeforces Round 7F+拉格朗日插值法)
题目链接 传送门 题面 题意 给你\(n,k\),要你求\(\sum\limits_{i=1}^{n}i^k\)的值. 思路 根据数学知识或者说题目提示可知\(\sum\limits_{i=1}^{n ...
- 使用 xpath helper 提取网页链接
需求是这样的,公司某个部门不会爬虫,不懂任何技术性的东西,但是希望去提取网页的一个分享链接,老大要求去开发谷歌浏览器插件,但一时半会也搞不定这个啊, 想到用 xpath helper 作为一个临时的替 ...
- 使用aliyun的oss服务器上传照片
1.控制台操作 首先介绍一下阿里云OSS对象存储的一些基本概念. 1.1 进入对象存储界面 登录阿里云账号,进入对象存储界面,如图所示. 进入后如图所示. 1.2 OSS基本概念 这里不过多介绍如何在 ...
- Python应用之-file 方法
#!/usr/bin/env python # *_* coding=utf-8 *_* """ desc: 文件方法 ######################### ...
- linux中>/dev/null 2>&1和2>&1 > /dev/null
转载:https://www.cnblogs.com/520playboy/p/6275022.html 背景 我们经常能在shell脚本中发现>/dev/null 2>&1这样的 ...
- Dict.Count
static void Main(string[] args) { Dictionary<string, string> paraNameValueDict = new Dictionar ...
- 五大开源 Web 代理服务器横评:Squid、Privoxy、Varnish、Polipo、Tinyproxy
https://linux.cn/article-7119-1.html Web 代理软件转发 HTTP 请求时并不会改变数据流量.它们可以配置成透明代理,而无需客户端配置.它们还可以作为反向代理放在 ...