Java集成钉钉配置代理给个人推送工作通知

        项目需求利用钉钉做工作通知发送给个人功能,由于用公司内网,程序设置代理的设置看了无数帖子,吐血整理出测试成功的代码,供有需求的人取之。

一、准备工作

        1.在钉钉开放平台创建应用,获取应用凭证(AgentId、AppKey、AppSecret)

         2.在pom.xml中写入钉钉依赖

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

二、实现代理

        由于钉钉开发文档中没有设置代理这个功能,只能是修改源码进行代理设置

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkConstants;
import com.dingtalk.api.DingTalkSignatureUtil;
import com.taobao.api.*;
import com.taobao.api.internal.parser.json.ObjectJsonParser;
import com.taobao.api.internal.util.*;

import javax.net.ssl.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

import static com.taobao.api.internal.util.WebV2Utils.*;


public class DefaultProxyDingTalkClient extends DefaultDingTalkClient {

    private static boolean ignoreSSLCheck = true;
    private static boolean ignoreHostCheck = true;

    public DefaultProxyDingTalkClient(String serverUrl, Proxy proxy) {
        super(serverUrl);
        this.setProxy(proxy);
    }

    @Override
    public <T extends TaobaoResponse> T execute(TaobaoRequest<T> request, String session) throws ApiException {
        if (request.getTopApiCallType() == null || request.getTopApiCallType().equals(DingTalkConstants.CALL_TYPE_TOP)) {
            return super.execute(request, session);
        } else {
            return executeOApi(request, session);
        }
    }

    @Override
    public <T extends TaobaoResponse> T execute(TaobaoRequest<T> request, String accessKey, String accessSecret, String suiteTicket, String corpId) throws ApiException {
        if (request.getTopApiCallType() == null || request.getTopApiCallType().equals(DingTalkConstants.CALL_TYPE_TOP)) {
            return super.execute(request, null);
        } else {
            return executeOApi(request, null, accessKey, accessSecret, suiteTicket, corpId);
        }
    }


    private <T extends TaobaoResponse> T executeOApi(TaobaoRequest<T> request, String session) throws ApiException {
        return executeOApi(request, session, null, null, null, null);
    }

