.Net钉钉开发笔记

首选要先理解钉钉的几个应用,因为应用不同,对应的接口也不一样,能够调用的权限也不一样,所以首先不要盲目的开发,看文档。

 

 

 也就是这四个。总体来说,如果你只是想在钉钉上开个门,用来进到自己的H5应用,就直接选微应用,然后如果你是要上架到应用市场去就选第三方企业应用。如果选择小程序就比较麻烦,针对ISV接口会不同,第三方企业应用的前端接口更加丰富。咱们主要讲微应用。微应用的前端API也有发Ding功能

开发:

首先你要下载钉钉sdk下载地址:https://ding-doc.dingtalk.com/doc#/faquestions/vzbp02

你可以自己用钉钉账号创建一个企业,创建部门、员工、用作测试。然后创建一个企业内部微应用。

获取Token方法:

 /// <summary>
        /// 获取token
        /// </summary>
        /// <returns></returns>
        public static string GetAccessToken()
        {
            var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");

            OapiGettokenRequest tokenRequest = new OapiGettokenRequest();
            tokenRequest.Corpid = Global.AppKey;
            tokenRequest.Corpsecret = Global.AppSecret;
            tokenRequest.SetHttpMethod("get");
            Api.Response.OapiGettokenResponse retString = client.Execute(tokenRequest);

            ////根据CorpId和CorpSecret发送get请求获得access_token
            //string url = string.Format("https://oapi.dingtalk.com/gettoken?corpid={0}&corpsecret={1}", Global.CorpId, Global.CorpSecret);
            ////返回内容
            //string retString = HttpMethod.HttpGet(url);
            //TokenEntity.TokenData obj = retString.ToObject<TokenEntity.TokenData>();
            if (retString.Errmsg == "ok")
            {
                string accessToken = retString.AccessToken;
              
                Access_Token = accessToken;
                //DingTalk.Log.Info($"钉钉 获取TOKNE:{accessToken}");
                return accessToken;
            }
            else
            {
                string message = "钉钉 获取TOKEN失败\r\n{" + retString.Errmsg + "}\r\nCORPID:{" + Global.AppKey + "}\r\nCORPSECRET:{" + Global.AppSecret + "}";
                return message;
            }
        }
Global方法:
 public class Global
    {

        private static string _AppKey = string.Empty;
        /// <summary>
        /// CorpId
        /// </summary>
        public static string AppKey
        {
            get
            {
                if (_AppKey.IsNullOrEmpty())
                {
                    try
                    {
                        _AppKey = ConfigurationManager.AppSettings["AppKey"];
                    }
                    catch { }
                }
                return _AppKey;
            }
        }

        public static string _AppId = string.Empty;
        /// <summary>
        /// CorpSecret
        /// </summary>
        public static string AppId
        {
            get
            {
                if (_AppId.IsNullOrEmpty())
                {
                    try
                    {
                        _AppSecret = ConfigurationManager.AppSettings["AppId"];
                    }
                    catch { }
                }
                return _AppSecret;
            }
        }

        public static string _AppSecret = string.Empty;
        /// <summary>
        /// CorpSecret
        /// </summary>
        public static string AppSecret
        {
            get
            {
                if (_AppSecret.IsNullOrEmpty())
                {
                    try
                    {
                        _AppSecret = ConfigurationManager.AppSettings["AppSecret"];
                    }
                    catch { }
                }
                return _AppSecret;
            }
        }


        private static long _AgentId = 0;

        /// <summary>
        /// 微应用agentId
        /// </summary> 
        public static long AgentId
        {
            get
            {
                if (_AgentId.Equals(0))
                {
                    try
                    {
                        _AgentId = Convert.ToInt64(System.Configuration.ConfigurationManager.AppSettings["AgentId"]);
                    }
                    catch { }
                }
                return _AgentId;
            }
        }

       
        private static string _suiteKey = string.Empty;

        public static string suiteKey
        {
            get
            {
                if (_suiteKey.IsNullOrEmpty())
                {
                    try
                    {
                        _suiteKey = ConfigurationManager.AppSettings["suiteKey"];
                    }
                    catch { }
                }
                return _suiteKey;
            }
        }

        private static string _suiteSecret = string.Empty;

        public static string suiteSecret
        {
            get
            {
                if (_suiteSecret.IsNullOrEmpty())
                {
                    try
                    {
                        _suiteSecret = ConfigurationManager.AppSettings["suiteSecret"];
                    }
                    catch { }
                }
                return _suiteSecret;
            }
        }

        private static long _suiteId = 0;

        public static long suiteId
        {
            get
            {
                if (_suiteId.Equals(0))
                {
                    try
                    {
                        _suiteId = Convert.ToInt64(System.Configuration.ConfigurationManager.AppSettings["suiteId"]);
                    }
                    catch { }
                }
                return _suiteId;
            }
        }

        /// <summary>
        ///  <!--加密Token-->
        /// </summary>
        private static string _Token = string.Empty;

        public static string Token
        {
            get
            {
                if (_Token.IsNullOrEmpty())
                {
                    try
                    {
                        _Token = ConfigurationManager.AppSettings["Token"];
                    }
                    catch { }
                }
                return _Token;
            }
        }

        /// <summary>
        ///  <!--数据加密秘钥-->
        /// </summary>
        private static string _SecretKey = string.Empty;

        public static string SecretKey
        {
            get
            {
                if (_SecretKey.IsNullOrEmpty())
                {
                    try
                    {
                        _SecretKey = ConfigurationManager.AppSettings["SecretKey"];
                    }
                    catch { }
                }
                return _SecretKey;
            }
        }

        /// <summary>
        /// 企业ID
        /// </summary>
        private static string _CorpId = string.Empty;

        public static string CorpId
        {
            get
            {
                if (_CorpId.IsNullOrEmpty())
                {
                    try
                    {
                        _CorpId = ConfigurationManager.AppSettings["CorpId"];
                    }
                    catch { }
                }
                return _CorpId;
            }
        }
    }

