第一步:获取钉钉token
private string GetToken()
{
var token = CacheFactory.Cache().GetCache<string>("DDToken");
if (!token.IsEmpty()) return token;
var url = "https://oapi.dingtalk.com/gettoken?corpid=" + CorpId + "&corpsecret=" + CorpSecret;
var str = Get(url);
var dictionary = str.ToObject<Dictionary<string, string>>();
if (dictionary == null || dictionary.Count == 0 || dictionary["errcode"] != "0")
{
return string.Empty;
}
token = dictionary["access_token"];
CacheFactory.Cache().WriteCache(token, "DDToken", DateTime.Now.AddMinutes(100));
return token;
}
第二步:获取角色列表
public List<DDRoleEntity> GetAllRole(long offset, out bool has_more, out string msg)
{
has_more = false;
msg = null;
IDingTalkClient client = new DefaultDingTalkClient("https://eco.taobao.com/router/rest", "json");
CorpRoleListRequest req = new CorpRoleListRequest();
req.Size = 100L;
req.Offset = offset;
CorpRoleListResponse rsp = client.Execute(req, Token);
var result = rsp.Body.ToObject<DDRoleListRequestResult>();
if (result == null) return null;
if (result.error_response != null)
{
msg = result.error_response.msg;
return null;
}
if (result.dingtalk_corp_role_list_response == null) return null;
if (result.dingtalk_corp_role_list_response.result == null) return null;
if (result.dingtalk_corp_role_list_response.result.has_more == "true")
{
has_more = true;
}
if (result.dingtalk_corp_role_list_response.result.list == null) return null;
if (result.dingtalk_corp_role_list_response.result.list.role_groups == null) return null;
var list = new List<DDRoleEntity>();
foreach (var role_group in result.dingtalk_corp_role_list_response.result.list.role_groups)
{
if (role_group.roles == null) continue;
if (role_group.roles.roles == null) continue;
foreach (var role in role_group.roles.roles)
{
if (role == null) continue;
list.Add(role);
}
}
return list;
}
第三步:获取部门列表
public DDDeptList GetDeptList()
{
var url = "https://oapi.dingtalk.com/department/list?access_token=" + Token + "&fetch_child=true";
var str = Get(url);
return str.ToObject<DDDeptList>();
}
循环部门列表,如果部门ID为1,则为根节点
第四步:获取部门详情
public DDDeptDetailEntity GetDeptDetail(long deptId)
{
var url = "https://oapi.dingtalk.com/department/get?access_token=" + Token + "&id=" + deptId;
var str = Get(url);
return str.ToObject<DDDeptDetailEntity>();
}
第五步:获取部门下面的人员
public DDUserList GetUserList(long ddDeptId)
{
var url = "https://oapi.dingtalk.com/user/getDeptMember?access_token=" + Token + "&deptId=" + ddDeptId;
var str = Get(url);
return str.ToObject<DDUserList>();
}
第六步:获取人员详情
public DDUserDetailEntity GetUserDetail(string userId)
{
var url = "https://oapi.dingtalk.com/user/get?access_token=" + Token + "&userid=" + userId;
var str = Get(url);
return str.ToObject<DDUserDetailEntity>();
}
公共方法:
public string Get(string url)
{
HttpWebResponse httpResponse = null;
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
httpRequest.Method = "GET";
httpRequest.ContentType = "application/json; charset=UTF-8";
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
}
catch (WebException ex)
{
httpResponse = (HttpWebResponse)ex.Response;
}
Stream st = httpResponse.GetResponseStream();
StreamReader reader = new StreamReader(st, Encoding.GetEncoding("utf-8"));
return reader.ReadToEnd();
}
public string Post(string url, string content)
{
string result = "";
HttpWebResponse httpResponse = null;
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
httpRequest.Method = "POST";
httpRequest.ContentType = "application/json";
byte[] data = Encoding.UTF8.GetBytes(content);
httpRequest.ContentLength = data.Length;
using (Stream reqStream = httpRequest.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
}
catch (WebException ex)
{
httpResponse = (HttpWebResponse)ex.Response;
}
Stream stream = httpResponse.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
result = reader.ReadToEnd();
}
return result;
}
公共类:
/// <summary>
/// 钉钉返回公用字段
/// </summary>
public class DDRequestEntity
{
/// <summary>
/// 返回码
/// </summary>
public int errcode { get; set; }
/// <summary>
/// 对返回码的文本描述内容
/// </summary>
public string errmsg { get; set; }
}
/// <summary>
/// 成员详情
/// </summary>
public class DDUserDetailEntity : DDRequestEntity
{
/// <summary>
/// 员工唯一标识ID(不可修改)
/// </summary>
public string userid { get; set; }
/// <summary>
/// 在本 服务窗运营服务商 范围内, 唯一标识关注者身份的id(不可修改)
/// </summary>
public string openid { get; set; }
/// <summary>
/// 成员名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 分机号(仅限企业内部开发调用)
/// </summary>
public string tel { get; set; }
/// <summary>
/// 办公地点(ISV不可见)
/// </summary>
public string workPlace { get; set; }
/// <summary>
/// 备注(ISV不可见)
/// </summary>
public string remark { get; set; }
/// <summary>
/// 手机号码(ISV不可见)
/// </summary>
public string mobile { get; set; }
/// <summary>
/// 员工的电子邮箱(ISV不可见)
/// </summary>
public string email { get; set; }
/// <summary>
/// 员工的企业邮箱,如果员工已经开通了企业邮箱,接口会返回,否则不会返回(ISV不可见)
/// </summary>
public string orgEmail { get; set; }
/// <summary>
/// 是否已经激活, true表示已激活, false表示未激活
/// </summary>
public bool active { get; set; }
/// <summary>
/// 在对应的部门中的排序, Map结构的json字符串, key是部门的Id, value是人员在这个部门的排序值
/// </summary>
public object orderInDepts { get; set; }
/// <summary>
/// 是否为企业的管理员, true表示是, false表示不是
/// </summary>
public bool isAdmin { get; set; }
/// <summary>
/// 是否为企业的老板, true表示是, false表示不是(【设置负责人】:主管理员登陆钉钉手机客户端 -【通讯录】-【企业名后面的管理】-【企业通讯录】-【负责人设置】进行添加则可。)
/// </summary>
public bool isBoss { get; set; }
/// <summary>
/// 在当前isv全局范围内唯一标识一个用户的身份, 用户无法修改
/// </summary>
public string unionid { get; set; }
/// <summary>
/// 在对应的部门中是否为主管, Map结构的json字符串, key是部门的Id, value是人员在这个部门中是否为主管, true表示是, false表示不是
/// </summary>
public string isLeaderInDepts { get; set; }
/// <summary>
/// 是否号码隐藏, true表示隐藏, false表示不隐藏
/// </summary>
public bool isHide { get; set; }
/// <summary>
/// 成员所属部门id列表
/// </summary>
public long[] department { get; set; }
/// <summary>
/// 职位信息
/// </summary>
public string position { get; set; }
/// <summary>
/// 头像url
/// </summary>
public string avatar { get; set; }
/// <summary>
/// 入职时间
/// </summary>
public long hiredDate { get; set; }
/// <summary>
/// 员工工号
/// </summary>
public string jobnumber { get; set; }
/// <summary>
/// 扩展属性,可以设置多种属性(但手机上最多只能显示10个扩展属性,具体显示哪些属性,请到OA管理后台->设置->通讯录信息设置和OA管理后台->设置->手机端显示信息设置)
/// </summary>
public object extattr { get; set; }
/// <summary>
/// 角色信息(ISV不可见),json数组格式
/// </summary>
public List<Role> roles { get; set; }
/// <summary>
/// 手机号码区号
/// </summary>
public string stateCode { get; set; }
/// <summary>
/// 是否是高管
/// </summary>
public bool isSenior { get; set; }
}
/// <summary>
/// 角色
/// </summary>
public class Role
{
/// <summary>
/// 角色id(ISV不可见)
/// </summary>
public long id { get; set; }
/// <summary>
/// 角色名称(ISV不可见)
/// </summary>
public string name { get; set; }
/// <summary>
/// 角色分组名称(ISV不可见)
/// </summary>
public string groupName { get; set; }
}
/// <summary>
/// 部门成员
/// </summary>
public class DDUserList : DDRequestEntity
{
/// <summary>
/// 在分页查询时返回,代表是否还有下一页更多数据
/// </summary>
public bool hasMore { get; set; }
/// <summary>
/// 成员列表
/// </summary>
public List<Dictionary<string, string>> userlist { get; set; }
}
/// <summary>
/// 角色列表请求返回结果
/// </summary>
public class DDRoleListRequestResult
{
/// <summary>
/// 异常信息
/// </summary>
public RoleErrorResponse error_response { get; set; }
/// <summary>
/// 响应数据
/// </summary>
public DingtalkCorpRoleListResponse dingtalk_corp_role_list_response { get; set; }
}
/// <summary>
/// 异常信息
/// </summary>
public class RoleErrorResponse
{
/// <summary>
/// 异常代码描述
/// </summary>
public string sub_msg { get; set; }
/// <summary>
/// 代码
/// </summary>
public int code { get; set; }
/// <summary>
/// 异常代码
/// </summary>
public string sub_code { get; set; }
/// <summary>
/// 提示信息
/// </summary>
public string msg { get; set; }
}
public class DingtalkCorpRoleListResponse
{
/// <summary>
/// 结果
/// </summary>
public RoleResult result { get; set; }
}
public class RoleResult
{
/// <summary>
/// 是否还有
/// </summary>
public string has_more { get; set; }
/// <summary>
/// 列表
/// </summary>
public RoleList list { get; set; }
}
public class RoleList
{
public List<RoleGroups> role_groups { get; set; }
}
public class RoleGroups
{
/// <summary>
/// 角色列表
/// </summary>
public RoleRoles roles { get; set; }
/// <summary>
/// 分组名称
/// </summary>
public string group_name { get; set; }
}
public class RoleRoles
{
public List<DDRoleEntity> roles { get; set; }
}
public class DDRoleEntity
{
public long id { get; set; }
public string role_name { get; set; }
}
/// <summary>
/// 钉钉部门详情
/// </summary>
public class DDDeptDetailEntity : DDRequestEntity
{
/// <summary>
/// 部门id
/// </summary>
public long id { get; set; }
/// <summary>
/// 部门名称
/// </summary>
public string name { get; set; }
/// <summary>
/// 父部门id,根部门为1
/// </summary>
public long parentid { get; set; }
/// <summary>
/// 在父部门中的次序值
/// </summary>
public int order { get; set; }
/// <summary>
/// 是否同步创建一个关联此部门的企业群, true表示是, false表示不是
/// </summary>
public bool createDeptGroup { get; set; }
/// <summary>
/// 当群已经创建后,是否有新人加入部门会自动加入该群, true表示是, false表示不是
/// </summary>
public bool autoAddUser { get; set; }
/// <summary>
/// 是否隐藏部门, true表示隐藏, false表示显示
/// </summary>
public bool deptHiding { get; set; }
/// <summary>
/// 可以查看指定隐藏部门的其他部门列表,如果部门隐藏,则此值生效,取值为其他的部门id组成的的字符串,使用|符号进行分割
/// </summary>
public string deptPermits { get; set; }
/// <summary>
/// 可以查看指定隐藏部门的其他人员列表,如果部门隐藏,则此值生效,取值为其他的人员userid组成的的字符串,使用|符号进行分割
/// </summary>
public string userPermits { get; set; }
/// <summary>
/// 是否本部门的员工仅可见员工自己, 为true时,本部门员工默认只能看到员工自己
/// </summary>
public bool outerDept { get; set; }
/// <summary>
/// 本部门的员工仅可见员工自己为true时,可以配置额外可见部门,值为部门id组成的的字符串,使用|符号进行分割
/// </summary>
public string outerPermitDepts { get; set; }
/// <summary>
/// 本部门的员工仅可见员工自己为true时,可以配置额外可见人员,值为userid组成的的字符串,使用| 符号进行分割
/// </summary>
public string outerPermitUsers { get; set; }
/// <summary>
/// 企业群群主
/// </summary>
public string orgDeptOwner { get; set; }
/// <summary>
/// 部门的主管列表,取值为由主管的userid组成的字符串,不同的userid使用|符号进行分割
/// </summary>
public string deptManagerUseridList { get; set; }
/// <summary>
/// 部门标识字段,开发者可用该字段来唯一标识一个部门,并与钉钉外部通讯录里的部门做映射
/// </summary>
public string sourceIdentifier { get; set; }
/// <summary>
/// 部门群是否包含子部门
/// </summary>
public string groupContainSubDept { get; set; }
}
/// <summary>
/// 所有上级父部门
/// </summary>
public class DDParentDepts : DDRequestEntity
{
/// <summary>
/// 该部门的所有父部门id列表
/// </summary>
public long[] parentIds { get; set; }
}
/// <summary>
/// 部门列表
/// </summary>
public class DDDeptList : DDRequestEntity
{
/// <summary>
/// 部门列表数据
/// </summary>
public List<DDDeptDetailEntity> department { get; set; }
}