起因
由于我录制过一个小程序的课程,里面有消息模板的讲解。最近有几位同学反馈 官方要 取消消息模板,使用订阅消息。为了方便大家容易学 Python Flask构建微信小程序订餐系统 课程。我把订阅消息结合这个课程讲解下如何实现
实现过程
其实对于我们来讲,对接第三方无非就是接口地址换了,或者流程上做一些调整。好,废话少说我们直接来通过实战讲解如何对接 订阅消息
第一步:阅读订阅消息官方文档
对接任何东西必然要先了解这个东西是什么?流程是什么样的?官方文档地址:点击这里传送门。
主要步骤就是 申请模板、获取发送权限、后端调用api发送。其中和模板消息最大的区别 就是要获取下发权限,这是最大的区别。也就是这个权限控制在用户手中了。
第二步:申请模板
第三步:获取授权
这一步就需要有个界面明确让用户订阅消息,如果用户拒绝 就不能给用户发送消息了。需要改一下我们课程的小程序。对应API地址:点击这里传送门。
那我们来修改我们支付相关的代码。修改记录 总共需要修改三个文件
mina/pages/my/order_list.js toPay:function( e ){ var that = this; //这里增加获取用户订阅消息权限,需要将申请的模板id填写进来。这里填写你自己的 var template_ids = ["gEWJzj_7_7bBej8grUY7V3ZWLLYU2sIp2jNSO5w2Fos" ]; //默认不能发送消息,当用户明确选择了允许才可以发. var can_send = 0; var data = { order_sn: e.currentTarget.dataset.id, can_send: can_send }; wx.requestSubscribeMessage({ tmplIds: template_ids, success:function( res ){ for (var tmp_id of template_ids ){ if (res.hasOwnProperty(tmp_id) && res[tmp_id] == "accept"){ can_send = 1; } } data['can_send'] = can_send; //成功调用支付下单 that.doPay( data ); }, fail:function( res ){ //失败调用支付下单 that.doPay(data); } }); }, doPay:function( data ){ //新增加的方法 wx.request({ url: app.buildUrl("/order/pay"), header: app.getRequestHeader(), method: 'POST', data: data, success: function (res) { var resp = res.data; if (resp.code != 200) { app.alert({ "content": resp.msg }); return; } var pay_info = resp.data.pay_info; wx.requestPayment({ 'timeStamp': pay_info.timeStamp, 'nonceStr': pay_info.nonceStr, 'package': pay_info.package, 'signType': 'MD5', 'paySign': pay_info.paySign, 'success': function (res) { }, 'fail': function (res) { } }); } }); }
web/controllers/api/Order.py:orderPay 最后几行 #保存prepay_id为了后面发模板消息 ''' 如果对接了订阅消息,这个prepay_id 就没有用了 为了节省一个字段,就用这个自动存放 能不能发送吧 ''' #pay_order_info.prepay_id = pay_info['prepay_id'] pay_order_info.prepay_id = req['can_send'] if 'can_send' in req else 0 db.session.add( pay_order_info ) db.session.commit() resp['data']['pay_info'] = pay_info return jsonify(resp)
jobs/tasks/queue/index.py def handlePay(self,item ): data = json.loads( item.data ) if 'member_id' not in data or 'pay_order_id' not in data: return False oauth_bind_info = OauthMemberBind.query.filter_by(member_id=data['member_id']).first() if not oauth_bind_info: return False pay_order_info = PayOrder.query.filter_by( id = data['pay_order_id']).first() if not pay_order_info: return False #更新销售总量 pay_order_items = PayOrderItem.query.filter_by( pay_order_id = pay_order_info.id ).all() notice_content = [] if pay_order_items: date_from = datetime.datetime.now().strftime( "%Y-%m-01 00:00:00" ) date_to = datetime.datetime.now().strftime( "%Y-%m-31 23:59:59" ) for item in pay_order_items: tmp_food_info = Food.query.filter_by( id = item.food_id ).first() if not tmp_food_info: continue notice_content.append( "%s %s份"%( tmp_food_info.name,item.quantity) ) #当月数量 tmp_stat_info = db.session.query(FoodSaleChangeLog, func.sum(FoodSaleChangeLog.quantity).label("total")) \ .filter( FoodSaleChangeLog.food_id == item.food_id )\ .filter( FoodSaleChangeLog.created_time >= date_from,FoodSaleChangeLog.created_time <= date_to ).first() tmp_month_count = tmp_stat_info[ 1 ] if tmp_stat_info[ 1 ] else 0 tmp_food_info.total_count += 1 tmp_food_info.month_count = tmp_month_count db.session.add( tmp_food_info ) db.session.commit() if pay_order_info.prepay_id != "1": #当prepay_id == 1表示用户接受发订阅消息 app.logger.info("skip notice~~") return ##发订阅消息 keyword1_val = pay_order_info.order_number keyword2_val = "、".join( notice_content ) keyword3_val = "总价:" + str( pay_order_info.total_price ) if pay_order_info.express_info: express_info = json.loads( pay_order_info.express_info ) keyword3_val += "快递信息:" + str( express_info['address'] ) #发送模板消息 target_wechat = WeChatService( ) access_token = target_wechat.getAccessToken() headers = {'Content-Type': 'application/json'} url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s"%access_token params = { "touser": oauth_bind_info.openid, "template_id":"gEWJzj_7_7bBej8grUY7V3ZWLLYU2sIp2jNSO5w2Fos", "page": "pages/my/order_list", "data": { "number1": { "value": keyword1_val }, "thing2": { "value": keyword2_val }, "thing3": { "value": keyword3_val } } } r = requests.post(url=url, data= json.dumps( params ).encode('utf-8'), headers=headers) r.encoding = "utf-8" app.logger.info(r.text) return True
效果截图
源代码提供
课程官方已经上传对应的源码补丁包:点击这里传送门