微信服务号推送消息接口开发

馋奶兔 提交于 2020-02-15 03:18:58

1.登录微信公众开发平台

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

拿到这个以后,下面会有一个二维码生成,这二维码就是沙箱环境的测试公招号!

2.基于Django开发接口

首先把用到的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'^index/$', views.index),

    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),
]

在项目中需要用户登录,让他关注我们网站的服务号,然后给他推送消息等。

 

准备工作:

1.登录的装饰器

def auth(func):
    '''
    登录认证的装饰器函数【其实可以写成一个中间件】
    :param func:
    :return:
    '''
    @functools.wraps(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
View Code
2.有一个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)

3.开始视图部分:

用户登录进来,注册一个session,然后跳到了绑定页面。

def login(request):
    """
    用户登录
    :param request: 
    :return: 
    """
    # models.UserInfo.objects.create(username='jesi',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:
            # 登录成功,将这三个值放到session中
            request.session['user_info'] = {'id': obj.id, 'name': obj.username, 'uid': obj.uid}
            return redirect('/bind/')
    else:
        return render(request, 'login.html')

4.bind给他返回一个页面

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

5.这个页面把上面的公招号图片放进来。

{% 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/jesi.jpg" %}">
    </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>
<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);
                $('#qrcode').empty().qrcode({text: result.data});
            }
        });
    }
</script>

</body>
</html>
View Code

 

6.这里面扫码关注后,点击继续扫码,点击事件发送一个请求数据,将这个数据做成一个URL自动生成一个二维码。

@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=settings.WECHAT_CONFIG["app_id"], # 'wx961b82840037d073',
            redirect_uri=settings.WECHAT_CONFIG["redirect_uri"], # 'http://47.99.191.149/callback/',
            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)

7.这个JS事件将前面的url生成一个二维码。

8.用户扫完下面的二维码以后,访问这个URL,然后
 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"

扫完这个二维码以后,绑定用户,微信会自动访问你的一个callback的URL,在callback的函数中将wx_id填入到登录用户中,以便以后推送消息。

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

    # 用户md5值
    state = request.GET.get("state")

    # 获取该用户openId(用户唯一,用于给用户发送消息)
    res = requests.get(
        url="https://api.weixin.qq.com/sns/oauth2/access_token",
        params={
            "appid": 'wx961b82840037d073',
            "secret": 'c3f919fab6cd528a6ed727c911e1c599',
            "code": code,
            "grant_type": 'authorization_code',
        }
    ).json()
    # 获取的到openid表示用户授权成功
    openid = res.get("openid")
    if openid:
        #将这个用户的wx_id和他的用户这条数据进行一个绑定
        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():
        """
        获取微信全局接口的凭证(默认有效期俩个小时)
        如果不每天请求次数过多, 通过设置缓存即可
        """
        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

    access_token = get_access_token()
    print(access_token)

    openid = models.UserInfo.objects.get(id=1).wx_id

    def send_custom_msg():
        body = {
            "touser": openid,
            "msgtype": "text",
            "text": {
                "content": '欢迎Python鬼才!'
            }
        }
        response = requests.post(
            url="https://api.weixin.qq.com/cgi-bin/message/custom/send",
            params={
                'access_token': access_token
            },
            data=bytes(json.dumps(body, ensure_ascii=False), encoding='utf-8')
        )
        # 这里可根据回执code进行判定是否发送成功(也可以根据code根据错误信息)
        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": 'w7OBa8MhE6sNxgNSnooTqB93kgvMbA8JEhwN85vjUdY',
                "data": {
                    "first": {
                        "value": "杨康",
                        "color": "#173177"
                    },
                    "keyword": {
                        "value": "Python鬼才",
                        "color": "#173177"
                    },
                }
            }
        )
        result = res.json()
        return result

    result = send_template_msg()

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

这里可以直接发送消息,可以发送一个模板,

收到的模板样子是:

 

注意点:

这里需要放你自己的IP公网地址,这样子才能让微信发起回调函数的执行!

 

 GitHub地址:

https://github.com/JesiDream/webcharAccounts


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!