python3调用企业微信api!开发一款属于自己的企业微信( 二 )

导入的所有用户例子:
python3调用企业微信api!开发一款属于自己的企业微信文章插图
导入的单个用户示例:
python3调用企业微信api!开发一款属于自己的企业微信文章插图
1.2.2批量从AD域导入OU到企业微信def ad_ou2wx(conn, search_base):"""每一层OU下员工的同步思路:结合上一步代码 , 将search_base根据每一次生成的子OU变化即可 """# TODO: 检查优化此部分代码 , 带上对应OU下员工的同步导入conn.search(search_base, '(objectclass=organizationalUnit)', attributes=['distinguishedName'])entry = conn.entriesfor i, c in enumerate(entry):ou_list = [x.split('OU=')[1] for x in str(c.distinguishedName).split(',')[:-2][::-1]]ou_list.insert(0, '测试')print(i+3, ou_list)response = api.httpCall(CORP_API_TYPE['DEPARTMENT_LIST'])for m in response['department']:if m['name'] == ou_list[-2]:# m是查询出部门列表信息 , 根据部门名字name查询出父IDp_id = m['id']# 父IDrequest_package = {"name": ou_list[-1],# 必须,中文名"parentid": p_id,# 必须,父id"id": i+3,# 不必须 , 子id , 为了方便下一层的创建 , 部门的ID为自然数}try:response = api.httpCall(CORP_API_TYPE['DEPARTMENT_CREATE'], request_package)if response['errcode'] == 0:logging.info('创建【' + ou_list[-1] + '】成功')except Exception as e:logging.error(e)break# 找到父子对应信息 , 就可以创建完子的部门 , 然后中断内层循环即可if __name__ == '__main__':LDAP_CON = ldap_con_ssl(*INF)# ad2wx(LDAP_CON)ad_ou2wx(LDAP_CON, SEARCH_BASE)企业微信批量导入成功举例:
python3调用企业微信api!开发一款属于自己的企业微信文章插图
日志举例:
python3调用企业微信api!开发一款属于自己的企业微信文章插图
附带批量删除部门department的代码【注意部门下不能有OU或人员 , 没写删这些的 , 测试时候经常需要批量删除空的depart】:
for n in range(3, 8)[::-1]:print(n)req_pack = {'id': str(n),}res = api.httpCall(CORP_API_TYPE['DEPARTMENT_DELETE'], req_pack)
python3调用企业微信api!开发一款属于自己的企业微信文章插图
1.2.3 【总结】批量从AD域导入OU以及OU下面的用户到企业微信【python3调用企业微信api!开发一款属于自己的企业微信】将上面的流程优化整合了一下 , 会在【测试】部门下面完整的 将AD域的多级OU及每一层OU下的用户导入企业微信 !
待优化点:错误处理、search搜索参数(保证内存占用尽量低)
from ldap3 import Server, Connection, ALL, ASYNC, BASE, LEVEL, SUBTREEfrom api.src.CorpApi import *from api.src.AbstractApi import *from api.examples.TestConf import *import logging# AD域LDAP_IP = '192.168.255.222'# LDAP服务器IPLDAP_ADMIN_USER = 'CN=Administrator,CN=Users,DC=bilibili,DC=com'# LDAP服务器管理员账户LDAP_ADMIN_PWD = 'QQqq#123'# LDAP服务器管理员密码INF = (LDAP_IP, LDAP_ADMIN_USER, LDAP_ADMIN_PWD)# AD域信息汇总SEARCH_BASE = "OU=B站,DC=bilibili,DC=com"# 搜索请求的基础,在这个OU下开始搜索# 企业微信CorpApi接口api = CorpApi(TestConf['CORP_ID'], TestConf['CONTACT_SYNC_SECRET'])# 日志设置LOG_FORMAT = "%(asctime)s %(levelname)s %(filename)s %(lineno)d %(message)s"logging.basicConfig(filename='localAD.log', level=logging.INFO, format=LOG_FORMAT)def ad2wx(conn, search_base, ou_id):"""从AD域到企业微信导入用户(可邀请) , 修改了请求包体 , 测试通过; 代码质量需要再次检查优化; """conn.search(str(search_base), '(objectclass=person)', attributes=['*'], search_scope=LEVEL)# 从AD域搜用户并遍历,LEVEL代表只搜索此OU下的用户entry = conn.entriesfor i, user in enumerate(entry):print(i+1, user.sAMAccountName)try:request_package = {"userid": str(user.sAMAccountName),# 由AD的必填字段登录名[sAMAccountName]到微信的[账号]字段"name": re.sub("[A-Za-z0-9]", "", str(user.cn)),# 由AD的必填字段cn例[小明2314] 截取数字之外的文字[小明]"enable": 1,# 启用用户"to_invite": False,# 默认邀请,测试时候不邀请"department": [ou_id],# 部门是对应AD域中所在OU}if hasattr(user, 'telephoneNumber') or hasattr(user, 'mail'):# 手机号/邮箱必须有一项(邀请需要)if hasattr(user, 'telephoneNumber'):request_package['mobile'] = str(user.telephoneNumber)if hasattr(user, 'mail'):request_package['email'] = str(user.mail)else:logging.error('【' + str(user.sAMAccountName) + '】 ' + "同步用户失败 , 用户未配置【手机号】与【邮箱】!")continueif hasattr(user, 'title'):request_package['position'] = str(user.title)request_package['external_position'] = str(user.title)response = api.httpCall(CORP_API_TYPE['USER_CREATE'], request_package)if response['errcode'] == 0:passelse:print("@@@@创建错误 , 已经存在或其他错误" + str(user.displayName))except ApiException as e:logging.debug(e.errCode, e.errMsg)except Exception as e:logging.debug('【' + str(user.sAMAccountName) + '】 ' + str(e), exc_info=True)# ,stack_info=Truedef ad_ou2wx(conn, search_base):"""每一层OU下员工的同步思路:结合上一步代码 , 将search_base根据每一次生成的子OU变化即可 , 并将Ou_id带入 """conn.search(search_base, '(objectclass=organizationalUnit)', attributes=['*'])entry = conn.entriesfor i, c in enumerate(entry):# print(c.distinguishedName)ou_list = [x.split('OU=')[1] for x in str(c.distinguishedName).split(',')[:-2][::-1]]ou_list.insert(0, '测试')print(i+3, ou_list)response = api.httpCall(CORP_API_TYPE['DEPARTMENT_LIST'])for m in response['department']:if m['name'] == ou_list[-2]:# m是查询出部门列表信息 , 根据部门名字name查询出父IDp_id = m['id']# 父IDou_id = i+3request_package = {"name": ou_list[-1],# 必须,中文名"parentid": p_id,# 必须,父id"id": ou_id,# 不必须 , 子id , 为了方便下一层的创建 , 部门的ID为自然数}try:response = api.httpCall(CORP_API_TYPE['DEPARTMENT_CREATE'], request_package)if response['errcode'] == 0:logging.info('创建【' + ou_list[-1] + '】成功')# 这里可以将OU下面的用户查询并导入sear_base = c.distinguishedNamead2wx(conn, sear_base, ou_id)except Exception as e:logging.error(e)break