钉钉服务端api接口使用

原文链接:http://www.cnblogs.com/xiaosongJiang/p/9991573.html

第一步:注册钉钉企业账号

打开链接: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请求接口封装

  1. function request(url, method, params, headers = {}) {

  2.  

    const options = {

  3.  

    url,

  4.  

    method,

  5.  

    // timeout: 3000,

  6.  

    headers: Object.assign(headers, {

  7.  

    ‘content-type‘: ‘application/json‘,

  8.  

    }),

  9.  

    rejectUnauthorized: false, // https

  10.  

    json: true,

  11.  

    };

  12.  

    switch (method) {

  13.  

    case ‘POST‘:

  14.  

    case ‘PUT‘:

  15.  

    options.body = params;

  16.  

    break;

  17.  

    case ‘GET‘:

  18.  

    case ‘DELETE‘:

  19.  

    options.qs = params;

  20.  

    break;

  21.  

    default:

  22.  

    break;

  23.  

    }

  24.  

    return new Promise((resolve, reject) => {

  25.  

    request(options, (error, response, body) => {

  26.  

    if (!error) {

  27.  

    resolve(body);

  28.  

    } else {

  29.  

    reject(error);

  30.  

    }

  31.  

    });

  32.  

    });

  33.  

    .catch (error => ({

  34.  

  35.  

    msg: error.message,

  36.  

    }));

  37.  

    }

  

三、接口见代码(后端使用koa.js)