企业内部应用主要用到:AppKey和AppSecret以及AgentId

获取部门用户列表,注意,先根据Token权限获取部门ID,然后获取该部门下面的用户列表,另外获取部门那个接口是获取一级部门,如果有二级部门就查不出来,需要递归去查询,然后根据部门ID集合去查询用户列表,另外建议自己写个实体类加上注释,用来反序列化存储钉钉返回的数据

 public class UserUtil
    {

        public ArrayList al = new ArrayList();
        public ArrayList al2 = new ArrayList();
        /// <summary>
        /// 根据部门ID获取该部门下面的用户列表
        /// </summary>
        /// <returns></returns>
        public List<userlist> GetUserInfoListByDepartment()
        {
            try
            {
                //获取access_token
                string access_token = TokenUtil.GetAccessToken();
                if (string.IsNullOrEmpty(access_token)) return null;
                DepartmentResult departmentResult = DepartmentUtil.GetDepartmentInfo();
                
                if (departmentResult.errcode != 0 || departmentResult.department.Count <= 0)
                    return null;
                List<userlist> userList = new List<userlist>();

                foreach (var item in departmentResult.department)
                {
                    //根据部门ID获取部门人员详情
                    string url = "https://oapi.dingtalk.com/user/list?access_token=" + access_token + "&department_id=" + item.id;
                    var client = new DefaultDingTalkClient(url);
                    OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
                    req.SetHttpMethod("get");
                    var retString = client.Execute(req);
                    //Log.Info($"获取钉钉用户列表结果:{retString.Body}");
                    var userResult = JsonConvert.DeserializeObject<UserResult>(retString.Body);
                    if (userResult.errcode == 0 && userResult.userlist != null && userResult.userlist.Count > 0)
                    {
                        userList.AddRange(userResult.userlist);//添加人员信息到集合中 
                    }
                }
                 
                return userList;
            }
            catch (Exception ex)
            {
                //Log.Error("获取钉钉用户列表异常");
                //Log.Error(ex);
                return new List<userlist>();
            }
        }

        /// <summary>
        /// 先根据Token权限获取部门ID,然后获取该部门下面的用户列表
        /// </summary>
        /// <returns></returns>
        public List<userlist> GetUserInfoListByDepartmentQx()
        {
            try
            {
                //获取access_token
                string access_token = TokenUtil.GetAccessToken();
                if (string.IsNullOrEmpty(access_token)) return null;
                DepartmentPowerEntity departmentpowerentity = DepartmentUtil.GetPowerDepartmentInfo();

                if (departmentpowerentity.errcode != 0)
                    return null;

                List<userlist> userList = new List<userlist>();

                foreach (var item in departmentpowerentity.auth_org_scopes.authed_dept)
                {
                    //根据部门ID获取部门人员详情
                    string url = "https://oapi.dingtalk.com/user/list?access_token=" + access_token + "&department_id=" + item;
                    var client = new DefaultDingTalkClient(url);
                    OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
                    req.SetHttpMethod("get");
                    var retString = client.Execute(req);
                    //Log.Info($"获取钉钉用户列表结果:{retString.Body}");
                    var userResult = JsonConvert.DeserializeObject<UserResult>(retString.Body);
                    if (userResult.errcode == 0 && userResult.userlist != null && userResult.userlist.Count > 0)
                    {
                        userList.AddRange(userResult.userlist);//添加人员信息到集合中 
                    }
                }
                return userList;
            }
            catch (Exception ex)
            {
                //Log.Error("获取钉钉用户列表异常");
                //Log.Error(ex);        
                return new List<userlist>();
            }
        }

        /// <summary>
        /// 递归查询所有的用户
        /// </summary>
        /// <returns></returns>
        public List<userlist> GetAllUserInfoListByDepartment()
        {
            try
            {
                //获取access_token
                string access_token = TokenUtil.GetAccessToken();
                if (string.IsNullOrEmpty(access_token)) return null;
                DepartmentPowerEntity departmentpowerentity = DepartmentUtil.GetPowerDepartmentInfo();

                if (departmentpowerentity.errcode != 0)
                    return null;

                for (int i = 0; i < departmentpowerentity.auth_org_scopes.authed_dept.Length; i++)
                {
                    al.Add(departmentpowerentity.auth_org_scopes.authed_dept[i]);
                }
                RecursionDepartment(al);

                List<userlist> userList = new List<userlist>();

                foreach (var m in al)
                {
                    al2.Add(m);
                }
                foreach (var n in al2)
                {
                    //根据部门ID获取部门人员详情
                    string url = "https://oapi.dingtalk.com/user/list?access_token=" + access_token + "&department_id=" + n;
                    var client = new DefaultDingTalkClient(url);
                    OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
                    req.SetHttpMethod("get");
                    var retString = client.Execute(req);
                    //Log.Info($"获取钉钉用户列表结果:{retString.Body}");
                    var userResult = JsonConvert.DeserializeObject<UserResult>(retString.Body);
                    if (userResult.errcode == 0 && userResult.userlist != null && userResult.userlist.Count > 0)
                    {
                        userList.AddRange(userResult.userlist);//添加人员信息到集合中 
                    }
                }

                return userList;
            }
            catch (Exception ex)
            {
                //Log.Error("获取钉钉用户列表异常");
                //Log.Error(ex);        
                return new List<userlist>();
            }
        }

        /// <summary>
        ///体验组织————递归查询所有的用户  
        /// </summary>
        /// <returns></returns>
        public List<userlist> ISV_GetAllUserInfoListByDepartment()
        {
            try
            {
                //获取access_token
                string access_token = TokenUtil.ISV_GetAccessToken();
                if (string.IsNullOrEmpty(access_token)) return null;
                DepartmentPowerEntity departmentpowerentity = DepartmentUtil.ISV_GetPowerDepartmentInfo();

                if (departmentpowerentity.errcode != 0)
                    return null;

                for (int i = 0; i < departmentpowerentity.auth_org_scopes.authed_dept.Length; i++)
                {
                    al.Add(departmentpowerentity.auth_org_scopes.authed_dept[i]);
                }
                RecursionDepartment(al);

                List<userlist> userList = new List<userlist>();

                foreach (var m in al)
                {
                    al2.Add(m);
                }
                foreach (var n in al2)
                {
                    //根据部门ID获取部门人员详情
                    string url = "https://oapi.dingtalk.com/user/list?access_token=" + access_token + "&department_id=" + n;
                    var client = new DefaultDingTalkClient(url);
                    OapiUserGetDeptMemberRequest req = new OapiUserGetDeptMemberRequest();
                    req.SetHttpMethod("get");
                    var retString = client.Execute(req);
                    //SimpleLog.Log.Info($"获取钉钉用户列表结果:{retString.Body}");
                    var userResult = JsonConvert.DeserializeObject<UserResult>(retString.Body);
                    if (userResult.errcode == 0 && userResult.userlist != null && userResult.userlist.Count > 0)
                    {
                        userList.AddRange(userResult.userlist);//添加人员信息到集合中 
                    }
                }

                return userList;
            }
            catch (Exception ex)
            {
                //Log.Error("获取钉钉用户列表异常");
                //Log.Error(ex);        
                return new List<userlist>();
            }
        }

        public void RecursionDepartment(ArrayList ids)
        {
            ArrayList list = new ArrayList();
            //第一次循环所有权限部门Id
            foreach (var n in ids)
            {

                //al第一次循环存有权限部门下面的所有子部门
                int[] kk = DepartmentUtil.GetAllAecondaryDepartmentInfo(n.ToString()).sub_dept_id_list;
                if (kk==null || kk.Length <= 0)
                    continue;
                for (int i = 0; i < kk.Length; i++)
                {
                    al2.Add(kk[i]);

                    //循环刷新存放子部门的部门Id集合
                    list.Add(kk[i]);
                }
            }
            if (list.Count == 0)
            {
                return;
            }
            RecursionDepartment(list);
        }


        /// <summary>
        /// 根据OA用户的手机号在钉钉
        /// </summary>
        /// <param name="mobile"></param>
        /// <returns></returns>
        public static userlist GetSingleUser(string mobile)
        {
            var userlist = UserList;
            userlist userInfo = new Model.userlist();
            foreach (var item in userlist)
            {
                if (item.mobile.Equals(mobile))
                {
                    userInfo = item;
                    break;
                }
            }
            return userInfo;
        }

        /// <summary>
        /// 将用户手机号分别映射成该用户在钉钉里面对应的USERID,便于用户后面发送短信
        /// </summary>
        /// <param name="mobilelist">将用户手机号集合</param>
        /// <returns></returns>
        public static string MapperUserIDToDingding(List<string> mobilelist)
        {
            var dingdinguser = UserList;
            var list = new List<string>();
            foreach (var oa in mobilelist)
            {
                foreach (var item in dingdinguser)
                {
                    if (oa.Equals(item.mobile))
                    {
                        list.Add(item.userid);
                        continue;
                    }
                }
            }
            return string.Join(",", from u in list select u);
        }


        #region 专用于存储钉钉用户
        private static object LockObject = new object();

        private static List<userlist> _userList = null;



        /// <summary>
        /// 用户保存所有用户信息
        /// </summary>
        public static List<userlist> UserList
        {
            get
            {
                if (_userList.IsNull())
                {
                    lock (LockObject)
                    {
                        if (_userList.IsNull())
                        {
                            //DingTalkLog.Log.Info($"开始获取钉钉用户列表。{_userList?.Count}");
                            _userList = new UserUtil().GetUserInfoListByDepartment();
                           // DingTalkLog.Log.Info("获取钉钉用户列表。{"++"_userList?.Count}");
                        }
                    }
                }
                return _userList;
            }
        }
        #endregion
    }

 

