def get_access_token(self): """获取微信全局唯一票据access_token""" url = WxConfig.config_get_access_token_url r = requests.get(url) logger.info('【获取微信全局唯一票据access_token】Response[' + str(r.status_code) + ']') if r.status_code == 200: res = r.text logger.info('【获取微信全局唯一票据access_token】>>>' + res) d = json.loads(res) if 'access_token' in d.keys(): access_token = d['access_token'] # 添加至redis中 self._token_cache.set_access_cache( self._token_cache.KEY_ACCESS_TOKEN, access_token) # 获取JS_SDK权限签名的jsapi_ticket self.get_jsapi_ticket() return access_token elif 'errcode' in d.keys(): errcode = d['errcode'] logger.info( '【获取微信全局唯一票据access_token-SDK】errcode[' + errcode + '] , will retry get_access_token() method after 10s') tornado.ioloop.IOLoop.instance().call_later( 10, self.get_access_token) else: logger.error('【获取微信全局唯一票据access_token】request access_token error' + ',will retry get_access_token() method after 10s') tornado.ioloop.IOLoop.instance().call_later( 10, self.get_access_token)
def get_jsapi_ticket(self): """获取JS_SDK权限签名的jsapi_ticket""" access_token = self._token_cache.get_cache(self._token_cache.KEY_ACCESS_TOKEN) if access_token: url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi' % access_token r = requests.get(url) logger.info('【微信JS-SDK】获取JS_SDK权限签名的jsapi_ticket的Response[' + str(r.status_code) + ']') if r.status_code == 200: res = r.text logger.info('【微信JS-SDK】获取JS_SDK权限签名的jsapi_ticket>>>>' + res) d = json.loads(res) errcode = d['errcode'] if errcode == 0: jsapi_ticket = d['ticket'] # 添加至redis中 self._token_cache.set_access_cache(self._token_cache.KEY_JSAPI_TICKET, jsapi_ticket) else: logger.info('【微信JS-SDK】获取JS_SDK权限签名的jsapi_ticket>>>>errcode[' + errcode + ']') logger.info('【微信JS-SDK】request jsapi_ticket error, will retry get_jsapi_ticket() method after 10s') tornado.ioloop.IOLoop.instance().call_later(10, self.get_jsapi_ticket) else: logger.info('【微信JS-SDK】request jsapi_ticket error, will retry get_jsapi_ticket() method after 10s') tornado.ioloop.IOLoop.instance().call_later(10, self.get_jsapi_ticket) else: logger.error('【微信JS-SDK】获取JS_SDK权限签名的jsapi_ticket时,access_token获取失败, will retry get_access_token() method after 10s') tornado.ioloop.IOLoop.instance().call_later(10, self.get_access_token)
def post(self): body = self.request.body logger.debug('微信消息回复中心】收到用户消息' + str(body.decode('utf-8'))) data = ET.fromstring(body) ToUserName = data.find('ToUserName').text FromUserName = data.find('FromUserName').text MsgType = data.find('MsgType').text if MsgType == 'text' or MsgType == 'voice': '''文本消息 or 语音消息''' try: MsgId = data.find("MsgId").text if MsgType == 'text': Content = data.find('Content').text # 文本消息内容 elif MsgType == 'voice': Content = data.find('Recognition').text # 语音识别结果,UTF8编码 if Content == u'你好': MsgType = 'text' reply_content = '您好,请问有什么可以帮助您的吗?' else: # 接入多客服系统 MsgType = 'transfer_customer_service' reply_content = Content CreateTime = int(time.time()) out = self.reply_text(FromUserName, ToUserName, CreateTime, MsgType, reply_content) logger.debug(out) self.write(out) # 查找不到关键字,同时默认回复 MsgType = "text" reply_content = "客服接入中,稍后将为您服务" if reply_content: CreateTime = int(time.time()) out = self.reply_text(FromUserName, ToUserName, CreateTime, MsgType, reply_content) self.write(out) except Exception as e: logger.error(str(e)) elif MsgType == 'event': '''接收事件推送''' try: Event = data.find('Event').text if Event == 'subscribe': # 关注事件 CreateTime = int(time.time()) reply_content = self.sys_order_reply MsgType = 'text' out = self.reply_text(FromUserName, ToUserName, CreateTime, MsgType, reply_content) self.write(out) except: pass
def get_menu(self): """获取menu,如果没有menu则进行创建""" menu = WxMenuServer() try: data = menu.get_menu() logger.debug('微信获取menu' + str(data)) if data == 0: pass else: menu.create_menu() except Exception as e: logger.error('Exception:' + e)
def get(self): try: signature = self.get_argument('signature') timestamp = self.get_argument('timestamp') nonce = self.get_argument('nonce') echostr = self.get_argument('echostr') result = self.check_signature(signature, timestamp, nonce) logger.debug('微信sign校验,signature=' + signature + ',×tamp=' + timestamp + '&nonce=' + nonce + '&echostr=' + echostr) if result: logger.debug('微信sign校验,返回echostr=' + echostr) self.write(echostr) else: logger.error('微信sign校验,---校验失败') except Exception as e: logger.error('微信sign校验,---Exception' + str(e))
def add_kf(self): access_token = self._token_cache.get_cache( self._token_cache.KEY_ACCESS_TOKEN) if access_token: url = WxConfig.add_kf + access_token data = self.add_kf_data() r = requests.post(url, data.encode('utf-8')) logger.debug('【微信多客服系统】Response' + str(r.status_code)) if r.status_code == 200: res = r.text logger.debug('[微信多客服系统]' + res) json_res = json.loads(res) if 'errcode' in json.loads(res): errcode = json_res['errcode'] return errcode else: logger.error('微信多客服系统获取不到access_token')
def delete_menu(self): """自定义菜单删除接口""" access_token = self._token_cache.get_cache( self._token_cache.KEY_ACCESS_TOKEN) if access_token: url = WxConfig.menu_delete_url + access_token r = requests.get(url) logger.debug('【微信自定义菜单】自定义菜单删除接口Response[' + str(r.status_code) + ']') if r.status_code == 200: res = r.text logger.debug('【微信自定义菜单】自定义菜单删除接口' + res) json_res = json.loads(res) if 'errcode' in json_res.keys(): errcode = json_res['errcode'] return errcode else: logger.error('【微信自定义菜单】自定义菜单删除接口获取不到access_token')
def invite_kf(self): access_token = self._token_cache.get_cache( self._token_cache.KEY_ACCESS_TOKEN) if access_token: url = WxConfig.invite_kf + access_token invite_data = { 'kf_account': 'bzw_lolface@gh_cacb86407b98', 'invite_wx': 'bzw_lolface' } r = requests.post( url, json.dumps(invite_data, ensure_ascii=False).encode('utf-8')) logger.debug('[微信多客服系统]Response' + str(r.status_code)) if r.status_code == 200: res = r.text logger.debug('[微信多客服系统]' + res) json_res = json.loads(res) if 'errcode' in json.loads(res): errcode = json_res('errcode') return errcode else: logger.error('[微信多客服系统获取不到access_token]')
def post(self): body = self.request.body logger.debug('微信消息回复中心】收到用户消息' + str(body.decode('utf-8'))) data = ET.fromstring(body) ToUserName = data.find('ToUserName').text FromUserName = data.find('FromUserName').text self._from_name = FromUserName self._to_name = ToUserName MsgType = data.find('MsgType').text if MsgType == 'text' or MsgType == 'voice': '''文本消息 or 语音消息''' try: MsgId = data.find("MsgId").text if MsgType == 'text': Content = data.find('Content').text # 文本消息内容 results = self.pattern.search(Content) if results: # 找到了符合订单ID的内容 order_id = results.group() self._order_id = order_id http_client = tornado.httpclient.AsyncHTTPClient() token = self._token_cache.get_cache( self._token_cache.KEY_WD_ACCESS_TOKEN) params = {"order_id": order_id} public = { "access_token": token, "version": "1.0", "format": "json", "method": "vdian.order.get" } url = r'https://api.vdian.com/api?param={"order_id":"%s"}&public={"method":"vdian.order.get","access_token":"%s","version":"1.0","format":"json"}' % ( order_id, token) http_client.fetch(url, callback=self.on_response) else: reply_content = WxConfig.COMMON_COPYWRITE CreateTime = int(time.time()) out = self.reply_text(FromUserName, ToUserName, CreateTime, reply_content) self.write(out) self.finish() except Exception as e: logger.error(str(e)) self.finish() elif MsgType == 'event': '''接收事件推送''' try: CreateTime = int(time.time()) Event = data.find('Event').text if Event == 'subscribe': # 关注事件 out = self.reply_text(FromUserName, ToUserName, CreateTime, WxConfig.ATTENTION_INIT_COPYWRITE_1) self.write(out) self.send_service_message_text( WxConfig.ATTENTION_INIT_COPYWRITE_2) elif Event == 'CLICK': key = data.find('EventKey').text if key == 'reprint': # 转载 out = self.reply_text(FromUserName, ToUserName, CreateTime, WxConfig.REPRINT_COPYWRITE) self.write(out) except Exception as e: logger.error(str(e)) finally: self.finish() elif MsgType == 'image': try: CreateTime = int(time.time()) out = self.reply_text(FromUserName, ToUserName, CreateTime, WxConfig.PART_IN_GUESSGANME_WAITTING) self.write(out) except Exception as e: logger.error(str(e)) finally: self.finish()
def on_response(self, response): try: CreateTime = int(time.time()) if response.error: out = self.reply_text(self._fddrom_name, self._to_name, CreateTime, WxConfig.HTTP_RESPONSE_ERROR_COPYWRITE) self.write(out) else: CreateTime = int(time.time()) res_json = json.loads(response.body) if res_json["status"]["status_code"] != 0 or res_json[ "result"]["status_ori"] == 10: out = self.reply_text(self._from_name, self._to_name, CreateTime, WxConfig.PART_IN_FAILURE_COPYWRITE) self.write(out) logger.info("==========非法订单以及请求==========") logger.info(res_json) return self.send_service_message_text( WxConfig.PART_IN_SUCCESS_COPYWRITE) name = res_json["result"]["buyer_info"]["name"] exit_media_id = self._media_cache.get_cache(self._order_id) if exit_media_id is not None: out = self.reply_image(self._from_name, self._to_name, CreateTime, exit_media_id) self.write(out) else: token = self._token_cache.get_cache( self._token_cache.KEY_ACCESS_TOKEN) rawImagePath = self.get_random_path() playload_image = {'access_token': token, 'type': 'image'} logger.info("【新创建图片】" + rawImagePath) namefont = ImageFont.truetype(self.get_font_path(), 20) idFont = ImageFont.truetype(self.get_font_path(), 12) im = Image.open(rawImagePath) draw = ImageDraw.Draw(im) draw.text((340, 363), name[0:9], fill=(0, 0, 0), font=namefont) draw.text((490, 980), self._order_id, fill=(165, 165, 165), font=idFont) newPath = self.workpath + "/core/product/" + self._order_id + '.jpeg' im.save(newPath) data = {'media': open(newPath, 'rb')} r = requests.post( url= 'http://file.api.weixin.qq.com/cgi-bin/media/upload', params=playload_image, files=data) image_json = json.loads(r.text) media_id = image_json["media_id"] self._media_cache.set_cache(self._order_id, media_id) out = self.reply_image(self._from_name, self._to_name, CreateTime, media_id) self.write(out) except Exception as e: logger.error(str(e)) finally: self.finish()