Django+wechapy 微信公众号开发

博主好久没有更新了

这次整理下最近研究的简单的公众号平台搭建

这边用的是 wechatpy库 官网链接

  1 # -*- coding: utf-8 -*-
  2 # 公众号
  3 # 作者: XX
  4 # 时间: 2019-12-25
  5 
  6 
  7 import logging
  8 import requests
  9 
 10 from Zmops import settings
 11 from api.gaodei import GaoDeiBase
 12 
 13 from wechat.pack import Pack
 14 
 15 from django.http.response import HttpResponse, HttpResponseRedirect
 16 from django.views.decorators.csrf import csrf_exempt
 17 from django.shortcuts import redirect
 18 from django.shortcuts import render
 19 from django.contrib import messages
 20 
 21 from wechatpy.exceptions import InvalidSignatureException, WeChatClientException
 22 from wechatpy import parse_message
 23 from wechatpy.replies import TextReply, ImageReply, VoiceReply
 24 from wechatpy import WeChatClient
 25 from wechatpy.oauth import WeChatOAuth
 26 from wechatpy.utils import check_signature
 27 
 28 
 29 logger = logging.getLogger("log")
 30 
 31 
 32 def views_index(request):
 33     return HttpResponse("Zmops 公众号平台")
 34 
 35 
 36 def views_create_menu(request):
 37     WechatBase().delete_menu()
 38     WechatBase().create_menu()
 39     return HttpResponse("成功创建自定义菜单")
 40 
 41 
 42 class WechatServer(object):
 43     """
 44     公众号服务类
 45     """
 46     @csrf_exempt
 47     def serve(self, request):
 48         # GET 方式用于微信公众平台绑定验证
 49         if request.method == "GET":
 50             signature = request.GET.get("signature", "")
 51             timestamp = request.GET.get("timestamp", "")
 52             nonce = request.GET.get("nonce", "")
 53             echo_str = request.GET.get("echostr", "")
 54             try:
 55                 logger.info("Token:%s" % settings.Token)
 56                 logger.info("signature:%s" % signature)
 57                 logger.info("timestamp:%s" % timestamp)
 58                 logger.info("nonce:%s" % nonce)
 59                 check_signature(settings.Token, signature, timestamp, nonce)
 60             except InvalidSignatureException:
 61                 echo_str = "错误的请求"
 62             logger.info(echo_str)
 63             response = HttpResponse(echo_str)
 64         elif request.method == "POST":
 65 
 66             msg = parse_message(request.body)
 67             open_id = msg.source
 68             msg_dict = msg.__dict__["_data"]
 69             logger.info("用户open_id:%s" % open_id)
 70             logger.info("用户msg_dict:%s" % msg_dict)
 71             # 文本消息
 72             if msg.type == "text":
 73                 reply = TextReply(message=msg)
 74                 reply.content = "收到你发送的文本消息"
 75                 xml = reply.render()
 76             # 图片消息
 77             elif msg.type == "image":
 78                 reply = ImageReply(message=msg)
 79                 reply.content = "收到你发送的图片消息"
 80                 reply.media_id = msg.media_id
 81                 xml = reply.render()
 82             # 语音消息
 83             elif msg.type == "voice":
 84                 reply = VoiceReply(message=msg)
 85                 reply.content = "收到你发送的语言消息"
 86                 reply.media_id = msg.media_id
 87                 xml = reply.render()
 88             # 动作消息
 89             elif msg.type == "event":
 90                 reply = TextReply(message=msg)
 91                 logger.info("操作的event:%s" % msg_dict["Event"])
 92                 if msg_dict["Event"] == "subscribe":
 93                     reply.content = "你成功关注了此公众号\n我们的目标是\n让天下没有难做的运维 !\n"
 94                     xml = reply.render()
 95                     wx_user_info = WechatBase().get_wx_user_info(open_id)
 96                     Pack().user_create(_json=wx_user_info, subscribe=1)
 97 
 98                 elif msg_dict["Event"] == "unsubscribe":
 99                     reply.content = "你取消关注了此公众号"
