I'm Sham
一个在通往码农道路上走走停停的行政文员

小程序制作笔记-消息推送通知之前后台实现

前面提到了,因为Sham做的小程序是用来提交反馈给供应商,然后让供应商处理的,目的是增加反馈效率,这里如果能添加一个消息提醒就更好了,于是查找资料,进坑出坑,终于搞定了,唯一美中不足的就是,1个formid只能推送1次,而且7天有效,这个是微信设置的,没办法。

开始上代码前,先说明下,消息推送用到的formid是对应微信用户openid的,如果不存储用户的formid,直接提交表单的话,只能自己受到信息,所以需要将用户提交表单时,将formid一起存入数据库,以便供应商反馈的时候推送信息。 下面就直接上代码 。

wxml部分,需要 给form添加 report-submit=’true’ ,这样我们就可以获取到当前的formid,用于消息推送,以新建的默认程序为例

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
<!--以下是推送的form表单(你也可以直接在现有的form中添加 report-submit='true',并添加获取openid-->
  <view class="usermotto">
    <form bindsubmit="FormSubmit" bindreset="formReset" report-submit='true'>
      <input type='text' value='{{openid}}' name="openid" style="display:none;"></input>
      <input type='text' value='{{userInfo.nickName}}' name="nickname" style="display:none;"></input>
      <button formType="submit" >点我提交信息推送测试</button>
    </form>
  </view>
</view>

然后就是JS中,在提交表单的同时,添加消息推送请求:

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  },
  //事件处理函数
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse){
      // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
      // 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    } else {
      // 在没有 open-type=getUserInfo 版本的兼容处理
      wx.getUserInfo({
        success: res => {
          app.globalData.userInfo = res.userInfo
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      })
    }

    //读取openid
    var that = this;
    wx.login({  
      success: function (res) {
        console.log(res.code)
        //发送请求
        wx.request({
          url: 'https://你的网址/getopenid.php', //接口地址
          data: { code: res.code },
          header: {
            'content-type': 'application/json' //默认值
          },
          success: function (res) {
            console.log(res.data)
            that.setData({
              openid: res.data.openid,
            })
          }
        })
      }
    });

  },
  getUserInfo: function(e) {
    console.log(e)
    app.globalData.userInfo = e.detail.userInfo
    this.setData({
      userInfo: e.detail.userInfo,
      hasUserInfo: true
    })
  },

//消息推送
FormSubmit: function (e) {
  var that = this;
  var formid = e.detail.formId;//开发工具里调试的时候显示的是the formId is a mock one,要到真机才能看到formid的值
  var tarPage = "/pages/index/index";//点击消息跳转的界面
  var openid = e.detail.value.openid;
  var nickname = e.detail.value.nickname;
  console.log(e);
  wx.request({
    url: 'https://你的网址/message.php',//服务器地址
    data: {
      formid: formid,
      nickname: nickname,
      openid: openid,//要获取用户的openid才能发送,如果还不会建议看上篇;
    },
    header: {
      "Content-type": "application/json",
    },
    success: function (res) {
      console.log(res.data);
    },
    fail: function (err) {
      console.log(err);
    }
  }) 
},
})

这样,小程序端就完成了,下面就是在服务器端接送请求并返回数据(代码直接使用的是网友分享的,如有侵权,请告知我):

首先是获取当前用户的openid:

<?php
//声明CODE,获取小程序传过来的CODE
$code = $_GET["code"];
//配置appid
$appid = "你的小程序APPID";
//配置appscret
$secret = "你的小程序SECRET";
//api接口
$api = "https://api.weixin.qq.com/sns/jscode2session?appid={$appid}&secret={$secret}&js_code={$code}&grant_type=authorization_code";
//获取GET请求
function httpGet($url){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_TIMEOUT, 500);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
    curl_setopt($curl, CURLOPT_URL, $url);
    $res = curl_exec($curl);
    curl_close($curl);
    return $res;
}
//发送
$str = httpGet($api);
echo $str;
?>

然后就是接受小程序传来的请求,然后返回数据给小程序用于推送消息