const host = ‘https://oapi.dingtalk.com/‘;
  1. /*

  2.  

    *发送工作通知消息

  3.  

    */

  4.  

    router.post(‘/api/dingtalkserve/asyncsend_v2‘, async ({ request, response, session }) => {

  5.  

    try {

  6.  

  7.  

    let body = request.fields;

  8.  

    if (!body[‘userid_list‘] && !body[‘dept_id_list‘] && !body[‘to_all_user‘]) {

  9.  

    return response.fail({

  10.  

    ‘msg‘: "userid_list,dept_id_list, to_all_user必须有一个不能为空"

  11.  

    });

  12.  

    }

  13.  

    if (!body[‘msg‘]) {

  14.  

    return response.fail({

  15.  

    ‘msg‘: "msg不能为空"

  16.  

    });

  17.  

    }

  18.  

  19.  

    // 获取TOKEN

  20.  

    let accessToken = await getAccessToken();

  21.  

    let params = {

  22.  

    agent_id: parseInt(agentId4EP),

  23.  

    msg: {

  24.  

    "msgtype": "text",

  25.  

    "text": {

  26.  

    "content": body[‘msg‘]

  27.  

    }

  28.  

    }

  29.  

    };

  30.  

    body[‘to_all_user‘] ? params[‘to_all_user‘] = true : false;

  31.  

    body[‘dept_id_list‘] ? params[‘dept_id_list‘] = body[‘dept_id_list‘] : "";

  32.  

    body[‘userid_list‘] ? params[‘userid_list‘] = body[‘userid_list‘] : "";

  33.  

    let messageRes = await request(`${host}topapi/message/corpconversation/asyncsend_v2?access_token=${accessToken}`, ‘POST‘, params);

  34.  

    return response.success({ ‘data‘: messageRes });

  35.  

    } catch (e) {

  36.  

    console.log(e);

  37.  

    return response.fail({

  38.  

    ‘msg‘: e

  39.  

    });

  40.  

    }

  41.  

    });

  42.  

  43.  

    /*

  44.  

    * 获取工作通知消息的发送进度

  45.  

    */

  46.  

    router.post(‘/api/dingtalkserve/getsendprogress‘, async ({ request, response, session }) => {

  47.  

    try {

  48.  

  49.  

    let body = request.fields;

  50.  

    if (!body[‘task_id‘]) {

  51.  

    return response.fail({

  52.  

    ‘msg‘: "task_id不能为空"

  53.  

    });

  54.  

    }

  55.  

    // 获取TOKEN

  56.  

    let accessToken = await getAccessToken();

  57.  

    let params = {

  58.  

    agent_id: parseInt(agentId4EP),

  59.  

    task_id: body[‘task_id‘]

  60.  

    };

  61.  

    let messageRes = await request(`${host}topapi/message/corpconversation/getsendprogress?access_token=${accessToken}`, ‘POST‘, params);

  62.  

    return response.success({ ‘data‘: messageRes });

  63.  

    } catch (e) {

  64.  

    console.log(e);

  65.  

    return response.fail({

  66.  

    ‘msg‘: e

  67.  

    });

  68.  

    }

  69.  

    });

  70.  

  71.  

    /*

  72.  

    * 获取工作通知消息的发送结果

  73.  

    */

  74.  

    router.post(‘/api/dingtalkserve/getsendresult‘, async ({ request, response, session }) => {

  75.  

    try {

  76.  

  77.  

    let body = request.fields;

  78.  

    if (!body[‘task_id‘]) {

  79.  

    return response.fail({

  80.  

    ‘msg‘: "task_id不能为空"

  81.  

    });

  82.  

    }

  83.  

    // 获取TOKEN

  84.  

    let accessToken = await getAccessToken();

  85.  

    let params = {

  86.  

    agent_id: parseInt(agentId4EP),

  87.  

    task_id: body[‘task_id‘]

  88.  

    };

  89.  

    let messageRes = await request(`${host}topapi/message/corpconversation/getsendresult?access_token=${accessToken}`, ‘POST‘, params);

  90.  

    return response.success({ ‘data‘: messageRes });

  91.  

    } catch (e) {

  92.  

    console.log(e);

  93.  

    return response.fail({

  94.  

    ‘msg‘: e

  95.  

    });

  96.  

    }

  97.  

    });

  98.  

  99.  

    /*

  100.  

    * 获取子部门ID列表

  101.  

    */

  102.  

    router.post(‘/api/dingtalkserve/list_ids‘, async ({ request, response, session }) => {

  103.  

    try {

  104.  

  105.  

    let body = request.fields;

  106.  

    if (!body[‘id‘]) {

  107.  

    return response.fail({

  108.  

    ‘msg‘: "父部门id不能为空"

  109.  

    });

  110.  

    }

  111.  

    // 获取TOKEN

  112.  

    let accessToken = await getAccessToken();

  113.  

    let params = {

  114.  

    access_token: accessToken,

  115.  

    id: body[‘id‘]

  116.  

    };

  117.  

    let messageRes = await request(`${host}department/list_ids`, ‘GET‘, params);

  118.  

    console.log("messageRes", messageRes)

  119.  

    return response.success({ ‘data‘: messageRes });

  120.  

    } catch (e) {

  121.  

    console.log(e);

  122.  

    return response.fail({

  123.  

    ‘msg‘: e

  124.  

    });

  125.  

    }

  126.  

    });

  127.  

  128.  

    /*

  129.  

    * 获取部门列表

  130.  

    */

  131.  

    router.post(‘/api/dingtalkserve/list‘, async ({ request, response, session }) => {

  132.  

    try {

  133.  

  134.  

    let body = request.fields;

  135.  

    if (!body[‘id‘]) {

  136.  

    return response.fail({

  137.  

    ‘msg‘: "父部门id不能为空"

  138.  

    });

  139.  

    }

  140.  

    // 获取TOKEN

  141.  

    let accessToken = await getAccessToken();

  142.  

    let params = {

  143.  

    access_token: accessToken,

  144.  

    id: body[‘id‘]

  145.  

    };

  146.  

    body[‘lang‘] ? params[‘lang‘] = body[‘lang‘] : "";

  147.  

    body[‘fetch_child‘] ? params[‘fetch_child‘] = true : false;

  148.  

    let messageRes = await request(`${host}department/list`, ‘GET‘, params);

  149.  

    console.log("messageRes", messageRes)

  150.  

    return response.success({ ‘data‘: messageRes });

  151.  

    } catch (e) {

  152.  

    console.log(e);

  153.  

    return response.fail({

  154.  

    ‘msg‘: e

  155.  

    });

  156.  

    }

  157.  

    });

  158.  

  159.  

    /*

  160.  

    * 获取部门详情

  161.  

    */

  162.  

    router.post(‘/api/dingtalkserve/departmentget‘, async ({ request, response, session }) => {

  163.  

    try {

  164.  

  165.  

    let body = request.fields;

  166.  

    if (!body[‘id‘]) {

  167.  

    return response.fail({

  168.  

    ‘msg‘: "部门id不能为空"

  169.  

    });

  170.  

    }

  171.  

    // 获取TOKEN

  172.  

    let accessToken = await getAccessToken();

  173.  

    let params = {

  174.  

    access_token: accessToken,

  175.  

    id: body[‘id‘]

  176.  

    };

  177.  

    body[‘lang‘] ? params[‘lang‘] = body[‘lang‘] : "";

  178.  

    let messageRes = await request(`${host}department/get`, ‘GET‘, params);

  179.  

    console.log("messageRes", messageRes)

  180.  

    return response.success({ ‘data‘: messageRes });

  181.  

    } catch (e) {

  182.  

    console.log(e);

  183.  

    return response.fail({

  184.  

    ‘msg‘: e

  185.  

    });

  186.  

    }

  187.  

    });

  188.  

  189.  

    /*

  190.  

    * 查询部门的所有上级父部门路径

  191.  

    */

  192.  

    router.post(‘/api/dingtalkserve/list_parent_depts_by_dept‘, async ({ request, response, session }) => {

  193.  

    try {

  194.  

  195.  

    let body = request.fields;

  196.  

    if (!body[‘id‘]) {

  197.  

    return response.fail({

  198.  

    ‘msg‘: "部门id不能为空"

  199.  

    });

  200.  

    }

  201.  

    // 获取TOKEN

  202.  

    let accessToken = await getAccessToken();

  203.  

    let params = {

  204.  

    access_token: accessToken,

  205.  

    id: body[‘id‘]

  206.  

    };

  207.  

    let messageRes = await request(`${host}department/list_parent_depts_by_dept`, ‘GET‘, params);

  208.  

    console.log("messageRes", messageRes)

  209.  

    return response.success({ ‘data‘: messageRes });

  210.  

    } catch (e) {

  211.  

    console.log(e);

  212.  

    return response.fail({

  213.  

    ‘msg‘: e

  214.  

    });

  215.  

    }

  216.  

    });

  217.  

    /*

  218.  

    * 查询指定用户的所有上级父部门路径

  219.  

    */

  220.  

    router.post(‘/api/dingtalkserve/list_parent_depts‘, async ({ request, response, session }) => {

  221.  

    try {

  222.  

  223.  

    let body = request.fields;

  224.  

    if (!body[‘userId‘]) {

  225.  

    return response.fail({

  226.  

    ‘msg‘: "用户id不能为空"

  227.  

    });

  228.  

    }

  229.  

    // 获取TOKEN

  230.  

    let accessToken = await getAccessToken();

  231.  

    let params = {

  232.  

    access_token: accessToken,

  233.  

    userId: body[‘userId‘]

  234.  

    };

  235.  

    let messageRes = await request(`${host}department/list_parent_depts`, ‘GET‘, params);

  236.  

    console.log("messageRes", messageRes)

  237.  

    return response.success({ ‘data‘: messageRes });

  238.  

    } catch (e) {

  239.  

    console.log(e);

  240.  

    return response.fail({

  241.  

    ‘msg‘: e

  242.  

    });

  243.  

    }

  244.  

    });

  245.  

  246.  

    /*

  247.  

    * 获取企业员工人数

  248.  

    */

  249.  

    router.post(‘/api/dingtalkserve/get_org_user_count‘, async ({ request, response, session }) => {

  250.  

    try {

  251.  

  252.  

    let body = request.fields;

  253.  

    if (!body[‘onlyActive‘]) {

  254.  

    return response.fail({

  255.  

    ‘msg‘: "激活钉钉状态不能为空"

  256.  

    });

  257.  

    }

  258.  

    // 获取TOKEN

  259.  

    let accessToken = await getAccessToken();

  260.  

    let params = {

  261.  

    access_token: accessToken,

  262.  

    onlyActive: body[‘onlyActive‘]

  263.  

    };

  264.  

    let messageRes = await request(`${host}user/get_org_user_count`, ‘GET‘, params);

  265.  

    console.log("messageRes", messageRes)

  266.  

    return response.success({ ‘data‘: messageRes });

  267.  

    } catch (e) {

  268.  

    console.log(e);

  269.  

    return response.fail({

  270.  

    ‘msg‘: e

  271.  

    });

  272.  

    }

  273.  

    });

  274.  

  275.  

    /*

  276.  

    * 获取用户详情

  277.  

    */

  278.  

    router.post(‘/api/dingtalkserve/userinfo‘, async ({ request, response, session }) => {

  279.  

    try {

  280.  

  281.  

    let body = request.fields;

  282.  

    if (!body[‘userid‘]) {

  283.  

    return response.fail({

  284.  

    ‘msg‘: "userid不能为空"

  285.  

    });

  286.  

    }

  287.  

    // 获取TOKEN

  288.  

    let accessToken = await getAccessToken();

  289.  

    let params = {

  290.  

    access_token: accessToken,

  291.  

    userid: body[‘userid‘]

  292.  

    };

  293.  

    body[‘lang‘] ? params[‘lang‘] = body[‘lang‘] : "";

  294.  

    let messageRes = await request(`${host}user/get`, ‘GET‘, params);

  295.  

    console.log("messageRes", messageRes)

  296.  

    return response.success({ ‘data‘: messageRes });

  297.  

    } catch (e) {

  298.  

    console.log(e);

  299.  

    return response.fail({

  300.  

    ‘msg‘: e

  301.  

    });

  302.  

    }

  303.  

    });

  304.  

  305.  

    /*

  306.  

    * 获取部门用户userid列表

  307.  

    */

  308.  

    router.post(‘/api/dingtalkserve/getDeptMember‘, async ({ request, response, session }) => {

  309.  

    try {

  310.  

    let body = request.fields;

  311.  

    if (!body[‘deptId‘]) {

  312.  

    return response.fail({

  313.  

    ‘msg‘: "部门id不能为空"

  314.  

    });

  315.  

    }

  316.  

    // 获取TOKEN

  317.  

    let accessToken = await getAccessToken();

  318.  

    let params = {

  319.  

    access_token: accessToken,

  320.  

    deptId: body[‘deptId‘]

  321.  

    };

  322.  

    let messageRes = await request(`${host}user/getDeptMember`, ‘GET‘, params);

  323.  

    console.log("messageRes", messageRes)

  324.  

    return response.success({ ‘data‘: messageRes });

  325.  

    } catch (e) {

  326.  

    console.log(e);

  327.  

    return response.fail({

  328.  

    ‘msg‘: e

  329.  

    });

  330.  

    }

  331.  

    });

  332.  

  333.  

    /*

  334.  

    * 获取部门用户(详情)

  335.  

    */

  336.  

    router.post(‘/api/dingtalkserve/listbypage‘, async ({ request, response, session }) => {

  337.  

    try {

  338.  

  339.  

    let body = request.fields;

  340.  

    if (!body[‘department_id‘]) {

  341.  

    return response.fail({

  342.  

    ‘msg‘: "部门id不能为空"

  343.  

    });

  344.  

    }

  345.  

    if (!body[‘offset‘]) {

  346.  

    return response.fail({

  347.  

    ‘msg‘: "偏移量不能为空"

  348.  

    });

  349.  

    }

  350.  

    if (!body[‘size‘]) {

  351.  

    return response.fail({

  352.  

    ‘msg‘: "每页数量不能为空"

  353.  

    });

  354.  

    }

  355.  

    // 获取TOKEN

  356.  

    let accessToken = await getAccessToken();

  357.  

    let params = {

  358.  

    access_token: accessToken,

  359.  

    department_id: body[‘department_id‘],

  360.  

    offset: parseInt(body[‘offset‘]),

  361.  

    size: parseInt(body[‘size‘])

  362.  

    };

  363.  

    let messageRes = await request(`${host}user/listbypage`, ‘GET‘, params);

  364.  

    console.log("messageRes", messageRes)

  365.  

    return response.success({ ‘data‘: messageRes });

  366.  

    } catch (e) {

  367.  

    console.log(e);

  368.  

    return response.fail({

  369.  

    ‘msg‘: e

  370.  

    });

  371.  

    }

  372.  

    });

  373.  

  374.  

    /*

  375.  

    * 根据unionid获取userid

  376.  

    */

  377.  

    router.post(‘/api/dingtalkserve/getUseridByUnionid‘, async ({ request, response, session }) => {

  378.  

    try {

  379.  

  380.  

    let body = request.fields;

  381.  

    if (!body[‘unionid‘]) {

  382.  

    return response.fail({

  383.  

    ‘msg‘: "unionid不能为空"

  384.  

    });

  385.  

    }

  386.  

    // 获取TOKEN

  387.  

    let accessToken = await getAccessToken();

  388.  

    let params = {

  389.  

    access_token: accessToken,

  390.  

    unionid: body[‘unionid‘]

  391.  

    };

  392.  

    let messageRes = await request(`${host}user/getUseridByUnionid`, ‘GET‘, params);

  393.  

    console.log("messageRes", messageRes)

  394.  

    return response.success({ ‘data‘: messageRes });

  395.  

    } catch (e) {

  396.  

    console.log(e);

  397.  

    return response.fail({

  398.  

    ‘msg‘: e

  399.  

    });

  400.  

    }

  401.  

    });

  402.  

  403.  

    /*

  404.  

    * 获取通讯录权限范围

  405.  

    */

  406.  

    router.post(‘/api/dingtalkserve/authScopes‘, async ({ request, response, session }) => {

  407.  

    try {

  408.  

    // 获取TOKEN

  409.  

    let accessToken = await getAccessToken();

  410.  

    let params = {

  411.  

    access_token: accessToken

  412.  

    };

  413.  

    let messageRes = await request(`${host}/auth/scopes`, ‘GET‘, params);

  414.  

    console.log("messageRes", messageRes)

  415.  

    return response.success({ ‘data‘: messageRes });

  416.  

    } catch (e) {

  417.  

    console.log(e);

  418.  

    return response.fail({

  419.  

    ‘msg‘: e

  420.  

    });

  421.  

    }

  422.  

    });

  423.  

  424.  

    /*

  425.  

    * 创建群

  426.  

    */

  427.  

    router.post(‘/api/dingtalkserve/createChat‘, async ({ request, response, session }) => {

  428.  

    try {

  429.  

  430.  

    let body = request.fields;

  431.  

    if (!body[‘name‘]) {

  432.  

    return response.fail({

  433.  

    ‘msg‘: "群名称不能为空"

  434.  

    });

  435.  

    }

  436.  

    if (!body[‘owner‘]) {

  437.  

    return response.fail({

  438.  

    ‘msg‘: "群主userid不能为空"

  439.  

    });

  440.  

    }

  441.  

    if (!body[‘useridlist‘]) {

  442.  

    return response.fail({

  443.  

    ‘msg‘: "群成员不能为空"

  444.  

    });

  445.  

    }

  446.  

    if (body[‘useridlist‘].indexOf(body[‘owner‘]) < 0) {

  447.  

    return response.fail({

  448.  

    ‘msg‘: "群主必须为群成员"

  449.  

    });

  450.  

    }

  451.  

    // 获取TOKEN

  452.  

    let accessToken = await getAccessToken();

  453.  

    let params = {

  454.  

    name: body[‘name‘],

  455.  

    owner: body[‘owner‘],

  456.  

    useridlist: body[‘useridlist‘].split(",")

  457.  

    };

  458.  

    let messageRes = await request(`${host}chat/create?access_token=${accessToken}`, ‘POST‘, params);

  459.  

    console.log("messageRes", messageRes)

  460.  

    return response.success({ ‘data‘: messageRes });

  461.  

    } catch (e) {

  462.  

    console.log(e);

  463.  

    return response.fail({

  464.  

    ‘msg‘: e

  465.  

    });

  466.  

    }

  467.  

    });

  468.  

  469.  

    /*

  470.  

    * 获取群聊会话信息

  471.  

    */

  472.  

    router.post(‘/api/dingtalkserve/chatInfo‘, async ({ request, response, session }) => {

  473.  

    try {

  474.  

  475.  

    let body = request.fields;

  476.  

    if (!body[‘chatid‘]) {

  477.  

    return response.fail({

  478.  

    ‘msg‘: "群id不能为空"

  479.  

    });

  480.  

    }

  481.  

    // 获取TOKEN

  482.  

    let accessToken = await getAccessToken();

  483.  

    let params = {

  484.  

    access_token: accessToken,

  485.  

    chatid: body[‘chatid‘]

  486.  

    };

  487.  

    let messageRes = await request(`${host}chat/get`, ‘GET‘, params);

  488.  

    console.log("messageRes", messageRes)

  489.  

    return response.success({ ‘data‘: messageRes });

  490.  

    } catch (e) {

  491.  

    console.log(e);

  492.  

    return response.fail({

  493.  

    ‘msg‘: e

  494.  

    });

  495.  

    }

  496.  

    });

  497.  

  498.  

    /*

  499.  

    * 发送群消息

  500.  

    */

  501.  

    router.post(‘/api/dingtalkserve/chatSend‘, async ({ request, response, session }) => {

  502.  

    try {

  503.  

  504.  

    let body = request.fields;

  505.  

    if (!body[‘chatid‘]) {

  506.  

    return response.fail({

  507.  

    ‘msg‘: "群id不能为空"

  508.  

    });

  509.  

    }

  510.  

    if (!body[‘msg‘]) {

  511.  

    return response.fail({

  512.  

    ‘msg‘: "群消息不能为空"

  513.  

    });

  514.  

    }

  515.  

    // 获取TOKEN

  516.  

    let accessToken = await getAccessToken();

  517.  

    let params = {

  518.  

    chatid: body[‘chatid‘],

  519.  

    msg: {

  520.  

    "msgtype": "text",

  521.  

    "text": {

  522.  

    "content": body[‘msg‘]

  523.  

    }

  524.  

    }

  525.  

    };

  526.  

    let messageRes = await request(`${host}chat/send?access_token=${accessToken}`, ‘POST‘, params);

  527.  

    console.log("messageRes", messageRes)

  528.  

    return response.success({ ‘data‘: messageRes });

  529.  

    } catch (e) {

  530.  

    console.log(e);

  531.  

    return response.fail({

  532.  

    ‘msg‘: e

  533.  

    });

  534.  

    }

  535.  

    });

  536.  

  537.  

    /*

  538.  

    * 查询群消息已读人员列表

  539.  

    */

  540.  

    router.post(‘/api/dingtalkserve/getReadList‘, async ({ request, response, session }) => {

  541.  

    try {

  542.  

  543.  

    let body = request.fields;

  544.  

    if (!body[‘messageId‘]) {

  545.  

    return response.fail({

  546.  

    ‘msg‘: "messageId不能为空"

  547.  

    });

  548.  

    }

  549.  

    if (!body[‘cursor‘]) {

  550.  

    return response.fail({

  551.  

    ‘msg‘: "cursor不能为空"

  552.  

    });

  553.  

    }

  554.  

    if (!body[‘size‘]) {

  555.  

    return response.fail({

  556.  

    ‘msg‘: "每页数量不能为空"

  557.  

    });

  558.  

    }

  559.  

    // 获取TOKEN

  560.  

    let accessToken = await getAccessToken();

  561.  

    let params = {

  562.  

    access_token: accessToken,

  563.  

    messageId: body[‘messageId‘],

  564.  

    cursor: body[‘cursor‘],

  565.  

    size: parseInt(body[‘size‘]),

  566.  

    };

  567.  

    let messageRes = await request(`${host}chat/getReadList`, ‘GET‘, params);

  568.  

    console.log("messageRes", messageRes)

  569.  

    return response.success({ ‘data‘: messageRes });

  570.  

    } catch (e) {

  571.  

    console.log(e);

  572.  

    return response.fail({

  573.  

    ‘msg‘: e

  574.  

    });

  575.  

    }

  576.  

    });

