# 基础知识填坑

一、注册完小程序后,想开发订阅号,仍需进行订阅号注册,并且需绑定不同邮箱。一个邮箱只能绑定一个服务。
二、个人订阅号每天只能发布一次内容,不过一次最多可以发8篇文章

# 高级开发填坑

一、私有云接收用户消息并回复

  1. Token认证:公众号-基本配置-Token,这里的Token和access_token没有任何关系,这里的Token自己随便填
  2. 官方demo中
urls = (
    '/wx', 'Handle',
)

应该改为

urls = (
    '/', 'Handle',
)
            token = "xxxx" #请按照公众平台官网\基本配置中信息填写

            list = [token, timestamp, nonce]
            list.sort()
            sha1 = hashlib.sha1()
            map(sha1.update, list)
            hashcode = sha1.hexdigest()
            print "handle/GET func: hashcode, signature: ", hashcode, signature
            if hashcode == signature:
                return echostr
            else:
                return ""

哈希部分计算有问题,不用管什么问题了,直接改成下面,因为平台最终能拿到它发出的消息,就算成功,我们这里就简单粗暴原样返回。

            token = "sdfsaf"
 
            list = [token, timestamp, nonce]
            list.sort()
            s = list[0] + list[1] + list[2]
            hashcode = hashlib.sha1(s.encode('utf-8')).hexdigest()
            print( "handle/GET func: hashcode, signature: ", hashcode, signature)
            if hashcode == signature:
                return echostr
            else:
                return echostr

  1. Token 认证成功后,就可以接收用户的消息,并自行回复了,下面是完整代码:

main.py

# -*- coding: utf-8 -*-
# filename: main.py
import web
from handle import Handle
 
urls = (
    '/', 'Handle',
)
 
if __name__ == '__main__':
    app = web.application(urls, globals())
    app.run()

handle.py

# -*- coding: utf-8 -*-
# filename: handle.py
 
import hashlib
import web
import receive
import time
import os
import reply
 
class Handle(object):
 
    def __init__(self):
        self.app_root = os.path.dirname(__file__)
        self.templates_root = os.path.join(self.app_root, 'templates')
        self.render = web.template.render(self.templates_root)
        
    def GET(self):
        try:
            data = web.input()
            if len(data) == 0:
                return "hello, this is handle view"
            signature = data.signature
            timestamp = data.timestamp
            nonce = data.nonce
            echostr = data.echostr
            token = "sdfsaf"
 
            list = [token, timestamp, nonce]
            list.sort()
            s = list[0] + list[1] + list[2]
            hashcode = hashlib.sha1(s.encode('utf-8')).hexdigest()
            print( "handle/GET func: hashcode, signature: ", hashcode, signature)
            if hashcode == signature:
                return echostr
            else:
                return echostr
        except (Exception) as Argument:
            return Argument
 
    def POST(self):
        try:
            webData = web.data()
            print("Handle Post webdata is:\n", webData)
            #打印消息体日志
            recMsg = receive.parse_xml(webData)
            
            if isinstance(recMsg, receive.Msg) and recMsg.MsgType == 'text':
                toUser = recMsg.FromUserName
                fromUser = recMsg.ToUserName
                content = str(recMsg.Content)
                print('Reply message info:\n')
                print('toUser =', toUser)
                print('fromUser = ', fromUser)
                print('content = ', content)
                replyMsg = reply.TextMsg(toUser, fromUser, content)
                return replyMsg.send()
                #return "success"
                #return self.render.reply_text(toUser, fromUser, int(time.time()), content)
            else:
                print("不支持的消息类型:",recMsg.MsgType)
                return "success"
        except (Exception) as Argment:
            return Argment

receive.py

# -*- coding: utf-8 -*-
# filename: receive.py
import xml.etree.ElementTree as ET
 
def parse_xml(web_data):
    if len(web_data) == 0:
        return None
    xmlData = ET.fromstring(web_data)
    msg_type = xmlData.find('MsgType').text
    if msg_type == 'text':
        return TextMsg(xmlData)
    elif msg_type == 'image':
        return ImageMsg(xmlData)
    elif msg_type == 'location':
        return LocationMsg(xmlData)
    elif msg_type == 'event':
        return EventMsg(xmlData)
              
class Event(object):
    def __init__(self, xmlData):
        self.ToUserName = xmlData.find('ToUserName').text
        self.FromUserName = xmlData.find('FromUserName').text
        self.CreateTime = xmlData.find('CreateTime').text
        self.MsgType = xmlData.find('MsgType').text
        self.Eventkey = xmlData.find('EventKey').text
 
