关于钉钉分布上传问题

关于钉钉分布上传的一些坑和BUG

提示:本博客需结合钉钉开发文档 ‘’新 “”老“ ” API 文档 使用


前言

钉钉内部程序免密登录若依实现后,需要用后台管理系统上传 必要的文件到钉盘或者群里

一、为啥使用分布上传

第三方程序 上传文件到钉钉 云盘 不能超过8MB 这远远不够

二、话不多说分布上传代码(所有不明白的东西需要结合官方新老文档查看)

代码如下(示例):

在这里插入代码片
package com.ruoyi.app.service;

import com.aliyun.dingtalkstorage_1_0.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
//import com.util.AccessTokenUtil;
//import lombok.val;
import org.testng.annotations.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.Map;
import com.ruoyi.app.service.DingTalkService;

import javax.annotation.Resource;

public class MultipartUpload {

    @Resource
    public DingTalkService dingTalkService;
    public static com.aliyun.dingtalkstorage_1_0.Client createClient() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkstorage_1_0.Client(config);
    }
    @Test
    public void test() throws Exception {
        com.aliyun.dingtalkstorage_1_0.Client client = MultipartUpload.createClient();

        String spaceId = "钉盘文件夹ID";
        String filePath = "D:\\filebak\\你的服务器上文件179期.pdf";
        // 每片文件大小
        long partSize = 1 * 1024 * 1024L;  // 1MB
        // 初始化分片上传接口
//        String accessToken = dingTalkService.getAccessToken();
        String accessToken ="你需要在钉钉开发者里创建";
    
        String unionId = "你的unionID";  //可以通过手机号获取 userid 再用userid 获取unionID 你也可以用免登授权码获取userID

        InitMultipartFileUploadHeaders initMultipartFileUploadHeaders = new InitMultipartFileUploadHeaders();
        initMultipartFileUploadHeaders.xAcsDingtalkAccessToken = accessToken;
        InitMultipartFileUploadRequest initMultipartFileUploadRequest = new InitMultipartFileUploadRequest();
        initMultipartFileUploadRequest.setUnionId(unionId);
        InitMultipartFileUploadRequest.InitMultipartFileUploadRequestOption initMultipartFileUploadRequestOption = new InitMultipartFileUploadRequest.InitMultipartFileUploadRequestOption();
        initMultipartFileUploadRequestOption.setStorageDriver("DINGTALK");
        initMultipartFileUploadRequest.setOption(initMultipartFileUploadRequestOption);
        String uploadKey = client.initMultipartFileUploadWithOptions(spaceId, initMultipartFileUploadRequest, initMultipartFileUploadHeaders, new RuntimeOptions()).getBody().getUploadKey();

        File file = new File(filePath);
        long fileLength = file.length();
        int partCount = (int) (fileLength / partSize) + ((fileLength % partSize != 0) ? 1 : 0);

        for (int i = 0; i < partCount; i++) {
            long startPos = i * partSize;
            long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
            // 获取分片上传信息
            GetMultipartFileUploadInfosHeaders getMultipartFileUploadInfosHeaders = new GetMultipartFileUploadInfosHeaders();
            getMultipartFileUploadInfosHeaders.xAcsDingtalkAccessToken = accessToken;
            GetMultipartFileUploadInfosRequest getMultipartFileUploadInfosRequest = new GetMultipartFileUploadInfosRequest();
            getMultipartFileUploadInfosRequest.setUnionId(unionId);
//            getMultipartFileUploadInfosRequest.setUploadKey("第一步初始化分片上传接口获取的uploadKey");
            getMultipartFileUploadInfosRequest.setUploadKey(uploadKey);
            getMultipartFileUploadInfosRequest.setPartNumbers(Arrays.asList(i + 1));
            GetMultipartFileUploadInfosResponseBody.GetMultipartFileUploadInfosResponseBodyMultipartHeaderSignatureInfosHeaderSignatureInfo headerSignatureInfo = client.getMultipartFileUploadInfosWithOptions(getMultipartFileUploadInfosRequest, getMultipartFileUploadInfosHeaders, new RuntimeOptions()).body.multipartHeaderSignatureInfos.get(0).headerSignatureInfo;

            uploadPartFile(startPos, curPartSize, headerSignatureInfo, file);
        }
        // 提交文件,完成上传
        CommitFileHeaders commitFileHeaders = new CommitFileHeaders();
        commitFileHeaders.xAcsDingtalkAccessToken = accessToken;
        CommitFileRequest.CommitFileRequestOption commitFileRequestOption
            = new CommitFileRequest.CommitFileRequestOption()
            .setSize(1024L)
            .setConflictStrategy("OVERWRITE");
        CommitFileRequest commitFileRequest = new CommitFileRequest()
            .setUnionId(unionId)
//            .setUploadKey(“第一步初始化分片上传接口获取的uploadKey”)
            .setUploadKey(uploadKey)
            .setName("自己取名字.pdf")
            .setParentId("0")
            .setOption(commitFileRequestOption);
        //CommitFileResponseBody.CommitFileResponseBodyDentry dentry = client.commitFileWithOptions("存储空间ID", commitFileRequest, commitFileHeaders, new RuntimeOptions()).body.dentry;
        CommitFileResponseBody.CommitFileResponseBodyDentry dentry = client.commitFileWithOptions(spaceId, commitFileRequest, commitFileHeaders, new RuntimeOptions()).body.dentry;
        System.out.println(dentry);
    }

    private void uploadPartFile(long start, long size, GetMultipartFileUploadInfosResponseBody.GetMultipartFileUploadInfosResponseBodyMultipartHeaderSignatureInfosHeaderSignatureInfo headerSignatureInfo, File file) throws Exception {
        InputStream inputStream = new FileInputStream(file);
        if (start > 0) {
            inputStream.skip(start);
        }

        URL url = new URL(headerSignatureInfo.getResourceUrls().get(0));
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("PUT");
        connection.setUseCaches(false);
        if (headerSignatureInfo.getHeaders() != null) {
            for (Map.Entry<String, String> entry : headerSignatureInfo.getHeaders().entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
        }
        connection.setReadTimeout(1000);
        connection.setConnectTimeout(1000);
        connection.connect();
        OutputStream out = connection.getOutputStream();
        byte[] buffer = new byte[1024];
        long remain = size;
        for (;remain > 0;) {
            int sizeToRead = remain < buffer.length ? (int)remain : buffer.length;
            int rsz = inputStream.read(buffer, 0, sizeToRead);
            if (rsz < 0) {
                break;
            }
            out.write(buffer, 0, rsz);
            remain -= rsz;
        }
        out.flush();
        out.close();
        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            System.out.println("上传成功");
        } else {
            System.out.println("上传失败");
        }
        connection.disconnect();
    }
}


