搭建服务
- 开通一个阿里云ecs,安装python3及需要的包(参考下方官方文档)
- 将py文件保存在ecs上,运行
- 在本地访问阿里云的IP地址
- 能完成这步说明网络没问题
server.py
1 # -*- coding: utf-8 -*- 2 # filename: server.py 3 import web 4 5 urls = ( 6 '/wx', 'Handle', 7 ) 8 9 class Handle(object): 10 def GET(self): 11 return "hello, this is handle view" 12 13 if __name__ == '__main__': 14 app = web.application(urls, globals()) 15 app.run()
公众号配置
- 注册公众号
- 验证token
- 官方文档是python2写的,不能直接用,python3代码如下
server.py
1 # -*- coding: utf-8 -*- 2 # filename: main.py 3 import web 4 from handle import Handle 5 6 urls = ( 7 '/wx', 'Handle', 8 ) 9 10 if __name__ == '__main__': 11 app = web.application(urls, globals()) 12 app.run()
handle.py
1 import hashlib 2 import web 3 4 class Handle(object): 5 def GET(self): 6 try: 7 data = web.input() 8 if len(data) == 0: 9 return "hello,this is handle view" 10 signature = data.signature 11 timestamp = data.timestamp 12 nonce = data.nonce 13 echostr = data.echostr 14 token = "hfxlcxc" 15 16 list = [token, timestamp, nonce] 17 list.sort() 18 sha1 = hashlib.sha1() 19 sha1.update(list[0].encode('utf-8')) 20 sha1.update(list[1].encode('utf-8')) 21 sha1.update(list[2].encode('utf-8')) 22 hashcode = sha1.hexdigest() 23 24 print("handle/GET func:hashcode, signature: ", hashcode, signature) 25 if hashcode == signature: 26 return echostr 27 else: 28 return "" 29 except (Exception,Argument): 30 return Argument
自动回复
- 调试接口
- 官方文档python里的xml中间有空格,虽然调试可以通过,但在微信里发消息不会自动回复
server.py
1 # -*- coding: utf-8 -*- 2 # filename: server.py 3 import web 4 from handle import Handle 5 6 urls = ( 7 '/wx', 'Handle', 8 ) 9 10 if __name__ == '__main__': 11 app = web.application(urls, globals()) 12 app.run()
handle.py
1 # -*- coding: utf-8 -*-# 2 # filename: handle.py 3 4 import hashlib 5 import web 6 import receive 7 import reply 8 9 class Handle(object): 10 def POST(self): 11 try: 12 webData = web.data() 13 print("Handle Post webdata is ",webData) 14 # 后台打印日志 15 recMsg = receive.parse_xml(webData) 16 if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text': 17 toUser = recMsg.FromUserName 18 fromUser = recMsg.ToUserName 19 content = "test!!" 20 replyMsg = reply.TextMsg(toUser, fromUser, content) 21 return replyMsg.send() 22 else: 23 print("暂不处理") 24 return "success" 25 except (Exception,Argment): 26 return Argment
receive.py
1 # -*- coding: utf-8 -*-# 2 # filename: receive.py 3 4 import xml.etree.ElementTree as ET 5 6 def parse_xml(web_data): 7 if len(web_data) == 0: 8 return None 9 xmlData = ET.fromstring(web_data) 10 msg_type = xmlData.find('MsgType').text 11 if msg_type == 'text': 12 return TextMsg(xmlData) 13 elif msg_type == 'image': 14 return ImageMsg(xmlData) 15 16 class Msg(object): 17 def __init__(self,xmlData): 18 self.ToUserName = xmlData.find('ToUserName').text 19 self.FromUserName = xmlData.find('FromUserName').text 20 self.CreateTime = xmlData.find('CreateTime').text 21 self.MsgType = xmlData.find('MsgType').text 22 self.MsgId = xmlData.find('MsgId').text 23 24 class TextMsg(Msg): 25 def __init__(self,xmlData): 26 Msg.__init__(self,xmlData) 27 self.Content = xmlData.find('Content').text.encode("utf-8") 28 29 class ImageMsg(Msg): 30 def __init__(self, xmlData): 31 Msg.__init__(self,xmlData) 32 self.PicUrl = xmlData.find('PicUrl').text 33 self.MediaId = xmlData.find('MediaId').text
reply.py
1 # -*- coding: utf-8 -*-# 2 # filename: reply.py 3 import time 4 5 class Msg(object): 6 def __init__(self): 7 pass 8 9 def send(self): 10 return "success" 11 12 class TextMsg(Msg): 13 def __init__(self, toUserName, fromUserName, content): 14 self.__dict = dict() 15 self.__dict['ToUserName'] = toUserName 16 self.__dict['FromUserName'] = fromUserName 17 self.__dict['CreateTime'] = int(time.time()) 18 self.__dict['Content'] = content 19 20 def send(self): 21 XmlForm = """<xml><ToUserName><![CDATA[{ToUserName}]]></ToUserName><FromUserName><![CDATA[{FromUserName}]]></FromUserName><CreateTime>{CreateTime}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{Content}]]></Content></xml>""" 22 return XmlForm.format(**self.__dict) 23 24 class ImageMsg(Msg): 25 def __init__(self, toUserName, fromUserName, mediaId): 26 self.__dict = dict() 27 self.__dict['ToUserName'] = toUserName 28 self.__dict['FromUserName'] = fromUserName 29 self.__dict['CreateTime'] = int(time.time()) 30 self.__dict['MediaId'] = mediaId 31 32 def send(self): 33 XmlForm = """<xml><ToUserName><![CDATA[{ToUserName}]]></ToUserName><FromUserName><![CDATA[{FromUserName}]]></FromUserName><CreateTime>{CreateTime}</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[{MediaId}]]></MediaId></Image></xml>""" 34 return XmlForm.format(**self.__dict)
参考
官方文档
https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html
w3c教程
https://www.w3cschool.cn/weixinkaifawendang/
token验证失败
https://www.cnblogs.com/roadwide/p/10566946.html
https://blog.csdn.net/qq_39866513/article/details/83218731
获取access token
https://blog.csdn.net/wchenjt/article/details/96154504
https://blog.csdn.net/qq_26626113/article/details/78251932
白名单
https://cloud.tencent.com/developer/article/1034608
接口调试
https://www.cnblogs.com/txw1958/p/mp-weixin-debug.html
自动回复失败