class Msg(object):
    def __init__(self, xmlData):
        self.ToUserName = xmlData.find('ToUserName').text
        self.FromUserName = xmlData.find('FromUserName').text
        self.CreateTime = xmlData.find('CreateTime').text
        self.MsgType = xmlData.find('MsgType').text
        self.MsgId = xmlData.find('MsgId').text
        
class TextMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.Content = xmlData.find('Content').text
        
class ImageMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.PicUrl = xmlData.find('PicUrl').text
        self.MediaId = xmlData.find('MediaId').text
 
class LocationMsg(Msg):
    def __init__(self, xmlData):
        Msg.__init__(self, xmlData)
        self.Location_X = xmlData.find('Location_X').text
        self.Location_Y = xmlData.find('Location_Y').text
 
class EventMsg(Msg):
    def __init__(self, xmlData):
        Event.__init__(self, xmlData)
        self.Event = xmlData.find('Event').text

reply.py

import time

class Msg(object):
    def __init__(self):
        pass
    def send(self):
        return "success"

class TextMsg(Msg):
    def __init__(self, toUserName, fromUserName, content):
        self.__dict = dict()
        self.__dict['ToUserName'] = toUserName
        self.__dict['FromUserName'] = fromUserName
        self.__dict['CreateTime'] = int(time.time())
        self.__dict['Content'] = content

    def send(self):
        XmlForm = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[text]]></MsgType>
        <Content><![CDATA[{Content}]]></Content>
        </xml>
        """
        return XmlForm.format(**self.__dict)
    
class ImageMsg(Msg):
    def __init__(self, toUserName, fromUserName, mediaId):
        self.__dict = dict()
        self.__dict['ToUserName'] = toUserName
        self.__dict['FromUserName'] = fromUserName
        self.__dict['CreateTime'] = int(time.time())
        self.__dict['MediaId'] = mediaId
    def send(self):
        XmlForm = """
        <xml>
        <ToUserName><![CDATA[{ToUserName}]]></ToUserName>
        <FromUserName><![CDATA[{FromUserName}]]></FromUserName>
        <CreateTime>{CreateTime}</CreateTime>
        <MsgType><![CDATA[image]]></MsgType>
        <Image>
        <MediaId><![CDATA[{MediaId}]]></MediaId>
        </Image>
        </xml>
        """
        return XmlForm.format(**self.__dict)

运行结果:

[root@VM_0_14_centos weixin2]# python3 main.py 80
http://0.0.0.0:80/
handle/GET func: hashcode, signature:  80cff3a11f705dbfd4d13544938e8f0604e15713 80cff3a11f705dbfd4d13544938e8f0604e15713
121.51.66.120:26665 - - [05/Mar/2020 23:42:23] "HTTP/1.1 GET /" - 200 OK
218.90.129.90:5470 - - [05/Mar/2020 23:42:24] "HTTP/1.1 GET /livereload" - 404 Not Found
Handle Post webdata is:
 b'<xml><ToUserName><![CDATA[gh_10cbc87900a0]]></ToUserName>\n<FromUserName><![CDATA[oTK-mwSbfgfFvLW55TkFabanv5EY]]></FromUserName>\n<CreateTime>1583422953</CreateTime>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[\xe6\xb5\x8b\xe8\xaf\x95]]></Content>\n<MsgId>22669168083602861</MsgId>\n</xml>'
Reply message info:

toUser = oTK-mwSbfgfFvLW55TkFabanv5EY
fromUser =  gh_10cbc87900a0
content =  测试
121.51.66.16:10414 - - [05/Mar/2020 23:42:33] "HTTP/1.1 POST /" - 200 OK
Handle Post webdata is:
 b'<xml><ToUserName><![CDATA[gh_10cbc87900a0]]></ToUserName>\n<FromUserName><![CDATA[oTK-mwSbfgfFvLW55TkFabanv5EY]]></FromUserName>\n<CreateTime>1583422958</CreateTime>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[\xe4\xbd\xa0\xe5\xa5\xbd]]></Content>\n<MsgId>22669167649346895</MsgId>\n</xml>'
Reply message info:

toUser = oTK-mwSbfgfFvLW55TkFabanv5EY
fromUser =  gh_10cbc87900a0
content =  你好
121.51.66.16:10415 - - [05/Mar/2020 23:42:38] "HTTP/1.1 POST /" - 200 OK

运行:

在这里插入图片描述