以上针对的是钉钉企业内部应用

如果是ISV开发者应用,则需要通过接口获取企业的基本信息

nodejs签名实现

  1. /*

  2.  

    * 把timestamp + "\n" + suiteTicket当做签名字符串, suiteSecret做为签名秘钥,

  3.  

    * 使用HmacSHA256算法计算签名, 然后进行Base64 encode获取最后结果。

  4.  

    * 然后把签名参数再进行urlconde, 加到请求url后面。

  5.  

    */

  6.  

    const crypto = require(‘crypto‘);

  7.  

    const accessKey = ‘suiteqh0ljtdheuee****‘; // suiteKey

  8.  

    const suiteSecret = ‘******‘;

  9.  

    const suiteTicket = ‘TestSuiteTicket‘;

  10.  

    const timestamp = Date.now();

  11.  

    const stringToSign = timestamp + "\n" + suiteTicket;

  12.  

  13.  

    const hash = crypto.createHmac(‘sha256‘, suiteSecret)

  14.  

    .update(stringToSign, ‘utf8‘)

  15.  

    .digest().toString(‘base64‘);

  16.  

    console.log(hash);

  17.  

    var request = require("request");

  18.  

    var urlencode = require(‘urlencode‘);

  19.  

  20.  

    var options = {

  21.  

    method: ‘POST‘,

  22.  

    url: ‘https://oapi.dingtalk.com/service/get_auth_info‘,

  23.  

    qs: {

  24.  

    signature: hash,

  25.  

    timestamp: timestamp,

  26.  

    suiteTicket: suiteTicket,

  27.  

    accessKey: accessKey

  28.  

    },

  29.  

    headers: {

  30.  

    ‘Cache-Control‘: ‘no-cache‘,

  31.  

    ‘Content-Type‘: ‘application/json‘

  32.  

    },

  33.  

    body: { auth_corpid: ‘dingd142a587da6ee21d35c2f4657eb6378f‘ },

  34.  

    json: true

  35.  

    };

  36.  

  37.  

    request(options, function (error, response, body) {

  38.  

    if (error) throw new Error(error);

  39.  

  40.  

    console.log(body);

  41.  

    });

  

