.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();
            }
        }

 

      



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM