Django 开发微信公众号

200 篇文章 8 订阅

其实这个功能一早就完成了,但是直到今天才有空把它记录下来~~

 

准备工作

在正式开始之前,需要做一些准备:

    a: 安装好wechat_sdk(怎么安装请看我前面写<<基于Django的微信公众号开发(2) -- 在sae添加第三方包>>);

    b: 成功通过了微信公众号的开发者认证;

    c: 新建一个应用(不是必须的), 我新建了一个dict应用.

 

需要注意的事项

在正式动手之前,首先我要说一下要注意的事(我踩过的坑):

    a: 微信公众号服务器在收到用户在公众号输入的信息之后, 只会转发到一个url上(就是你开发者认证时所填的那个url,所以只能通过这个url来接收信息)

    b: 公众号收到用户的信息之后, 将会把它打包成规定的xml的模式通过你注册的url发送到你的服务器上, 你发送给用户的消息同样要包装成同样格式的xml才能成功, 否则公众号服 务器一律拒绝并在用户端返回"该公众号提供的服务出现故障, 请稍后再试"的提示(幸运的是在wechat_sdk已经有打包这种xml的方法了, 如果你想了解, 你可以看看公众号的开发文档)

    c: 返回给用户的文字一定要用utf-8格式

    d: 每次发送的消息长度长度不能超过2048字节, 由于采用utf-8编码, 所以请留意每个汉字都算作3个字节, 超长就要记得截断发两次了

 

调试技巧

    无论你的服务器在调试过程中出了什么错, 在用户端都是提示"该公众号提供的服务出现故障, 请稍后再试"的提示, 所以想只靠一个测试账号来调试明显是很不靠谱的. 在公众号平台上有一个调试 工具, 但是他也只会返回访问的错误代码(200/500之类的), 并没有给出提示, 同样也是很不靠谱, 那么我们该怎么样知道我的服务器跟微信发送消息这部分出了什么问题呢?

    我在开发过程中发现了一个技巧, 我们的服务器从公众号服务器接收了一个包含xml格式的包, 并且开始读取处理, 最后把处理结果(返回给用户的文字)打包成xml包发送给公众号服务器. 原理是这样子. 那么我们只要伪造一个用户发送信息的xml段, 保存在一个xml文件里面, 需要用的时候就读取这个xml文件, 在后台控制台调试输出包装好的xml就行了 (当然你得先排除网络连接的问题,因为网络连接导致你的服务器接收不了,或者发送不了都有可能发生的,还有就是环境的问题,不过只要你正确配置就不太可能这种问题的). 需要发送不同的信息的时候, 写个函数修改xml里面的消息部分就可以了.

 

开发过程

首先, 我们现在可以把用于通过微信公众号验证的代码给注释掉了(最好不要删除), 然后我们新建一个相同名字的函数

