python 与 纷享CRM 对接
公司上线了纷享CRM,纷享就只做了业务端的功能需求,没有考虑生产端和仓储端的需求,个人认为生产进度和库存进度恰恰是CRM最重要的功能,如果没有办法实现,这个和一个聊天工具没有差别,用QQ,微信还免费。
最终这个坑就扔给我们了
#尝试PING服务器地址,如果是联通进行一下步
def PingDevice(self, ThreadID, langNo = 'GBK'):
FunName = _getframe().f_code.co_name
self.LogInfo = 'Thread-{}, DeviceNo={}, DeviceName={}, DeviceIP={}'.format(ThreadID, self.CRMDict['appNo'], self.CRMDict['appName'], self.CRMDict['appURL'])
try:
with Popen('ping -l 1 -n 1 {}'.format(self.CRMDict['appURL']), stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = True) as file:
dataStr = file.stdout.read().decode(langNo)
if langNo == 'GBK':
if dataStr.find('已接收 = 1') > 0:
self.LogObject.warning('{} Success: {}'.format(FunName, self.LogInfo))
return True
except:
self.LogObject.error('{} Except: {}, {}, {}'.format(FunName, self.LogInfo, exc_info()[0], exc_info()[1]))
return False
# 获取 纷享CorpAccessToken
def OpenDevice(self):
FunName = _getframe().f_code.co_name
self.CRMDict['appOpen'] = False
urlData = {
'url': 'https://open.fxiaoke.com/cgi/corpAccessToken/get/V2',
'data': {
'appId': self.CRMDict['appId'],
'appSecret': self.CRMDict['appSecret'],
'permanentCode': self.CRMDict['permanentCode']
}
}
if self.OpenDeviceLoadURL(urlData['url'], urlData['data']):
# 获取 AppAccessToken
urlData = {
'url': 'https://open.fxiaoke.com/cgi/appAccessToken/get',
'data': {
'appId': self.CRMDict['appId'],
'appSecret': self.CRMDict['appSecret']
}
}
if self.OpenDeviceLoadURL(urlData['url'], urlData['data']):
sleep(1)
self.CRMDict['appOpen'] = True
self.LogObject.warning('{} Success: {}'.format(FunName, self.CRMDict['appOpen']))
return True
return False
#获取URL
def LoadURL(self, urlStr, urlData):
FunName = _getframe().f_code.co_name
if urlStr is None or urlData is None: return False
self.CRMDict['errorCode'] = None
self.CRMDict['errorMessage'] = None
self.CRMDict['errorDescription'] = None
if self.CRMDict['urlCount'] == 800:
self.CRMDict['urlCount'] = 0
sleep(24) # 速度太快,会被踢
self.CRMDict['urlCount'] = self.CRMDict['urlCount'] + 1
try:
headerStr = {
'User-Agent': self.CRMDict['urlAgent'],
'Content-Type': self.CRMDict['urlType']
}
jsonData = bytes(dumps(urlData), self.CRMDict['urlCode'])
req = Request(url=urlStr, data=jsonData, headers=headerStr, method='POST')
res = urlopen(req)
if not res is None and res.reason == 'OK':
resData = res.read().decode(self.CRMDict['appCode'])
jsonDict = loads(resData)
if isinstance(jsonDict, dict):
self.CRMDict.update(jsonDict)
if self.CRMDict['errorCode'] == 0 and self.CRMDict['errorMessage'] == 'success':
self.LogObject.info('{} Success: {}, {}'.format(FunName, urlStr, jsonDict))
return True
else:
self.LogObject.warning('{} Error: {}, {}'.format(FunName, urlStr, jsonDict))
if self.CRMDict['errorCode'] == 20016 and self.CRMDict['appOpen']:
if self.PingDevice(1):
if self.OpenDevice():
return self.OpenDeviceLoadURL(urlStr, urlData)
return False
except:
self.LogObject.error('{} Except: {}, {}, {}'.format(FunName, urlStr, exc_info()[0], exc_info()[1]))
return False
#纷享CRM的功能基本调用这个功能就可以完成了,
#如果还不行,就可以改一下URL和DATA
def QueryDataObject(self, objectNo = None, objectOffset = 0):
if not objectNo is None: self.CRMDict['apiName'] = objectNo
if not objectOffset is None: self.CRMDict['offset'] = objectOffset
urlData = {
'url': 'https://open.fxiaoke.com/cgi/crm/data/query',
'data': {
'corpAccessToken': self.CRMDict['corpAccessToken'],
'corpId': self.CRMDict['corpId'],
'currentOpenUserId': self.CRMDict['currentOpenUserId'],
'apiName': self.CRMDict['apiName'],
'searchQuery': {'offset': self.CRMDict['offset'], 'limit': self.CRMDict['limit']}
}
}
return self.LoadURL(urlData['url'], urlData['data'])
#功能和上一个函数差别不大
def QueryDataObjectRange(self, objectNo = None, queryRange = dict):
if not objectNo is None: self.CRMDict['apiName'] = objectNo
urlData = {
'url': 'https://open.fxiaoke.com/cgi/crm/data/query',
'data': {
'corpAccessToken': self.CRMDict['corpAccessToken'],
'corpId': self.CRMDict['corpId'],
'currentOpenUserId': self.CRMDict['currentOpenUserId'],
'apiName': self.CRMDict['apiName'],
'searchQuery': {'offset': 0, 'limit': self.CRMDict['limit'], 'rangeConditions': [{'fieldName': 'last_modified_time', 'from': queryRange['from'], 'to': queryRange['to']}]}
}
}
return self.LoadURL(urlData['url'], urlData['data'])
#通过下载数据,然后更新到数据库
def object_dept_query(self):
FunName = _getframe().f_code.co_name
dataSQL = list()
timeList = tuple()
dataList = list()
# 0
dataSQL.append('''
SELECT to_char(SYSDATE, 'yyyymmddhh24miss') AS today
FROM dual
''')
# 1
dataSQL.append('''
INSERT INTO "crm_object_dept"("timeid", "id", "name",
"parentId", "isStop", "order"
)
SELECT :1, :2, :3,
:4, :5, :6
FROM dual
''')
urlData = {
'url': 'https://open.fxiaoke.com/cgi/department/list',
'data': {
'corpAccessToken': self.CRMDict['corpAccessToken'],
'corpId': self.CRMDict['corpId'],
}
}
try:
timeList = self.DBObject.DBQueryOne(True, dataSQL[0])
if self.LoadURL(urlData['url'], urlData['data']):
if isinstance(self.CRMDict['departments'], list):
for data in self.CRMDict['departments']:
# print(data)
dataTupe = (
str(timeList[0]),
self.GetDictData(data,'id'),
self.GetDictData(data,'name'),
self.GetDictData(data,'parentId'),
self.GetDictData(data,'isStop'),
self.GetDictData(data,'order'),
)
dataList.append(dataTupe)
if len(dataList) > 0:
if isinstance(timeList, tuple):
if self.DBObject.DBExecuteMany(True, dataSQL[1], dataList):
self.LogObject.warning('{} Success, CreateCount={}'.format(FunName, len(dataList)))
except:
self.LogObject.error('{} Except: {}, {}, {}'.format(FunName, exc_info()[0], exc_info()[1]))