审批接口:
创建审批实例去看审批接口。说一下注册审批回调接口。上代码
注册:
protected void Button1_Click(object sender, EventArgs e)
    {
        string _token = TokenUtil.GetAccessToken();      //获取Token

        DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/call_back/register_call_back");
        OapiCallBackRegisterCallBackRequest request = new OapiCallBackRegisterCallBackRequest();

        request.Url = "https://***";      //回调Url

        request.AesKey = "";    //数据加密密钥。用于回调数据的加密,长度固定为43个字符,从a-z, A-Z, 0-9共62个字符中选取,您可以随机生成

        request.Token = "";  //加解密需要用到的token

        List<string> _arr = new List<string>();

        _arr.Add("bpms_task_change");              //需要监听的事件类型,具体填写方法看这里 https://open-doc.dingtalk.com/microapp/serverapi2/skn8ld

        _arr.Add("bpms_instance_change");

        request.CallBackTag = _arr;

        OapiCallBackRegisterCallBackResponse response = client.Execute(request, _token);
        string _str = response.Body;
        Response.Write(_str);
    }

当你随便注册了几个监听事件,想再加几个,发现提示已被注册,怎么办呢? https://ding-doc.dingtalk.com/doc#/serverapi2/pwz3r5

回调的接口代码,这个要上的话代码有点多,而且我官方的那个加密解密方法dll在我这报了错,我就自己copy过来写了,大概根据官方的那个JAVA去写,差不多,只是比如.setToken直接去掉Set,.Token=“Token”就可以了。

大概调用接口应该熟悉了,另外建议写个日志方法,在关键的地方加上日志,以便查错。这里发一个钉钉的Log方法吧

 public static void WriteLog(string strMemo)
        {
            string directoryPath = HttpContext.Current.Server.MapPath(@"Logs");
            string fileName = directoryPath + @"\log" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
            if (!Directory.Exists(directoryPath))
                Directory.CreateDirectory(directoryPath);
            StreamWriter sr = null;
            try
            {
                if (!File.Exists(fileName))
                {
                    sr = File.CreateText(fileName);
                }
                else
                {
                    sr = File.AppendText(fileName);
                }
                sr.WriteLine(DateTime.Now + ": " + strMemo);
            }
            catch (Exception ex)
            {
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
        }

 

      



 

posted @ 2019-09-26 16:33  三千弱水,取一瓢饮  阅读(1266)  评论(2编辑  收藏  举报