下面是我的一些代码(为了更了解整个基本的结构, 代码有所删减, 主要是获取数据部分跟格式组装部分)

 
  1. # 这是段代码是我dict应用的返回微信消息响应部分, 主要功能是获取消息->做出对应反应->返回消息

  2. # 为了方便大家理解, 有一部分我将会用"(--tips--)"的格式进行简化, 只保留必要部分

  3. # 代码开始

  4.  
  5.  
  6. # -*- coding: utf-8 -*-

  7.  
  8. # 这段是需要添加的,主要是为了添加path,保证django的正常运行

  9. # (因为我的django用的是自己的包嘛)

  10. import os

  11. import sys

  12. root = os.path.dirname(__file__)

  13. sys.path.insert(0, os.path.join(root, '../site-packages/Django-1.9.7-py2.7.egg'))

  14. os.environ['DJANGO_SETTINGS_MODULE'] = 'yuuuuchang.settings'

  15.  
  16. from django.shortcuts import render

  17. from django.http.response import HttpResponse, HttpResponseBadRequest

  18. from django.views.decorators.csrf import csrf_exempt

  19.  
  20. from wechat_sdk import WechatBasic

  21. from wechat_sdk.exceptions import ParseError

  22. from wechat_sdk.messages import TextMessage, VoiceMessage, ImageMessage, VideoMessage, LinkMessage, LocationMessage, \

  23. EventMessage

  24.  
  25. # (-- 个人数据的调用, 自定义返回格式的组装, 跟数据库查询的入口 --)

  26.  
  27. # wechat_sdk需要初始化一些数据

  28. wechat = WechatBasic(token=WECHAT_TOKEN, appid=WEIXIN_APPID, appsecret=WEIXIN_APPSECRET)

  29.  
  30. # def wechat_message(request):

  31. # """ 微信认证 """

  32. # if request.method == 'GET':

  33. # signature = request.GET.get('signature')

  34. # timestamp = request.GET.get('timestamp')

  35. # nonce = request.GET.get('nonce')

  36. #

  37. # if not wechat.check_signature(signature=signature, timestamp=timestamp, nonce=nonce):

  38. # return HttpResponseBadRequest('Verify Failed')

  39. # else:

  40. # return HttpResponse(request.GET.get('echostr', ''), content_type='text/plain')

  41.  
  42.  
  43. def wechat_message(request):

  44. """ 消息入口,用户通过输入框发送的消息都发到这里处理 """

  45.  
  46. # 解析本次请求的 XML 数据

  47. try:

  48. wechat.parse_data(data=request.body)

  49. except ParseError:

  50. return HttpResponseBadRequest('无效的xml数据')

  51.  
  52. # 获取解析好的微信请求信息

  53. message = wechat.get_message()

  54.  
  55. # 假如信息是文本格式

  56. # (TextMessage是wechat_sdk定义的一个文本消息类,下面还有语音类之类的,经过上面解析的消息都会归属到这些类中)

  57. if isinstance(message, TextMessage):

  58. context = message.content.strip()

  59.  
  60. # 假设用户输入的是什么文字,然后做出相应反应

  61. if context == '笔记' or context == 'blog':

  62. tips = '这里设置你需要发给用户的文字'

  63.  
  64. elif context == '学习' or context == 'study':

  65. tips = '这里设置你需要发给用户的文字'

  66.  
  67. elif context == 'help':

  68. tips = '这里设置你需要发给用户的文字'

  69.  
  70. else:

  71. # (-- 获取到context, 并且用这个context作为查询条件在数据库中查找相应结果 --)

  72. # (-- 如果你也有从数据库获取数据然后返回的操作,记得把结果转utf-8格式 --)

  73.  
  74. # 没有查询结果

  75. if len(foundword) == 0:

  76. tips = '未查询到结果,换个词试试?'

  77.  
  78. # 查询到一个

  79. elif len(foundword) == 1:

  80. # (-- 将结果用自定义的格式打包好(主要是换行跟缩进),然后放到tips里面 --)

  81.  
  82. # 查询到多个结果

  83. else:

  84. # (-- 将结果用自定义的格式打包好(主要是换行跟缩进),然后放到tips里面 --)

  85.  
  86. # 如果收到语音信息

  87. if isinstance(message, VoiceMessage):

  88. tips = '打字啦,语音消息我听不懂~'

  89.  
  90. # 如果收到图片信息(下面看提示就知道了,不多说)

  91. if isinstance(message, ImageMessage):

  92. tips = '虽然有点看不懂~但是我喜欢这张图!'

  93.  
  94. if isinstance(message, VideoMessage):

  95. tips = '这个是..视频消息?怎么打开教教我嘛~'

  96.  
  97. if isinstance(message, LinkMessage):

  98. tips = '不要发奇怪的地址给我,我真的看不懂咧'

  99.  
  100. if isinstance(message, LocationMessage):

  101. tips = '这个...哪边是北?(路痴专用懵X表情)'

  102.  
  103. # 这里是定义用户对公众号所做的事(事件,比如关注,取消关注等)

  104. if isinstance(message, EventMessage):

  105. # 公众号被关注的时候

  106. if message.type == 'subscribe':

  107. tips = '''感谢你关注"鱼肠笔记"! balabala...'''

  108. else:

  109. (-- 省略 --)

  110.  
  111. # 最后, 经过前面诸多处理, 我们得出了一个tips的文本信息, 这就是我们想对用户说的, 我们需要打包, 然后以规定格式返回

  112. # 首先是打包, wechat_sdk已经做了一个方法了

  113. result = wechat.response_text(content=tips)

  114.  
  115. # 然后是返回,记得规定是xml格式返回

  116. return HttpResponse(result, content_type='application/xml')

 

基本上的要点就是这样了, 太偏远的我已经剔除掉

你可以下手玩玩, 祝你玩得愉快~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值