前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >钉钉开发笔记

钉钉开发笔记

原创
作者头像
谭广健
发布2022-04-03 14:54:54
1.2K0
发布2022-04-03 14:54:54
举报
文章被收录于专栏:谭广健的专栏谭广健的专栏

钉钉作为一个热门的办公软件,很多公司都在用。我个人还是偏爱企业微信,但无奈要做一个与钉钉对接系统的中间件,就将这次钉钉开发的笔记写一下吧。首先钉钉的接口有新旧2种接口,但都是互通的;所以别害怕。接口接入首先要获得SDK,SDK从Java、Node.js、PHP、Go、C#和Python都有还有小例子,总体来说还是比较齐全(大厂一般都会提供,某度除外)。C# dotnet add packageCloud.SDK.Dingtalk 就可以安装了。

一、获得AccessToken

安装成功了就是进入第一关,获得AccessToken,这个基本就是入门的钥匙了。我这里写了2个方法,第一种方法比较简单,就是用旧接口,通过GET直接获得;

代码语言:javascript
复制
 public static OapiGettokenResponse GetAccessToken(string Appkey, string Appsecret)
        {
            DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.Appkey = Appkey;//Appkey
            request.Appsecret = Appsecret;//Appsecret
            request.SetHttpMethod("GET");
            OapiGettokenResponse response = client.Execute(request);          
            if (response.Errcode == 0)
            {
                return response;
            }
            else
            {              
                return null;
            }
        }

由于这个AccessToken都有时效性,所以我发现了第二种方法,但我没试。。。

代码语言:javascript
复制
        private static readonly long agentId =1;
        private static readonly string appkey = "******";
        private static readonly string appsecret = "******";
        private static string _accessToken = "";
        private static DateTime _accessTokenTime = DateTime.Now.AddMinutes(-1);
        public static string GetAccessToken()
        {
            //没有AccessToken或者AccessToken过期,则重新获取
            if (string.IsNullOrEmpty(_accessToken) || _accessTokenTime < DateTime.Now)
            {
                var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
                var req = new OapiGettokenRequest { Appkey = appkey, Appsecret = appsecret };
                req.SetHttpMethod("Get");
                var execute = client.Execute(req);
                if (execute.Errcode == 0)
                {
                    _accessToken = execute.AccessToken;
                    _accessTokenTime = DateTime.Now.AddHours(1);
                }
            }
            return _accessToken;
        }

二、捞取用户资料

我比较喜欢简单^_^,ok.获得了AccessToken我们就进行数据的捞取了,我们这里看看怎么捞取钉钉的人员吧。钉钉没有直接人员获得只能通过部门进行递归获得,至于如何递归,这个咱也会略提。

代码语言:javascript
复制
        /// <summary>
        ///     取得所有部门编号
        /// </summary>
        /// <returns></returns>
        public static List<long> GetDepartIds(long DeptId, string accesstoken)
        {
            var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsubid");
            var req = new OapiV2DepartmentListsubidRequest { DeptId = DeptId };
            var res = client.Execute(req, accesstoken);
            if (res.Errcode == 0) return res.Result.DeptIdList;
            return new List<long>();
        }        
        /// <summary>
        ///   取得部门详细资料,返回JSON
        /// </summary>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        public static void GetDepartSub(long DeptId,string accesstoken)
        {
            var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
            var req = new OapiV2DepartmentListsubidRequest { DeptId = DeptId };
            var res = client.Execute(req,accesstoken);
            JSON=res.Body;
        }
        
        /// <summary>
        ///     取得部门下用户列表(仅用户Id)
        /// </summary>
        /// <param name="depid"></param>
        /// <returns></returns>
        public static List<string> GetDepartUserIds(long depid, string accesstoken)
        {
            var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
            var req = new OapiUserListidRequest { DeptId = depid };
            var res = client.Execute(req,accesstoken);

            if (res.Errcode == 0)
            {
                if (res.Result == null) return new List<string>();
                if (res.Result.UseridList == null) return new List<string>();
                return res.Result.UseridList;
            }
            return new List<string>();
        }
        
        /// <summary>
        ///     根据用户UserId取得用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static string GetUserInfoByUserId(string userId, string accesstoken)
        {
            var client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            var req = new OapiV2UserGetRequest();
            req.Userid = userId;
            req.Language = "zh_CN";
            var res = client.Execute(req, accesstoken);
            if (res.Errcode == 0)
            {            
                return res.Result.Userid+"|"+res.Result.Unionid+"|"+ res.Result.Name+"|"+ res.Result.Mobile;
            } else { 
            return "";
            }
        }
        
        /// <summary>
        /// 获取用户详细资料
        /// </summary>
        /// <param name="Userid"></param>
        /// <param name="accesstoken"></param>
        /// <returns></returns>
        public static OapiUserGetResponse Getuserinfo(string Userid,string accesstoken)
        {
            
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
            OapiUserGetRequest request = new OapiUserGetRequest();            
            request.Userid = Userid;
            request.SetHttpMethod("GET");            
            OapiUserGetResponse response = client.Execute(request, accesstoken);
            if (response.Errcode == 0)
            {
                return response;
            }
            else
            {
                LogHelper.WriteLog(response.ErrMsg);
                return null;
            }
        }
        

以上旧API,但可以调出数据。如何能进行递归获取?好吧,下面就是递归的部分思路