钉钉 新老文档的坑注意 有两个文档 和两个 开发 Jar 包

   <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>alibaba-dingtalk-service-sdk</artifactId>
            <version>2.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dingtalk</artifactId>
            <version>2.0.14</version>
        </dependency>

在这里插入图片描述这两个文档 记录了 权限啥的 但是 分布上传 这些详细的东西 还是得用新文档 这是钉钉开发文档自己去找新的鉴权用老的

总结

钉钉文档有新旧 找不明白 看新文档 同时引入新老jar包 功能全面又好用
这里把Util 也发你们 还有 获取用户一些信息

package com.ruoyi.app.utils;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.ruoyi.app.constant.DingTalkUrlConstant;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;

/**
 * 获取access_token工具类
 */
@Slf4j
public class DingTalkUtil {

    public static Client creatClient() throws Exception {
        Config config=new Config();
        config.protocol="https";
        config.regionId="central";
        return new Client(config);
    }

    /**
     * 在使用accessToken时,请注意:
     * accessToken的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的accessToken。
     * 开发者需要缓存accessToken,用于后续接口的调用。因为每个应用的accessToken是彼此独立的,所以进行缓存时需要区分应用来进行存储。
     * 不能频繁调用接口,否则会受到频率拦截。
     *
     * @param corpId
     * @param ssoSecret
     * @return
     */
    public static String getAccessToken(String corpId, String ssoSecret) throws Exception {

        Client client = DingTalkUtil.creatClient();
        GetSsoAccessTokenRequest  getSsoAccessTokenRequest = new GetSsoAccessTokenRequest().setCorpid(corpId).setSsoSecret(ssoSecret);

        try {
            GetSsoAccessTokenResponse response = client.getSsoAccessToken(getSsoAccessTokenRequest);
            if(ObjectUtil.isNotEmpty(response)){
                return response.getBody().getAccessToken();
            }
        } catch (TeaException err) {
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
//                System.out.println("获取accessToken发生TeaException错误:"+err.message);
                throw new Exception(err.getMessage());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
//                System.out.println("获取accessToken发生Exception错误:"+err.message);
                throw new Exception(err.getMessage());
            }

        }
        return null;
    }

    public static String getAccessToken2(String appKey,String appSecret){
        try {
            DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlConstant.GET_ACCESS_TOKEN_URL);
            OapiGettokenRequest req = new OapiGettokenRequest();
            req.setAppkey(appKey);
            req.setAppsecret(appSecret);
            req.setHttpMethod("GET");
            OapiGettokenResponse rsp = client.execute(req);
            //System.out.println(rsp.getBody());
            return rsp.getAccessToken();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取jsapi_ticket
     * @param access_token
     * @return
     */
    public static String getJsapiTicket(String access_token) throws Exception {

        Client client = DingTalkUtil.creatClient();
        CreateJsapiTicketHeaders createJsapiTicketHeaders = new CreateJsapiTicketHeaders();
        createJsapiTicketHeaders.xAcsDingtalkAccessToken=access_token;

        try {

            CreateJsapiTicketResponse response =  client.createJsapiTicketWithOptions(createJsapiTicketHeaders, new RuntimeOptions());
            if(ObjectUtil.isNotEmpty(response)){
                return response.getBody().getJsapiTicket();
            }
        } catch (TeaException err) {
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
//                System.out.println("获取jsapiTicket发生TeaException错误:"+err.message);
                throw new Exception(err.getMessage());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!Common.empty(err.code) && !Common.empty(err.message)) {
                // err 中含有 code 和 message 属性,可帮助开发定位问题
//                System.out.println("获取jsapiTicket发生Exception错误:"+err.message);
                throw new Exception(err.getMessage());
            }

        }
        return null;

    }

}

