微信公衆號開發基本分爲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就丟到緩存裏了。