借道公众号实现新订单推送

使用场景

小程序里,只能是用户发起form请求,才能被动收到1次或3次通知,比如支付,发货的通知,因此有客户下单,作为管理员收不到消息推送的,必须要时不时地看一下web后台订单管理很不方便,于是借道服务号的模板消息,向指定用户(即管理员)推送来单了的消息。本文的初衷就是为了解决这个无奈的。

解题思路

1.在小程序后台生成一个二维码,带着appid的参数,生成链接地址,例如https://mp.it577.net/bind?appid=wx15***pq 2.扫一扫拿到上述的参数进入服务号体系,取得操作人即web后台管理员的openid 3.将openid与appid相关联 4.小程序中有用户在就向公众号暴露的发起推送指令,例如https://mp.it577.net/message/push?appid=wx15***pq 5.公众号接收到指令向管理员的openid推送订单模板信息

步骤

一、创建了数据库,使用express-generator脚手架生成应用

1.服务号api体系 1.1 bind (appid),其中appid由二维码参数得到,其中openid进入服务号时自然获得 1.2 pushMessage (appid,templateid,data) 2.小程序api体系 1.1 payment回调成功,即用户付款成功之后,向服务号api调用pushMessage接口

小程序web后台代码

1.创建二维码

这里使用一个第三方module,qr-image

详情用法如下

var {bindUrl} = require('../utils/config');
    var qr = require('qr-image');
    try {
        var img = qr.image(bindUrl, {size :5});
        res.writeHead(200, {'Content-Type': 'image/png'});
        img.pipe(res);
    } catch (e) {
        res.writeHead(414, {'Content-Type': 'text/html'});
        res.end('<h1>414 Request-URI Too Large</h1>');
    }

服务号代码

1.公众号管理后台绑定可信域名

2.请求服务号网页授权登录接口

文档地址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

3.代码描述

router.get('/auth', function(req, res) {
    var REDIRECT_URI = encodeURI(req.protocol + '://' + req.headers.host + req.originalUrl.replace(req.url, '') + '/code');
    console.log(REDIRECT_URI);
    var obj = {
        appid: mp.APPID,
        redirect_uri: REDIRECT_URI,
        response_type: 'code',
        scope: 'snsapi_userinfo',
        state: req.query.appid
    };
    var param = querystring.stringify(obj);
    var url = `https://open.weixin.qq.com/connect/oauth2/authorize?${param}`;
    console.log(url);
    res.redirect(url);
});

router.get('/code', function(req, res) {
    console.log("req.query");
    console.log(req.query.code);
    var obj = {
        appid: mp.APPID,
        secret: mp.SECRET,
        code: req.query.code,
        grant_type: 'authorization_code'
    };
    var appid = req.query.state;
    var param = querystring.stringify(obj);
    var url = `https://api.weixin.qq.com/sns/oauth2/access_token?${param}`;
    request(url, function(error, response, body) {
        console.log('error:', error); // Print the error if one occurred
        console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
        console.log('body:', body); // Print the HTML for the Google homepage.
        if (!body.errcode) {
            var data = JSON.parse(body);
            console.log(data);
            data = _.extend(data, {appid: appid});
            // 获取粉丝信息
            var infoUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${data.access_token}&openid=${data.openid}&lang=zh_CN`;
            request(infoUrl, function (error, response, body) {
            	console.log(infoUrl)
            	console.log(body)
            	data = _.extend(data, JSON.parse(body));
	            // 判断是否已经存在
	            Customer.findOneAndUpdate(_.pick(data, 'openid appid'), data, {upsert: true}, (err, result) => {
	            	if (err) {
	            		console.log(err);
	            	}
	        		res.render('success');
	            });
            });
        }
    });
});

以上代码共完成了3部分操作:1.请求code,2.取出用户openId,3.绑定openId与小程序appid

3.小程序有用户下单支付向服务器请求推送模块消息

首先,创建服务号的模板消息,注意,这里并不是小程序的模板消息。

依然获得了data格式如下

{{first.DATA}}

订单编号:{{keyword1.DATA}}

客户昵称:{{keyword2.DATA}}

订单价格:{{keyword3.DATA}}

订单标题:{{keyword4.DATA}}

订单截止时间:{{keyword5.DATA}}

{{remark.DATA}}

接下来,在服务号创建被暴露一个message/push接口,供用户支付成功被调用

// 推送消息
router.post('/push', function(req, res) {
    // 使用querystring来格式化query字符串
    var url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${mp.APPID}&secret=${mp.SECRET}`;
    console.log(url);
    request(url, function(error, response, body) {
        var access_token = JSON.parse(body).access_token;
        // 请求模板消息接口
        var messageUrl = `https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=${access_token}`;

        // 通过appid反查openid
        Customer.findOne({
            appid: req.body.appid
        }, (err, customer) => {
            if (err) {
                console.log(err);
            }
            // 用户id
            var openid = customer.openid;
            //
            var data = {
                "touser": openid,
                "template_id": "8_Vlmaf3EpW4fu-u94yTwHUurQWsymvdBxM-lsHZBTM",
                "url": req.body.url,
                "data": {
                    "first": {
                        "value": "来新订单了",
                        "color": "#173177"
                    },
                    "keyword1": {
                        "value": req.body.title,
                        "color": "#173177"
                    },
                    "keyword2": {
                        "value": moment.full(req.body.createdAt),
                        "color": "#173177"
                    },
                    "keyword3": {
                        "value": req.body.address,
                        "color": "#173177"
                    },
                    "keyword4": {
                        "value": req.body.nickname,
                        "color": "#173177"
                    },
                    "keyword5": {
                        "value": "已支付",
                        "color": "#173177"
                    },
                    "remark": {
                        "value": "请登录后台查看",
                        "color": "#173177"
                    }
                }
            };
            request({
                    url: messageUrl,
                    method: "POST",
                    json: true,
                    body: data
                },
                function(error, response, body) {
                    console.log('error:', error); // Print the error if one occurred
                    console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
                    console.log('body:', body); // Print the HTML for the Google homepage.
                }
            );
        });
    });
    res.send('push message success');
});

顺带提一句,querystring这个第三方module很好用,将对象转成?name=huangxj&age=30这样的字符串

结尾

经过这样的操作,就完成了借道服务号完成向小程序管理员推送消息的任务。以上思路来自于Bmob的消息推送机制,还有粉丝【是我没跑】的提点。

另辟蹊径

以上是通过软方式解决,还有一种是通过市面上云打印机的硬方案,用户下单,直接给打印推单子,机子直接吐小票,更要干脆利落。

mp

转载于:https://my.oschina.net/huangxiujie/blog/1601056

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值