Django——微信推送

微信推送前提

微信推送流程:
    -用户需要关注我
    -需要诱导用户把openid存到我的数据库中
        -生成一个微信地址的二维码(放了一个回调地址)
        -用户扫描二维码,朝该地址发请求,用户一旦点击允许,微信会朝回调地址发送请求,携带一些参数(但是这些参数中没有openid)
        -服务器再次向微信服务器发送请求,携带code,请求回用户的openid,把openid存到自己的数据库
    -发消息
        -先要获取一个access_token,获取用户openid
        -发送消息,需要携带者两个东西,给指定的人发送消息(可以发模板消息,可以发普通消息)

 

settings 中配置:

WECHAT_CONFIG = {
    'app_id': 'wx6edde7a6a97e4fcd',
    'appsecret': '02d8bb38434c75d83e671047a6c7d182',
    'redirect_uri': 'http://42.56.89.12/callback/',
}

 

models中

import hashlib
from django.db import models

class UserInfo(models.Model):
    username = models.CharField("用户名", max_length=64, unique=True)
    password = models.CharField("密码", max_length=64)
    uid = models.CharField(verbose_name='个人唯一ID',max_length=64, unique=True)
    wx_id = models.CharField(verbose_name="微信ID", max_length=128, blank=True, null=True, db_index=True)

    def save(self, *args, **kwargs):
        # 创建用户时,为用户自动生成个人唯一ID
        if not self.pk:
            m = hashlib.md5()
            m.update(self.username.encode(encoding="utf-8"))
            self.uid = m.hexdigest()
        super(UserInfo, self).save(*args, **kwargs)

 

url中:

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/$', views.login),
    url(r'^bind/$', views.bind),
    url(r'^bind_qcode/$', views.bind_qcode),
    url(r'^callback/$', views.callback),
    url(r'^sendmsg/$', views.sendmsg),
]

 

 

views中

环境搭建

import json
import functools
import requests
from django.conf import settings
from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse
from app01 import models


def auth(func):
    def inner(request, *args, **kwargs):
        user_info = request.session.get('user_info')
        if not user_info:
            return redirect('/login/')
        return func(request, *args, **kwargs)

    return inner


def login(request):
    """
    用户登录
    :param request: 
    :return: 
    """
    # models.UserInfo.objects.create(username='luffy',password=123)

    if request.method == "POST":
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.UserInfo.objects.filter(username=user, password=pwd).first()
        if obj:
            request.session['user_info'] = {'id': obj.id, 'name': obj.username, 'uid': obj.uid}
            return redirect('/bind/')
    else:
        return render(request, 'login.html')


@auth
def bind(request):
    """
    用户登录后,关注公众号,并绑定个人微信(用于以后消息推送)
    :param request: 
    :return: 
    """
    return render(request, 'bind.html')


@auth
def bind_qcode(request):
    """
    生成二维码
    :param request: 
    :return: 
    """
    ret = {'code': 1000}
    try:
        # 生成一个地址
        access_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={appid}&redirect_uri=
{redirect_uri}&response_type=code&scope=snsapi_userinfo&state={state}#wechat_redirect
" access_url = access_url.format( # 商户的appid appid=settings.WECHAT_CONFIG["app_id"], # 'wx6edde7a6a97e4fcd', # 回调地址 redirect_uri=settings.WECHAT_CONFIG["redirect_uri"], # 当前登录用户的唯一id,与第三方平台交互的用户唯一id state=request.session['user_info']['uid'] # 为当前用户生成MD5值 ) ret['data'] = access_url except Exception as e: ret['code'] = 1001 ret['msg'] = str(e) return JsonResponse(ret)

 

回调函数:

def callback(request):
    """
    用户在手机微信上扫码后,微信自动调用该方法。
    用于获取扫码用户的唯一ID,以后用于给他推送消息。
    :param request: 
    :return: 
    """
    code = request.GET.get("code")

    # 用户md5值,用户唯一id
    state = request.GET.get("state")
    print(code)

    # 获取该用户openId(用户唯一,用于给用户发送消息)
    # request模块朝https://api.weixin.qq.com/sns/oauth2/access_token地址发get请求
    res = requests.get(
        url="https://api.weixin.qq.com/sns/oauth2/access_token",
        params={
            "appid": settings.WECHAT_CONFIG["app_id"],
            "secret": settings.WECHAT_CONFIG["appsecret"],
            "code": code,
            "grant_type": 'authorization_code',
        }
    ).json()
    # res.data   是json格式
    # res=json.loads(res.data)
    # res是一个字典
    # 获取的到openid表示用户授权成功
    openid = res.get("openid")
    if openid:
        models.UserInfo.objects.filter(uid=state).update(wx_id=openid)
        response = "<h1>授权成功 %s </h1>" % openid
    else:
        response = "<h1>用户扫码之后,手机上的提示</h1>"
    return HttpResponse(response)

 