    private <T extends TaobaoResponse> T executeOApi(TaobaoRequest<T> request, String session, String accessKey, String accessSecret, String suiteTicket, String corpId) throws ApiException {
        long start = System.currentTimeMillis();
        // 构建响应解释器
        TaobaoParser<T> parser = null;
        if (this.needEnableParser) {
            parser = new ObjectJsonParser<T>(request.getResponseClass(), true);
        }

        // 本地校验请求参数
        if (this.needCheckRequest) {
            try {
                request.check();
            } catch (ApiRuleException e) {
                T localResponse = null;
                try {
                    localResponse = request.getResponseClass().newInstance();
                } catch (Exception xe) {
                    throw new ApiException(xe);
                }
                localResponse.setErrorCode(e.getErrCode());
                localResponse.setMsg(e.getErrMsg());
                return localResponse;
            }
        }

        RequestParametersHolder requestHolder = new RequestParametersHolder();
        TaobaoHashMap appParams = new TaobaoHashMap(request.getTextParams());
        requestHolder.setApplicationParams(appParams);

        // 添加协议级请求参数
        TaobaoHashMap protocalMustParams = new TaobaoHashMap();
        protocalMustParams.put(DingTalkConstants.ACCESS_TOKEN, session);
        requestHolder.setProtocalMustParams(protocalMustParams);


        try {
            String fullUrl;
            // 签名优先
            if (accessKey != null) {
                Long timestamp = System.currentTimeMillis();
                // 验证签名有效性
                String canonicalString = DingTalkSignatureUtil.getCanonicalStringForIsv(timestamp, suiteTicket);
                String signature = DingTalkSignatureUtil.computeSignature(accessSecret, canonicalString);
                Map<String, String> ps = new HashMap<String, String>();
                ps.put("accessKey", accessKey);
                ps.put("signature", signature);
                ps.put("timestamp", timestamp + "");
                if (suiteTicket != null) {
                    ps.put("suiteTicket", suiteTicket);
                }
                if (corpId != null) {
                    ps.put("corpId", corpId);
                }

                String queryStr = DingTalkSignatureUtil.paramToQueryString(ps, "utf-8");
                if (this.serverUrl.indexOf("?") > 0) {
                    fullUrl = this.serverUrl + "&" + queryStr;
                } else {
                    fullUrl = this.serverUrl + "?" + queryStr;
                }
            } else {
                if (this.serverUrl.indexOf("?") > 0) {
                    fullUrl = this.serverUrl + (session != null && session.length() > 0 ? ("&access_token=" + session) : "");
                } else {
                    fullUrl = this.serverUrl + (session != null && session.length() > 0 ? ("?access_token=" + session) : "");
                }
            }

            HttpResponseData data = null;
            // 是否需要压缩响应
            if (this.useGzipEncoding) {
                request.getHeaderMap().put(Constants.ACCEPT_ENCODING, Constants.CONTENT_ENCODING_GZIP);
            }

            if ("GET".equals(request.getTopHttpMethod())) {
                data = doGet(fullUrl, appParams, Constants.CHARSET_UTF8, connectTimeout, readTimeout);
            } else {
                // 是否需要上传文件
                if (request instanceof TaobaoUploadRequest) {
                    TaobaoUploadRequest<T> uRequest = (TaobaoUploadRequest<T>) request;
                    Map<String, FileItem> fileParams = TaobaoUtils.cleanupMap(uRequest.getFileParams());
                    //todo 这里添加代理, 可以进入WebV2Utils 类中,参考接口调用时, 传参proxy的地方,自己改写下
                    data = WebV2Utils.doPost(fullUrl, appParams, fileParams, Constants.CHARSET_UTF8, connectTimeout, readTimeout, request.getHeaderMap());
                } else {

                    Map<String, Object> jsonParams = new HashMap<String, Object>();
                    for (Map.Entry<String, String> paramEntry : appParams.entrySet()) {
                        String key = paramEntry.getKey();
                        String value = paramEntry.getValue();
                        if (value.startsWith("[") && value.endsWith("]")) {
                            List<Map<String, Object>> childMap = (List<Map<String, Object>>) TaobaoUtils.jsonToObject(value);
                            jsonParams.put(key, childMap);
                        } else if (value.startsWith("{") && value.endsWith("}")) {
                            Map<String, Object> childMap = (Map<String, Object>) TaobaoUtils.jsonToObject(value);
                            jsonParams.put(key, childMap);
                        } else {
                            jsonParams.put(key, value);
                        }
                    }
                    data = doPostWithJson(fullUrl, jsonParams, Constants.CHARSET_UTF8, connectTimeout, readTimeout);
                }
            }
            requestHolder.setResponseBody(data.getBody());
            requestHolder.setResponseHeaders(data.getHeaders());
        } catch (IOException e) {
            TaobaoLogger.logApiError("_dingtalk_", request.getApiMethodName(), serverUrl, requestHolder.getAllParams(), System.currentTimeMillis() - start, e.toString());
            throw new ApiException(e);
        }

        T tRsp = null;
        if (this.needEnableParser) {
            tRsp = parser.parse(requestHolder.getResponseBody(), Constants.RESPONSE_TYPE_DINGTALK_OAPI);
            tRsp.setBody(requestHolder.getResponseBody());
        } else {
            try {
                tRsp = request.getResponseClass().newInstance();
                tRsp.setBody(requestHolder.getResponseBody());
            } catch (Exception e) {
                throw new ApiException(e);
            }
        }

        tRsp.setParams(appParams);
        if (!tRsp.isSuccess()) {
            TaobaoLogger.logApiError("_dingtalk_", request.getApiMethodName(), serverUrl, requestHolder.getAllParams(), System.currentTimeMillis() - start, tRsp.getBody());
        }
        return tRsp;
    }

    public HttpResponseData doGet(String url, Map<String, String> params, String charset, int connectTimeout, int readTimeout) throws IOException {
        HttpURLConnection conn = null;
        String rsp = null;
        HttpResponseData data = new HttpResponseData();

        try {
            String ctype = "application/x-www-form-urlencoded;charset=" + charset;
            String query = buildQuery(params, charset);
            conn = getConnection(buildGetUrl(url, query), "GET", ctype, (Map) null, this.getProxy());
            conn.setConnectTimeout(connectTimeout);
            conn.setReadTimeout(readTimeout);
            rsp = getResponseAsString(conn);
            data.setBody(rsp);
            data.setHeaders(conn.getHeaderFields());
        } finally {
            if (conn != null) {
                conn.disconnect();
            }

        }

        return data;
    }