钉钉文档开发者链接 :https://open-doc.dingtalk.com/microapp/serverapi2/isu6nk

转载于:https://www.cnblogs.com/xiaosongJiang/p/9991573.html

原文地址:https://www.cnblogs.com/westsoft/p/11282057.html

时间: 2024-10-01 22:34:52

钉钉服务端api接口使用的相关文章

C#开发BIMFACE系列10 服务端API之获取文件下载链接

通过BIMFACE控制台或者调用服务接口上传文件成功后,默认场景下需要下载该源文件,下载文件一般需要知道文件的下载链接即可.BIMACE平台提供了“获取文件下载链接”的服务接口.下面详细介绍其使用方法. 请求地址:GET https://file.bimface.com/download/url 说明:应用通过该接口获取文件的下载地址,然后下载文件.下载地址有效时间是5分钟. 参数: 请求 path(示例):https://file.bimface.com/download/url?fileId

C#开发BIMFACE系列11 服务端API之源文件删除

通过BIMFACE控制台或者调用服务接口上传文件成功后,如果不再需要该文件,则可以通过BIMFACE平台提供的“源文件删除”服务接口删除具体的文件.下面详细介绍其使用方法. 请求地址:DELETE https://file.bimface.com/file 说明:根据文件ID删除文件 参数: 请求 path(示例):https://file.bimface.com/file?fileId=1418750515413120 请求 header(示例):"Authorization: Bearer