还有一些自己写的service这个最好去看旧文档 直接copy

package com.ruoyi.app.service;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.dingtalkoauth2_1_0.Client;
import com.aliyun.dingtalkoauth2_1_0.models.GetSsoUserInfoHeaders;
import com.aliyun.dingtalkoauth2_1_0.models.GetSsoUserInfoRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetSsoUserInfoResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teautil.Common;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.ruoyi.app.config.DingConfig;
import com.ruoyi.app.constant.DingTalkUrlConstant;
import com.ruoyi.app.model.SignatureParams;
import com.ruoyi.app.utils.DingTalkUtil;
import com.taobao.api.ApiException;
import com.taobao.api.FileItem;
import com.taobao.api.internal.util.WebUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.URL;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.util.*;

@Slf4j
@Service
public class DingTalkService {
    @Resource
    private DingConfig dingConfig;

    // 获取UserID
    public String getUserId(String code) throws Exception {
        try {
            DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlConstant.GET_USER_INFO_URL);
            OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
            req.setCode(code);
            OapiV2UserGetuserinfoResponse rsp = client.execute(req, getAccessToken());
            if(rsp.isSuccess()){
                OapiV2UserGetuserinfoResponse.UserGetByCodeResponse userGetByCodeResponse = rsp.getResult();
                return userGetByCodeResponse.getUserid();
            } else {
                throw new Exception(rsp.getErrmsg());
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }


    // 开启分块上传事务
  public String upload(String code ,String accessToken) throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/file/upload/transaction");
      OapiFileUploadTransactionRequest request = new OapiFileUploadTransactionRequest();
      request.setAgentId(dingConfig.getAgentId().toString());
      request.setFileSize(1000L);
      request.setChunkNumbers(1L);
      request.setHttpMethod("GET");
      OapiFileUploadTransactionResponse response = client.execute(request,accessToken);
    System.out.println(response.getBody());
    if(response.isSuccess()) {
        return response.getUploadId();
    } else {
        throw new Exception(response.getErrmsg());
    }
    }
    //上传文件块
    public String uploadChunk(String accessToken) throws Exception {

        OapiFileUploadChunkRequest request = new OapiFileUploadChunkRequest();
        request.setAgentId(dingConfig.getAgentId().toString());
        request.setChunkSequence(1L);
        request.setUploadId("你的id");
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/file/upload/chunk?"+ WebUtils.buildQuery(request.getTextParams(),"utf-8"));
        request = new OapiFileUploadChunkRequest();
      //老文档 这些都废了


        request.setFile(new FileItem("C://Users//ccy//Desktop//1.pdf"));

        OapiFileUploadChunkResponse response = client.execute(request,accessToken);
        System.out.println(response.getBody());
        return response.getBody();
    }




