python 与 纷享CRM 对接

本文分享了使用Python与纷享CRM系统进行对接的经验,详细介绍了如何通过编程方式实现服务器状态检查、获取CorpAccessToken及AppAccessToken,以及如何查询CRM数据并更新到数据库的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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]))	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值