钉钉的文档写的比较宽泛,又更新比较快,所以在解决回调的对接后做个记录,避免后面再次踩坑,也给遇到困惑的大家带来一点灵感,互相帮助~
钉钉官方文档在这: https://developers.dingtalk.com/document/app/callback-overview,有需要的朋友自取。
所谓回调,我的简单理解就是由a(数据主系统)提供入口,b(第三方系统)通过a提供的开放的接口和方法进行授权、注册等一系列操作后,可以实现a有数据变动或业务操作时,调用b的接口从而触发业务关联和数据传输,达到独立系统之间数据同步和共享的目的。
一、登录开发后台创建应用,记录所需参数
首先我们在钉钉客户端进入后台管理,登录开发者后台,创建一个应用(这个应用目的就是配置钉钉http回调的url和需要订阅的哪些事件,意思就是比如需要钉钉用户新增时自动调用你的接口发消息啊,保存钉钉用户数据到你的数据库啊之类的,就需要在这里勾选用户新增事件,去订阅它)。
首先点应用进来,"基础信息"里面就看到有几个参数,我们只需记录这一个应用的Appkey即可,回调会用到。
二、配置key和token、回调地址
然后我们点左边导航的"事件订阅",里面有加密 aes_key、签名 token,可以自己设置,也可以点随机生成,这两个参数也是注册回调需要用到的,小笔记录起!然后我们看到下面还有一个请求网址,这个就是我们自己的接口地址(必须要公网能访问)了,用来接收钉钉触发了订阅的事件,向我们发起的请求。
三、编写回调接口地址代码
我的接口地址配置的如上图,对应代码如下。
/// <summary>
/// 钉钉注册的回调地址
/// </summary>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <param name="body"></param>
/// <returns></returns>
[HttpPost]
[Route("Api/DINGDV2/CallBack")]
public dynamic CallBack(string signature, string timestamp, string nonce, PostBody body)
{
//接收encrypt参数
string encryptStr = body.encrypt.Replace("{\"encrypt\":\"", "").Replace("\"}", "");
//应用签名Token
string token = "Token";
//应用加密 aes_key
string aes_key = "aes_key";
//应用appKey
string suitekey = "appKey";
#region 验证回调的url
DingTalkCrypt dingTalk = new DingTalkCrypt(token, aes_key, suitekey);
string sEchoStr = "";
int ret = dingTalk.VerifyURL(signature, timestamp, nonce, encryptStr, ref sEchoStr);
#endregion
#region 解密接受信息,进行事件处理
string plainText = "";
ret = dingTalk.DecryptMsg(signature, timestamp, nonce, encryptStr, ref plainText);
Hashtable tb = (Hashtable)JsonConvert.DeserializeObject(plainText, typeof(Hashtable));
string eventType = tb["EventType"].ToString();
string res = "success";//固定字符,加密返回后验证合法性
#region 根据触发的事件编写自己的业务逻辑
//用户新增事件
if (eventType == "user_add_org")
{}
//用户离职事件
if (eventType == "user_leave_org")
{}
#endregion
DateTime dt1 = Convert.ToDateTime("1970-01-01 00:00:00");
TimeSpan ts = DateTime.Now - dt1;
long time = (long)Math.Ceiling(ts.TotalSeconds);
timestamp = time.ToString();//DateTime.Now.GetTimeStamp().ToString();
string encrypt = "";
string signature2 = "";
dingTalk = new DingTalkCrypt(token, aes_key, suitekey);
ret = dingTalk.EncryptMsg(res, timestamp, nonce, ref encrypt, ref signature2);
Hashtable jsonMap = new Hashtable
{
{"msg_signature", signature2},
{"encrypt", encrypt},
{"timeStamp", timestamp},
{"nonce", nonce}
};
return Json(jsonMap);
#endregion
}
相信大家都是看了钉钉文档才到网上搜坑的吧,那我就不多解释,请求的几个参数:string signature, string timestamp, string nonce, PostBody body,意思就是为了验证你的接口的有效合法性,你要拿来解密处理,并在1500ms内返回包含success的加密字符串(JSON格式)就可以了,就认为你的接口是正常的,可以放心把数据推送给你啦,如果验证失败,会判定为失败的回调信息,具体返回的信息在文档中有解释,什么参数错误啊之类的多检查就好了。这几个参数传入格式是钉钉固定的格式,照着写就是。
代码中用到了在钉钉git上淘的两个加密解密的帮助类DingTalkCrypt、Cryptography,有需要的朋友点这里下载完整代码查看~完整代码.zzziiippp
四、选择需要订阅的事件
OK,回调接口也写完了,接下来就是订阅事件了,回到开发者后台,我们创建的应用,还是点开左边栏的事件订阅,往下滑,我们看到有很多的事件,根据业务需要进行选择就可以了,比如
我代码里面写的"eventType == "user_add_org"",对应的事件就是通讯录用户新增事件,勾选之后,用户新增之后就会触发接口,根据eventType进行区分,进而触发我们自己编写的业务代码,这样就实现了回调。