废话不多说,直接上码,有问题请留言。该项目基于 python2.7 + django 1.11.3
url.py
#coding:utf8
from django.conf.urls import url
from app.views import *
urlpatterns = [
url(r'^wx_token$', weixin_main), #token 验证
url(r'^upImg$', upload_img), # 上传图片 template
url(r'^jsSDK$', js_sdk), # 前端获取微信验证数据
url(r'^serverId$', server_id), # 输出上传图片serverid
]
views.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import hashlib
import json
import uuid
import requests
from django.http import JsonResponse
from django.shortcuts import render,HttpResponse
import redis
import sys
tt = sys.platform
appId = 'wx6********4a15a'
keys = 'bdeb5a**********6ab2902a'
token = 'yi****dian'
# Create your views here.
if tt == "win32": # 判断操作系统 win32 为 Windows
pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
else:
pool = redis.ConnectionPool(host='localhost',port=6379,decode_responses=True,password='******')
r=redis.Redis(connection_pool=pool)
def weixin_main(request):
if request.method == "GET":
#接收微信服务器get请求发过来的参数
signature = request.GET.get('signature', None)
timestamp = request.GET.get('timestamp', None)
nonce = request.GET.get('nonce', None)
echostr = request.GET.get('echostr', None)
#服务器配置中的token
token = token
#把参数放到list中排序后合成一个字符串,再用sha1加密得到新的字符串与微信发来的signature对比,如果相同就返回echostr给服务器,校验通过
hashlist = [token, timestamp, nonce]
hashlist.sort()
hashstr = ''.join([s for s in hashlist])
hashstr = hashlib.sha1(hashstr).hexdigest()
if hashstr == signature:
return HttpResponse(echostr)
else:
return HttpResponse("field")
else:
othercontent = autoreply(request)
return HttpResponse(othercontent)
#微信服务器推送消息是xml的,根据利用ElementTree来解析出的不同xml内容返回不同的回复信息,就实现了基本的自动回复功能了,也可以按照需求用其他的XML解析方法
import xml.etree.ElementTree as ET
def autoreply(request):
try:
webData = request.body
xmlData = ET.fromstring(webData)
msg_type = xmlData.find('MsgType').text
ToUserName = xmlData.find('ToUserName').text
FromUserName = xmlData.find('FromUserName').text
CreateTime = xmlData.find('CreateTime').text
MsgType = xmlData.find('MsgType').text
MsgId = xmlData.find('MsgId').text
toUser = FromUserName
fromUser = ToUserName
if msg_type == 'text':
content = "您好,欢迎来到Python大学习!希望我们可以一起进步!"
replyMsg = TextMsg(toUser, fromUser, content)
print "成功了!!!!!!!!!!!!!!!!!!!"
print replyMsg
return replyMsg.send()
elif msg_type == 'image':
content = "图片已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
elif msg_type == 'voice':
content = "语音已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
elif msg_type == 'video':
content = "视频已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
elif msg_type == 'shortvideo':
content = "小视频已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
elif msg_type == 'location':
content = "位置已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
else:
msg_type == 'link'
content = "链接已收到,谢谢"
replyMsg = TextMsg(toUser, fromUser, content)
return replyMsg.send()
except Exception, Argment:
return Argment
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
import time
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 Sign:
def __init__(self, jsapi_ticket, url):
self.ret = {
'nonceStr': self.__create_nonce_str(),
'jsapi_ticket': jsapi_ticket,
'timestamp': self.__create_timestamp(),
'url': url,
}
def __create_nonce_str(self):
return str(uuid.uuid4())
def __create_timestamp(self):
return int(time.time())
def sign(self):
string = '&'.join(['%s=%s' % (key.lower(), self.ret[key]) for key in sorted(self.ret)])
self.ret['signature'] = hashlib.sha1(string.encode('utf-8')).hexdigest()
return self.ret
def js_sdk(request):
local_url = request.GET.get('localUrl','')
ticket = r.get('ticket')
if not ticket:
acc = r.get('access_token')
if not acc:
acc_url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'%(appId,keys)
acc = requests.get(acc_url, verify=False).json()['access_token']
r.set('access_token',acc)
r.expire('access_token',7100)
url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"%acc
t = requests.get(url,verify=False).text
tt = json.loads(t)['ticket']
r.set('ticket',tt)
r.expire('ticket',7100)
else:
tt = ticket
data = Sign(tt,local_url).sign()
data['appId']=appId
return JsonResponse(data)
def upload_img(request):
return render(request,'up.html')
def server_id(request):
serverid = request.GET.get('serverId',None)
print("img ID :>>>>> ",serverid)
return HttpResponse(status=200)
up.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
</head>
<body>
<button id="choose">选择</button>
<button id="upload">上传</button>
<img src="" alt="" id="chooseImage1">
</body>
</html>
<script>
var localUrl = window.location.href;
var configData;
$.ajax({
url: '/jsSDK',
method: 'GET',
data: {localUrl: localUrl},
success: function (data) {
configData = {
debug: false,
appId: data.appId,
timestamp: data.timestamp,
nonceStr: data.nonceStr,
signature: data.signature,
jsApiList: ['chooseImage', 'previewImage', 'uploadImage', 'downloadImage']
};
wx.config(configData);
wx.ready(function () {
document.querySelector('#choose').onclick = function () {
var img1 = $('#chooseImage1');
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
var imgLocalId = res.localIds;
if (!imgLocalId) {
alert(2);
fnPicInfo('', imgLocalId, 'choose', 'fb', JSON.stringify(res));
}
img1.attr('src',imgLocalId);
$("#upload").click(function () {
wx.uploadImage({
localId: imgLocalId[0],
isShowProgressTips: 1,
success:function (res) {
if(res.serverId.indexOf("wxLocalResource://")>=0){
mui.alert('',"图片上传失败,请重新上传!",'');
return;
}
mediaId = res.serverId;
if(!mediaId){
fnPicInfo(mediaId,imgLocalId,'upload','fb',JSON.stringify(res));
}
alert(JSON.stringify(res));
serverId = res.serverId;
$.ajax({
url:'/serverId',
method:'GET',
data:{serverId:serverId},
success:function () {
}
})
}
})
})
}
})
}
})
}
})
</script>