100                     xml = reply.render()
101                     wx_user_info = WechatBase().get_wx_user_info(open_id)
102                     Pack().user_create(_json=wx_user_info, subscribe=0)
103 
104                 elif msg_dict["Event"] == "LOCATION":
105                     latitude = msg_dict["Latitude"]
106                     longitude = msg_dict["Longitude"]
107                     reply.content = {
108                         "latitude": latitude,
109                         "longitude": longitude
110                     }
111                     xml = reply.render()
112                 else:
113                     reply.content = "你的动作类型未知"
114                     xml = reply.render()
115             # 未知消息类型
116             else:
117                 # 捕捉公众号消息类型
118                 logger.info("公众号接收到的消息类型:%s" % msg.type)
119                 reply = TextReply(message=msg)
120                 reply.content = "收到你发送的未知消息类型:%s" % msg.type
121                 xml = reply.render()
122             response = HttpResponse(xml, content_type="application/xml")
123         else:
124             response = HttpResponse("公众号系统异常", content_type="application/xml")
125         return response
126 
143 
144 
145 class WechatBase(object):
146     def __init__(self):
147         self.AppID = settings.AppID
148         self.AppSecret = settings.AppSecret
149         self.URL = settings.URL
150 
151     def get_access_token(self):
152         response = requests.get(url="https://api.weixin.qq.com/cgi-bin/token", params={
153             "grant_type": "client_credential",
154             "appid": self.AppID,
155             "secret": self.AppSecret
156         })
157         text = response.text
158 
159         if text["expires_in"] == 7200:
160             access_token = text["access_token"]
161             return access_token
162         else:
163             logger.info("获取access_token异常")
164             return False
165 
166     # 获取微信代理授权
167     def get_wx_client(self):
168         logger.info("获取微信代理授权")
169         return WeChatClient(self.AppID, self.AppSecret)
170 
171     def get_wx_user_info(self, openid):
172         wx_client = self.get_wx_client()
173         try:
174             wx_user_info = wx_client.user.get(user_id=openid)
175             logger.info("微信用户信息:%s" % wx_user_info)
176             return wx_user_info
177         except WeChatClientException as e:
178             logger.error(e)
179             return False
180 
181     def get_wechat_oauth(self, redirect_url):
182         return WeChatOAuth(app_id=self.AppID, secret=self.AppSecret, redirect_uri=redirect_url, scope="snsapi_userinfo")
183 
184     def create_menu(self):
185         wx_client = self.get_wx_client()
186         wx_client.menu.create({
187             "button": [
188                 {
189                     "type": "view",
190                     "name": "更新菜单",
191                     "url": self.URL + "/api/menu/create"
192                 },
193                 {
194                     "type": "view",
195                     "name": "当前IP地图",
196                     "url": self.URL + "/api/address_ip/get"
197                 },
198                 {
199                     "type": "view",
200                     "name": "功能测试",
201                     "url": self.URL + "/api/test"
202                 }
203             ],
204             "matchrule": {
205                 "tag_id": None,
206                 "sex": None,
207                 "country": "XX",
208                 "province": "XX",
209                 "city": "XX",
210                 "client_platform_type": None
211 
212             }
213         })
214         logger.info("成功创建菜单")
215 
216     def delete_menu(self):
217         wx_client = self.get_wx_client()
218         wx_client.menu.delete()
219         logger.info("成功删除菜单")
220 
237 
238 # 定义授权装饰器
239 def oauth(method):
240     def warpper(request):
241         if request.session.get("user_info", None) is None:
242             code = request.GET.get("code", None)
243             # logger.info()(request.get_raw_uri())
244             wechat_oauth = WechatBase().get_wechat_oauth(request.get_raw_uri())
245             url = wechat_oauth.authorize_url
246             if code:
247                 try:
248                     wechat_oauth.fetch_access_token(code)
249                     user_info = wechat_oauth.get_user_info()
250                 except Exception as e:
251                     logger.error(e)
252                 else:
253                     request.session["user_info"] = user_info
254             else:
255                 return redirect(url)
256 
257         return method(request)
258 
259     return warpper
260 
261 
262 @oauth
263 def views_get_user_info(request):
264     user_info = request.session.get("user_info")
265     logger.info(user_info)
266     return HttpResponse(str(user_info))

 

在上传代码部署过程中 会需要生成 requirements 文件

这边命令是

1 pip freeze > requirements.txt

基于已生成的 requirements文件 安装相关模块

1 pip install -r requirements.txt

 

posted on 2020-01-07 14:08  堕落的伊丝莉  阅读(1678)  评论(0编辑  收藏  举报