C#开发BIMFACE系列14 服务端API之批量获取转换状态详情

系列目录     [已更新最新开发文章,点击查看详细] 上一篇<C#开发BIMFACE系列13 服务端API之获取转换状态>中介绍了根据文件ID查询单个文件的转换状态. 本文介绍批量获取转换状态详情. 请求地址:POST https://api.bimface.com/translateDetails 说明:应用发起转换以后,可以根据筛选条件,通过该接口批量查询转换状态详情 参数: 请求 path(示例):https://api.bimface.com/translateDetails 请求

C#开发BIMFACE系列24 服务端API之获取模型数据9:获取单个房间信息

系列目录     [已更新最新开发文章,点击查看详细] 大厦建筑模型中,基本上包含多个楼层,每个楼层包含多个房间等信息.在<C#开发BIMFACE系列21 服务端API之获取模型数据6:获取单模型的楼层信息>中介绍了如何获取一个模型中包含的楼层信息.面积分区.房间等信息.本篇主要介绍如何获取单个模型中单个房间信息. 请求地址:GET https://api.bimface.com/data/v2/files/{fileId}/rooms/{roomId} 说明:获取单个模型种单个房间信息 参数

python的flex服务端数据接口开发

python的flex服务端数据接口开发 python 如果给flex提供服务端,需要提供一个网关和一个可供客户端(flex)调用的类.这方面我更加推荐用twisted来写这个网关,因为twisted有很好的异步机制. 下面的我写的一个简单的验证用户的python服务端: ______________________________DBServer.py # Copyright (c) 2009-2010 The Newjh Project."""@author: Roy@s

