python3调用企业微信api
python3调用企业微信api
最后更新时间:2020/5/11
前段时间,我将企业微信官方提供的python接口代码的部分功能修改成了python3的,并且自己也使用并测试过部分功能;
因为并没有将公司的敏感信息抹去,所以代码一直没有更新到github;
等度过了springboot的学习期并完成开发任务就来重新整理一版本;
项目地址:RandolphCYG/husky_weworkapi
注意: 目前还没提交修改的测试代码,2020/5/11 本周将整理
0.初期代码
这是自己写的发消息的测试代码(非接口),以测试一下调用企业微接口是不是需要很多东西,后来发现,完全没这个必要。
import json
import sys
import urllib
import urllib.request
from urllib import request, parseCORPID = '' # CorpID 企业ID
CORPSECRET = '' # Secret 应用密钥
touser = '' # userid
content = 'WECHAT2LDAP 测试'
headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"}def getToken(corpid, corpsecret):"""功能获取access_tokencorpid:企业IDcorpsecret:应用密钥"""url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' % (corpid, corpsecret)req = urllib.request.Request(url, headers=headers)results = json.loads(urllib.request.urlopen(req).read())print(results)return results['access_token']def sendmsg(access_token, content):"""功能:发送消息"""url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token"""touser 成员 @all 就是所有toparty 部门ID @all 就是所有msgtype 文本类型agentid 企业应用IDcontent 内容safe 是否保密 0是不保密"""values = {"touser" : touser,"toparty" : '2',"msgtype" : "text","agentid" : 1000005, # 新建企业微信应用"text" : {"content" : content},"safe" :"0"}send_data = json.dumps(values).encode()send_request = urllib.request.Request(url, send_data, headers=headers)response = json.loads(urllib.request.urlopen(send_request).read())print(response)if response['errcode'] == 0:print('发送消息成功')if __name__ == '__main__':access_token = getToken(CORPID, CORPSECRET)content = "发送消息测试"sendmsg(access_token, content)
1.python3企业微信接口代码魔改(例子)
1.1企业微信准备
通讯录同步
应用开启API同步:
确定一个部门的ID:测试部门ID:2
,下面通过调API批量从AD域中将用户同步进企业微信
1.2【魔改企业微信api源码&使用】准备
文件位置 C:\Users\randolph\Desktop\wechatapi\api\examples\ADTest.py
1.2.1批量从AD域导入用户到企业微信
from ldap3 import Server, Connection, ALL
from api.src.CorpApi import *
from api.src.AbstractApi import *
from api.examples.TestConf import *
import logging# AD域
LDAP_IP = '192.168.255.222' # LDAP服务器IP
LDAP_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):"""从AD域到企业微信导入用户(可邀请),修改了请求包体,测试通过;代码质量需要再次检查优化;"""conn.search(search_base, '(objectclass=person)', attributes=['*']) # 从AD域搜用户并遍历entry = conn.entriesfor i, user in enumerate(entry):# print(i+1, user)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": [2], # 部门是[测试],还没有改成同步部门【todo】}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=Trueif __name__ == '__main__':LDAP_CON = ldap_con_ssl(*INF)ad2wx(LDAP_CON, SEARCH_BASE)
导入的所有用户例子:
导入的单个用户示例:
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)
企业微信批量导入成功举例:
日志举例:
附带批量删除部门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)
1.2.3 【总结】批量从AD域导入OU以及OU下面的用户到企业微信
将上面的流程优化整合了一下,会在【测试】部门下面完整的将AD域的多级OU及每一层OU下的用户导入企业微信
!
待优化点:错误处理、search搜索参数(保证内存占用尽量低)
from ldap3 import Server, Connection, ALL, ASYNC, BASE, LEVEL, SUBTREE
from api.src.CorpApi import *
from api.src.AbstractApi import *
from api.examples.TestConf import *
import logging# AD域
LDAP_IP = '192.168.255.222' # LDAP服务器IP
LDAP_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
效果:
python3调用企业微信api相关推荐
- python3调用企业微信api!开发一款属于自己的企业微信
python3调用企业微信api 最后更新时间:2020/5/11 前段时间,我将企业微信官方提供的python接口代码的部分功能修改成了python3的,并且自己也使用并测试过部分功能: 因为并没有 ...
- insert时调用本身字段_python3调用企业微信api!开发一款属于自己的企业微信
python3调用企业微信api 最后更新时间:2020/5/11 前段时间,我将企业微信官方提供的python接口代码的部分功能修改成了python3的,并且自己也使用并测试过部分功能: 因为并没有 ...
- python企业微信特定用户_python3调用企业微信api!开发一款属于自己的企业微信...
python3调用企业微信api 最后更新时间:2020/5/11 前段时间,我将企业微信官方提供的python接口代码的部分功能修改成了python3的,并且自己也使用并测试过部分功能: 因为并没有 ...
- 【Linux学习】如何编写Shell脚本调用企业微信api来发消息给企业微信成员?
一.前言 最近通过python实现了发送消息给企业微信的功能,参考链接: [Jenkins学习 ]如何编写Python脚本来调用企业微信的api通知企业微信成员关于Jenkins的编译结果? http ...
- Node.JS调用企业微信API:生成渠道二维码
目标: 通过API设置成员的"联系我"方式生成渠道标识二维码,实现标记客户扫码渠道,方便个渠道客户信息统计等. 实现环境: 白码低代码平台(该平台提供企业微信API,可直接调用,减 ...
- SERP调用企业微信API接口,发送文本信息实例
SERP企业轻量级ERP(SSDCRM)起源于vtigercrm早期版本.随着我们不停的迭代研发与完善,今日已经形成了自己鲜明的应用风格.我们在完善平台内部功能的基础上,积极研发平台与企业微信,钉钉, ...
- 调用企业微信API,ios端异常
在企业微信中调用wx.openEnterpriseChat方法时,安卓客户端可以正常执行,ios端无反应,pc端无反应: 后续更改wx.config文件,新增beta:true配置,问题依旧没解决,后 ...
- Python3 使用企业微信 API 发送消息
现在大部分情况下,企业里运维监控的系统都需要给运维人员发送一些报警之类的信息,之前都是发送邮件,目前有腾讯推出了企业微信,也开放了其 API 接口.我们可以利用其 API 接口来给企业微信第账号发送信 ...
- python连接企业微信数据库_python调用企业微信API
#!/usr/bin/env python # -*- coding:utf-8 -*- # 2017-07-25 编写 import json import sys import urllib, u ...
- java欢迎词,企业微信API:成员个性化新客户欢迎语的nodejs实现
目标: 在企业微信上只能设置统一的新客户欢迎语,因此我们通过API来实现为对每个成员设置个性化欢迎语. 实现环境: 白码低代码平台(该平台是低代码代发平台,提供企业微信API,可直接调用,减少前期配置 ...
最新文章
- Android逆向之调试smali代码基础
- : Andorid的Linux基础教学之五 中断机制
- 老板居然让我用Java造假数据
- 学习C#以及C还有数据库
- C语言知识体系思维导图
- Java --- 基础学习Ⅰ
- 读《大道至简—是懒人造就了方法 》有感
- eclipse支持html,让eclipse完全支持HTML/JS/CSS智能提示
- SAP License:SAP凭证的类别和记账码
- 程序员吐槽:互联网就是高薪富士康,还不如在事业单位混日子
- 关于TFS的文档和报告打叉的解决
- 百度人脸识别:即使不用,也要import,否则C调用Python会崩溃
- NVIDIA Nsight Eclipse 安装
- python 文件对话框 颜色对话框_PyQt5系列教程(9):颜色、字体、打开文件对话框...
- “谷歌金山词霸”换汤不换药 实验结果令人失望
- IBM Cloud Satellite在Tencent Cloud上的部署--Part1准备
- 有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中——C语言
- FaceBook有戏没戏(转)
- 开发必备的最高100个 Flutter 开源精品项目
- 精选20个高品质的免费素材,可以下载PSD格式