<?php
temMsg();
function temMsg()
{
    $nickname = $_GET['nickname'];  //微信名
    $formid = $_GET['formid'];   
 	$fbdate =  date("Y年m月d日");
    $temid = '你的模板ID';  //这个是模板的ID
    $page = '/pages/index/index';  //这个是用户点击消息后跳转到的小程序页面
    $openid = $_GET['openid'];
    if(!$openid||!$formid)die('failed!');
    $key1 = $nickname;//发送的消息
    $key2 = $fbdate;
    $key3 = '我们已经收到您提交的反馈,将尽快处理并答复';
    $access_token = returnAssKey();
    $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token='.$access_token;
    $data = array(//这里一定要按照微信给的格式
        "touser"=>$openid,
        "template_id"=>$temid,
        "page"=>$page,
        "form_id"=>$formid,
        "data"=>array(
            "keyword1"=>array(
                "value"=>$key1,
                "color"=>"#173177"
            ),
            "keyword2"=>array(
                "value"=>$key2,
                "color"=>"#173177"
            ),
            "keyword3"=>array(
                "value"=>$key3,
                "color"=>"#173177"
            )
        ),
      "emphasis_keyword"=>"keyword1.DATA",      //需要进行加大的消息 ,如不需要,去除就行;
    );
    $res = postCurl($url,$data,'json');//将data数组转换为json数据
    if($res){
        echo json_encode(array('state'=>4,'msg'=>$res));
    }else{
        echo json_encode(array('state'=>5,'msg'=>$res));
    }
}

function returnAsskey()
{
    $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的小程序APPID&secret=你的小程序SECRET';
    $ass_key = curl_get($url);
    $a1 = $ass_key->access_token;
    return $a1;
}

function postCurl($url,$data,$type)
{
    if($type == 'json'){
        $data = json_encode($data);//对数组进行json编码
        $header= array("Content-type: application/json;charset=UTF-8","Accept: application/json","Cache-Control: no-cache", "Pragma: no-cache");
    }
    $curl = curl_init();
    curl_setopt($curl,CURLOPT_URL,$url);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
    if(!empty($data)){
        curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
    }
    curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
    $res = curl_exec($curl);
    if(curl_errno($curl)){
        echo 'Error+'.curl_error($curl);
    }
    curl_close($curl);
    return $res;
}

function curl_get($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);
    return json_decode($data);//对数据进行json解码
}
?>

这样,推送功能就完成了,但是因为小程序设计工具里无法获取formid,需要真机上运行才有效,所以需要上传小程序服务器,然后使用体验版或者正式版,赶紧去试试吧。

文章最后,说明下,因为前面提到formid是与openid对对应的,而且如果是表单推送的话,formid只能使用一次,及如果在你提交表单的时候,使用过推送功能,那么,如果当管理员处理你的反馈只有,就无法再使用该formid推送消息了。

网上有方法来避免这种事情,一种是在用户提交的时候,一次提交多个formid给服务器备用,另外一种添加一个功能,让用户另外点击别的表单来提交formid。

但是因为目前小程序formid还有个限制,就是7天内有效,所以Sham在设计小程序的时候,在用户提交反馈的时候,使用发送邮件来通知管理员有人提交反馈了,然后将该formid存入反馈数据库内,如果管理员7天内给出反馈的话,那么,用户就能收到消息推送,知道管理员已经处理,当然也能同时添加邮件推送,防止7天过期。

以上就是Sham关于小程序消息推送的记录分享,作为一个“伸手党”,知道“伸手党”的需求,所以打包上传了本文全部源码,供参考。


温馨提示: 下载地址需要 评论本文刷新本页 才能查看!
(如果评论提交较慢,请耐心等候)
赞(1) 赏杯咖啡!
未经允许不得转载:Sham@双目瞿 » 小程序制作笔记-消息推送通知之前后台实现

评论 2

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #0

    谢谢大佬

    小小菜鸟1年前 (2020-04-15)回复
  2. #0

    再来学习一下

    学习1年前 (2020-03-03)回复

如果你觉得文章好,请赏1杯速溶咖啡给Sham吧!

微信扫一扫打赏