申请到自己的公众号以及有了自己的服务器后,可以编写并配置自己的微信开发接口.
如果没有服务器,可以去搜索小米球,作为临时学习用。非常方便。
在django里面定义处理微信访问的视图
@csrf_exempt def wechatindex(request): wechatObj = wechatCallbackapiTest(request) if request.GET.get('echostr',None): echostr = wechatObj.valid() return HttpResponse(echostr) else: #POST print(request.body) result = wechatObj.responseMsg() print(result) return HttpResponse(result)
微信访问的url都带有 timestamp, signature, nonce 等微信验证需要的参数
def _checkSignature(self): signature = self.request.GET['signature'] timestamp = self.request.GET['timestamp'] nonce = self.request.GET['nonce'] list = [TOKEN,timestamp,nonce] list.sort() sha1 = hashlib.sha1() sha1.update(list[0].encode('utf-8')) sha1.update(list[1].encode('utf-8')) sha1.update(list[2].encode('utf-8')) hashcode = sha1.hexdigest() print('hashcode:' + hashcode) print('signature:' + signature) if hashcode == signature: return True else: return False
def valid(self): echoStr = self.request.GET['echostr'] if self._checkSignature(): return echoStr #验证成功的话,要返回 echoStr到微信公众平台 else: return ''
解析用户发送的消息。用户post的消息存在 request.body里面
def _parseMsg(self,xmlbody): '''解析用户发送的消息''' try: xmlData = ET.fromstring(xmlbody) msg ={} msg['ToUserName'] = xmlData.find('ToUserName').text msg['FromUserName'] = xmlData.find('FromUserName').text msg['CreateTime'] = xmlData.find('CreateTime').text msg['MsgType'] = xmlData.find('MsgType').text msg['MsgId'] = xmlData.find('MsgId').text if msg['MsgType'] == 'text': msg['Content'] = xmlData.find('Content').text elif msg['MsgType'] == 'image': msg['PicUrl'] = xmlData.find('PicUrl').text msg['MediaId'] = xmlData.find('MediaId').text elif msg['MsgType'] == 'voice': msg['MediaId'] = xmlData.find('MediaId').text msg['Format'] = xmlData.find('Format').text msg['Recognition'] = xmlData.find('Recognition').text elif msg['MsgType'] == 'video': msg['MediaId'] = xmlData.find('MediaId').text msg['ThumbMediaId'] = xmlData.find('ThumbMediaId').text elif msg['MsgType'] == 'location': msg['MediaId'] = xmlData.find('MediaId').text msg['Location_X'] = xmlData.find('Location_X').text # 地理位置消息 msg['Location_Y'] = xmlData.find('Location_Y').text msg['Scale'] = xmlData.find('Scale').text msg['Label'] = xmlData.find('Label').text elif msg['MsgType'] == 'link': msg['Title'] = xmlData.find('Title').text msg['Description'] = xmlData.find('Description').text msg['Url'] = xmlData.find('Url').text return msg except Exception as e: raise e
公众号回复用户消息的简单示例:
def responseMsg(self): if self.request.body !='': postObj = self._parseMsg(self.request.body) keyword = postObj['Content'] textTpl = ''' <xml> <ToUserName><![CDATA[{0}]]></ToUserName> <FromUserName><![CDATA[{1}]]></FromUserName> <CreateTime>{2}</CreateTime> <MsgType><![CDATA[{3}]]></MsgType> <Content><![CDATA[{4}]]></Content> </xml> ''' if keyword == '?' or keyword == '?': result = textTpl.format(postObj['FromUserName'], postObj['ToUserName'], int(time.time()), 'text', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) ) return result else: return ''