代码语言:javascript
复制
            var Departinfo = DING_SDK.GetDepartIds(469151981,accesstoken.AccessToken);
            foreach (var departid in Departinfo) {                
                var Duserinfo_A = DING_SDK.GetDepartUserIds(departid, accesstoken.AccessToken);
                if (Duserinfo_A.Count > 0) {
                    foreach (var item in Duserinfo_A)
                    {
                        var Userinff = DING_SDK.GetUserInfoByUserId(item.ToString(), accesstoken.AccessToken);
                    }
                }
            };

三、新接口

最后给一下新接口的调用。

代码语言:javascript
复制
 /**
            * 使用 Token 初始化账号Client
            * @return Client
            * @throws Exception
            */
        public static AlibabaCloud.SDK.Dingtalktodo_1_0.Client CreateClient()
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config();
            config.Protocol = "https";
            config.RegionId = "central";
            return new AlibabaCloud.SDK.Dingtalktodo_1_0.Client(config);
        }


        public static void NEW_SDK(string accesstoken, string unionId) {
            AlibabaCloud.SDK.Dingtalktodo_1_0.Client client = CreateClient();
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.QueryOrgTodoTasksHeaders queryOrgTodoTasksHeaders = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.QueryOrgTodoTasksHeaders();
            queryOrgTodoTasksHeaders.XAcsDingtalkAccessToken = accesstoken;
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.QueryOrgTodoTasksRequest queryOrgTodoTasksRequest = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.QueryOrgTodoTasksRequest
            {
                NextToken = "0",
                //IsDone = true,
            };
            try
            {               
               var bbb=client.QueryOrgTodoTasksWithOptions(unionId, queryOrgTodoTasksRequest, queryOrgTodoTasksHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions());
            }
            catch (TeaException err)
            {
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
            catch (Exception _err)
            {
                TeaException err = new TeaException(new Dictionary<string, object>
                {
                    { "message", _err.Message }
                });
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
        }


        public static void Add_SDK(string accesstoken, string unionId)
        {

            AlibabaCloud.SDK.Dingtalktodo_1_0.Client client = CreateClient();
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskHeaders createTodoTaskHeaders = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskHeaders();
            createTodoTaskHeaders.XAcsDingtalkAccessToken = accesstoken;
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs
            {
                DingNotify = "1",
            };
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl
            {
                AppUrl = "https://www.dingtalk.com",
                PcUrl = "https://www.dingtalk.com",
            };
            AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest createTodoTaskRequest = new AlibabaCloud.SDK.Dingtalktodo_1_0.Models.CreateTodoTaskRequest
            {
                SourceId = "isv_disgtalkTodo1",
                Subject = "接入钉钉待办",
                CreatorId = unionId,
                Description = "应用可以调用该接口发起一个钉钉待办任务,该待办事项会出现在钉钉客户端“待办”页面,需要注意的是,通过开放接口发起的待办,目前仅支持直接跳转ISV应用详情页(ISV在调该接口时需传入自身应用详情页链接)。",
                DueTime = 1617675000000,
                ExecutorIds = new List<string>
                {
                   unionId
                },
                ParticipantIds = new List<string>
                {
                    unionId
                },
                DetailUrl = detailUrl,
                IsOnlyShowExecutor = true,
                Priority = 20,
                NotifyConfigs = notifyConfigs,
            };
            try
            {
                client.CreateTodoTaskWithOptions(unionId, createTodoTaskRequest, createTodoTaskHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions());
            }
            catch (TeaException err)
            {
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
            catch (Exception _err)
            {
                TeaException err = new TeaException(new Dictionary<string, object>
                {
                    { "message", _err.Message }
                });
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
        }
        public static AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Client ACreateClient()
        {
            AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config();
            config.Protocol = "https";
            config.RegionId = "central";
            return new AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Client(config);
        }


        public static void Get_SDK(string accesstoken) {

            AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Client client = ACreateClient();
            AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Models.QueryTodoStatisticalDataHeaders queryTodoStatisticalDataHeaders = new AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Models.QueryTodoStatisticalDataHeaders();
            queryTodoStatisticalDataHeaders.XAcsDingtalkAccessToken = accesstoken;
            AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Models.QueryTodoStatisticalDataRequest queryTodoStatisticalDataRequest = new AlibabaCloud.SDK.Dingtalkdatacenter_1_0.Models.QueryTodoStatisticalDataRequest
            {
                StatDate = "20210403",
            };
            try
            {
                var ccc=client.QueryTodoStatisticalDataWithOptions(queryTodoStatisticalDataRequest, queryTodoStatisticalDataHeaders, new AlibabaCloud.TeaUtil.Models.RuntimeOptions());

            }
            catch (TeaException err)
            {
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
            catch (Exception _err)
            {
                TeaException err = new TeaException(new Dictionary<string, object>
                {
                    { "message", _err.Message }
                });
                if (!AlibabaCloud.TeaUtil.Common.Empty(err.Code) && !AlibabaCloud.TeaUtil.Common.Empty(err.Message))
                {
                    // err 中含有 code 和 message 属性,可帮助开发定位问题
                }
            }
        }

最后做个总结吧,钉钉经过这么多年的积累和背靠阿里团队在接入方便还是比较好的,但是可能软件迭代的比较勤,估有些功能还没有一个十分好的开发,例如我们这次做的待办事项,只能通过接口写入的数据来获取而非接口写入的就不可以。估计是因为新旧数据的问题,但没有去详研。。毕竟对钉钉个人还是有点小抵触的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、获得AccessToken
  • 二、捞取用户资料
  • 三、新接口
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档