企业微信如何实现应用内的审批状态实时监控呢?之前我也查了很多文档,当然包括企业微信官方的文档,但是给出的文档内部问题多多,因此,我特意写了这篇博客。将企业微信审核项目实时状态反馈到公司的邮箱或者个人邮箱。
首先你需要三个配置文件,这三个配置文件是有官方提供的,但是存在很多问题,所以我对其进行了修改(文件中选中的文件)。需要者可私信。
另外的两个文件
1.创建服务器连接文件
from bottle import request, route, run, http_date
from WXBizMsgCrypt3 import WXBizMsgCrypt
from pcs import get_info
import sys
import smtplib
import json
import xmltodict
@route('/info', method=['POST', 'GET'])
def info():
if request.method == 'GET':
msg_signature = request.GET.get('msg_signature')
timestamp = request.GET.get('timestamp')
nonce = request.GET.get('nonce')
echostr = request.GET.get('echostr')
print({
'm': msg_signature,
't': timestamp,
'n': nonce,
'e': echostr
})
sToken = "自己申请可见"
sEncodingAESKey = "自己申请可见"
sCorpID = "公司id"
wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)
sVerifyMsgSig = msg_signature
sVerifyTimeStamp = timestamp
sVerifyNonce = nonce
sVerifyEchoStr = echostr
ret, sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr)
if (ret != 0):
print('sEchoStr:{}'.format(sEchoStr))
print("ERR: VerifyURL ret: " + str(ret))
sys.exit(1)
print('{}验证成功'.format(sEchoStr))
return http_date(str(sEchoStr).replace("b'", '').replace("'", ''))
else:
sToken = "自己申请可见"
sEncodingAESKey = "自己申请可见"
sCorpID = "公司id"
wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)
sReqMsgSig = request.params.get('msg_signature')
sReqTimeStamp = request.params.get('timestamp')
sReqNonce = request.params.get('nonce')
sReqData = request.body.read()
print({
'sReqMsgSig': sReqMsgSig,
'sReqTimeStamp': sReqTimeStamp,
'sReqNonce': sReqNonce,
'sReqData': sReqData
})
ret, sMsg = wxcpt.DecryptMsg(sReqData, sReqMsgSig, sReqTimeStamp, sReqNonce)
# print(ret, sMsg)
if (ret != 0):
# print("ERR: DecryptMsg ret: " + str(ret))
sys.exit(1)
# 解密成功,sMsg即为xml格式的明文
# TODO: 对明文的处理
# For example:
json_all = xmltodict.parse(sMsg)
results = get_info((json.loads(json.dumps(json_all)))['xml']['ApprovalInfo']['SpNo'])
# QQ邮件
# 1、配置邮箱SMTP服务器的主机地址,将来使用这个服务器收发邮件。
HOST = 'smtp.exmail.qq.com'
# 2、配置服务的端口,默认的邮件端口是25.
PORT = '465'
# 3、指定发件人和收件人。
FROM = '发送者邮箱'
TO = '接受者邮箱'
title = json.loads(results)
# 4、 邮件标题
SUBJECT = '状态提示{},{},{}'.format(title['审批状态'], title['审批名称'], title['控件信息'][0])
# 5、 邮件内容
CONTENT = results
# 创建邮件发送对象
# 普通的邮件发送形式
# 数据在传输过程中会被加密。
smtp_obj = smtplib.SMTP_SSL()
# 需要进行发件人的认证,授权。
# smtp_obj就是一个第三方客户端对象
smtp_obj.connect(host=HOST, port=PORT)
# 如果使用第三方客户端登录,要求使用授权码,不能使用真实密码,防止密码泄露。
res = smtp_obj.login(user=FROM, password='此处为邮箱密码')
# print(res)
if res == (235, b'Authentication successful'):
print('发送成功')
else:
print('发送失败')
# 发送邮件
msg = '\n'.join(['From: {}'.format(FROM), 'To: {}'.format(TO), 'Subject: {}'.format(SUBJECT), '', CONTENT])
smtp_obj.sendmail(from_addr=FROM, to_addrs=[TO], msg=msg.encode('utf-8'))
@route('/test')
def test():
http_date('网站测试')
run(host='0.0.0.0', port=8000, debug=True, server='tornado')
2.自建配置文件获取返回信息
import requests
import json
import time
def get_info(msg):
acc_url = '获取token url'
response = requests.get(acc_url).content.decode()
token = json.loads(response)['access_token']
print(token)
datas = {"sp_no" : msg}
detail_url = '获取状态 url'.format(token)
detail_res = requests.post(detail_url,data=json.dumps(datas)).content.decode()
details = json.loads(detail_res)
# print(details)
map = {
1 : '审批中',
2 : '已同意',
3 : '已驳回',
4 : '已转审'
}
li = []
for x in details["info"]["apply_data"]["contents"]:
# print(i)
if x['control'] == 'Text':
val = '{}:{}'.format(x['title'][0]['text'], x['value'].get('text'))
elif x['control'] == 'Date':
val = '{}:{}'.format(x['title'][0]['text'], time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(int(x['value']['date']['s_timestamp']))))
elif x['control'] == 'Selector':
val = '{}:{}'.format(x['title'][0]['text'], x['value']['selector']['options'][0]['value'][0]['text'])
elif x['control'] == 'Textarea':
val = '{}:{}'.format(x['title'][0]['text'], x['value']['text'])
elif x['control'] == 'Contact':
val = '{}:{}'.format(x['title'][0]['text'], [m['name'] for m in x['value']['members']])
elif x['control'] == 'Number':
val = '{}:{}'.format(x['title'][0]['text'], x['value']['new_number'])
elif x['control'] == 'Tips':
val = '成功获取所有信息'
elif x['control'] == 'Table':
if x['value']['children']:
vaa = []
for h in x['value']['children']:
vak = []
for v in h['list']:
print(v)
vas = ['{}:{}'.format(v['title'][0]['text'], v['value']['new_number']) if v['control'] == 'Number' else '{}:{}'.format(v['title'][0]['text'], v['value']['text'])]
vak.append(vas)
# print(vak)
vaa.append(vak)
val = []
for n in vaa:
cv = '{}{}'.format(n[0][0], n[1][0])
val.append(cv)
else:
val = '暂无信息'
else:
val = '{}:{}'.format(x['title'][0]['text'], x['value'].get('tips'))
li.append(val)
# print(li)
infos = {
'审批编号': details["info"]["sp_no"],
'审批名称': details["info"]["sp_name"],
'审批状态': map[details["info"]["sp_status"]],
'审批提交时间': time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(details["info"]["apply_time"])),
'审批意见': details["info"]["sp_record"][0]["details"][0]["speech"],
'控件信息': li
}
return json.dumps(infos,indent=3, ensure_ascii=False)
需要安装的第三方库
bottle
pyemail
xmltodict
pycryptodome
requests