    public Map getUserIdName(String code) throws Exception {
        try {
            DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlConstant.GET_USER_INFO_URL);
            OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
            req.setCode(code);
            OapiV2UserGetuserinfoResponse rsp = client.execute(req, getAccessToken());
            if(rsp.isSuccess()){
                OapiV2UserGetuserinfoResponse.UserGetByCodeResponse userGetByCodeResponse = rsp.getResult();
                Map map = new HashMap();
                map.put("userId",userGetByCodeResponse.getUserid());
                map.put("userName",userGetByCodeResponse.getName());
                return  map;
            } else {
                throw new Exception(rsp.getErrmsg());
            }
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }


    //提交文件上传事务
    public String uploadTransaction(String accessToken) throws Exception {

        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/file/upload/transaction");
        OapiFileUploadTransactionRequest request = new OapiFileUploadTransactionRequest();
        request.setAgentId(dingConfig.getAgentId().toString());
        request.setFileSize(1000L);
        request.setChunkNumbers(1L);
        request.setUploadId("你的上传ID");
        request.setHttpMethod("GET");
        OapiFileUploadTransactionResponse response = client.execute(request,accessToken);
        System.out.println(response.getBody());
        return response.getBody();
    }


    //上传文件转存到钉盘
    public String dinpand (String code ,String accessToken) throws Exception{
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/cspace/add");
        OapiCspaceAddRequest req = new OapiCspaceAddRequest();
        req.setAgentId(dingConfig.getAgentId().toString());
        req.setCode(code);
        req.setMediaId("上传成功返回的ud");
        req.setSpaceId("空间id");
        req.setName("3.pdf");
        req.setOverwrite(true);
        req.setHttpMethod("GET");
        OapiCspaceAddResponse rsp = client.execute(req, accessToken);
        System.out.println(rsp.getBody());
            return rsp.getBody();
    }