服务端测试之接口测试用例设计

小伙伴们大家好,上一次和大家分享了<服务端测试之接口测试初探>,讲了一些接口测试的基本概念和理论知识.在上次的分享中,简单提到了接口测试用例设计包含的几个方面.本期我将在上次分享的基础上,和各位小伙伴一起具体看看这几个方面都是什么,在实际的项目中应该如何使用. 一.功能性用例设计 之前讲过,服务端的接口是和客户端的功能相对应的,对功能的验证,可以参照接口说明文档来进行.概括起来讲,就是我们需要验证接口说明文档中提到的各种情况,保证这些情况下接口的返回和最初设计的是一样的,这样我们就可以认为该接

APP服务端API(数据接口)设计应该考虑到的问题

1.跨平台性 2.良好的响应速度 3.接口要为移动客户端考虑 4.考虑移动端的网络情况和耗电量 5.通用的数据交换格式 6.接口统计功能 7.客户端与服务端的肥瘦平衡 8.隐式用户与显式用户 9.安全问题 10.良好的接口说明文档和测试程序 11.版本的维护 详细分析请参考 :https://www.hutuseng.com/article/how-to-design-api 原文地址:http://blog.51cto.com/825272560/2058638

移动APP服务端API设计应该考虑到的问题

转载:http://www.hutuseng.com/article/how-to-design-api 2014年,移动APP的热度丝毫没有减退,怎样为您的移动端app设计良好的服务器端接口(API)呢? 下面谈谈我个人的一些想法. 2014年,移动APP的热度丝毫没有减退,并没有像桌面软件被WEB网站那样所取代,不但如此,越来越多的传统应用.网站也都开始制作自己的移动APP,也就是我们常说的IOS客户端.android客户端.这仿佛又回到了多年前的CS架构,那时候我们用VB.VC.Delph

移动端API接口优化的术和结果

最近一直在忙工作的事情,所以文章写得有些少. 有3-5篇文章都是写到一半然后被别的事情给打断了,所以,我得找个时间好好补补. 最近一直在关注移动端接口API的可用性问题,在移动时代这个做这个优化能产生相当大的优化结果.根据经验数据一般不做任何优化,接口的可用性在95%左右.举个例子,广告接口的可用性直接决定了收入,那么丢失的5%收入如何捡回来,对一家收入还不错的公司来说,是一件非常重大的事情.例如日营收1亿+的百度. 造成这样的主要的原因有两大块 1. app端网络状况并不好 即便是wifi条件