获取微信接口:

def sendmsg(request):
    def get_access_token():
        """
        获取微信全局接口的凭证(默认有效期俩个小时)
        如果不每天请求次数过多, 通过设置缓存即可
        """
        # 相当于百度的登录功能,返回token,token失效时间是两小时
        result = requests.get(
            url="https://api.weixin.qq.com/cgi-bin/token",
            params={
                "grant_type": "client_credential",
                "appid": settings.WECHAT_CONFIG['app_id'],
                "secret": settings.WECHAT_CONFIG['appsecret'],
            }
        ).json()
        if result.get("access_token"):
            access_token = result.get('access_token')
        else:
            access_token = None
        return access_token
    # 给用户推送消息,必须用token,你要给用户推消息,需要微信的认证
    access_token = get_access_token()
    # 用户唯一id
    openid = models.UserInfo.objects.get(id=1).wx_id

    def send_custom_msg():
        body = {
            # 给哪个用户发消息
            "touser": openid,
            # 消息类型是文本类型
            "msgtype": "text",
            # 消息内容
            "text": {
                "content": 'lqz大帅哥'
            }
        }
        # param这个会拼在连接后,get形式传的参
        response = requests.post(
            url="https://api.weixin.qq.com/cgi-bin/message/custom/send",
            # 放到路径?后面的东西
            params={
                'access_token': access_token
            },
            # 这是post请求body体中的内容,body中的内容都是bytes格式
            data=bytes(json.dumps(body, ensure_ascii=False), encoding='utf-8')
        )
        # 一发消息,微信立马给结果,同步
        # 这里可根据回执code进行判定是否发送成功(也可以根据code根据错误信息)
        # response这个是朝微信地址发请求的响应.json,把json格式字符串,转成字典
        result = response.json()
        return result

    def send_template_msg():
        """
        发送模版消息
        """
        res = requests.post(
            url="https://api.weixin.qq.com/cgi-bin/message/template/send",
            params={
                'access_token': access_token
            },
            json={
                "touser": openid,
                "template_id": 'TPCDGRunTouUbP6667wi5-xR3_aPM7l7fx8nbQdq-DM',
                "data": {
                    "first": {
                        "value": "hehe",
                        "color": "#173177"
                    },
                    "second": {
                        "value": "大帅哥",
                        "color": "#173177"
                    },
                }
            },
        )
        result = res.json()
        return result

    # result = send_custom_msg()
    result = send_template_msg()

    if result.get('errcode') == 0:
        return HttpResponse('发送成功')
    return HttpResponse('发送失败')

 

HTML模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="post">
        {% csrf_token %}
        <input type="text" name="user" placeholder="用户名">
        <input type="password" name="pwd" placeholder="密码">
        <input type="submit" value="登录">
    </form>
</body>
</html>
login

 

{% load staticfiles %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div style="width: 600px;margin: 0 auto">
    <h1>并绑定个人用户(用于以后的消息提醒)</h1>
    <div>
        <h3>第一步:关注微信服务号</h3>
        <img style="height: 100px;width: 100px" src="{% static "img/luffy.jpeg" %}">
    </div>
    <input type="button" value="下一步【获取绑定二维码】" onclick="getBindUserQcode()">
    <div>
        <h3>第二步:绑定个人账户</h3>
        <div id="qrcode" style="width: 250px;height: 250px;background-color: white;margin: 100px auto;"></div>
    </div>
</div>
<script src="{% static "js/jquery.min.js" %}"></script>
{#qrcode 可以生成二维码 #}
<script src="{% static "js/jquery.qrcode.min.js" %}"></script>
<script src="{% static "js/qrcode.js" %}"></script>
<script>
    //你平时看到的所有二维码,都是一个地址
    function getBindUserQcode() {
        $.ajax({
            url: '/bind_qcode/',
            type: 'GET',
            success: function (result) {
                console.log(result);
                //result:{'code':1000,'data':url地址}
                //result.data 取出来的是什么?是后台生成的一个地址
                //通过js生成一个二维码图片放到div中
                $('#qrcode').empty().qrcode({text: result.data});
            }
        });
    }
</script>

</body>
</html>
bind

 

posted @ 2019-03-06 22:13  萤huo虫  阅读(255)  评论(0编辑  收藏  举报