    // 获取钉钉用户详情
    public String getUserInfo(String userId ,String access_token) throws Exception {


        try {
            DingTalkClient client = new DefaultDingTalkClient(DingTalkUrlConstant.USER_GET_URL);
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            req.setLanguage("en_US");
            OapiV2UserGetResponse rsp = client.execute(req, access_token);

//            System.out.println(rsp.getBody());
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;
    }


    public String getlistparentbydept(String deptId ,String access_token) throws Exception {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listparentbydept");
            OapiV2DepartmentListparentbydeptRequest req = new OapiV2DepartmentListparentbydeptRequest();
            req.setDeptId(Long.valueOf(deptId));
            OapiV2DepartmentListparentbydeptResponse rsp = client.execute(req, access_token);
//            System.out.println(rsp.getBody());
            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;

    }


    public String getDeptName(Long deptId ,String access_token) throws Exception {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
            OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
            req.setDeptId(deptId);
            req.setLanguage("zh_CN");
            OapiV2DepartmentGetResponse rsp = client.execute(req, access_token);
//            System.out.println(rsp.getBody());



            return rsp.getBody();
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return null;

    }


    // 获取用户信息详情
//public GetSsoUserInfoResponse getSsoUserInfo(String code) throws Exception {
//        try {
//            Client client = new Client(
//                dingConfig.getAppKey(),
//                dingConfig.getAppSecret()
//            );
//            GetSsoUserInfoRequest getSsoUserInfoRequest = new GetSsoUserInfoRequest();
//            getSsoUserInfoRequest.code = code;
//            GetSsoUserInfoHeaders getSsoUserInfoHeaders = new GetSsoUserInfoHeaders();
//            GetSsoUserInfoResponse getSsoUserInfoResponse = client.getSsoUserInfo(getSsoUserInfoRequest, getSsoUserInfoHeaders, new RuntimeOptions());
//            if (getSsoUserInfoResponse.success) {
//                return getSsoUserInfoResponse;
//            } else {
//                throw new Exception(getSsoUserInfoResponse.body);
//            }
//        } catch (TeaException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }



    // 获取accessToken
    public String getAccessToken() throws Exception {
        return DingTalkUtil.getAccessToken2(dingConfig.getAppKey(),dingConfig.getAppSecret());
    }

    public SignatureParams signature(String url) throws Exception{
        String accessToken=getAccessToken();
        String jsticket=DingTalkUtil.getJsapiTicket(accessToken);
        String nonceStr=getRandomStr(10);
        Long timeStamp=new Date().getTime();
        String plain = "jsapi_ticket=" + jsticket + "&noncestr=" + nonceStr + "&timestamp=" + String.valueOf(timeStamp)
            + "&url=" + decodeUrl(url);
        SignatureParams signatureParams=new SignatureParams();
        //ServiceResult result=ServiceResult.getSuccessResult();
        signatureParams.setAgentId(dingConfig.getAgentId());
        signatureParams.setCorpId(dingConfig.getCorpId());
        signatureParams.setAccessToken(accessToken);
        signatureParams.setJsticket(jsticket);
        signatureParams.setNonceStr(nonceStr);
        signatureParams.setTimeStamp(timeStamp);
        signatureParams.setUrl(url);
        try {
            MessageDigest sha1 = MessageDigest.getInstance("SHA-256");
            sha1.reset();
            sha1.update(plain.getBytes("UTF-8"));
            signatureParams.setSignature(byteToHex(sha1.digest()));
            //return byteToHex(sha1.digest());
            return signatureParams;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    // 字节数组转化成十六进制字符串
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    /**
     * 因为ios端上传递的url是encode过的,android是原始的url。开发者使用的也是原始url,
     * 所以需要把参数进行一般urlDecode
     *
     * @param url
     * @return
     * @throws Exception
     */
    private static String decodeUrl(String url) throws Exception {
        URL urler = new URL(url);
        StringBuilder urlBuffer = new StringBuilder();
        urlBuffer.append(urler.getProtocol());
        urlBuffer.append(":");
        if (urler.getAuthority() != null && urler.getAuthority().length() > 0) {
            urlBuffer.append("//");
            urlBuffer.append(urler.getAuthority());
        }
        if (urler.getPath() != null) {
            urlBuffer.append(urler.getPath());
        }
        if (urler.getQuery() != null) {
            urlBuffer.append('?');
            urlBuffer.append(URLDecoder.decode(urler.getQuery(), "utf-8"));
        }
        return urlBuffer.toString();
    }

    public static String getRandomStr(int count) {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}

静态常量

package com.ruoyi.app.constant;

/**
 * 钉钉开放接口网关常量
 */
public class DingTalkUrlConstant {

    /**
     * 获取access_token url
     */
    public static final String GET_ACCESS_TOKEN_URL = "https://oapi.dingtalk.com/gettoken";

    /**
     * 获取jsapi_ticket url
     */
    public static final String GET_JSAPI_TICKET_URL = "https://oapi.dingtalk.com/oauth2/jsapiTickets";

    /**
     * 通过免登授权码获取用户信息 url
     */
    public static final String GET_USER_INFO_URL = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo";
    /**
     * 根据用户id获取用户详情 url
     */
    public static final String USER_GET_URL = "https://oapi.dingtalk.com/topapi/v2/user/get";

    /**
     * 发送消息 url
     */
    public static final String SEND_MESSAGE_URL = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2";

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值