• 钉钉服务端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 + " " + 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 + " " + 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

  • 相关阅读:
    storm学习途径
    Spark中的RDD操作简介
    【转】Hadoop web页面的授权设定
    源码安装ipython,并在ipython中整合spark
    Spark调优
    在Java中调用C
    查看Mysql表空间大小 优化空间
    update A inner join
    kibana 汉化
    xcode-select --install不能下载该软件的解决办法
  • 原文地址:https://www.cnblogs.com/westsoft/p/11282057.html
Copyright © 2020-2023  润新知