    private static HttpURLConnection getConnection(URL url, String method, String ctype, Map<String, String> headerMap, Proxy proxy) throws IOException {
        HttpURLConnection conn = null;
        if (proxy == null) {
            conn = (HttpURLConnection)url.openConnection();
        } else {
            conn = (HttpURLConnection)url.openConnection(proxy);
        }

        if (conn instanceof HttpsURLConnection) {
            HttpsURLConnection connHttps = (HttpsURLConnection)conn;
            if (ignoreSSLCheck) {
                try {
                    SSLContext ctx = SSLContext.getInstance("TLS");
                    ctx.init((KeyManager[])null, new TrustManager[]{new TrustAllTrustManager()}, new SecureRandom());
                    connHttps.setSSLSocketFactory(ctx.getSocketFactory());
                    connHttps.setHostnameVerifier(new HostnameVerifier() {
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    });
                } catch (Exception var8) {
                    throw new IOException(var8.toString());
                }
            } else if (ignoreHostCheck) {
                connHttps.setHostnameVerifier(new HostnameVerifier() {
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            }

            conn = connHttps;
        }

        ((HttpURLConnection)conn).setRequestMethod(method);
        ((HttpURLConnection)conn).setDoInput(true);
        ((HttpURLConnection)conn).setDoOutput(true);
        if (headerMap != null && headerMap.get("TOP_HTTP_DNS_HOST") != null) {
            ((HttpURLConnection)conn).setRequestProperty("Host", (String)headerMap.get("TOP_HTTP_DNS_HOST"));
        } else {
            ((HttpURLConnection)conn).setRequestProperty("Host", url.getHost());
        }

        ((HttpURLConnection)conn).setRequestProperty("Accept", "text/xml,text/javascript");
        ((HttpURLConnection)conn).setRequestProperty("User-Agent", "top-sdk-java");
        ((HttpURLConnection)conn).setRequestProperty("Content-Type", ctype);
        if (headerMap != null) {
            Iterator var9 = headerMap.entrySet().iterator();

            while(var9.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry)var9.next();
                if (!"TOP_HTTP_DNS_HOST".equals(entry.getKey())) {
                    ((HttpURLConnection)conn).setRequestProperty((String)entry.getKey(), (String)entry.getValue());
                }
            }
        }

        return (HttpURLConnection)conn;
    }

    private static URL buildGetUrl(String url, String query) throws IOException {
        return StringUtils.isEmpty(query) ? new URL(url) : new URL(buildRequestUrl(url, query));
    }

    protected static String getResponseAsString(HttpURLConnection conn) throws IOException {
        String charset = getResponseCharset(conn.getContentType());
        if (conn.getResponseCode() < 400) {
            String contentEncoding = conn.getContentEncoding();
            return "gzip".equalsIgnoreCase(contentEncoding) ? getStreamAsString(new GZIPInputStream(conn.getInputStream()), charset) : getStreamAsString(conn.getInputStream(), charset);
        } else {
            if (conn.getResponseCode() == 400) {
                InputStream error = conn.getErrorStream();
                if (error != null) {
                    return getStreamAsString(error, charset);
                }
            }

            throw new IOException(conn.getResponseCode() + " " + conn.getResponseMessage());
        }
    }


    /**
     * 执行请求
     * content_type: aplication/json
     *
     * @param url
     * @param params
     * @param charset
     * @param connectTimeout
     * @param readTimeout
     * @return
     * @throws IOException
     */
    private HttpResponseData doPostWithJson(String url, Map<String, Object> params, String charset, int connectTimeout, int readTimeout) throws IOException {
        String ctype = "application/json;charset=" + charset;
        byte[] content = {};

        String body = TaobaoUtils.objectToJson(params);
        if (body != null) {
            content = body.getBytes(charset);
        }
        return WebV2Utils.doPost(url, ctype, content, connectTimeout, readTimeout, null, this.getProxy());
    }
}

三、编写工具类方法

import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiUserGetByMobileRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiUserGetByMobileResponse;
import com.dzbodyshop.daoke.ep.config.DefaultProxyDingTalkClient;
import com.taobao.api.ApiException;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 
 * @date 2022/8/25 14:04
 */
public class DingDingToPerUtil {

    //代理
    private final static String HOST = "xxxxxxx";
    private final static int PORT = xxxx;
    //AppKey
    private final static String DING_APP_KEY = "xxxxxxxxxx";
    //AppSecret
    private final static String DING_APP_SECRET = "xxxxxxxxxxxxxx";
    //AgentId
    private final static int DING_AGENT_ID = xxxxxx;

