微信公众号开发基本分为2大种类型python
1.用户直接作了某些操做(回复信息、订阅、扫码、发语音、点按钮等),此时这些信息微信会发送到微信服务器的80端口,这是一种开发类型;
2.经过链接(按钮、文章)引导用户到另外一个网站,网站经过oauth实现微信的三方登陆作到用户打通,而后提供更多服务git
注意第二种类型的其余网站能够跟第一种类型(只提供80端口服务)的网站是一个servergithub
代码位置weixin_server tag:80-port-20160415django
wechat sdk操做都须要一个wechat的东西,生成这玩意儿须要加载一个wechat_config,config里面包含了你的appid,appsecret,以及你消息加密解密的配置,为了简少根据加密方式形成的代码变动,我在配置里面添加了settings.WEIXIN_ENCRYPT_MODE
,这样直接填写你的加密模式,就能够在任何用到wechat的地方直接import一个wechat变量,之因此要用get_wechat
的方式实时生成是为了作access_token的缓存,下面会讲。缓存
from .wechat import get_wechat wechat = get_wechat()
微信在作一些操做是须要用到access_token(生成二维码等),而天天access_token接口的调用上限为2000,须要本身作缓存, sdk文档讲了几种方式,我以为放在cache中拿比较稳当。服务器
代码我不贴了,这是位置
weixin/config.py
weixin/wechat.py微信
微信会在用户对公众号交互时像咱们的服务器80端口post一些事件,sdk文档 message源码,大致看了下我写了个mixinapp
# -*- coding: utf-8 -*- from weixin.wechat import get_wechat from wechat_sdk.messages import MESSAGE_TYPES, EventMessage wechat = get_wechat() REVERSED_MESSAGE_TYPES = {value:key for key, value in MESSAGE_TYPES.iteritems()} class WeixinDispatchMixin(object): def dispatch_weixin(self, request, *args, **kwargs): content = request.body signature = request.GET.get('signature', '') msg_signature = request.GET.get('msg_signature', '') timestamp = request.GET.get('timestamp', '') nonce = request.GET.get('nonce', '') try: wechat.parse_data( content, msg_signature=msg_signature, timestamp=timestamp, nonce=nonce) except ParseError: return HttpResponse('Invalid Body Text') handler_name = self.get_weixin_handler_name(request, wechat, *args, **kwargs) handler = getattr(self, handler_name, self.http_method_not_allowed) return handler(request, wechat, *args, **kwargs) def get_weixin_handler_name(self, request, parsed_wechat, *args, **kwargs): message = parsed_wechat.message if isinstance(message, EventMessage): event_name = REVERSED_MESSAGE_TYPES[type(message)] event_detail_name = 'weixin_handler_{}_{}'.format(event_name, message.type) if hasattr(self, event_detail_name): event_name = event_detail_name return event_name return u'weixin_handler_{}'.format(REVERSED_MESSAGE_TYPES.get(type(message), 'unsupport'))
mixin参考django的dispatch,这样在继承的类里面直接实现weixin_handler_xxx方法便可,然而event有更多的类型,若是是通用处理则直接实现weixin_handler_event,若是要更加细化,例如扫码的event,则实现weixin_handler_event_scan方法,能够参考weixin_server/views.pypost
菜单能够直接在admin定制,因为菜单相似一种配置,同一时间最多且只有1个,我就把edx的config_model拿过来了,本身定制了下admin,这样你能够直接在admin里面修改菜单,微信会生效。微信菜单会缓存5分钟,你能够取消关注,而后在关注查看菜单变化效果。网站
菜单这块儿的代码有点意思,感兴趣的能够看下。
weixin/models.py
weixin/admin.py
二维码的逻辑略有不一样(相对于sdk的其余response_xxx),因此我写了个qrcode.py封装了一下,注意永久二维码只能生产10万张,业务场景不要乱用,二维码的这些id、url都是须要作本地存储的,我没接model就丢到缓存里了。