钉钉开发文档

接收回调消息

更新时间: 2018-6-25

在接收回调消息之前您首先要拿到您创建应用时填写的"回调URL","Token","数据加密密钥(ENCODING_AES_KEY)",点击应用管理-应用信息-查看详情可以看到:

undefined

参数说明

参数 说明
回调URL ISV接收钉钉推送数据的地址
Token ISV在注册时任意填写的(建议3~32位英文字母+数字组合),用来生成signature,并和回调参数中的signature比对,校验消息的合法性
数据加密密钥(ENCODING_AES_KEY) 用于消息体的加解密
suiteKey 应用key

回调地址说明

钉钉服务器会向开发者创建应用时填写的回调URL定时推送SuiteTicket,以及临时授权码和授权变更等事件。

以服务端QuickStart的java版本 CallbackController做示例,您提供的回调URL是:

http://您服务端部署的IP:您的端口/callback

钉钉服务器每一次访问回调URL的时候将发出如下请求(下面链接中的signature,timestamp,nonce的值只是示例,并不代表真实值):

http://您服务端部署的IP:您的端口/callback?signature=111108bb8e6dbce3c9671d6fdb69d15066227608&timestamp=1783610513&nonce=380320111

包含的json数据为:

{
"encrypt":"1ojQf0NSvw2WPvW7LijxS8UvISr8pdDP+rXpPbcLGOmIBNbWetRg7IP0vdhVgkVwSoZBJeQwY2zhROsJq/HJ+q6tp1qhl9L1+ccC9ZjKs1wV5bmA9NoAWQiZ+7MpzQVq+j74rJQljdVyBdI/dGOvsnBSCxCVW0ISWX0vn9lYTuuHSoaxwCGylH9xRhYHL9bRDskBc7bO0FseHQQasdfghjkl"
}

其中的encrypt字段是经过加密的消息体,encrypt经过解密验签步骤后,产生json数据,根据内容可以区分不同事件,事件类型详见回调协议章节。

消息体解密示例

try {
         // 创建加解密类
         // 第一个参数为创建应用之时填写的token
         // 第二个参数为创建应用之时生成的数据加密密钥(ENCODING_AES_KEY)
         // 第三个参数,ISV开发传入应用的suiteKey
         // 具体参数值请查看开发者后台(//open-dev.dingtalk.com)
         // 注:其中,对于第三个参数,在第一次接受『验证回调URL有效性事件的时候』
         // 传入Env.CREATE_SUITE_KEY,对于这种情况,已在异常中catch做了处理。
         //  
        dingTalkEncryptor = new DingTalkEncryptor(Env.TOKEN, Env.ENCODING_AES_KEY, Env.SUITE_KEY);
         // 
         // 获取从encrypt解密出来的明文
         // 
        plainText = dingTalkEncryptor.getDecryptMsg(msgSignature, timeStamp, nonce, encrypt);
    } catch (DingTalkEncryptException e) {
        // TODO Auto-generated catch block
        dingTalkEncryptException = e;
        e.printStackTrace();
    } finally {
 
    }
 
    // 
    //  对从encrypt解密出来的明文进行处理
    //  不同的eventType的明文数据格式不同
    // 
 
    JSONObject plainTextJson = JSONObject.parseObject(plainText);
    String eventType = plainTextJson.getString("EventType");
    // res是需要返回给钉钉服务器的字符串,一般为success
    // "check_create_suite_url"和"check_update_suite_url"事件为random字段
    // 具体请查看文档或者对应eventType的处理步骤
    // 
    String res = "success";
 
    switch (eventType) {
        case "check_create_suite_url":
            //可返回表明服务端“收到了”的字段
            break;
    }
 
    //  对返回信息进行加密
    long timeStampLong = Long.parseLong(timeStamp);
    Map<String, String> jsonMap = null;
    try {
        // 
        // jsonMap是需要返回给钉钉服务器的加密数据包
        // 
        jsonMap = dingTalkEncryptor.getEncryptedMap(res, timeStampLong, nonce);
    } catch (DingTalkEncryptException e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    JSONObject json = new JSONObject();
    json.putAll(jsonMap);
    response.getWriter().append(json.toString());

除此之外,在接收到推送之后,需要返回相应的加密字符串(代表了你收到了推送)。

demo代码 地址
示例代码 CallbackController.java
加解密方案说明 加解密方案说明

温馨提示:如果您需要在没有公网IP或域名的服务器上(比如您自己的办公电脑)调试回调URL,可借助内网穿透工具映射一个可公网访问的地址,注意仅用于测试开发阶段。