    /**
     * 获取AccessToken
     *
     * @return AccessToken
     * @throws ApiException
     */
    private static String getAccessToken() throws ApiException {
        DefaultDingTalkClient client = new DefaultProxyDingTalkClient("https://oapi.dingtalk.com/gettoken", proxy());

        OapiGettokenRequest request = new OapiGettokenRequest();
        //Appkey
        request.setAppkey(DING_APP_KEY);
        //Appsecret
        request.setAppsecret(DING_APP_SECRET);
        /*请求方式*/
        request.setHttpMethod("GET");

        OapiGettokenResponse response = client.execute(request);
        return response.getAccessToken();
    }

    /**
     * 根据手机号获取用户urid
     *
     * @param mobiles
     * @return
     * @throws ApiException
     */
    private static String getUridByMobile(String mobiles) throws ApiException {
        //获取应用密钥
        String accessToken = getAccessToken();
        String[] mobilesList = mobiles.split(",");
        List<String> list = new ArrayList<>();
        for (String mobile : mobilesList) {
            //根据手机号获取用户信息Urid
            DingTalkClient clientByMobile = new DefaultProxyDingTalkClient("https://oapi.dingtalk.com/user/get_by_mobile", proxy());
            OapiUserGetByMobileRequest req = new OapiUserGetByMobileRequest();
            req.setMobile(mobile);
            req.setHttpMethod("GET");
            OapiUserGetByMobileResponse rsp = clientByMobile.execute(req, accessToken);
            if (rsp.isSuccess()) {
                list.add(rsp.getUserid());
            }
        }
        return StringUtils.ListToString(list); // list转为String(逗号分隔)
    }

    public static Boolean workStatusNotice(String mobiles, String info) throws ApiException {
        //获取应用密钥
        String accessToken = getAccessToken();
        boolean result = true;
        //根据手机号获取用户信息Urid
        String uridList = getUridByMobile(mobiles);
        if (StringUtils.isEmpty(uridList)) {
            return false;
        }
        DingTalkClient client = new DefaultProxyDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2", proxy());
        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
        request.setUseridList(uridList); // 接收者的userid列表,最大用户列表长度100。
        request.setAgentId(Long.valueOf(DING_AGENT_ID)); // 发送消息时使用的微应用的AgentID
        request.setToAllUser(false); //是否发送给企业全部用户
        OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
        //文本消息
        OapiMessageCorpconversationAsyncsendV2Request.Text text = new OapiMessageCorpconversationAsyncsendV2Request.Text();
        text.setContent(info);
        msg.setMsgtype("text");
        msg.setText(text);
        request.setMsg(msg);
        OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request, accessToken);
        result = response.isSuccess();
        return result;
    }

    /**
     * 设置代理
     *
     * @return
     */
    private static Proxy proxy() {

        return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(HOST, PORT));
    }
}

写完收工,希望有帮助。

                            【开发云】年年都是折扣价,不用四处薅羊毛

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要实现钉钉消息推送,可以使用钉钉提供的开放平台API,具体步骤如下: 1. 首先在钉钉开放平台注册应用,获得相应的AppKey和AppSecret。 2. 在应用中创建一个机器人,并获得机器人Webhook地址。 3. 使用Java的HttpURLConnection或者HttpClient等工具,向机器人Webhook地址发送POST请求,请求内容为JSON格式的消息。 4. 在请求头中添加Content-Type和Charset等必要的参数。 5. 如果需要对消息进行加密,可以使用钉钉提供的加密算法进行加密。 6. 钉钉会对收到的消息进行安全校验,如果校验失败则无法正常推送消息。 7. 如果推送成功,钉钉会返回JSON格式的响应,可以根据响应结果判断是否推送成功。 下面是一个示例代码: ``` import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; public class DingTalkUtil { private static final String WEBHOOK_TOKEN = "机器人Webhook地址"; private static final String CONTENT_TYPE = "application/json"; private static final String CHARSET = "UTF-8"; public static void sendTextMessage(String message) { try { URL url = new URL(WEBHOOK_TOKEN); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", CONTENT_TYPE); conn.setRequestProperty("Charset", CHARSET); OutputStream os = conn.getOutputStream(); os.write(message.getBytes(CHARSET)); os.flush(); os.close(); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 处理推送成功的逻辑 } else { // 处理推送失败的逻辑 } conn.disconnect(); } catch (Exception e) { // 处理异常情况 } } } ``` 其中,sendTextMessage方法可以用来向机器人发送文本消息。需要注意的是,钉钉还支持发送Markdown格式和ActionCard格式的消息,具体使用方法可以参考钉钉开放平台文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欢脱野驴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值